diff --git a/build-tools-internal/version.properties b/build-tools-internal/version.properties index 3723956fae44..8071a0dba037 100644 --- a/build-tools-internal/version.properties +++ b/build-tools-internal/version.properties @@ -1,5 +1,5 @@ elasticsearch = 8.7.0 -lucene = 9.4.2 +lucene = 9.5.0-snapshot-d19c3e2e0ed bundled_jdk_vendor = openjdk bundled_jdk = 19.0.1+10@afdd2e245b014143b62ccb916125e3ce @@ -21,12 +21,12 @@ netty = 4.1.86.Final commons_lang3 = 3.9 +antlr4 = 4.11.1 # when updating this version, you need to ensure compatibility with: # - modules/ingest-attachment (transitive dependency, check the upstream POM) # - distribution/tools/plugin-cli # - x-pack/plugin/security bouncycastle=1.64 - # used by security and idp (need to be in sync due to cross-dependency in testing) opensaml = 4.0.1 diff --git a/distribution/src/config/jvm.options b/distribution/src/config/jvm.options index c999c666ade3..959f9b3450a5 100644 --- a/distribution/src/config/jvm.options +++ b/distribution/src/config/jvm.options @@ -73,3 +73,6 @@ ## GC logging -Xlog:gc*,gc+age=trace,safepoint:file=@loggc@:utctime,level,pid,tags:filecount=32,filesize=64m + +# temporarily disable the Panama-based MMapDirectory +-Dorg.apache.lucene.store.MMapDirectory.enableMemorySegments=false diff --git a/docs/Versions.asciidoc b/docs/Versions.asciidoc index b9bdf7334c07..8e5464f0b388 100644 --- a/docs/Versions.asciidoc +++ b/docs/Versions.asciidoc @@ -1,8 +1,8 @@ include::{docs-root}/shared/versions/stack/{source_branch}.asciidoc[] -:lucene_version: 9.4.2 -:lucene_version_path: 9_4_2 +:lucene_version: 9.5.0 +:lucene_version_path: 9_5_0 :jdk: 11.0.2 :jdk_major: 11 :build_type: tar diff --git a/docs/changelog/92957.yaml b/docs/changelog/92957.yaml new file mode 100644 index 000000000000..0afc61ba9ec6 --- /dev/null +++ b/docs/changelog/92957.yaml @@ -0,0 +1,5 @@ +pr: 92957 +summary: Upgrade to lucene-9.5.0-snapshot-d19c3e2e0ed +area: Search +type: upgrade +issues: [] diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 91e031a6fbec..c342d23530f7 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -759,26 +759,36 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1678,49 +1688,82 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2611,6 +2654,11 @@ + + + + + @@ -2621,6 +2669,11 @@ + + + + + @@ -2631,6 +2684,11 @@ + + + + + @@ -2641,6 +2699,11 @@ + + + + + @@ -2651,6 +2714,11 @@ + + + + + @@ -2661,6 +2729,11 @@ + + + + + @@ -2671,6 +2744,11 @@ + + + + + @@ -2681,6 +2759,11 @@ + + + + + @@ -2691,6 +2774,11 @@ + + + + + @@ -2701,6 +2789,11 @@ + + + + + @@ -2711,6 +2804,11 @@ + + + + + @@ -2721,6 +2819,11 @@ + + + + + @@ -2731,6 +2834,11 @@ + + + + + @@ -2741,6 +2849,11 @@ + + + + + @@ -2751,6 +2864,11 @@ + + + + + @@ -2761,6 +2879,11 @@ + + + + + @@ -2771,6 +2894,11 @@ + + + + + @@ -2781,6 +2909,11 @@ + + + + + @@ -2791,6 +2924,11 @@ + + + + + @@ -2801,6 +2939,11 @@ + + + + + @@ -2811,6 +2954,11 @@ + + + + + @@ -2821,6 +2969,11 @@ + + + + + @@ -2831,6 +2984,11 @@ + + + + + @@ -2841,6 +2999,11 @@ + + + + + @@ -3329,24 +3492,34 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/h3/src/test/java/org/elasticsearch/h3/ParentChildNavigationTests.java b/libs/h3/src/test/java/org/elasticsearch/h3/ParentChildNavigationTests.java index 7c0d85472b54..11d5a01b2d4e 100644 --- a/libs/h3/src/test/java/org/elasticsearch/h3/ParentChildNavigationTests.java +++ b/libs/h3/src/test/java/org/elasticsearch/h3/ParentChildNavigationTests.java @@ -21,7 +21,6 @@ package org.elasticsearch.h3; import com.carrotsearch.randomizedtesting.generators.RandomPicks; import org.apache.lucene.geo.Point; -import org.apache.lucene.spatial3d.geom.GeoArea; import org.apache.lucene.spatial3d.geom.GeoPoint; import org.apache.lucene.spatial3d.geom.GeoPolygon; import org.apache.lucene.spatial3d.geom.GeoPolygonFactory; @@ -133,23 +132,13 @@ public class ParentChildNavigationTests extends ESTestCase { public void testNoChildrenIntersecting() { String[] h3Addresses = H3.getStringRes0Cells(); String h3Address = RandomPicks.randomFrom(random(), h3Addresses); - // Once testIssue91915 is fixed, put upper limit of the loop to H3.MAX_H3_RES - for (int i = 1; i <= 10; i++) { + for (int i = 1; i <= H3.MAX_H3_RES; i++) { h3Addresses = H3.h3ToChildren(h3Address); assertIntersectingChildren(h3Address, h3Addresses); h3Address = RandomPicks.randomFrom(random(), h3Addresses); } } - public void testIssue91915() { - GeoPolygon polygon1 = getGeoPolygon("8ec82ea0650155f"); - GeoPolygon polygon2 = getGeoPolygon("8ec82ea06501447"); - // these polygons are disjoint but due to https://github.com/apache/lucene/issues/11883 - // they are reported as intersects. Once this is fixed this test will fail, we should adjust - // testNoChildrenIntersecting - assertEquals("see https://github.com/elastic/elasticsearch/issues/91915", GeoArea.OVERLAPS, polygon1.getRelationship(polygon2)); - } - private void assertIntersectingChildren(String h3Address, String[] children) { int size = H3.h3ToNotIntersectingChildrenSize(h3Address); for (int i = 0; i < size; i++) { diff --git a/libs/x-content/src/main/java/org/elasticsearch/xcontent/XContentBuilder.java b/libs/x-content/src/main/java/org/elasticsearch/xcontent/XContentBuilder.java index 32417bc86142..5208cbfb2952 100644 --- a/libs/x-content/src/main/java/org/elasticsearch/xcontent/XContentBuilder.java +++ b/libs/x-content/src/main/java/org/elasticsearch/xcontent/XContentBuilder.java @@ -435,6 +435,22 @@ public final class XContentBuilder implements Closeable, Flushable { return this; } + public XContentBuilder array(String name, byte[] values) throws IOException { + return field(name).values(values); + } + + private XContentBuilder values(byte[] values) throws IOException { + if (values == null) { + return nullValue(); + } + startArray(); + for (byte b : values) { + value(b); + } + endArray(); + return this; + } + //////////////////////////////////////////////////////////////////////////// // Double ////////////////////////////////// diff --git a/modules/lang-expression/build.gradle b/modules/lang-expression/build.gradle index 771b4f7c0186..66c9dcf6a236 100644 --- a/modules/lang-expression/build.gradle +++ b/modules/lang-expression/build.gradle @@ -17,7 +17,7 @@ esplugin { dependencies { api "org.apache.lucene:lucene-expressions:${versions.lucene}" runtimeOnly "org.apache.lucene:lucene-codecs:${versions.lucene}" - runtimeOnly 'org.antlr:antlr4-runtime:4.5.1-1' + runtimeOnly "org.antlr:antlr4-runtime:${versions.antlr4}" runtimeOnly 'org.ow2.asm:asm:7.2' runtimeOnly 'org.ow2.asm:asm-commons:7.2' runtimeOnly 'org.ow2.asm:asm-tree:7.2' diff --git a/modules/lang-painless/build.gradle b/modules/lang-painless/build.gradle index 682802534438..2dab15f7ddb4 100644 --- a/modules/lang-painless/build.gradle +++ b/modules/lang-painless/build.gradle @@ -34,7 +34,7 @@ configurations { } dependencies { - api 'org.antlr:antlr4-runtime:4.5.3' + api "org.antlr:antlr4-runtime:${versions.antlr4}" api 'org.ow2.asm:asm-util:7.2' api 'org.ow2.asm:asm-tree:7.2' api 'org.ow2.asm:asm-commons:7.2' @@ -174,7 +174,7 @@ configurations { } dependencies { - regenerate 'org.antlr:antlr4:4.5.3' + regenerate "org.antlr:antlr4:${versions.antlr4}" } String grammarPath = 'src/main/antlr' @@ -274,7 +274,7 @@ configurations { } dependencies { - regenerate 'org.antlr:antlr4:4.5.3' + regenerate "org.antlr:antlr4:${versions.antlr4}" } String suggestGrammarPath = 'src/main/antlr' diff --git a/modules/lang-painless/src/main/java/module-info.java b/modules/lang-painless/src/main/java/module-info.java index 7196d87e8402..539c2919b81f 100644 --- a/modules/lang-painless/src/main/java/module-info.java +++ b/modules/lang-painless/src/main/java/module-info.java @@ -13,7 +13,7 @@ module org.elasticsearch.painless { requires org.elasticsearch.server; requires org.elasticsearch.xcontent; - requires antlr4.runtime; + requires org.antlr.antlr4.runtime; requires org.apache.lucene.core; requires org.objectweb.asm; requires org.objectweb.asm.commons; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessLexer.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessLexer.java index 4e810af6b239..983327eac2d0 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessLexer.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessLexer.java @@ -1,17 +1,22 @@ // ANTLR GENERATED CODE: DO NOT EDIT package org.elasticsearch.painless.antlr; -import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.RuleContext; +import org.antlr.v4.runtime.RuntimeMetaData; +import org.antlr.v4.runtime.Vocabulary; +import org.antlr.v4.runtime.VocabularyImpl; +import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNDeserializer; +import org.antlr.v4.runtime.atn.LexerATNSimulator; +import org.antlr.v4.runtime.atn.PredictionContextCache; import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; -@SuppressWarnings({ "all", "warnings", "unchecked", "unused", "cast" }) +@SuppressWarnings({ "all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue" }) abstract class PainlessLexer extends Lexer { static { - RuntimeMetaData.checkVersion("4.5.3", RuntimeMetaData.VERSION); + RuntimeMetaData.checkVersion("4.11.1", RuntimeMetaData.VERSION); } protected static final DFA[] _decisionToDFA; @@ -25,269 +30,284 @@ abstract class PainlessLexer extends Lexer { 68, AOR = 69, ALSH = 70, ARSH = 71, AUSH = 72, OCTAL = 73, HEX = 74, INTEGER = 75, DECIMAL = 76, STRING = 77, REGEX = 78, TRUE = 79, FALSE = 80, NULL = 81, PRIMITIVE = 82, DEF = 83, ID = 84, DOTINTEGER = 85, DOTID = 86; public static final int AFTER_DOT = 1; + public static String[] channelNames = { "DEFAULT_TOKEN_CHANNEL", "HIDDEN" }; + public static String[] modeNames = { "DEFAULT_MODE", "AFTER_DOT" }; - public static final String[] ruleNames = { - "WS", - "COMMENT", - "LBRACK", - "RBRACK", - "LBRACE", - "RBRACE", - "LP", - "RP", - "DOLLAR", - "DOT", - "NSDOT", - "COMMA", - "SEMICOLON", - "IF", - "IN", - "ELSE", - "WHILE", - "DO", - "FOR", - "CONTINUE", - "BREAK", - "RETURN", - "NEW", - "TRY", - "CATCH", - "THROW", - "THIS", - "INSTANCEOF", - "BOOLNOT", - "BWNOT", - "MUL", - "DIV", - "REM", - "ADD", - "SUB", - "LSH", - "RSH", - "USH", - "LT", - "LTE", - "GT", - "GTE", - "EQ", - "EQR", - "NE", - "NER", - "BWAND", - "XOR", - "BWOR", - "BOOLAND", - "BOOLOR", - "COND", - "COLON", - "ELVIS", - "REF", - "ARROW", - "FIND", - "MATCH", - "INCR", - "DECR", - "ASSIGN", - "AADD", - "ASUB", - "AMUL", - "ADIV", - "AREM", - "AAND", - "AXOR", - "AOR", - "ALSH", - "ARSH", - "AUSH", - "OCTAL", - "HEX", - "INTEGER", - "DECIMAL", - "STRING", - "REGEX", - "TRUE", - "FALSE", - "NULL", - "PRIMITIVE", - "DEF", - "ID", - "DOTINTEGER", - "DOTID" }; + private static String[] makeRuleNames() { + return new String[] { + "WS", + "COMMENT", + "LBRACK", + "RBRACK", + "LBRACE", + "RBRACE", + "LP", + "RP", + "DOLLAR", + "DOT", + "NSDOT", + "COMMA", + "SEMICOLON", + "IF", + "IN", + "ELSE", + "WHILE", + "DO", + "FOR", + "CONTINUE", + "BREAK", + "RETURN", + "NEW", + "TRY", + "CATCH", + "THROW", + "THIS", + "INSTANCEOF", + "BOOLNOT", + "BWNOT", + "MUL", + "DIV", + "REM", + "ADD", + "SUB", + "LSH", + "RSH", + "USH", + "LT", + "LTE", + "GT", + "GTE", + "EQ", + "EQR", + "NE", + "NER", + "BWAND", + "XOR", + "BWOR", + "BOOLAND", + "BOOLOR", + "COND", + "COLON", + "ELVIS", + "REF", + "ARROW", + "FIND", + "MATCH", + "INCR", + "DECR", + "ASSIGN", + "AADD", + "ASUB", + "AMUL", + "ADIV", + "AREM", + "AAND", + "AXOR", + "AOR", + "ALSH", + "ARSH", + "AUSH", + "OCTAL", + "HEX", + "INTEGER", + "DECIMAL", + "STRING", + "REGEX", + "TRUE", + "FALSE", + "NULL", + "PRIMITIVE", + "DEF", + "ID", + "DOTINTEGER", + "DOTID" }; + } - private static final String[] _LITERAL_NAMES = { - null, - null, - null, - "'{'", - "'}'", - "'['", - "']'", - "'('", - "')'", - "'$'", - "'.'", - "'?.'", - "','", - "';'", - "'if'", - "'in'", - "'else'", - "'while'", - "'do'", - "'for'", - "'continue'", - "'break'", - "'return'", - "'new'", - "'try'", - "'catch'", - "'throw'", - "'this'", - "'instanceof'", - "'!'", - "'~'", - "'*'", - "'/'", - "'%'", - "'+'", - "'-'", - "'<<'", - "'>>'", - "'>>>'", - "'<'", - "'<='", - "'>'", - "'>='", - "'=='", - "'==='", - "'!='", - "'!=='", - "'&'", - "'^'", - "'|'", - "'&&'", - "'||'", - "'?'", - "':'", - "'?:'", - "'::'", - "'->'", - "'=~'", - "'==~'", - "'++'", - "'--'", - "'='", - "'+='", - "'-='", - "'*='", - "'/='", - "'%='", - "'&='", - "'^='", - "'|='", - "'<<='", - "'>>='", - "'>>>='", - null, - null, - null, - null, - null, - null, - "'true'", - "'false'", - "'null'", - null, - "'def'" }; - private static final String[] _SYMBOLIC_NAMES = { - null, - "WS", - "COMMENT", - "LBRACK", - "RBRACK", - "LBRACE", - "RBRACE", - "LP", - "RP", - "DOLLAR", - "DOT", - "NSDOT", - "COMMA", - "SEMICOLON", - "IF", - "IN", - "ELSE", - "WHILE", - "DO", - "FOR", - "CONTINUE", - "BREAK", - "RETURN", - "NEW", - "TRY", - "CATCH", - "THROW", - "THIS", - "INSTANCEOF", - "BOOLNOT", - "BWNOT", - "MUL", - "DIV", - "REM", - "ADD", - "SUB", - "LSH", - "RSH", - "USH", - "LT", - "LTE", - "GT", - "GTE", - "EQ", - "EQR", - "NE", - "NER", - "BWAND", - "XOR", - "BWOR", - "BOOLAND", - "BOOLOR", - "COND", - "COLON", - "ELVIS", - "REF", - "ARROW", - "FIND", - "MATCH", - "INCR", - "DECR", - "ASSIGN", - "AADD", - "ASUB", - "AMUL", - "ADIV", - "AREM", - "AAND", - "AXOR", - "AOR", - "ALSH", - "ARSH", - "AUSH", - "OCTAL", - "HEX", - "INTEGER", - "DECIMAL", - "STRING", - "REGEX", - "TRUE", - "FALSE", - "NULL", - "PRIMITIVE", - "DEF", - "ID", - "DOTINTEGER", - "DOTID" }; + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, + null, + null, + "'{'", + "'}'", + "'['", + "']'", + "'('", + "')'", + "'$'", + "'.'", + "'?.'", + "','", + "';'", + "'if'", + "'in'", + "'else'", + "'while'", + "'do'", + "'for'", + "'continue'", + "'break'", + "'return'", + "'new'", + "'try'", + "'catch'", + "'throw'", + "'this'", + "'instanceof'", + "'!'", + "'~'", + "'*'", + "'/'", + "'%'", + "'+'", + "'-'", + "'<<'", + "'>>'", + "'>>>'", + "'<'", + "'<='", + "'>'", + "'>='", + "'=='", + "'==='", + "'!='", + "'!=='", + "'&'", + "'^'", + "'|'", + "'&&'", + "'||'", + "'?'", + "':'", + "'?:'", + "'::'", + "'->'", + "'=~'", + "'==~'", + "'++'", + "'--'", + "'='", + "'+='", + "'-='", + "'*='", + "'/='", + "'%='", + "'&='", + "'^='", + "'|='", + "'<<='", + "'>>='", + "'>>>='", + null, + null, + null, + null, + null, + null, + "'true'", + "'false'", + "'null'", + null, + "'def'" }; + } + + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + + private static String[] makeSymbolicNames() { + return new String[] { + null, + "WS", + "COMMENT", + "LBRACK", + "RBRACK", + "LBRACE", + "RBRACE", + "LP", + "RP", + "DOLLAR", + "DOT", + "NSDOT", + "COMMA", + "SEMICOLON", + "IF", + "IN", + "ELSE", + "WHILE", + "DO", + "FOR", + "CONTINUE", + "BREAK", + "RETURN", + "NEW", + "TRY", + "CATCH", + "THROW", + "THIS", + "INSTANCEOF", + "BOOLNOT", + "BWNOT", + "MUL", + "DIV", + "REM", + "ADD", + "SUB", + "LSH", + "RSH", + "USH", + "LT", + "LTE", + "GT", + "GTE", + "EQ", + "EQR", + "NE", + "NER", + "BWAND", + "XOR", + "BWOR", + "BOOLAND", + "BOOLOR", + "COND", + "COLON", + "ELVIS", + "REF", + "ARROW", + "FIND", + "MATCH", + "INCR", + "DECR", + "ASSIGN", + "AADD", + "ASUB", + "AMUL", + "ADIV", + "AREM", + "AAND", + "AXOR", + "AOR", + "ALSH", + "ARSH", + "AUSH", + "OCTAL", + "HEX", + "INTEGER", + "DECIMAL", + "STRING", + "REGEX", + "TRUE", + "FALSE", + "NULL", + "PRIMITIVE", + "DEF", + "ID", + "DOTINTEGER", + "DOTID" }; + } + + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); /** @@ -344,6 +364,11 @@ abstract class PainlessLexer extends Lexer { return _serializedATN; } + @Override + public String[] getChannelNames() { + return channelNames; + } + @Override public String[] getModeNames() { return modeNames; @@ -381,229 +406,408 @@ abstract class PainlessLexer extends Lexer { return true; } - public static final String _serializedATN = "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2X\u027e\b\1\b\1\4" - + "\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n" - + "\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22" - + "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31" - + "\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t" - + " \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t" - + "+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64" - + "\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t" - + "=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4" - + "I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\t" - + "T\4U\tU\4V\tV\4W\tW\3\2\6\2\u00b2\n\2\r\2\16\2\u00b3\3\2\3\2\3\3\3\3\3" - + "\3\3\3\7\3\u00bc\n\3\f\3\16\3\u00bf\13\3\3\3\3\3\3\3\3\3\3\3\7\3\u00c6" - + "\n\3\f\3\16\3\u00c9\13\3\3\3\3\3\5\3\u00cd\n\3\3\3\3\3\3\4\3\4\3\5\3\5" - + "\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\3\13\3\13\3\f\3\f\3" - + "\f\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\17\3\20\3\20\3\20\3\21\3\21\3" - + "\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\24\3\24\3" - + "\24\3\24\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3" - + "\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3" - + "\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3" - + "\33\3\33\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3" - + "\35\3\35\3\35\3\35\3\36\3\36\3\37\3\37\3 \3 \3!\3!\3!\3\"\3\"\3#\3#\3" - + "$\3$\3%\3%\3%\3&\3&\3&\3\'\3\'\3\'\3\'\3(\3(\3)\3)\3)\3*\3*\3+\3+\3+\3" - + ",\3,\3,\3-\3-\3-\3-\3.\3.\3.\3/\3/\3/\3/\3\60\3\60\3\61\3\61\3\62\3\62" - + "\3\63\3\63\3\63\3\64\3\64\3\64\3\65\3\65\3\66\3\66\3\67\3\67\3\67\38\3" - + "8\38\39\39\39\3:\3:\3:\3;\3;\3;\3;\3<\3<\3<\3=\3=\3=\3>\3>\3?\3?\3?\3" - + "@\3@\3@\3A\3A\3A\3B\3B\3B\3C\3C\3C\3D\3D\3D\3E\3E\3E\3F\3F\3F\3G\3G\3" - + "G\3G\3H\3H\3H\3H\3I\3I\3I\3I\3I\3J\3J\6J\u01be\nJ\rJ\16J\u01bf\3J\5J\u01c3" - + "\nJ\3K\3K\3K\6K\u01c8\nK\rK\16K\u01c9\3K\5K\u01cd\nK\3L\3L\3L\7L\u01d2" - + "\nL\fL\16L\u01d5\13L\5L\u01d7\nL\3L\5L\u01da\nL\3M\3M\3M\7M\u01df\nM\f" - + "M\16M\u01e2\13M\5M\u01e4\nM\3M\3M\6M\u01e8\nM\rM\16M\u01e9\5M\u01ec\n" - + "M\3M\3M\5M\u01f0\nM\3M\6M\u01f3\nM\rM\16M\u01f4\5M\u01f7\nM\3M\5M\u01fa" - + "\nM\3N\3N\3N\3N\3N\3N\7N\u0202\nN\fN\16N\u0205\13N\3N\3N\3N\3N\3N\3N\3" - + "N\7N\u020e\nN\fN\16N\u0211\13N\3N\5N\u0214\nN\3O\3O\3O\3O\6O\u021a\nO" - + "\rO\16O\u021b\3O\3O\7O\u0220\nO\fO\16O\u0223\13O\3O\3O\3P\3P\3P\3P\3P" - + "\3Q\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S" - + "\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S" - + "\3S\3S\3S\5S\u025d\nS\3T\3T\3T\3T\3U\3U\7U\u0265\nU\fU\16U\u0268\13U\3" - + "V\3V\3V\7V\u026d\nV\fV\16V\u0270\13V\5V\u0272\nV\3V\3V\3W\3W\7W\u0278" - + "\nW\fW\16W\u027b\13W\3W\3W\7\u00bd\u00c7\u0203\u020f\u021b\2X\4\3\6\4" - + "\b\5\n\6\f\7\16\b\20\t\22\n\24\13\26\f\30\r\32\16\34\17\36\20 \21\"\22" - + "$\23&\24(\25*\26,\27.\30\60\31\62\32\64\33\66\348\35:\36<\37> @!B\"D#" - + "F$H%J&L\'N(P)R*T+V,X-Z.\\/^\60`\61b\62d\63f\64h\65j\66l\67n8p9r:t;v|?~@\u0080A\u0082B\u0084C\u0086D\u0088E\u008aF\u008cG\u008eH\u0090" - + "I\u0092J\u0094K\u0096L\u0098M\u009aN\u009cO\u009eP\u00a0Q\u00a2R\u00a4" - + "S\u00a6T\u00a8U\u00aaV\u00acW\u00aeX\4\2\3\25\5\2\13\f\17\17\"\"\4\2\f" - + "\f\17\17\3\2\629\4\2NNnn\4\2ZZzz\5\2\62;CHch\3\2\63;\3\2\62;\b\2FFHHN" - + "Nffhhnn\4\2GGgg\4\2--//\6\2FFHHffhh\4\2$$^^\4\2))^^\3\2\f\f\4\2\f\f\61" - + "\61\t\2WWeekknouuwwzz\5\2C\\aac|\6\2\62;C\\aac|\u02a4\2\4\3\2\2\2\2\6" - + "\3\2\2\2\2\b\3\2\2\2\2\n\3\2\2\2\2\f\3\2\2\2\2\16\3\2\2\2\2\20\3\2\2\2" - + "\2\22\3\2\2\2\2\24\3\2\2\2\2\26\3\2\2\2\2\30\3\2\2\2\2\32\3\2\2\2\2\34" - + "\3\2\2\2\2\36\3\2\2\2\2 \3\2\2\2\2\"\3\2\2\2\2$\3\2\2\2\2&\3\2\2\2\2(" - + "\3\2\2\2\2*\3\2\2\2\2,\3\2\2\2\2.\3\2\2\2\2\60\3\2\2\2\2\62\3\2\2\2\2" - + "\64\3\2\2\2\2\66\3\2\2\2\28\3\2\2\2\2:\3\2\2\2\2<\3\2\2\2\2>\3\2\2\2\2" - + "@\3\2\2\2\2B\3\2\2\2\2D\3\2\2\2\2F\3\2\2\2\2H\3\2\2\2\2J\3\2\2\2\2L\3" - + "\2\2\2\2N\3\2\2\2\2P\3\2\2\2\2R\3\2\2\2\2T\3\2\2\2\2V\3\2\2\2\2X\3\2\2" - + "\2\2Z\3\2\2\2\2\\\3\2\2\2\2^\3\2\2\2\2`\3\2\2\2\2b\3\2\2\2\2d\3\2\2\2" - + "\2f\3\2\2\2\2h\3\2\2\2\2j\3\2\2\2\2l\3\2\2\2\2n\3\2\2\2\2p\3\2\2\2\2r" - + "\3\2\2\2\2t\3\2\2\2\2v\3\2\2\2\2x\3\2\2\2\2z\3\2\2\2\2|\3\2\2\2\2~\3\2" - + "\2\2\2\u0080\3\2\2\2\2\u0082\3\2\2\2\2\u0084\3\2\2\2\2\u0086\3\2\2\2\2" - + "\u0088\3\2\2\2\2\u008a\3\2\2\2\2\u008c\3\2\2\2\2\u008e\3\2\2\2\2\u0090" - + "\3\2\2\2\2\u0092\3\2\2\2\2\u0094\3\2\2\2\2\u0096\3\2\2\2\2\u0098\3\2\2" - + "\2\2\u009a\3\2\2\2\2\u009c\3\2\2\2\2\u009e\3\2\2\2\2\u00a0\3\2\2\2\2\u00a2" - + "\3\2\2\2\2\u00a4\3\2\2\2\2\u00a6\3\2\2\2\2\u00a8\3\2\2\2\2\u00aa\3\2\2" - + "\2\3\u00ac\3\2\2\2\3\u00ae\3\2\2\2\4\u00b1\3\2\2\2\6\u00cc\3\2\2\2\b\u00d0" - + "\3\2\2\2\n\u00d2\3\2\2\2\f\u00d4\3\2\2\2\16\u00d6\3\2\2\2\20\u00d8\3\2" - + "\2\2\22\u00da\3\2\2\2\24\u00dc\3\2\2\2\26\u00de\3\2\2\2\30\u00e2\3\2\2" - + "\2\32\u00e7\3\2\2\2\34\u00e9\3\2\2\2\36\u00eb\3\2\2\2 \u00ee\3\2\2\2\"" - + "\u00f1\3\2\2\2$\u00f6\3\2\2\2&\u00fc\3\2\2\2(\u00ff\3\2\2\2*\u0103\3\2" - + "\2\2,\u010c\3\2\2\2.\u0112\3\2\2\2\60\u0119\3\2\2\2\62\u011d\3\2\2\2\64" - + "\u0121\3\2\2\2\66\u0127\3\2\2\28\u012d\3\2\2\2:\u0132\3\2\2\2<\u013d\3" - + "\2\2\2>\u013f\3\2\2\2@\u0141\3\2\2\2B\u0143\3\2\2\2D\u0146\3\2\2\2F\u0148" - + "\3\2\2\2H\u014a\3\2\2\2J\u014c\3\2\2\2L\u014f\3\2\2\2N\u0152\3\2\2\2P" - + "\u0156\3\2\2\2R\u0158\3\2\2\2T\u015b\3\2\2\2V\u015d\3\2\2\2X\u0160\3\2" - + "\2\2Z\u0163\3\2\2\2\\\u0167\3\2\2\2^\u016a\3\2\2\2`\u016e\3\2\2\2b\u0170" - + "\3\2\2\2d\u0172\3\2\2\2f\u0174\3\2\2\2h\u0177\3\2\2\2j\u017a\3\2\2\2l" - + "\u017c\3\2\2\2n\u017e\3\2\2\2p\u0181\3\2\2\2r\u0184\3\2\2\2t\u0187\3\2" - + "\2\2v\u018a\3\2\2\2x\u018e\3\2\2\2z\u0191\3\2\2\2|\u0194\3\2\2\2~\u0196" - + "\3\2\2\2\u0080\u0199\3\2\2\2\u0082\u019c\3\2\2\2\u0084\u019f\3\2\2\2\u0086" - + "\u01a2\3\2\2\2\u0088\u01a5\3\2\2\2\u008a\u01a8\3\2\2\2\u008c\u01ab\3\2" - + "\2\2\u008e\u01ae\3\2\2\2\u0090\u01b2\3\2\2\2\u0092\u01b6\3\2\2\2\u0094" - + "\u01bb\3\2\2\2\u0096\u01c4\3\2\2\2\u0098\u01d6\3\2\2\2\u009a\u01e3\3\2" - + "\2\2\u009c\u0213\3\2\2\2\u009e\u0215\3\2\2\2\u00a0\u0226\3\2\2\2\u00a2" - + "\u022b\3\2\2\2\u00a4\u0231\3\2\2\2\u00a6\u025c\3\2\2\2\u00a8\u025e\3\2" - + "\2\2\u00aa\u0262\3\2\2\2\u00ac\u0271\3\2\2\2\u00ae\u0275\3\2\2\2\u00b0" - + "\u00b2\t\2\2\2\u00b1\u00b0\3\2\2\2\u00b2\u00b3\3\2\2\2\u00b3\u00b1\3\2" - + "\2\2\u00b3\u00b4\3\2\2\2\u00b4\u00b5\3\2\2\2\u00b5\u00b6\b\2\2\2\u00b6" - + "\5\3\2\2\2\u00b7\u00b8\7\61\2\2\u00b8\u00b9\7\61\2\2\u00b9\u00bd\3\2\2" - + "\2\u00ba\u00bc\13\2\2\2\u00bb\u00ba\3\2\2\2\u00bc\u00bf\3\2\2\2\u00bd" - + "\u00be\3\2\2\2\u00bd\u00bb\3\2\2\2\u00be\u00c0\3\2\2\2\u00bf\u00bd\3\2" - + "\2\2\u00c0\u00cd\t\3\2\2\u00c1\u00c2\7\61\2\2\u00c2\u00c3\7,\2\2\u00c3" - + "\u00c7\3\2\2\2\u00c4\u00c6\13\2\2\2\u00c5\u00c4\3\2\2\2\u00c6\u00c9\3" - + "\2\2\2\u00c7\u00c8\3\2\2\2\u00c7\u00c5\3\2\2\2\u00c8\u00ca\3\2\2\2\u00c9" - + "\u00c7\3\2\2\2\u00ca\u00cb\7,\2\2\u00cb\u00cd\7\61\2\2\u00cc\u00b7\3\2" - + "\2\2\u00cc\u00c1\3\2\2\2\u00cd\u00ce\3\2\2\2\u00ce\u00cf\b\3\2\2\u00cf" - + "\7\3\2\2\2\u00d0\u00d1\7}\2\2\u00d1\t\3\2\2\2\u00d2\u00d3\7\177\2\2\u00d3" - + "\13\3\2\2\2\u00d4\u00d5\7]\2\2\u00d5\r\3\2\2\2\u00d6\u00d7\7_\2\2\u00d7" - + "\17\3\2\2\2\u00d8\u00d9\7*\2\2\u00d9\21\3\2\2\2\u00da\u00db\7+\2\2\u00db" - + "\23\3\2\2\2\u00dc\u00dd\7&\2\2\u00dd\25\3\2\2\2\u00de\u00df\7\60\2\2\u00df" - + "\u00e0\3\2\2\2\u00e0\u00e1\b\13\3\2\u00e1\27\3\2\2\2\u00e2\u00e3\7A\2" - + "\2\u00e3\u00e4\7\60\2\2\u00e4\u00e5\3\2\2\2\u00e5\u00e6\b\f\3\2\u00e6" - + "\31\3\2\2\2\u00e7\u00e8\7.\2\2\u00e8\33\3\2\2\2\u00e9\u00ea\7=\2\2\u00ea" - + "\35\3\2\2\2\u00eb\u00ec\7k\2\2\u00ec\u00ed\7h\2\2\u00ed\37\3\2\2\2\u00ee" - + "\u00ef\7k\2\2\u00ef\u00f0\7p\2\2\u00f0!\3\2\2\2\u00f1\u00f2\7g\2\2\u00f2" - + "\u00f3\7n\2\2\u00f3\u00f4\7u\2\2\u00f4\u00f5\7g\2\2\u00f5#\3\2\2\2\u00f6" - + "\u00f7\7y\2\2\u00f7\u00f8\7j\2\2\u00f8\u00f9\7k\2\2\u00f9\u00fa\7n\2\2" - + "\u00fa\u00fb\7g\2\2\u00fb%\3\2\2\2\u00fc\u00fd\7f\2\2\u00fd\u00fe\7q\2" - + "\2\u00fe\'\3\2\2\2\u00ff\u0100\7h\2\2\u0100\u0101\7q\2\2\u0101\u0102\7" - + "t\2\2\u0102)\3\2\2\2\u0103\u0104\7e\2\2\u0104\u0105\7q\2\2\u0105\u0106" - + "\7p\2\2\u0106\u0107\7v\2\2\u0107\u0108\7k\2\2\u0108\u0109\7p\2\2\u0109" - + "\u010a\7w\2\2\u010a\u010b\7g\2\2\u010b+\3\2\2\2\u010c\u010d\7d\2\2\u010d" - + "\u010e\7t\2\2\u010e\u010f\7g\2\2\u010f\u0110\7c\2\2\u0110\u0111\7m\2\2" - + "\u0111-\3\2\2\2\u0112\u0113\7t\2\2\u0113\u0114\7g\2\2\u0114\u0115\7v\2" - + "\2\u0115\u0116\7w\2\2\u0116\u0117\7t\2\2\u0117\u0118\7p\2\2\u0118/\3\2" - + "\2\2\u0119\u011a\7p\2\2\u011a\u011b\7g\2\2\u011b\u011c\7y\2\2\u011c\61" - + "\3\2\2\2\u011d\u011e\7v\2\2\u011e\u011f\7t\2\2\u011f\u0120\7{\2\2\u0120" - + "\63\3\2\2\2\u0121\u0122\7e\2\2\u0122\u0123\7c\2\2\u0123\u0124\7v\2\2\u0124" - + "\u0125\7e\2\2\u0125\u0126\7j\2\2\u0126\65\3\2\2\2\u0127\u0128\7v\2\2\u0128" - + "\u0129\7j\2\2\u0129\u012a\7t\2\2\u012a\u012b\7q\2\2\u012b\u012c\7y\2\2" - + "\u012c\67\3\2\2\2\u012d\u012e\7v\2\2\u012e\u012f\7j\2\2\u012f\u0130\7" - + "k\2\2\u0130\u0131\7u\2\2\u01319\3\2\2\2\u0132\u0133\7k\2\2\u0133\u0134" - + "\7p\2\2\u0134\u0135\7u\2\2\u0135\u0136\7v\2\2\u0136\u0137\7c\2\2\u0137" - + "\u0138\7p\2\2\u0138\u0139\7e\2\2\u0139\u013a\7g\2\2\u013a\u013b\7q\2\2" - + "\u013b\u013c\7h\2\2\u013c;\3\2\2\2\u013d\u013e\7#\2\2\u013e=\3\2\2\2\u013f" - + "\u0140\7\u0080\2\2\u0140?\3\2\2\2\u0141\u0142\7,\2\2\u0142A\3\2\2\2\u0143" - + "\u0144\7\61\2\2\u0144\u0145\6!\2\2\u0145C\3\2\2\2\u0146\u0147\7\'\2\2" - + "\u0147E\3\2\2\2\u0148\u0149\7-\2\2\u0149G\3\2\2\2\u014a\u014b\7/\2\2\u014b" - + "I\3\2\2\2\u014c\u014d\7>\2\2\u014d\u014e\7>\2\2\u014eK\3\2\2\2\u014f\u0150" - + "\7@\2\2\u0150\u0151\7@\2\2\u0151M\3\2\2\2\u0152\u0153\7@\2\2\u0153\u0154" - + "\7@\2\2\u0154\u0155\7@\2\2\u0155O\3\2\2\2\u0156\u0157\7>\2\2\u0157Q\3" - + "\2\2\2\u0158\u0159\7>\2\2\u0159\u015a\7?\2\2\u015aS\3\2\2\2\u015b\u015c" - + "\7@\2\2\u015cU\3\2\2\2\u015d\u015e\7@\2\2\u015e\u015f\7?\2\2\u015fW\3" - + "\2\2\2\u0160\u0161\7?\2\2\u0161\u0162\7?\2\2\u0162Y\3\2\2\2\u0163\u0164" - + "\7?\2\2\u0164\u0165\7?\2\2\u0165\u0166\7?\2\2\u0166[\3\2\2\2\u0167\u0168" - + "\7#\2\2\u0168\u0169\7?\2\2\u0169]\3\2\2\2\u016a\u016b\7#\2\2\u016b\u016c" - + "\7?\2\2\u016c\u016d\7?\2\2\u016d_\3\2\2\2\u016e\u016f\7(\2\2\u016fa\3" - + "\2\2\2\u0170\u0171\7`\2\2\u0171c\3\2\2\2\u0172\u0173\7~\2\2\u0173e\3\2" - + "\2\2\u0174\u0175\7(\2\2\u0175\u0176\7(\2\2\u0176g\3\2\2\2\u0177\u0178" - + "\7~\2\2\u0178\u0179\7~\2\2\u0179i\3\2\2\2\u017a\u017b\7A\2\2\u017bk\3" - + "\2\2\2\u017c\u017d\7<\2\2\u017dm\3\2\2\2\u017e\u017f\7A\2\2\u017f\u0180" - + "\7<\2\2\u0180o\3\2\2\2\u0181\u0182\7<\2\2\u0182\u0183\7<\2\2\u0183q\3" - + "\2\2\2\u0184\u0185\7/\2\2\u0185\u0186\7@\2\2\u0186s\3\2\2\2\u0187\u0188" - + "\7?\2\2\u0188\u0189\7\u0080\2\2\u0189u\3\2\2\2\u018a\u018b\7?\2\2\u018b" - + "\u018c\7?\2\2\u018c\u018d\7\u0080\2\2\u018dw\3\2\2\2\u018e\u018f\7-\2" - + "\2\u018f\u0190\7-\2\2\u0190y\3\2\2\2\u0191\u0192\7/\2\2\u0192\u0193\7" - + "/\2\2\u0193{\3\2\2\2\u0194\u0195\7?\2\2\u0195}\3\2\2\2\u0196\u0197\7-" - + "\2\2\u0197\u0198\7?\2\2\u0198\177\3\2\2\2\u0199\u019a\7/\2\2\u019a\u019b" - + "\7?\2\2\u019b\u0081\3\2\2\2\u019c\u019d\7,\2\2\u019d\u019e\7?\2\2\u019e" - + "\u0083\3\2\2\2\u019f\u01a0\7\61\2\2\u01a0\u01a1\7?\2\2\u01a1\u0085\3\2" - + "\2\2\u01a2\u01a3\7\'\2\2\u01a3\u01a4\7?\2\2\u01a4\u0087\3\2\2\2\u01a5" - + "\u01a6\7(\2\2\u01a6\u01a7\7?\2\2\u01a7\u0089\3\2\2\2\u01a8\u01a9\7`\2" - + "\2\u01a9\u01aa\7?\2\2\u01aa\u008b\3\2\2\2\u01ab\u01ac\7~\2\2\u01ac\u01ad" - + "\7?\2\2\u01ad\u008d\3\2\2\2\u01ae\u01af\7>\2\2\u01af\u01b0\7>\2\2\u01b0" - + "\u01b1\7?\2\2\u01b1\u008f\3\2\2\2\u01b2\u01b3\7@\2\2\u01b3\u01b4\7@\2" - + "\2\u01b4\u01b5\7?\2\2\u01b5\u0091\3\2\2\2\u01b6\u01b7\7@\2\2\u01b7\u01b8" - + "\7@\2\2\u01b8\u01b9\7@\2\2\u01b9\u01ba\7?\2\2\u01ba\u0093\3\2\2\2\u01bb" - + "\u01bd\7\62\2\2\u01bc\u01be\t\4\2\2\u01bd\u01bc\3\2\2\2\u01be\u01bf\3" - + "\2\2\2\u01bf\u01bd\3\2\2\2\u01bf\u01c0\3\2\2\2\u01c0\u01c2\3\2\2\2\u01c1" - + "\u01c3\t\5\2\2\u01c2\u01c1\3\2\2\2\u01c2\u01c3\3\2\2\2\u01c3\u0095\3\2" - + "\2\2\u01c4\u01c5\7\62\2\2\u01c5\u01c7\t\6\2\2\u01c6\u01c8\t\7\2\2\u01c7" - + "\u01c6\3\2\2\2\u01c8\u01c9\3\2\2\2\u01c9\u01c7\3\2\2\2\u01c9\u01ca\3\2" - + "\2\2\u01ca\u01cc\3\2\2\2\u01cb\u01cd\t\5\2\2\u01cc\u01cb\3\2\2\2\u01cc" - + "\u01cd\3\2\2\2\u01cd\u0097\3\2\2\2\u01ce\u01d7\7\62\2\2\u01cf\u01d3\t" - + "\b\2\2\u01d0\u01d2\t\t\2\2\u01d1\u01d0\3\2\2\2\u01d2\u01d5\3\2\2\2\u01d3" - + "\u01d1\3\2\2\2\u01d3\u01d4\3\2\2\2\u01d4\u01d7\3\2\2\2\u01d5\u01d3\3\2" - + "\2\2\u01d6\u01ce\3\2\2\2\u01d6\u01cf\3\2\2\2\u01d7\u01d9\3\2\2\2\u01d8" - + "\u01da\t\n\2\2\u01d9\u01d8\3\2\2\2\u01d9\u01da\3\2\2\2\u01da\u0099\3\2" - + "\2\2\u01db\u01e4\7\62\2\2\u01dc\u01e0\t\b\2\2\u01dd\u01df\t\t\2\2\u01de" - + "\u01dd\3\2\2\2\u01df\u01e2\3\2\2\2\u01e0\u01de\3\2\2\2\u01e0\u01e1\3\2" - + "\2\2\u01e1\u01e4\3\2\2\2\u01e2\u01e0\3\2\2\2\u01e3\u01db\3\2\2\2\u01e3" - + "\u01dc\3\2\2\2\u01e4\u01eb\3\2\2\2\u01e5\u01e7\5\26\13\2\u01e6\u01e8\t" - + "\t\2\2\u01e7\u01e6\3\2\2\2\u01e8\u01e9\3\2\2\2\u01e9\u01e7\3\2\2\2\u01e9" - + "\u01ea\3\2\2\2\u01ea\u01ec\3\2\2\2\u01eb\u01e5\3\2\2\2\u01eb\u01ec\3\2" - + "\2\2\u01ec\u01f6\3\2\2\2\u01ed\u01ef\t\13\2\2\u01ee\u01f0\t\f\2\2\u01ef" - + "\u01ee\3\2\2\2\u01ef\u01f0\3\2\2\2\u01f0\u01f2\3\2\2\2\u01f1\u01f3\t\t" - + "\2\2\u01f2\u01f1\3\2\2\2\u01f3\u01f4\3\2\2\2\u01f4\u01f2\3\2\2\2\u01f4" - + "\u01f5\3\2\2\2\u01f5\u01f7\3\2\2\2\u01f6\u01ed\3\2\2\2\u01f6\u01f7\3\2" - + "\2\2\u01f7\u01f9\3\2\2\2\u01f8\u01fa\t\r\2\2\u01f9\u01f8\3\2\2\2\u01f9" - + "\u01fa\3\2\2\2\u01fa\u009b\3\2\2\2\u01fb\u0203\7$\2\2\u01fc\u01fd\7^\2" - + "\2\u01fd\u0202\7$\2\2\u01fe\u01ff\7^\2\2\u01ff\u0202\7^\2\2\u0200\u0202" - + "\n\16\2\2\u0201\u01fc\3\2\2\2\u0201\u01fe\3\2\2\2\u0201\u0200\3\2\2\2" - + "\u0202\u0205\3\2\2\2\u0203\u0204\3\2\2\2\u0203\u0201\3\2\2\2\u0204\u0206" - + "\3\2\2\2\u0205\u0203\3\2\2\2\u0206\u0214\7$\2\2\u0207\u020f\7)\2\2\u0208" - + "\u0209\7^\2\2\u0209\u020e\7)\2\2\u020a\u020b\7^\2\2\u020b\u020e\7^\2\2" - + "\u020c\u020e\n\17\2\2\u020d\u0208\3\2\2\2\u020d\u020a\3\2\2\2\u020d\u020c" - + "\3\2\2\2\u020e\u0211\3\2\2\2\u020f\u0210\3\2\2\2\u020f\u020d\3\2\2\2\u0210" - + "\u0212\3\2\2\2\u0211\u020f\3\2\2\2\u0212\u0214\7)\2\2\u0213\u01fb\3\2" - + "\2\2\u0213\u0207\3\2\2\2\u0214\u009d\3\2\2\2\u0215\u0219\7\61\2\2\u0216" - + "\u0217\7^\2\2\u0217\u021a\n\20\2\2\u0218\u021a\n\21\2\2\u0219\u0216\3" - + "\2\2\2\u0219\u0218\3\2\2\2\u021a\u021b\3\2\2\2\u021b\u021c\3\2\2\2\u021b" - + "\u0219\3\2\2\2\u021c\u021d\3\2\2\2\u021d\u0221\7\61\2\2\u021e\u0220\t" - + "\22\2\2\u021f\u021e\3\2\2\2\u0220\u0223\3\2\2\2\u0221\u021f\3\2\2\2\u0221" - + "\u0222\3\2\2\2\u0222\u0224\3\2\2\2\u0223\u0221\3\2\2\2\u0224\u0225\6O" - + "\3\2\u0225\u009f\3\2\2\2\u0226\u0227\7v\2\2\u0227\u0228\7t\2\2\u0228\u0229" - + "\7w\2\2\u0229\u022a\7g\2\2\u022a\u00a1\3\2\2\2\u022b\u022c\7h\2\2\u022c" - + "\u022d\7c\2\2\u022d\u022e\7n\2\2\u022e\u022f\7u\2\2\u022f\u0230\7g\2\2" - + "\u0230\u00a3\3\2\2\2\u0231\u0232\7p\2\2\u0232\u0233\7w\2\2\u0233\u0234" - + "\7n\2\2\u0234\u0235\7n\2\2\u0235\u00a5\3\2\2\2\u0236\u0237\7d\2\2\u0237" - + "\u0238\7q\2\2\u0238\u0239\7q\2\2\u0239\u023a\7n\2\2\u023a\u023b\7g\2\2" - + "\u023b\u023c\7c\2\2\u023c\u025d\7p\2\2\u023d\u023e\7d\2\2\u023e\u023f" - + "\7{\2\2\u023f\u0240\7v\2\2\u0240\u025d\7g\2\2\u0241\u0242\7u\2\2\u0242" - + "\u0243\7j\2\2\u0243\u0244\7q\2\2\u0244\u0245\7t\2\2\u0245\u025d\7v\2\2" - + "\u0246\u0247\7e\2\2\u0247\u0248\7j\2\2\u0248\u0249\7c\2\2\u0249\u025d" - + "\7t\2\2\u024a\u024b\7k\2\2\u024b\u024c\7p\2\2\u024c\u025d\7v\2\2\u024d" - + "\u024e\7n\2\2\u024e\u024f\7q\2\2\u024f\u0250\7p\2\2\u0250\u025d\7i\2\2" - + "\u0251\u0252\7h\2\2\u0252\u0253\7n\2\2\u0253\u0254\7q\2\2\u0254\u0255" - + "\7c\2\2\u0255\u025d\7v\2\2\u0256\u0257\7f\2\2\u0257\u0258\7q\2\2\u0258" - + "\u0259\7w\2\2\u0259\u025a\7d\2\2\u025a\u025b\7n\2\2\u025b\u025d\7g\2\2" - + "\u025c\u0236\3\2\2\2\u025c\u023d\3\2\2\2\u025c\u0241\3\2\2\2\u025c\u0246" - + "\3\2\2\2\u025c\u024a\3\2\2\2\u025c\u024d\3\2\2\2\u025c\u0251\3\2\2\2\u025c" - + "\u0256\3\2\2\2\u025d\u00a7\3\2\2\2\u025e\u025f\7f\2\2\u025f\u0260\7g\2" - + "\2\u0260\u0261\7h\2\2\u0261\u00a9\3\2\2\2\u0262\u0266\t\23\2\2\u0263\u0265" - + "\t\24\2\2\u0264\u0263\3\2\2\2\u0265\u0268\3\2\2\2\u0266\u0264\3\2\2\2" - + "\u0266\u0267\3\2\2\2\u0267\u00ab\3\2\2\2\u0268\u0266\3\2\2\2\u0269\u0272" - + "\7\62\2\2\u026a\u026e\t\b\2\2\u026b\u026d\t\t\2\2\u026c\u026b\3\2\2\2" - + "\u026d\u0270\3\2\2\2\u026e\u026c\3\2\2\2\u026e\u026f\3\2\2\2\u026f\u0272" - + "\3\2\2\2\u0270\u026e\3\2\2\2\u0271\u0269\3\2\2\2\u0271\u026a\3\2\2\2\u0272" - + "\u0273\3\2\2\2\u0273\u0274\bV\4\2\u0274\u00ad\3\2\2\2\u0275\u0279\t\23" - + "\2\2\u0276\u0278\t\24\2\2\u0277\u0276\3\2\2\2\u0278\u027b\3\2\2\2\u0279" - + "\u0277\3\2\2\2\u0279\u027a\3\2\2\2\u027a\u027c\3\2\2\2\u027b\u0279\3\2" - + "\2\2\u027c\u027d\bW\4\2\u027d\u00af\3\2\2\2$\2\3\u00b3\u00bd\u00c7\u00cc" - + "\u01bf\u01c2\u01c9\u01cc\u01d3\u01d6\u01d9\u01e0\u01e3\u01e9\u01eb\u01ef" - + "\u01f4\u01f6\u01f9\u0201\u0203\u020d\u020f\u0213\u0219\u021b\u0221\u025c" - + "\u0266\u026e\u0271\u0279\5\b\2\2\4\3\2\4\2\2"; + public static final String _serializedATN = "\u0004\u0000V\u027c\u0006\uffff\uffff\u0006\uffff\uffff\u0002\u0000\u0007" + + "\u0000\u0002\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007" + + "\u0003\u0002\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007" + + "\u0006\u0002\u0007\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n" + + "\u0007\n\u0002\u000b\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002" + + "\u000e\u0007\u000e\u0002\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002" + + "\u0011\u0007\u0011\u0002\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002" + + "\u0014\u0007\u0014\u0002\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002" + + "\u0017\u0007\u0017\u0002\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002" + + "\u001a\u0007\u001a\u0002\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002" + + "\u001d\u0007\u001d\u0002\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002" + + " \u0007 \u0002!\u0007!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002" + + "%\u0007%\u0002&\u0007&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002" + + "*\u0007*\u0002+\u0007+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002" + + "/\u0007/\u00020\u00070\u00021\u00071\u00022\u00072\u00023\u00073\u0002" + + "4\u00074\u00025\u00075\u00026\u00076\u00027\u00077\u00028\u00078\u0002" + + "9\u00079\u0002:\u0007:\u0002;\u0007;\u0002<\u0007<\u0002=\u0007=\u0002" + + ">\u0007>\u0002?\u0007?\u0002@\u0007@\u0002A\u0007A\u0002B\u0007B\u0002" + + "C\u0007C\u0002D\u0007D\u0002E\u0007E\u0002F\u0007F\u0002G\u0007G\u0002" + + "H\u0007H\u0002I\u0007I\u0002J\u0007J\u0002K\u0007K\u0002L\u0007L\u0002" + + "M\u0007M\u0002N\u0007N\u0002O\u0007O\u0002P\u0007P\u0002Q\u0007Q\u0002" + + "R\u0007R\u0002S\u0007S\u0002T\u0007T\u0002U\u0007U\u0001\u0000\u0004\u0000" + + "\u00b0\b\u0000\u000b\u0000\f\u0000\u00b1\u0001\u0000\u0001\u0000\u0001" + + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0005\u0001\u00ba\b\u0001\n" + + "\u0001\f\u0001\u00bd\t\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001" + + "\u0001\u0001\u0001\u0005\u0001\u00c4\b\u0001\n\u0001\f\u0001\u00c7\t\u0001" + + "\u0001\u0001\u0001\u0001\u0003\u0001\u00cb\b\u0001\u0001\u0001\u0001\u0001" + + "\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004" + + "\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006\u0001\u0007\u0001\u0007" + + "\u0001\b\u0001\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001\n\u0001\n\u0001" + + "\n\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001\f\u0001\f\u0001\r\u0001" + + "\r\u0001\r\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000f\u0001\u000f" + + "\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0001\u0010" + + "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001\u0011" + + "\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0013\u0001\u0013" + + "\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013" + + "\u0001\u0013\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014" + + "\u0001\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015" + + "\u0001\u0015\u0001\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016" + + "\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0018\u0001\u0018" + + "\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0019\u0001\u0019" + + "\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u001a\u0001\u001a" + + "\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001b" + + "\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b" + + "\u0001\u001b\u0001\u001b\u0001\u001c\u0001\u001c\u0001\u001d\u0001\u001d" + + "\u0001\u001e\u0001\u001e\u0001\u001f\u0001\u001f\u0001\u001f\u0001 \u0001" + + " \u0001!\u0001!\u0001\"\u0001\"\u0001#\u0001#\u0001#\u0001$\u0001$\u0001" + + "$\u0001%\u0001%\u0001%\u0001%\u0001&\u0001&\u0001\'\u0001\'\u0001\'\u0001" + + "(\u0001(\u0001)\u0001)\u0001)\u0001*\u0001*\u0001*\u0001+\u0001+\u0001" + + "+\u0001+\u0001,\u0001,\u0001,\u0001-\u0001-\u0001-\u0001-\u0001.\u0001" + + ".\u0001/\u0001/\u00010\u00010\u00011\u00011\u00011\u00012\u00012\u0001" + + "2\u00013\u00013\u00014\u00014\u00015\u00015\u00015\u00016\u00016\u0001" + + "6\u00017\u00017\u00017\u00018\u00018\u00018\u00019\u00019\u00019\u0001" + + "9\u0001:\u0001:\u0001:\u0001;\u0001;\u0001;\u0001<\u0001<\u0001=\u0001" + + "=\u0001=\u0001>\u0001>\u0001>\u0001?\u0001?\u0001?\u0001@\u0001@\u0001" + + "@\u0001A\u0001A\u0001A\u0001B\u0001B\u0001B\u0001C\u0001C\u0001C\u0001" + + "D\u0001D\u0001D\u0001E\u0001E\u0001E\u0001E\u0001F\u0001F\u0001F\u0001" + + "F\u0001G\u0001G\u0001G\u0001G\u0001G\u0001H\u0001H\u0004H\u01bc\bH\u000b" + + "H\fH\u01bd\u0001H\u0003H\u01c1\bH\u0001I\u0001I\u0001I\u0004I\u01c6\b" + + "I\u000bI\fI\u01c7\u0001I\u0003I\u01cb\bI\u0001J\u0001J\u0001J\u0005J\u01d0" + + "\bJ\nJ\fJ\u01d3\tJ\u0003J\u01d5\bJ\u0001J\u0003J\u01d8\bJ\u0001K\u0001" + + "K\u0001K\u0005K\u01dd\bK\nK\fK\u01e0\tK\u0003K\u01e2\bK\u0001K\u0001K" + + "\u0004K\u01e6\bK\u000bK\fK\u01e7\u0003K\u01ea\bK\u0001K\u0001K\u0003K" + + "\u01ee\bK\u0001K\u0004K\u01f1\bK\u000bK\fK\u01f2\u0003K\u01f5\bK\u0001" + + "K\u0003K\u01f8\bK\u0001L\u0001L\u0001L\u0001L\u0001L\u0001L\u0005L\u0200" + + "\bL\nL\fL\u0203\tL\u0001L\u0001L\u0001L\u0001L\u0001L\u0001L\u0001L\u0005" + + "L\u020c\bL\nL\fL\u020f\tL\u0001L\u0003L\u0212\bL\u0001M\u0001M\u0001M" + + "\u0001M\u0004M\u0218\bM\u000bM\fM\u0219\u0001M\u0001M\u0005M\u021e\bM" + + "\nM\fM\u0221\tM\u0001M\u0001M\u0001N\u0001N\u0001N\u0001N\u0001N\u0001" + + "O\u0001O\u0001O\u0001O\u0001O\u0001O\u0001P\u0001P\u0001P\u0001P\u0001" + + "P\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001" + + "Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001" + + "Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001" + + "Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0001Q\u0003Q\u025b" + + "\bQ\u0001R\u0001R\u0001R\u0001R\u0001S\u0001S\u0005S\u0263\bS\nS\fS\u0266" + + "\tS\u0001T\u0001T\u0001T\u0005T\u026b\bT\nT\fT\u026e\tT\u0003T\u0270\b" + + "T\u0001T\u0001T\u0001U\u0001U\u0005U\u0276\bU\nU\fU\u0279\tU\u0001U\u0001" + + "U\u0005\u00bb\u00c5\u0201\u020d\u0219\u0000V\u0002\u0001\u0004\u0002\u0006" + + "\u0003\b\u0004\n\u0005\f\u0006\u000e\u0007\u0010\b\u0012\t\u0014\n\u0016" + + "\u000b\u0018\f\u001a\r\u001c\u000e\u001e\u000f \u0010\"\u0011$\u0012&" + + "\u0013(\u0014*\u0015,\u0016.\u00170\u00182\u00194\u001a6\u001b8\u001c" + + ":\u001d<\u001e>\u001f@ B!D\"F#H$J%L&N\'P(R)T*V+X,Z-\\.^/`0b1d2f3h4j5l" + + "6n7p8r9t:v;x~?\u0080@\u0082A\u0084B\u0086C\u0088D\u008aE\u008cF\u008e" + + "G\u0090H\u0092I\u0094J\u0096K\u0098L\u009aM\u009cN\u009eO\u00a0P\u00a2" + + "Q\u00a4R\u00a6S\u00a8T\u00aaU\u00acV\u0002\u0000\u0001\u0013\u0003\u0000" + + "\t\n\r\r \u0002\u0000\n\n\r\r\u0001\u000007\u0002\u0000LLll\u0002\u0000" + + "XXxx\u0003\u000009AFaf\u0001\u000019\u0001\u000009\u0006\u0000DDFFLLd" + + "dffll\u0002\u0000EEee\u0002\u0000++--\u0004\u0000DDFFddff\u0002\u0000" + + "\"\"\\\\\u0002\u0000\'\'\\\\\u0001\u0000\n\n\u0002\u0000\n\n//\u0007\u0000" + + "UUcciilmssuuxx\u0003\u0000AZ__az\u0004\u000009AZ__az\u02a2\u0000\u0002" + + "\u0001\u0000\u0000\u0000\u0000\u0004\u0001\u0000\u0000\u0000\u0000\u0006" + + "\u0001\u0000\u0000\u0000\u0000\b\u0001\u0000\u0000\u0000\u0000\n\u0001" + + "\u0000\u0000\u0000\u0000\f\u0001\u0000\u0000\u0000\u0000\u000e\u0001\u0000" + + "\u0000\u0000\u0000\u0010\u0001\u0000\u0000\u0000\u0000\u0012\u0001\u0000" + + "\u0000\u0000\u0000\u0014\u0001\u0000\u0000\u0000\u0000\u0016\u0001\u0000" + + "\u0000\u0000\u0000\u0018\u0001\u0000\u0000\u0000\u0000\u001a\u0001\u0000" + + "\u0000\u0000\u0000\u001c\u0001\u0000\u0000\u0000\u0000\u001e\u0001\u0000" + + "\u0000\u0000\u0000 \u0001\u0000\u0000\u0000\u0000\"\u0001\u0000\u0000" + + "\u0000\u0000$\u0001\u0000\u0000\u0000\u0000&\u0001\u0000\u0000\u0000\u0000" + + "(\u0001\u0000\u0000\u0000\u0000*\u0001\u0000\u0000\u0000\u0000,\u0001" + + "\u0000\u0000\u0000\u0000.\u0001\u0000\u0000\u0000\u00000\u0001\u0000\u0000" + + "\u0000\u00002\u0001\u0000\u0000\u0000\u00004\u0001\u0000\u0000\u0000\u0000" + + "6\u0001\u0000\u0000\u0000\u00008\u0001\u0000\u0000\u0000\u0000:\u0001" + + "\u0000\u0000\u0000\u0000<\u0001\u0000\u0000\u0000\u0000>\u0001\u0000\u0000" + + "\u0000\u0000@\u0001\u0000\u0000\u0000\u0000B\u0001\u0000\u0000\u0000\u0000" + + "D\u0001\u0000\u0000\u0000\u0000F\u0001\u0000\u0000\u0000\u0000H\u0001" + + "\u0000\u0000\u0000\u0000J\u0001\u0000\u0000\u0000\u0000L\u0001\u0000\u0000" + + "\u0000\u0000N\u0001\u0000\u0000\u0000\u0000P\u0001\u0000\u0000\u0000\u0000" + + "R\u0001\u0000\u0000\u0000\u0000T\u0001\u0000\u0000\u0000\u0000V\u0001" + + "\u0000\u0000\u0000\u0000X\u0001\u0000\u0000\u0000\u0000Z\u0001\u0000\u0000" + + "\u0000\u0000\\\u0001\u0000\u0000\u0000\u0000^\u0001\u0000\u0000\u0000" + + "\u0000`\u0001\u0000\u0000\u0000\u0000b\u0001\u0000\u0000\u0000\u0000d" + + "\u0001\u0000\u0000\u0000\u0000f\u0001\u0000\u0000\u0000\u0000h\u0001\u0000" + + "\u0000\u0000\u0000j\u0001\u0000\u0000\u0000\u0000l\u0001\u0000\u0000\u0000" + + "\u0000n\u0001\u0000\u0000\u0000\u0000p\u0001\u0000\u0000\u0000\u0000r" + + "\u0001\u0000\u0000\u0000\u0000t\u0001\u0000\u0000\u0000\u0000v\u0001\u0000" + + "\u0000\u0000\u0000x\u0001\u0000\u0000\u0000\u0000z\u0001\u0000\u0000\u0000" + + "\u0000|\u0001\u0000\u0000\u0000\u0000~\u0001\u0000\u0000\u0000\u0000\u0080" + + "\u0001\u0000\u0000\u0000\u0000\u0082\u0001\u0000\u0000\u0000\u0000\u0084" + + "\u0001\u0000\u0000\u0000\u0000\u0086\u0001\u0000\u0000\u0000\u0000\u0088" + + "\u0001\u0000\u0000\u0000\u0000\u008a\u0001\u0000\u0000\u0000\u0000\u008c" + + "\u0001\u0000\u0000\u0000\u0000\u008e\u0001\u0000\u0000\u0000\u0000\u0090" + + "\u0001\u0000\u0000\u0000\u0000\u0092\u0001\u0000\u0000\u0000\u0000\u0094" + + "\u0001\u0000\u0000\u0000\u0000\u0096\u0001\u0000\u0000\u0000\u0000\u0098" + + "\u0001\u0000\u0000\u0000\u0000\u009a\u0001\u0000\u0000\u0000\u0000\u009c" + + "\u0001\u0000\u0000\u0000\u0000\u009e\u0001\u0000\u0000\u0000\u0000\u00a0" + + "\u0001\u0000\u0000\u0000\u0000\u00a2\u0001\u0000\u0000\u0000\u0000\u00a4" + + "\u0001\u0000\u0000\u0000\u0000\u00a6\u0001\u0000\u0000\u0000\u0000\u00a8" + + "\u0001\u0000\u0000\u0000\u0001\u00aa\u0001\u0000\u0000\u0000\u0001\u00ac" + + "\u0001\u0000\u0000\u0000\u0002\u00af\u0001\u0000\u0000\u0000\u0004\u00ca" + + "\u0001\u0000\u0000\u0000\u0006\u00ce\u0001\u0000\u0000\u0000\b\u00d0\u0001" + + "\u0000\u0000\u0000\n\u00d2\u0001\u0000\u0000\u0000\f\u00d4\u0001\u0000" + + "\u0000\u0000\u000e\u00d6\u0001\u0000\u0000\u0000\u0010\u00d8\u0001\u0000" + + "\u0000\u0000\u0012\u00da\u0001\u0000\u0000\u0000\u0014\u00dc\u0001\u0000" + + "\u0000\u0000\u0016\u00e0\u0001\u0000\u0000\u0000\u0018\u00e5\u0001\u0000" + + "\u0000\u0000\u001a\u00e7\u0001\u0000\u0000\u0000\u001c\u00e9\u0001\u0000" + + "\u0000\u0000\u001e\u00ec\u0001\u0000\u0000\u0000 \u00ef\u0001\u0000\u0000" + + "\u0000\"\u00f4\u0001\u0000\u0000\u0000$\u00fa\u0001\u0000\u0000\u0000" + + "&\u00fd\u0001\u0000\u0000\u0000(\u0101\u0001\u0000\u0000\u0000*\u010a" + + "\u0001\u0000\u0000\u0000,\u0110\u0001\u0000\u0000\u0000.\u0117\u0001\u0000" + + "\u0000\u00000\u011b\u0001\u0000\u0000\u00002\u011f\u0001\u0000\u0000\u0000" + + "4\u0125\u0001\u0000\u0000\u00006\u012b\u0001\u0000\u0000\u00008\u0130" + + "\u0001\u0000\u0000\u0000:\u013b\u0001\u0000\u0000\u0000<\u013d\u0001\u0000" + + "\u0000\u0000>\u013f\u0001\u0000\u0000\u0000@\u0141\u0001\u0000\u0000\u0000" + + "B\u0144\u0001\u0000\u0000\u0000D\u0146\u0001\u0000\u0000\u0000F\u0148" + + "\u0001\u0000\u0000\u0000H\u014a\u0001\u0000\u0000\u0000J\u014d\u0001\u0000" + + "\u0000\u0000L\u0150\u0001\u0000\u0000\u0000N\u0154\u0001\u0000\u0000\u0000" + + "P\u0156\u0001\u0000\u0000\u0000R\u0159\u0001\u0000\u0000\u0000T\u015b" + + "\u0001\u0000\u0000\u0000V\u015e\u0001\u0000\u0000\u0000X\u0161\u0001\u0000" + + "\u0000\u0000Z\u0165\u0001\u0000\u0000\u0000\\\u0168\u0001\u0000\u0000" + + "\u0000^\u016c\u0001\u0000\u0000\u0000`\u016e\u0001\u0000\u0000\u0000b" + + "\u0170\u0001\u0000\u0000\u0000d\u0172\u0001\u0000\u0000\u0000f\u0175\u0001" + + "\u0000\u0000\u0000h\u0178\u0001\u0000\u0000\u0000j\u017a\u0001\u0000\u0000" + + "\u0000l\u017c\u0001\u0000\u0000\u0000n\u017f\u0001\u0000\u0000\u0000p" + + "\u0182\u0001\u0000\u0000\u0000r\u0185\u0001\u0000\u0000\u0000t\u0188\u0001" + + "\u0000\u0000\u0000v\u018c\u0001\u0000\u0000\u0000x\u018f\u0001\u0000\u0000" + + "\u0000z\u0192\u0001\u0000\u0000\u0000|\u0194\u0001\u0000\u0000\u0000~" + + "\u0197\u0001\u0000\u0000\u0000\u0080\u019a\u0001\u0000\u0000\u0000\u0082" + + "\u019d\u0001\u0000\u0000\u0000\u0084\u01a0\u0001\u0000\u0000\u0000\u0086" + + "\u01a3\u0001\u0000\u0000\u0000\u0088\u01a6\u0001\u0000\u0000\u0000\u008a" + + "\u01a9\u0001\u0000\u0000\u0000\u008c\u01ac\u0001\u0000\u0000\u0000\u008e" + + "\u01b0\u0001\u0000\u0000\u0000\u0090\u01b4\u0001\u0000\u0000\u0000\u0092" + + "\u01b9\u0001\u0000\u0000\u0000\u0094\u01c2\u0001\u0000\u0000\u0000\u0096" + + "\u01d4\u0001\u0000\u0000\u0000\u0098\u01e1\u0001\u0000\u0000\u0000\u009a" + + "\u0211\u0001\u0000\u0000\u0000\u009c\u0213\u0001\u0000\u0000\u0000\u009e" + + "\u0224\u0001\u0000\u0000\u0000\u00a0\u0229\u0001\u0000\u0000\u0000\u00a2" + + "\u022f\u0001\u0000\u0000\u0000\u00a4\u025a\u0001\u0000\u0000\u0000\u00a6" + + "\u025c\u0001\u0000\u0000\u0000\u00a8\u0260\u0001\u0000\u0000\u0000\u00aa" + + "\u026f\u0001\u0000\u0000\u0000\u00ac\u0273\u0001\u0000\u0000\u0000\u00ae" + + "\u00b0\u0007\u0000\u0000\u0000\u00af\u00ae\u0001\u0000\u0000\u0000\u00b0" + + "\u00b1\u0001\u0000\u0000\u0000\u00b1\u00af\u0001\u0000\u0000\u0000\u00b1" + + "\u00b2\u0001\u0000\u0000\u0000\u00b2\u00b3\u0001\u0000\u0000\u0000\u00b3" + + "\u00b4\u0006\u0000\u0000\u0000\u00b4\u0003\u0001\u0000\u0000\u0000\u00b5" + + "\u00b6\u0005/\u0000\u0000\u00b6\u00b7\u0005/\u0000\u0000\u00b7\u00bb\u0001" + + "\u0000\u0000\u0000\u00b8\u00ba\t\u0000\u0000\u0000\u00b9\u00b8\u0001\u0000" + + "\u0000\u0000\u00ba\u00bd\u0001\u0000\u0000\u0000\u00bb\u00bc\u0001\u0000" + + "\u0000\u0000\u00bb\u00b9\u0001\u0000\u0000\u0000\u00bc\u00be\u0001\u0000" + + "\u0000\u0000\u00bd\u00bb\u0001\u0000\u0000\u0000\u00be\u00cb\u0007\u0001" + + "\u0000\u0000\u00bf\u00c0\u0005/\u0000\u0000\u00c0\u00c1\u0005*\u0000\u0000" + + "\u00c1\u00c5\u0001\u0000\u0000\u0000\u00c2\u00c4\t\u0000\u0000\u0000\u00c3" + + "\u00c2\u0001\u0000\u0000\u0000\u00c4\u00c7\u0001\u0000\u0000\u0000\u00c5" + + "\u00c6\u0001\u0000\u0000\u0000\u00c5\u00c3\u0001\u0000\u0000\u0000\u00c6" + + "\u00c8\u0001\u0000\u0000\u0000\u00c7\u00c5\u0001\u0000\u0000\u0000\u00c8" + + "\u00c9\u0005*\u0000\u0000\u00c9\u00cb\u0005/\u0000\u0000\u00ca\u00b5\u0001" + + "\u0000\u0000\u0000\u00ca\u00bf\u0001\u0000\u0000\u0000\u00cb\u00cc\u0001" + + "\u0000\u0000\u0000\u00cc\u00cd\u0006\u0001\u0000\u0000\u00cd\u0005\u0001" + + "\u0000\u0000\u0000\u00ce\u00cf\u0005{\u0000\u0000\u00cf\u0007\u0001\u0000" + + "\u0000\u0000\u00d0\u00d1\u0005}\u0000\u0000\u00d1\t\u0001\u0000\u0000" + + "\u0000\u00d2\u00d3\u0005[\u0000\u0000\u00d3\u000b\u0001\u0000\u0000\u0000" + + "\u00d4\u00d5\u0005]\u0000\u0000\u00d5\r\u0001\u0000\u0000\u0000\u00d6" + + "\u00d7\u0005(\u0000\u0000\u00d7\u000f\u0001\u0000\u0000\u0000\u00d8\u00d9" + + "\u0005)\u0000\u0000\u00d9\u0011\u0001\u0000\u0000\u0000\u00da\u00db\u0005" + + "$\u0000\u0000\u00db\u0013\u0001\u0000\u0000\u0000\u00dc\u00dd\u0005.\u0000" + + "\u0000\u00dd\u00de\u0001\u0000\u0000\u0000\u00de\u00df\u0006\t\u0001\u0000" + + "\u00df\u0015\u0001\u0000\u0000\u0000\u00e0\u00e1\u0005?\u0000\u0000\u00e1" + + "\u00e2\u0005.\u0000\u0000\u00e2\u00e3\u0001\u0000\u0000\u0000\u00e3\u00e4" + + "\u0006\n\u0001\u0000\u00e4\u0017\u0001\u0000\u0000\u0000\u00e5\u00e6\u0005" + + ",\u0000\u0000\u00e6\u0019\u0001\u0000\u0000\u0000\u00e7\u00e8\u0005;\u0000" + + "\u0000\u00e8\u001b\u0001\u0000\u0000\u0000\u00e9\u00ea\u0005i\u0000\u0000" + + "\u00ea\u00eb\u0005f\u0000\u0000\u00eb\u001d\u0001\u0000\u0000\u0000\u00ec" + + "\u00ed\u0005i\u0000\u0000\u00ed\u00ee\u0005n\u0000\u0000\u00ee\u001f\u0001" + + "\u0000\u0000\u0000\u00ef\u00f0\u0005e\u0000\u0000\u00f0\u00f1\u0005l\u0000" + + "\u0000\u00f1\u00f2\u0005s\u0000\u0000\u00f2\u00f3\u0005e\u0000\u0000\u00f3" + + "!\u0001\u0000\u0000\u0000\u00f4\u00f5\u0005w\u0000\u0000\u00f5\u00f6\u0005" + + "h\u0000\u0000\u00f6\u00f7\u0005i\u0000\u0000\u00f7\u00f8\u0005l\u0000" + + "\u0000\u00f8\u00f9\u0005e\u0000\u0000\u00f9#\u0001\u0000\u0000\u0000\u00fa" + + "\u00fb\u0005d\u0000\u0000\u00fb\u00fc\u0005o\u0000\u0000\u00fc%\u0001" + + "\u0000\u0000\u0000\u00fd\u00fe\u0005f\u0000\u0000\u00fe\u00ff\u0005o\u0000" + + "\u0000\u00ff\u0100\u0005r\u0000\u0000\u0100\'\u0001\u0000\u0000\u0000" + + "\u0101\u0102\u0005c\u0000\u0000\u0102\u0103\u0005o\u0000\u0000\u0103\u0104" + + "\u0005n\u0000\u0000\u0104\u0105\u0005t\u0000\u0000\u0105\u0106\u0005i" + + "\u0000\u0000\u0106\u0107\u0005n\u0000\u0000\u0107\u0108\u0005u\u0000\u0000" + + "\u0108\u0109\u0005e\u0000\u0000\u0109)\u0001\u0000\u0000\u0000\u010a\u010b" + + "\u0005b\u0000\u0000\u010b\u010c\u0005r\u0000\u0000\u010c\u010d\u0005e" + + "\u0000\u0000\u010d\u010e\u0005a\u0000\u0000\u010e\u010f\u0005k\u0000\u0000" + + "\u010f+\u0001\u0000\u0000\u0000\u0110\u0111\u0005r\u0000\u0000\u0111\u0112" + + "\u0005e\u0000\u0000\u0112\u0113\u0005t\u0000\u0000\u0113\u0114\u0005u" + + "\u0000\u0000\u0114\u0115\u0005r\u0000\u0000\u0115\u0116\u0005n\u0000\u0000" + + "\u0116-\u0001\u0000\u0000\u0000\u0117\u0118\u0005n\u0000\u0000\u0118\u0119" + + "\u0005e\u0000\u0000\u0119\u011a\u0005w\u0000\u0000\u011a/\u0001\u0000" + + "\u0000\u0000\u011b\u011c\u0005t\u0000\u0000\u011c\u011d\u0005r\u0000\u0000" + + "\u011d\u011e\u0005y\u0000\u0000\u011e1\u0001\u0000\u0000\u0000\u011f\u0120" + + "\u0005c\u0000\u0000\u0120\u0121\u0005a\u0000\u0000\u0121\u0122\u0005t" + + "\u0000\u0000\u0122\u0123\u0005c\u0000\u0000\u0123\u0124\u0005h\u0000\u0000" + + "\u01243\u0001\u0000\u0000\u0000\u0125\u0126\u0005t\u0000\u0000\u0126\u0127" + + "\u0005h\u0000\u0000\u0127\u0128\u0005r\u0000\u0000\u0128\u0129\u0005o" + + "\u0000\u0000\u0129\u012a\u0005w\u0000\u0000\u012a5\u0001\u0000\u0000\u0000" + + "\u012b\u012c\u0005t\u0000\u0000\u012c\u012d\u0005h\u0000\u0000\u012d\u012e" + + "\u0005i\u0000\u0000\u012e\u012f\u0005s\u0000\u0000\u012f7\u0001\u0000" + + "\u0000\u0000\u0130\u0131\u0005i\u0000\u0000\u0131\u0132\u0005n\u0000\u0000" + + "\u0132\u0133\u0005s\u0000\u0000\u0133\u0134\u0005t\u0000\u0000\u0134\u0135" + + "\u0005a\u0000\u0000\u0135\u0136\u0005n\u0000\u0000\u0136\u0137\u0005c" + + "\u0000\u0000\u0137\u0138\u0005e\u0000\u0000\u0138\u0139\u0005o\u0000\u0000" + + "\u0139\u013a\u0005f\u0000\u0000\u013a9\u0001\u0000\u0000\u0000\u013b\u013c" + + "\u0005!\u0000\u0000\u013c;\u0001\u0000\u0000\u0000\u013d\u013e\u0005~" + + "\u0000\u0000\u013e=\u0001\u0000\u0000\u0000\u013f\u0140\u0005*\u0000\u0000" + + "\u0140?\u0001\u0000\u0000\u0000\u0141\u0142\u0005/\u0000\u0000\u0142\u0143" + + "\u0004\u001f\u0000\u0000\u0143A\u0001\u0000\u0000\u0000\u0144\u0145\u0005" + + "%\u0000\u0000\u0145C\u0001\u0000\u0000\u0000\u0146\u0147\u0005+\u0000" + + "\u0000\u0147E\u0001\u0000\u0000\u0000\u0148\u0149\u0005-\u0000\u0000\u0149" + + "G\u0001\u0000\u0000\u0000\u014a\u014b\u0005<\u0000\u0000\u014b\u014c\u0005" + + "<\u0000\u0000\u014cI\u0001\u0000\u0000\u0000\u014d\u014e\u0005>\u0000" + + "\u0000\u014e\u014f\u0005>\u0000\u0000\u014fK\u0001\u0000\u0000\u0000\u0150" + + "\u0151\u0005>\u0000\u0000\u0151\u0152\u0005>\u0000\u0000\u0152\u0153\u0005" + + ">\u0000\u0000\u0153M\u0001\u0000\u0000\u0000\u0154\u0155\u0005<\u0000" + + "\u0000\u0155O\u0001\u0000\u0000\u0000\u0156\u0157\u0005<\u0000\u0000\u0157" + + "\u0158\u0005=\u0000\u0000\u0158Q\u0001\u0000\u0000\u0000\u0159\u015a\u0005" + + ">\u0000\u0000\u015aS\u0001\u0000\u0000\u0000\u015b\u015c\u0005>\u0000" + + "\u0000\u015c\u015d\u0005=\u0000\u0000\u015dU\u0001\u0000\u0000\u0000\u015e" + + "\u015f\u0005=\u0000\u0000\u015f\u0160\u0005=\u0000\u0000\u0160W\u0001" + + "\u0000\u0000\u0000\u0161\u0162\u0005=\u0000\u0000\u0162\u0163\u0005=\u0000" + + "\u0000\u0163\u0164\u0005=\u0000\u0000\u0164Y\u0001\u0000\u0000\u0000\u0165" + + "\u0166\u0005!\u0000\u0000\u0166\u0167\u0005=\u0000\u0000\u0167[\u0001" + + "\u0000\u0000\u0000\u0168\u0169\u0005!\u0000\u0000\u0169\u016a\u0005=\u0000" + + "\u0000\u016a\u016b\u0005=\u0000\u0000\u016b]\u0001\u0000\u0000\u0000\u016c" + + "\u016d\u0005&\u0000\u0000\u016d_\u0001\u0000\u0000\u0000\u016e\u016f\u0005" + + "^\u0000\u0000\u016fa\u0001\u0000\u0000\u0000\u0170\u0171\u0005|\u0000" + + "\u0000\u0171c\u0001\u0000\u0000\u0000\u0172\u0173\u0005&\u0000\u0000\u0173" + + "\u0174\u0005&\u0000\u0000\u0174e\u0001\u0000\u0000\u0000\u0175\u0176\u0005" + + "|\u0000\u0000\u0176\u0177\u0005|\u0000\u0000\u0177g\u0001\u0000\u0000" + + "\u0000\u0178\u0179\u0005?\u0000\u0000\u0179i\u0001\u0000\u0000\u0000\u017a" + + "\u017b\u0005:\u0000\u0000\u017bk\u0001\u0000\u0000\u0000\u017c\u017d\u0005" + + "?\u0000\u0000\u017d\u017e\u0005:\u0000\u0000\u017em\u0001\u0000\u0000" + + "\u0000\u017f\u0180\u0005:\u0000\u0000\u0180\u0181\u0005:\u0000\u0000\u0181" + + "o\u0001\u0000\u0000\u0000\u0182\u0183\u0005-\u0000\u0000\u0183\u0184\u0005" + + ">\u0000\u0000\u0184q\u0001\u0000\u0000\u0000\u0185\u0186\u0005=\u0000" + + "\u0000\u0186\u0187\u0005~\u0000\u0000\u0187s\u0001\u0000\u0000\u0000\u0188" + + "\u0189\u0005=\u0000\u0000\u0189\u018a\u0005=\u0000\u0000\u018a\u018b\u0005" + + "~\u0000\u0000\u018bu\u0001\u0000\u0000\u0000\u018c\u018d\u0005+\u0000" + + "\u0000\u018d\u018e\u0005+\u0000\u0000\u018ew\u0001\u0000\u0000\u0000\u018f" + + "\u0190\u0005-\u0000\u0000\u0190\u0191\u0005-\u0000\u0000\u0191y\u0001" + + "\u0000\u0000\u0000\u0192\u0193\u0005=\u0000\u0000\u0193{\u0001\u0000\u0000" + + "\u0000\u0194\u0195\u0005+\u0000\u0000\u0195\u0196\u0005=\u0000\u0000\u0196" + + "}\u0001\u0000\u0000\u0000\u0197\u0198\u0005-\u0000\u0000\u0198\u0199\u0005" + + "=\u0000\u0000\u0199\u007f\u0001\u0000\u0000\u0000\u019a\u019b\u0005*\u0000" + + "\u0000\u019b\u019c\u0005=\u0000\u0000\u019c\u0081\u0001\u0000\u0000\u0000" + + "\u019d\u019e\u0005/\u0000\u0000\u019e\u019f\u0005=\u0000\u0000\u019f\u0083" + + "\u0001\u0000\u0000\u0000\u01a0\u01a1\u0005%\u0000\u0000\u01a1\u01a2\u0005" + + "=\u0000\u0000\u01a2\u0085\u0001\u0000\u0000\u0000\u01a3\u01a4\u0005&\u0000" + + "\u0000\u01a4\u01a5\u0005=\u0000\u0000\u01a5\u0087\u0001\u0000\u0000\u0000" + + "\u01a6\u01a7\u0005^\u0000\u0000\u01a7\u01a8\u0005=\u0000\u0000\u01a8\u0089" + + "\u0001\u0000\u0000\u0000\u01a9\u01aa\u0005|\u0000\u0000\u01aa\u01ab\u0005" + + "=\u0000\u0000\u01ab\u008b\u0001\u0000\u0000\u0000\u01ac\u01ad\u0005<\u0000" + + "\u0000\u01ad\u01ae\u0005<\u0000\u0000\u01ae\u01af\u0005=\u0000\u0000\u01af" + + "\u008d\u0001\u0000\u0000\u0000\u01b0\u01b1\u0005>\u0000\u0000\u01b1\u01b2" + + "\u0005>\u0000\u0000\u01b2\u01b3\u0005=\u0000\u0000\u01b3\u008f\u0001\u0000" + + "\u0000\u0000\u01b4\u01b5\u0005>\u0000\u0000\u01b5\u01b6\u0005>\u0000\u0000" + + "\u01b6\u01b7\u0005>\u0000\u0000\u01b7\u01b8\u0005=\u0000\u0000\u01b8\u0091" + + "\u0001\u0000\u0000\u0000\u01b9\u01bb\u00050\u0000\u0000\u01ba\u01bc\u0007" + + "\u0002\u0000\u0000\u01bb\u01ba\u0001\u0000\u0000\u0000\u01bc\u01bd\u0001" + + "\u0000\u0000\u0000\u01bd\u01bb\u0001\u0000\u0000\u0000\u01bd\u01be\u0001" + + "\u0000\u0000\u0000\u01be\u01c0\u0001\u0000\u0000\u0000\u01bf\u01c1\u0007" + + "\u0003\u0000\u0000\u01c0\u01bf\u0001\u0000\u0000\u0000\u01c0\u01c1\u0001" + + "\u0000\u0000\u0000\u01c1\u0093\u0001\u0000\u0000\u0000\u01c2\u01c3\u0005" + + "0\u0000\u0000\u01c3\u01c5\u0007\u0004\u0000\u0000\u01c4\u01c6\u0007\u0005" + + "\u0000\u0000\u01c5\u01c4\u0001\u0000\u0000\u0000\u01c6\u01c7\u0001\u0000" + + "\u0000\u0000\u01c7\u01c5\u0001\u0000\u0000\u0000\u01c7\u01c8\u0001\u0000" + + "\u0000\u0000\u01c8\u01ca\u0001\u0000\u0000\u0000\u01c9\u01cb\u0007\u0003" + + "\u0000\u0000\u01ca\u01c9\u0001\u0000\u0000\u0000\u01ca\u01cb\u0001\u0000" + + "\u0000\u0000\u01cb\u0095\u0001\u0000\u0000\u0000\u01cc\u01d5\u00050\u0000" + + "\u0000\u01cd\u01d1\u0007\u0006\u0000\u0000\u01ce\u01d0\u0007\u0007\u0000" + + "\u0000\u01cf\u01ce\u0001\u0000\u0000\u0000\u01d0\u01d3\u0001\u0000\u0000" + + "\u0000\u01d1\u01cf\u0001\u0000\u0000\u0000\u01d1\u01d2\u0001\u0000\u0000" + + "\u0000\u01d2\u01d5\u0001\u0000\u0000\u0000\u01d3\u01d1\u0001\u0000\u0000" + + "\u0000\u01d4\u01cc\u0001\u0000\u0000\u0000\u01d4\u01cd\u0001\u0000\u0000" + + "\u0000\u01d5\u01d7\u0001\u0000\u0000\u0000\u01d6\u01d8\u0007\b\u0000\u0000" + + "\u01d7\u01d6\u0001\u0000\u0000\u0000\u01d7\u01d8\u0001\u0000\u0000\u0000" + + "\u01d8\u0097\u0001\u0000\u0000\u0000\u01d9\u01e2\u00050\u0000\u0000\u01da" + + "\u01de\u0007\u0006\u0000\u0000\u01db\u01dd\u0007\u0007\u0000\u0000\u01dc" + + "\u01db\u0001\u0000\u0000\u0000\u01dd\u01e0\u0001\u0000\u0000\u0000\u01de" + + "\u01dc\u0001\u0000\u0000\u0000\u01de\u01df\u0001\u0000\u0000\u0000\u01df" + + "\u01e2\u0001\u0000\u0000\u0000\u01e0\u01de\u0001\u0000\u0000\u0000\u01e1" + + "\u01d9\u0001\u0000\u0000\u0000\u01e1\u01da\u0001\u0000\u0000\u0000\u01e2" + + "\u01e9\u0001\u0000\u0000\u0000\u01e3\u01e5\u0003\u0014\t\u0000\u01e4\u01e6" + + "\u0007\u0007\u0000\u0000\u01e5\u01e4\u0001\u0000\u0000\u0000\u01e6\u01e7" + + "\u0001\u0000\u0000\u0000\u01e7\u01e5\u0001\u0000\u0000\u0000\u01e7\u01e8" + + "\u0001\u0000\u0000\u0000\u01e8\u01ea\u0001\u0000\u0000\u0000\u01e9\u01e3" + + "\u0001\u0000\u0000\u0000\u01e9\u01ea\u0001\u0000\u0000\u0000\u01ea\u01f4" + + "\u0001\u0000\u0000\u0000\u01eb\u01ed\u0007\t\u0000\u0000\u01ec\u01ee\u0007" + + "\n\u0000\u0000\u01ed\u01ec\u0001\u0000\u0000\u0000\u01ed\u01ee\u0001\u0000" + + "\u0000\u0000\u01ee\u01f0\u0001\u0000\u0000\u0000\u01ef\u01f1\u0007\u0007" + + "\u0000\u0000\u01f0\u01ef\u0001\u0000\u0000\u0000\u01f1\u01f2\u0001\u0000" + + "\u0000\u0000\u01f2\u01f0\u0001\u0000\u0000\u0000\u01f2\u01f3\u0001\u0000" + + "\u0000\u0000\u01f3\u01f5\u0001\u0000\u0000\u0000\u01f4\u01eb\u0001\u0000" + + "\u0000\u0000\u01f4\u01f5\u0001\u0000\u0000\u0000\u01f5\u01f7\u0001\u0000" + + "\u0000\u0000\u01f6\u01f8\u0007\u000b\u0000\u0000\u01f7\u01f6\u0001\u0000" + + "\u0000\u0000\u01f7\u01f8\u0001\u0000\u0000\u0000\u01f8\u0099\u0001\u0000" + + "\u0000\u0000\u01f9\u0201\u0005\"\u0000\u0000\u01fa\u01fb\u0005\\\u0000" + + "\u0000\u01fb\u0200\u0005\"\u0000\u0000\u01fc\u01fd\u0005\\\u0000\u0000" + + "\u01fd\u0200\u0005\\\u0000\u0000\u01fe\u0200\b\f\u0000\u0000\u01ff\u01fa" + + "\u0001\u0000\u0000\u0000\u01ff\u01fc\u0001\u0000\u0000\u0000\u01ff\u01fe" + + "\u0001\u0000\u0000\u0000\u0200\u0203\u0001\u0000\u0000\u0000\u0201\u0202" + + "\u0001\u0000\u0000\u0000\u0201\u01ff\u0001\u0000\u0000\u0000\u0202\u0204" + + "\u0001\u0000\u0000\u0000\u0203\u0201\u0001\u0000\u0000\u0000\u0204\u0212" + + "\u0005\"\u0000\u0000\u0205\u020d\u0005\'\u0000\u0000\u0206\u0207\u0005" + + "\\\u0000\u0000\u0207\u020c\u0005\'\u0000\u0000\u0208\u0209\u0005\\\u0000" + + "\u0000\u0209\u020c\u0005\\\u0000\u0000\u020a\u020c\b\r\u0000\u0000\u020b" + + "\u0206\u0001\u0000\u0000\u0000\u020b\u0208\u0001\u0000\u0000\u0000\u020b" + + "\u020a\u0001\u0000\u0000\u0000\u020c\u020f\u0001\u0000\u0000\u0000\u020d" + + "\u020e\u0001\u0000\u0000\u0000\u020d\u020b\u0001\u0000\u0000\u0000\u020e" + + "\u0210\u0001\u0000\u0000\u0000\u020f\u020d\u0001\u0000\u0000\u0000\u0210" + + "\u0212\u0005\'\u0000\u0000\u0211\u01f9\u0001\u0000\u0000\u0000\u0211\u0205" + + "\u0001\u0000\u0000\u0000\u0212\u009b\u0001\u0000\u0000\u0000\u0213\u0217" + + "\u0005/\u0000\u0000\u0214\u0215\u0005\\\u0000\u0000\u0215\u0218\b\u000e" + + "\u0000\u0000\u0216\u0218\b\u000f\u0000\u0000\u0217\u0214\u0001\u0000\u0000" + + "\u0000\u0217\u0216\u0001\u0000\u0000\u0000\u0218\u0219\u0001\u0000\u0000" + + "\u0000\u0219\u021a\u0001\u0000\u0000\u0000\u0219\u0217\u0001\u0000\u0000" + + "\u0000\u021a\u021b\u0001\u0000\u0000\u0000\u021b\u021f\u0005/\u0000\u0000" + + "\u021c\u021e\u0007\u0010\u0000\u0000\u021d\u021c\u0001\u0000\u0000\u0000" + + "\u021e\u0221\u0001\u0000\u0000\u0000\u021f\u021d\u0001\u0000\u0000\u0000" + + "\u021f\u0220\u0001\u0000\u0000\u0000\u0220\u0222\u0001\u0000\u0000\u0000" + + "\u0221\u021f\u0001\u0000\u0000\u0000\u0222\u0223\u0004M\u0001\u0000\u0223" + + "\u009d\u0001\u0000\u0000\u0000\u0224\u0225\u0005t\u0000\u0000\u0225\u0226" + + "\u0005r\u0000\u0000\u0226\u0227\u0005u\u0000\u0000\u0227\u0228\u0005e" + + "\u0000\u0000\u0228\u009f\u0001\u0000\u0000\u0000\u0229\u022a\u0005f\u0000" + + "\u0000\u022a\u022b\u0005a\u0000\u0000\u022b\u022c\u0005l\u0000\u0000\u022c" + + "\u022d\u0005s\u0000\u0000\u022d\u022e\u0005e\u0000\u0000\u022e\u00a1\u0001" + + "\u0000\u0000\u0000\u022f\u0230\u0005n\u0000\u0000\u0230\u0231\u0005u\u0000" + + "\u0000\u0231\u0232\u0005l\u0000\u0000\u0232\u0233\u0005l\u0000\u0000\u0233" + + "\u00a3\u0001\u0000\u0000\u0000\u0234\u0235\u0005b\u0000\u0000\u0235\u0236" + + "\u0005o\u0000\u0000\u0236\u0237\u0005o\u0000\u0000\u0237\u0238\u0005l" + + "\u0000\u0000\u0238\u0239\u0005e\u0000\u0000\u0239\u023a\u0005a\u0000\u0000" + + "\u023a\u025b\u0005n\u0000\u0000\u023b\u023c\u0005b\u0000\u0000\u023c\u023d" + + "\u0005y\u0000\u0000\u023d\u023e\u0005t\u0000\u0000\u023e\u025b\u0005e" + + "\u0000\u0000\u023f\u0240\u0005s\u0000\u0000\u0240\u0241\u0005h\u0000\u0000" + + "\u0241\u0242\u0005o\u0000\u0000\u0242\u0243\u0005r\u0000\u0000\u0243\u025b" + + "\u0005t\u0000\u0000\u0244\u0245\u0005c\u0000\u0000\u0245\u0246\u0005h" + + "\u0000\u0000\u0246\u0247\u0005a\u0000\u0000\u0247\u025b\u0005r\u0000\u0000" + + "\u0248\u0249\u0005i\u0000\u0000\u0249\u024a\u0005n\u0000\u0000\u024a\u025b" + + "\u0005t\u0000\u0000\u024b\u024c\u0005l\u0000\u0000\u024c\u024d\u0005o" + + "\u0000\u0000\u024d\u024e\u0005n\u0000\u0000\u024e\u025b\u0005g\u0000\u0000" + + "\u024f\u0250\u0005f\u0000\u0000\u0250\u0251\u0005l\u0000\u0000\u0251\u0252" + + "\u0005o\u0000\u0000\u0252\u0253\u0005a\u0000\u0000\u0253\u025b\u0005t" + + "\u0000\u0000\u0254\u0255\u0005d\u0000\u0000\u0255\u0256\u0005o\u0000\u0000" + + "\u0256\u0257\u0005u\u0000\u0000\u0257\u0258\u0005b\u0000\u0000\u0258\u0259" + + "\u0005l\u0000\u0000\u0259\u025b\u0005e\u0000\u0000\u025a\u0234\u0001\u0000" + + "\u0000\u0000\u025a\u023b\u0001\u0000\u0000\u0000\u025a\u023f\u0001\u0000" + + "\u0000\u0000\u025a\u0244\u0001\u0000\u0000\u0000\u025a\u0248\u0001\u0000" + + "\u0000\u0000\u025a\u024b\u0001\u0000\u0000\u0000\u025a\u024f\u0001\u0000" + + "\u0000\u0000\u025a\u0254\u0001\u0000\u0000\u0000\u025b\u00a5\u0001\u0000" + + "\u0000\u0000\u025c\u025d\u0005d\u0000\u0000\u025d\u025e\u0005e\u0000\u0000" + + "\u025e\u025f\u0005f\u0000\u0000\u025f\u00a7\u0001\u0000\u0000\u0000\u0260" + + "\u0264\u0007\u0011\u0000\u0000\u0261\u0263\u0007\u0012\u0000\u0000\u0262" + + "\u0261\u0001\u0000\u0000\u0000\u0263\u0266\u0001\u0000\u0000\u0000\u0264" + + "\u0262\u0001\u0000\u0000\u0000\u0264\u0265\u0001\u0000\u0000\u0000\u0265" + + "\u00a9\u0001\u0000\u0000\u0000\u0266\u0264\u0001\u0000\u0000\u0000\u0267" + + "\u0270\u00050\u0000\u0000\u0268\u026c\u0007\u0006\u0000\u0000\u0269\u026b" + + "\u0007\u0007\u0000\u0000\u026a\u0269\u0001\u0000\u0000\u0000\u026b\u026e" + + "\u0001\u0000\u0000\u0000\u026c\u026a\u0001\u0000\u0000\u0000\u026c\u026d" + + "\u0001\u0000\u0000\u0000\u026d\u0270\u0001\u0000\u0000\u0000\u026e\u026c" + + "\u0001\u0000\u0000\u0000\u026f\u0267\u0001\u0000\u0000\u0000\u026f\u0268" + + "\u0001\u0000\u0000\u0000\u0270\u0271\u0001\u0000\u0000\u0000\u0271\u0272" + + "\u0006T\u0002\u0000\u0272\u00ab\u0001\u0000\u0000\u0000\u0273\u0277\u0007" + + "\u0011\u0000\u0000\u0274\u0276\u0007\u0012\u0000\u0000\u0275\u0274\u0001" + + "\u0000\u0000\u0000\u0276\u0279\u0001\u0000\u0000\u0000\u0277\u0275\u0001" + + "\u0000\u0000\u0000\u0277\u0278\u0001\u0000\u0000\u0000\u0278\u027a\u0001" + + "\u0000\u0000\u0000\u0279\u0277\u0001\u0000\u0000\u0000\u027a\u027b\u0006" + + "U\u0002\u0000\u027b\u00ad\u0001\u0000\u0000\u0000\"\u0000\u0001\u00b1" + + "\u00bb\u00c5\u00ca\u01bd\u01c0\u01c7\u01ca\u01d1\u01d4\u01d7\u01de\u01e1" + + "\u01e7\u01e9\u01ed\u01f2\u01f4\u01f7\u01ff\u0201\u020b\u020d\u0211\u0217" + + "\u0219\u021f\u025a\u0264\u026c\u026f\u0277\u0003\u0006\u0000\u0000\u0002" + + "\u0001\u0000\u0002\u0000\u0000"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java index 07ab6dd43890..45d35e87fc43 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/PainlessParser.java @@ -1,18 +1,31 @@ // ANTLR GENERATED CODE: DO NOT EDIT package org.elasticsearch.painless.antlr; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.FailedPredicateException; +import org.antlr.v4.runtime.NoViableAltException; +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.RuleContext; +import org.antlr.v4.runtime.RuntimeMetaData; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.Vocabulary; +import org.antlr.v4.runtime.VocabularyImpl; +import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNDeserializer; +import org.antlr.v4.runtime.atn.ParserATNSimulator; +import org.antlr.v4.runtime.atn.PredictionContextCache; import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; -import org.antlr.v4.runtime.tree.*; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; +import org.antlr.v4.runtime.tree.TerminalNode; import java.util.List; -@SuppressWarnings({ "all", "warnings", "unchecked", "unused", "cast" }) +@SuppressWarnings({ "all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue" }) class PainlessParser extends Parser { static { - RuntimeMetaData.checkVersion("4.5.3", RuntimeMetaData.VERSION); + RuntimeMetaData.checkVersion("4.11.1", RuntimeMetaData.VERSION); } protected static final DFA[] _decisionToDFA; @@ -32,220 +45,234 @@ class PainlessParser extends Parser { RULE_refcasttype = 22, RULE_chain = 23, RULE_primary = 24, RULE_postfix = 25, RULE_postdot = 26, RULE_callinvoke = 27, RULE_fieldaccess = 28, RULE_braceaccess = 29, RULE_arrayinitializer = 30, RULE_listinitializer = 31, RULE_mapinitializer = 32, RULE_maptoken = 33, RULE_arguments = 34, RULE_argument = 35, RULE_lambda = 36, RULE_lamtype = 37, RULE_funcref = 38; - public static final String[] ruleNames = { - "source", - "function", - "parameters", - "statement", - "rstatement", - "dstatement", - "trailer", - "block", - "empty", - "initializer", - "afterthought", - "declaration", - "decltype", - "type", - "declvar", - "trap", - "noncondexpression", - "expression", - "unary", - "unarynotaddsub", - "castexpression", - "primordefcasttype", - "refcasttype", - "chain", - "primary", - "postfix", - "postdot", - "callinvoke", - "fieldaccess", - "braceaccess", - "arrayinitializer", - "listinitializer", - "mapinitializer", - "maptoken", - "arguments", - "argument", - "lambda", - "lamtype", - "funcref" }; - private static final String[] _LITERAL_NAMES = { - null, - null, - null, - "'{'", - "'}'", - "'['", - "']'", - "'('", - "')'", - "'$'", - "'.'", - "'?.'", - "','", - "';'", - "'if'", - "'in'", - "'else'", - "'while'", - "'do'", - "'for'", - "'continue'", - "'break'", - "'return'", - "'new'", - "'try'", - "'catch'", - "'throw'", - "'this'", - "'instanceof'", - "'!'", - "'~'", - "'*'", - "'/'", - "'%'", - "'+'", - "'-'", - "'<<'", - "'>>'", - "'>>>'", - "'<'", - "'<='", - "'>'", - "'>='", - "'=='", - "'==='", - "'!='", - "'!=='", - "'&'", - "'^'", - "'|'", - "'&&'", - "'||'", - "'?'", - "':'", - "'?:'", - "'::'", - "'->'", - "'=~'", - "'==~'", - "'++'", - "'--'", - "'='", - "'+='", - "'-='", - "'*='", - "'/='", - "'%='", - "'&='", - "'^='", - "'|='", - "'<<='", - "'>>='", - "'>>>='", - null, - null, - null, - null, - null, - null, - "'true'", - "'false'", - "'null'", - null, - "'def'" }; - private static final String[] _SYMBOLIC_NAMES = { - null, - "WS", - "COMMENT", - "LBRACK", - "RBRACK", - "LBRACE", - "RBRACE", - "LP", - "RP", - "DOLLAR", - "DOT", - "NSDOT", - "COMMA", - "SEMICOLON", - "IF", - "IN", - "ELSE", - "WHILE", - "DO", - "FOR", - "CONTINUE", - "BREAK", - "RETURN", - "NEW", - "TRY", - "CATCH", - "THROW", - "THIS", - "INSTANCEOF", - "BOOLNOT", - "BWNOT", - "MUL", - "DIV", - "REM", - "ADD", - "SUB", - "LSH", - "RSH", - "USH", - "LT", - "LTE", - "GT", - "GTE", - "EQ", - "EQR", - "NE", - "NER", - "BWAND", - "XOR", - "BWOR", - "BOOLAND", - "BOOLOR", - "COND", - "COLON", - "ELVIS", - "REF", - "ARROW", - "FIND", - "MATCH", - "INCR", - "DECR", - "ASSIGN", - "AADD", - "ASUB", - "AMUL", - "ADIV", - "AREM", - "AAND", - "AXOR", - "AOR", - "ALSH", - "ARSH", - "AUSH", - "OCTAL", - "HEX", - "INTEGER", - "DECIMAL", - "STRING", - "REGEX", - "TRUE", - "FALSE", - "NULL", - "PRIMITIVE", - "DEF", - "ID", - "DOTINTEGER", - "DOTID" }; + private static String[] makeRuleNames() { + return new String[] { + "source", + "function", + "parameters", + "statement", + "rstatement", + "dstatement", + "trailer", + "block", + "empty", + "initializer", + "afterthought", + "declaration", + "decltype", + "type", + "declvar", + "trap", + "noncondexpression", + "expression", + "unary", + "unarynotaddsub", + "castexpression", + "primordefcasttype", + "refcasttype", + "chain", + "primary", + "postfix", + "postdot", + "callinvoke", + "fieldaccess", + "braceaccess", + "arrayinitializer", + "listinitializer", + "mapinitializer", + "maptoken", + "arguments", + "argument", + "lambda", + "lamtype", + "funcref" }; + } + + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, + null, + null, + "'{'", + "'}'", + "'['", + "']'", + "'('", + "')'", + "'$'", + "'.'", + "'?.'", + "','", + "';'", + "'if'", + "'in'", + "'else'", + "'while'", + "'do'", + "'for'", + "'continue'", + "'break'", + "'return'", + "'new'", + "'try'", + "'catch'", + "'throw'", + "'this'", + "'instanceof'", + "'!'", + "'~'", + "'*'", + "'/'", + "'%'", + "'+'", + "'-'", + "'<<'", + "'>>'", + "'>>>'", + "'<'", + "'<='", + "'>'", + "'>='", + "'=='", + "'==='", + "'!='", + "'!=='", + "'&'", + "'^'", + "'|'", + "'&&'", + "'||'", + "'?'", + "':'", + "'?:'", + "'::'", + "'->'", + "'=~'", + "'==~'", + "'++'", + "'--'", + "'='", + "'+='", + "'-='", + "'*='", + "'/='", + "'%='", + "'&='", + "'^='", + "'|='", + "'<<='", + "'>>='", + "'>>>='", + null, + null, + null, + null, + null, + null, + "'true'", + "'false'", + "'null'", + null, + "'def'" }; + } + + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + + private static String[] makeSymbolicNames() { + return new String[] { + null, + "WS", + "COMMENT", + "LBRACK", + "RBRACK", + "LBRACE", + "RBRACE", + "LP", + "RP", + "DOLLAR", + "DOT", + "NSDOT", + "COMMA", + "SEMICOLON", + "IF", + "IN", + "ELSE", + "WHILE", + "DO", + "FOR", + "CONTINUE", + "BREAK", + "RETURN", + "NEW", + "TRY", + "CATCH", + "THROW", + "THIS", + "INSTANCEOF", + "BOOLNOT", + "BWNOT", + "MUL", + "DIV", + "REM", + "ADD", + "SUB", + "LSH", + "RSH", + "USH", + "LT", + "LTE", + "GT", + "GTE", + "EQ", + "EQR", + "NE", + "NER", + "BWAND", + "XOR", + "BWOR", + "BOOLAND", + "BOOLOR", + "COND", + "COLON", + "ELVIS", + "REF", + "ARROW", + "FIND", + "MATCH", + "INCR", + "DECR", + "ASSIGN", + "AADD", + "ASUB", + "AMUL", + "ADIV", + "AREM", + "AAND", + "AXOR", + "AOR", + "ALSH", + "ARSH", + "AUSH", + "OCTAL", + "HEX", + "INTEGER", + "DECIMAL", + "STRING", + "REGEX", + "TRUE", + "FALSE", + "NULL", + "PRIMITIVE", + "DEF", + "ID", + "DOTINTEGER", + "DOTID" }; + } + + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); /** @@ -281,7 +308,7 @@ class PainlessParser extends Parser { @Override public String getGrammarFileName() { - return "PainlessParser.g4"; + return "java-escape"; } @Override @@ -304,6 +331,7 @@ class PainlessParser extends Parser { _interp = new ParserATNSimulator(this, _ATN, _decisionToDFA, _sharedContextCache); } + @SuppressWarnings("CheckReturnValue") public static class SourceContext extends ParserRuleContext { public TerminalNode EOF() { return getToken(PainlessParser.EOF, 0); @@ -368,14 +396,8 @@ class PainlessParser extends Parser { setState(87); _errHandler.sync(this); _la = _input.LA(1); - while ((((_la) & ~0x3f) == 0 - && ((1L << _la) & ((1L << LBRACE) | (1L << LP) | (1L << DOLLAR) | (1L << IF) | (1L << WHILE) | (1L << DO) | (1L << FOR) - | (1L << CONTINUE) | (1L << BREAK) | (1L << RETURN) | (1L << NEW) | (1L << TRY) | (1L << THROW) | (1L << BOOLNOT) - | (1L << BWNOT) | (1L << ADD) | (1L << SUB) | (1L << INCR) | (1L << DECR))) != 0) - || ((((_la - 73)) & ~0x3f) == 0 - && ((1L << (_la - 73)) & ((1L << (OCTAL - 73)) | (1L << (HEX - 73)) | (1L << (INTEGER - 73)) | (1L << (DECIMAL - - 73)) | (1L << (STRING - 73)) | (1L << (REGEX - 73)) | (1L << (TRUE - 73)) | (1L << (FALSE - 73)) | (1L - << (NULL - 73)) | (1L << (PRIMITIVE - 73)) | (1L << (DEF - 73)) | (1L << (ID - 73)))) != 0)) { + while (((_la) & ~0x3f) == 0 && ((1L << _la) & 1729382310161040032L) != 0 + || (((_la - 73)) & ~0x3f) == 0 && ((1L << (_la - 73)) & 4095L) != 0) { { { setState(84); @@ -399,6 +421,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class FunctionContext extends ParserRuleContext { public DecltypeContext decltype() { return getRuleContext(DecltypeContext.class, 0); @@ -457,6 +480,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class ParametersContext extends ParserRuleContext { public TerminalNode LP() { return getToken(PainlessParser.LP, 0); @@ -516,9 +540,9 @@ class PainlessParser extends Parser { setState(97); match(LP); setState(109); + _errHandler.sync(this); _la = _input.LA(1); - if (((((_la - 82)) & ~0x3f) == 0 - && ((1L << (_la - 82)) & ((1L << (PRIMITIVE - 82)) | (1L << (DEF - 82)) | (1L << (ID - 82)))) != 0)) { + if ((((_la - 82)) & ~0x3f) == 0 && ((1L << (_la - 82)) & 7L) != 0) { { setState(98); decltype(); @@ -558,6 +582,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class StatementContext extends ParserRuleContext { public RstatementContext rstatement() { return getRuleContext(RstatementContext.class, 0); @@ -597,6 +622,7 @@ class PainlessParser extends Parser { int _la; try { setState(117); + _errHandler.sync(this); switch (_input.LA(1)) { case IF: case WHILE: @@ -642,6 +668,8 @@ class PainlessParser extends Parser { if (!(_la == EOF || _la == SEMICOLON)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } } @@ -659,6 +687,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class RstatementContext extends ParserRuleContext { public RstatementContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -676,6 +705,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class ForContext extends RstatementContext { public TerminalNode FOR() { return getToken(PainlessParser.FOR, 0); @@ -728,6 +758,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class TryContext extends RstatementContext { public TerminalNode TRY() { return getToken(PainlessParser.TRY, 0); @@ -756,6 +787,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class WhileContext extends RstatementContext { public TerminalNode WHILE() { return getToken(PainlessParser.WHILE, 0); @@ -792,6 +824,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class IneachContext extends RstatementContext { public TerminalNode FOR() { return getToken(PainlessParser.FOR, 0); @@ -832,6 +865,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class IfContext extends RstatementContext { public TerminalNode IF() { return getToken(PainlessParser.IF, 0); @@ -872,6 +906,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class EachContext extends RstatementContext { public TerminalNode FOR() { return getToken(PainlessParser.FOR, 0); @@ -968,6 +1003,7 @@ class PainlessParser extends Parser { setState(132); match(RP); setState(135); + _errHandler.sync(this); switch (_input.LA(1)) { case LBRACK: case LBRACE: @@ -1023,14 +1059,10 @@ class PainlessParser extends Parser { setState(138); match(LP); setState(140); + _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 - && ((1L << _la) & ((1L << LBRACE) | (1L << LP) | (1L << DOLLAR) | (1L << NEW) | (1L << BOOLNOT) | (1L << BWNOT) - | (1L << ADD) | (1L << SUB) | (1L << INCR) | (1L << DECR))) != 0) - || ((((_la - 73)) & ~0x3f) == 0 - && ((1L << (_la - 73)) & ((1L << (OCTAL - 73)) | (1L << (HEX - 73)) | (1L << (INTEGER - 73)) | (1L << (DECIMAL - - 73)) | (1L << (STRING - 73)) | (1L << (REGEX - 73)) | (1L << (TRUE - 73)) | (1L << (FALSE - 73)) | (1L - << (NULL - 73)) | (1L << (PRIMITIVE - 73)) | (1L << (DEF - 73)) | (1L << (ID - 73)))) != 0)) { + if (((_la) & ~0x3f) == 0 && ((1L << _la) & 1729382310068880032L) != 0 + || (((_la - 73)) & ~0x3f) == 0 && ((1L << (_la - 73)) & 4095L) != 0) { { setState(139); initializer(); @@ -1040,14 +1072,10 @@ class PainlessParser extends Parser { setState(142); match(SEMICOLON); setState(144); + _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 - && ((1L << _la) & ((1L << LBRACE) | (1L << LP) | (1L << DOLLAR) | (1L << NEW) | (1L << BOOLNOT) | (1L << BWNOT) - | (1L << ADD) | (1L << SUB) | (1L << INCR) | (1L << DECR))) != 0) - || ((((_la - 73)) & ~0x3f) == 0 - && ((1L << (_la - 73)) & ((1L << (OCTAL - 73)) | (1L << (HEX - 73)) | (1L << (INTEGER - 73)) | (1L << (DECIMAL - - 73)) | (1L << (STRING - 73)) | (1L << (REGEX - 73)) | (1L << (TRUE - 73)) | (1L << (FALSE - 73)) | (1L - << (NULL - 73)) | (1L << (ID - 73)))) != 0)) { + if (((_la) & ~0x3f) == 0 && ((1L << _la) & 1729382310068880032L) != 0 + || (((_la - 73)) & ~0x3f) == 0 && ((1L << (_la - 73)) & 2559L) != 0) { { setState(143); expression(); @@ -1057,14 +1085,10 @@ class PainlessParser extends Parser { setState(146); match(SEMICOLON); setState(148); + _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 - && ((1L << _la) & ((1L << LBRACE) | (1L << LP) | (1L << DOLLAR) | (1L << NEW) | (1L << BOOLNOT) | (1L << BWNOT) - | (1L << ADD) | (1L << SUB) | (1L << INCR) | (1L << DECR))) != 0) - || ((((_la - 73)) & ~0x3f) == 0 - && ((1L << (_la - 73)) & ((1L << (OCTAL - 73)) | (1L << (HEX - 73)) | (1L << (INTEGER - 73)) | (1L << (DECIMAL - - 73)) | (1L << (STRING - 73)) | (1L << (REGEX - 73)) | (1L << (TRUE - 73)) | (1L << (FALSE - 73)) | (1L - << (NULL - 73)) | (1L << (ID - 73)))) != 0)) { + if (((_la) & ~0x3f) == 0 && ((1L << _la) & 1729382310068880032L) != 0 + || (((_la - 73)) & ~0x3f) == 0 && ((1L << (_la - 73)) & 2559L) != 0) { { setState(147); afterthought(); @@ -1074,6 +1098,7 @@ class PainlessParser extends Parser { setState(150); match(RP); setState(153); + _errHandler.sync(this); switch (_input.LA(1)) { case LBRACK: case LBRACE: @@ -1200,6 +1225,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class DstatementContext extends ParserRuleContext { public DstatementContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -1217,6 +1243,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class DeclContext extends DstatementContext { public DeclarationContext declaration() { return getRuleContext(DeclarationContext.class, 0); @@ -1233,6 +1260,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class BreakContext extends DstatementContext { public TerminalNode BREAK() { return getToken(PainlessParser.BREAK, 0); @@ -1249,6 +1277,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class ThrowContext extends DstatementContext { public TerminalNode THROW() { return getToken(PainlessParser.THROW, 0); @@ -1269,6 +1298,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class ContinueContext extends DstatementContext { public TerminalNode CONTINUE() { return getToken(PainlessParser.CONTINUE, 0); @@ -1285,6 +1315,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class ExprContext extends DstatementContext { public ExpressionContext expression() { return getRuleContext(ExpressionContext.class, 0); @@ -1301,6 +1332,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class DoContext extends DstatementContext { public TerminalNode DO() { return getToken(PainlessParser.DO, 0); @@ -1337,6 +1369,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class ReturnContext extends DstatementContext { public TerminalNode RETURN() { return getToken(PainlessParser.RETURN, 0); @@ -1409,14 +1442,10 @@ class PainlessParser extends Parser { setState(191); match(RETURN); setState(193); + _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 - && ((1L << _la) & ((1L << LBRACE) | (1L << LP) | (1L << DOLLAR) | (1L << NEW) | (1L << BOOLNOT) | (1L << BWNOT) - | (1L << ADD) | (1L << SUB) | (1L << INCR) | (1L << DECR))) != 0) - || ((((_la - 73)) & ~0x3f) == 0 - && ((1L << (_la - 73)) & ((1L << (OCTAL - 73)) | (1L << (HEX - 73)) | (1L << (INTEGER - 73)) | (1L << (DECIMAL - - 73)) | (1L << (STRING - 73)) | (1L << (REGEX - 73)) | (1L << (TRUE - 73)) | (1L << (FALSE - 73)) | (1L - << (NULL - 73)) | (1L << (ID - 73)))) != 0)) { + if (((_la) & ~0x3f) == 0 && ((1L << _la) & 1729382310068880032L) != 0 + || (((_la - 73)) & ~0x3f) == 0 && ((1L << (_la - 73)) & 2559L) != 0) { { setState(192); expression(); @@ -1452,6 +1481,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class TrailerContext extends ParserRuleContext { public BlockContext block() { return getRuleContext(BlockContext.class, 0); @@ -1482,6 +1512,7 @@ class PainlessParser extends Parser { enterRule(_localctx, 12, RULE_trailer); try { setState(202); + _errHandler.sync(this); switch (_input.LA(1)) { case LBRACK: enterOuterAlt(_localctx, 1); { @@ -1538,6 +1569,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class BlockContext extends ParserRuleContext { public TerminalNode LBRACK() { return getToken(PainlessParser.LBRACK, 0); @@ -1602,15 +1634,10 @@ class PainlessParser extends Parser { _alt = getInterpreter().adaptivePredict(_input, 16, _ctx); } setState(212); + _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 - && ((1L << _la) & ((1L << LBRACE) | (1L << LP) | (1L << DOLLAR) | (1L << DO) | (1L << CONTINUE) | (1L << BREAK) | (1L - << RETURN) | (1L << NEW) | (1L << THROW) | (1L << BOOLNOT) | (1L << BWNOT) | (1L << ADD) | (1L << SUB) | (1L - << INCR) | (1L << DECR))) != 0) - || ((((_la - 73)) & ~0x3f) == 0 - && ((1L << (_la - 73)) & ((1L << (OCTAL - 73)) | (1L << (HEX - 73)) | (1L << (INTEGER - 73)) | (1L << (DECIMAL - - 73)) | (1L << (STRING - 73)) | (1L << (REGEX - 73)) | (1L << (TRUE - 73)) | (1L << (FALSE - 73)) | (1L - << (NULL - 73)) | (1L << (PRIMITIVE - 73)) | (1L << (DEF - 73)) | (1L << (ID - 73)))) != 0)) { + if (((_la) & ~0x3f) == 0 && ((1L << _la) & 1729382310143591072L) != 0 + || (((_la - 73)) & ~0x3f) == 0 && ((1L << (_la - 73)) & 4095L) != 0) { { setState(211); dstatement(); @@ -1630,6 +1657,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class EmptyContext extends ParserRuleContext { public TerminalNode SEMICOLON() { return getToken(PainlessParser.SEMICOLON, 0); @@ -1670,6 +1698,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class InitializerContext extends ParserRuleContext { public DeclarationContext declaration() { return getRuleContext(DeclarationContext.class, 0); @@ -1725,6 +1754,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class AfterthoughtContext extends ParserRuleContext { public ExpressionContext expression() { return getRuleContext(ExpressionContext.class, 0); @@ -1765,6 +1795,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class DeclarationContext extends ParserRuleContext { public DecltypeContext decltype() { return getRuleContext(DecltypeContext.class, 0); @@ -1840,6 +1871,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class DecltypeContext extends ParserRuleContext { public TypeContext type() { return getRuleContext(TypeContext.class, 0); @@ -1915,6 +1947,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class TypeContext extends ParserRuleContext { public TerminalNode DEF() { return getToken(PainlessParser.DEF, 0); @@ -1966,6 +1999,7 @@ class PainlessParser extends Parser { try { int _alt; setState(251); + _errHandler.sync(this); switch (_input.LA(1)) { case DEF: enterOuterAlt(_localctx, 1); { @@ -2016,6 +2050,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class DeclvarContext extends ParserRuleContext { public TerminalNode ID() { return getToken(PainlessParser.ID, 0); @@ -2055,6 +2090,7 @@ class PainlessParser extends Parser { setState(253); match(ID); setState(256); + _errHandler.sync(this); _la = _input.LA(1); if (_la == ASSIGN) { { @@ -2076,6 +2112,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class TrapContext extends ParserRuleContext { public TerminalNode CATCH() { return getToken(PainlessParser.CATCH, 0); @@ -2146,6 +2183,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class NoncondexpressionContext extends ParserRuleContext { public NoncondexpressionContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -2163,6 +2201,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class SingleContext extends NoncondexpressionContext { public UnaryContext unary() { return getRuleContext(UnaryContext.class, 0); @@ -2179,6 +2218,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class CompContext extends NoncondexpressionContext { public List noncondexpression() { return getRuleContexts(NoncondexpressionContext.class); @@ -2231,6 +2271,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class BoolContext extends NoncondexpressionContext { public List noncondexpression() { return getRuleContexts(NoncondexpressionContext.class); @@ -2259,6 +2300,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class BinaryContext extends NoncondexpressionContext { public List noncondexpression() { return getRuleContexts(NoncondexpressionContext.class); @@ -2331,6 +2373,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class ElvisContext extends NoncondexpressionContext { public List noncondexpression() { return getRuleContexts(NoncondexpressionContext.class); @@ -2355,6 +2398,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class InstanceofContext extends NoncondexpressionContext { public NoncondexpressionContext noncondexpression() { return getRuleContext(NoncondexpressionContext.class, 0); @@ -2422,9 +2466,11 @@ class PainlessParser extends Parser { if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)"); setState(269); _la = _input.LA(1); - if (!((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << MUL) | (1L << DIV) | (1L << REM))) != 0))) { + if (!(((_la) & ~0x3f) == 0 && ((1L << _la) & 15032385536L) != 0)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } setState(270); @@ -2441,6 +2487,8 @@ class PainlessParser extends Parser { if (!(_la == ADD || _la == SUB)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } setState(273); @@ -2457,6 +2505,8 @@ class PainlessParser extends Parser { if (!(_la == FIND || _la == MATCH)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } setState(276); @@ -2470,9 +2520,11 @@ class PainlessParser extends Parser { if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)"); setState(278); _la = _input.LA(1); - if (!((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LSH) | (1L << RSH) | (1L << USH))) != 0))) { + if (!(((_la) & ~0x3f) == 0 && ((1L << _la) & 481036337152L) != 0)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } setState(279); @@ -2486,10 +2538,11 @@ class PainlessParser extends Parser { if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)"); setState(281); _la = _input.LA(1); - if (!((((_la) & ~0x3f) == 0 - && ((1L << _la) & ((1L << LT) | (1L << LTE) | (1L << GT) | (1L << GTE))) != 0))) { + if (!(((_la) & ~0x3f) == 0 && ((1L << _la) & 8246337208320L) != 0)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } setState(282); @@ -2503,10 +2556,11 @@ class PainlessParser extends Parser { if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)"); setState(284); _la = _input.LA(1); - if (!((((_la) & ~0x3f) == 0 - && ((1L << _la) & ((1L << EQ) | (1L << EQR) | (1L << NE) | (1L << NER))) != 0))) { + if (!(((_la) & ~0x3f) == 0 && ((1L << _la) & 131941395333120L) != 0)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } setState(285); @@ -2608,6 +2662,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class ExpressionContext extends ParserRuleContext { public ExpressionContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -2625,6 +2680,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class ConditionalContext extends ExpressionContext { public NoncondexpressionContext noncondexpression() { return getRuleContext(NoncondexpressionContext.class, 0); @@ -2657,6 +2713,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class AssignmentContext extends ExpressionContext { public NoncondexpressionContext noncondexpression() { return getRuleContext(NoncondexpressionContext.class, 0); @@ -2725,6 +2782,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class NonconditionalContext extends ExpressionContext { public NoncondexpressionContext noncondexpression() { return getRuleContext(NoncondexpressionContext.class, 0); @@ -2778,12 +2836,11 @@ class PainlessParser extends Parser { noncondexpression(0); setState(320); _la = _input.LA(1); - if (!(((((_la - 61)) & ~0x3f) == 0 - && ((1L << (_la - 61)) & ((1L << (ASSIGN - 61)) | (1L << (AADD - 61)) | (1L << (ASUB - 61)) | (1L << (AMUL - 61)) - | (1L << (ADIV - 61)) | (1L << (AREM - 61)) | (1L << (AAND - 61)) | (1L << (AXOR - 61)) | (1L << (AOR - 61)) - | (1L << (ALSH - 61)) | (1L << (ARSH - 61)) | (1L << (AUSH - 61)))) != 0))) { + if (!((((_la - 61)) & ~0x3f) == 0 && ((1L << (_la - 61)) & 4095L) != 0)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } setState(321); @@ -2801,6 +2858,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class UnaryContext extends ParserRuleContext { public UnaryContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -2818,6 +2876,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class NotaddsubContext extends UnaryContext { public UnarynotaddsubContext unarynotaddsub() { return getRuleContext(UnarynotaddsubContext.class, 0); @@ -2834,6 +2893,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class PreContext extends UnaryContext { public ChainContext chain() { return getRuleContext(ChainContext.class, 0); @@ -2858,6 +2918,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class AddsubContext extends UnaryContext { public UnaryContext unary() { return getRuleContext(UnaryContext.class, 0); @@ -2888,6 +2949,7 @@ class PainlessParser extends Parser { int _la; try { setState(330); + _errHandler.sync(this); switch (_input.LA(1)) { case INCR: case DECR: @@ -2898,6 +2960,8 @@ class PainlessParser extends Parser { if (!(_la == INCR || _la == DECR)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } setState(326); @@ -2913,6 +2977,8 @@ class PainlessParser extends Parser { if (!(_la == ADD || _la == SUB)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } setState(328); @@ -2954,6 +3020,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class UnarynotaddsubContext extends ParserRuleContext { public UnarynotaddsubContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -2971,6 +3038,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class CastContext extends UnarynotaddsubContext { public CastexpressionContext castexpression() { return getRuleContext(CastexpressionContext.class, 0); @@ -2987,6 +3055,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class NotContext extends UnarynotaddsubContext { public UnaryContext unary() { return getRuleContext(UnaryContext.class, 0); @@ -3011,6 +3080,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class ReadContext extends UnarynotaddsubContext { public ChainContext chain() { return getRuleContext(ChainContext.class, 0); @@ -3027,6 +3097,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class PostContext extends UnarynotaddsubContext { public ChainContext chain() { return getRuleContext(ChainContext.class, 0); @@ -3076,6 +3147,8 @@ class PainlessParser extends Parser { if (!(_la == INCR || _la == DECR)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } } @@ -3088,6 +3161,8 @@ class PainlessParser extends Parser { if (!(_la == BOOLNOT || _la == BWNOT)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } setState(337); @@ -3112,6 +3187,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class CastexpressionContext extends ParserRuleContext { public CastexpressionContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -3129,6 +3205,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class RefcastContext extends CastexpressionContext { public TerminalNode LP() { return getToken(PainlessParser.LP, 0); @@ -3157,6 +3234,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class PrimordefcastContext extends CastexpressionContext { public TerminalNode LP() { return getToken(PainlessParser.LP, 0); @@ -3229,6 +3307,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class PrimordefcasttypeContext extends ParserRuleContext { public TerminalNode DEF() { return getToken(PainlessParser.DEF, 0); @@ -3268,6 +3347,8 @@ class PainlessParser extends Parser { if (!(_la == PRIMITIVE || _la == DEF)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } } @@ -3281,6 +3362,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class RefcasttypeContext extends ParserRuleContext { public TerminalNode DEF() { return getToken(PainlessParser.DEF, 0); @@ -3348,6 +3430,7 @@ class PainlessParser extends Parser { int _la; try { setState(384); + _errHandler.sync(this); switch (_input.LA(1)) { case DEF: enterOuterAlt(_localctx, 1); { @@ -3444,6 +3527,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class ChainContext extends ParserRuleContext { public ChainContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -3461,6 +3545,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class DynamicContext extends ChainContext { public PrimaryContext primary() { return getRuleContext(PrimaryContext.class, 0); @@ -3485,6 +3570,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class NewarrayContext extends ChainContext { public ArrayinitializerContext arrayinitializer() { return getRuleContext(ArrayinitializerContext.class, 0); @@ -3550,6 +3636,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class PrimaryContext extends ParserRuleContext { public PrimaryContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -3567,6 +3654,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class ListinitContext extends PrimaryContext { public ListinitializerContext listinitializer() { return getRuleContext(ListinitializerContext.class, 0); @@ -3583,6 +3671,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class RegexContext extends PrimaryContext { public TerminalNode REGEX() { return getToken(PainlessParser.REGEX, 0); @@ -3599,6 +3688,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class NullContext extends PrimaryContext { public TerminalNode NULL() { return getToken(PainlessParser.NULL, 0); @@ -3615,6 +3705,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class StringContext extends PrimaryContext { public TerminalNode STRING() { return getToken(PainlessParser.STRING, 0); @@ -3631,6 +3722,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class MapinitContext extends PrimaryContext { public MapinitializerContext mapinitializer() { return getRuleContext(MapinitializerContext.class, 0); @@ -3647,6 +3739,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class CalllocalContext extends PrimaryContext { public ArgumentsContext arguments() { return getRuleContext(ArgumentsContext.class, 0); @@ -3671,6 +3764,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class TrueContext extends PrimaryContext { public TerminalNode TRUE() { return getToken(PainlessParser.TRUE, 0); @@ -3687,6 +3781,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class FalseContext extends PrimaryContext { public TerminalNode FALSE() { return getToken(PainlessParser.FALSE, 0); @@ -3703,6 +3798,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class VariableContext extends PrimaryContext { public TerminalNode ID() { return getToken(PainlessParser.ID, 0); @@ -3719,6 +3815,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class NumericContext extends PrimaryContext { public TerminalNode OCTAL() { return getToken(PainlessParser.OCTAL, 0); @@ -3747,6 +3844,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class NewobjectContext extends PrimaryContext { public TerminalNode NEW() { return getToken(PainlessParser.NEW, 0); @@ -3771,6 +3869,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class PrecedenceContext extends PrimaryContext { public TerminalNode LP() { return getToken(PainlessParser.LP, 0); @@ -3819,11 +3918,11 @@ class PainlessParser extends Parser { enterOuterAlt(_localctx, 2); { setState(400); _la = _input.LA(1); - if (!(((((_la - 73)) & ~0x3f) == 0 - && ((1L << (_la - 73)) & ((1L << (OCTAL - 73)) | (1L << (HEX - 73)) | (1L << (INTEGER - 73)) | (1L << (DECIMAL - - 73)))) != 0))) { + if (!((((_la - 73)) & ~0x3f) == 0 && ((1L << (_la - 73)) & 15L) != 0)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } } @@ -3892,6 +3991,8 @@ class PainlessParser extends Parser { if (!(_la == DOLLAR || _la == ID)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } setState(410); @@ -3920,6 +4021,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class PostfixContext extends ParserRuleContext { public CallinvokeContext callinvoke() { return getRuleContext(CallinvokeContext.class, 0); @@ -3985,6 +4087,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class PostdotContext extends ParserRuleContext { public CallinvokeContext callinvoke() { return getRuleContext(CallinvokeContext.class, 0); @@ -4040,6 +4143,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class CallinvokeContext extends ParserRuleContext { public TerminalNode DOTID() { return getToken(PainlessParser.DOTID, 0); @@ -4085,6 +4189,8 @@ class PainlessParser extends Parser { if (!(_la == DOT || _la == NSDOT)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } setState(427); @@ -4102,6 +4208,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class FieldaccessContext extends ParserRuleContext { public TerminalNode DOT() { return getToken(PainlessParser.DOT, 0); @@ -4147,6 +4254,8 @@ class PainlessParser extends Parser { if (!(_la == DOT || _la == NSDOT)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } setState(431); @@ -4154,6 +4263,8 @@ class PainlessParser extends Parser { if (!(_la == DOTINTEGER || _la == DOTID)) { _errHandler.recoverInline(this); } else { + if (_input.LA(1) == Token.EOF) matchedEOF = true; + _errHandler.reportMatch(this); consume(); } } @@ -4167,6 +4278,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class BraceaccessContext extends ParserRuleContext { public TerminalNode LBRACE() { return getToken(PainlessParser.LBRACE, 0); @@ -4219,6 +4331,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class ArrayinitializerContext extends ParserRuleContext { public ArrayinitializerContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -4236,6 +4349,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class NewstandardarrayContext extends ArrayinitializerContext { public TerminalNode NEW() { return getToken(PainlessParser.NEW, 0); @@ -4292,6 +4406,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class NewinitializedarrayContext extends ArrayinitializerContext { public TerminalNode NEW() { return getToken(PainlessParser.NEW, 0); @@ -4434,14 +4549,10 @@ class PainlessParser extends Parser { setState(460); match(LBRACK); setState(469); + _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 - && ((1L << _la) & ((1L << LBRACE) | (1L << LP) | (1L << DOLLAR) | (1L << NEW) | (1L << BOOLNOT) | (1L << BWNOT) - | (1L << ADD) | (1L << SUB) | (1L << INCR) | (1L << DECR))) != 0) - || ((((_la - 73)) & ~0x3f) == 0 - && ((1L << (_la - 73)) & ((1L << (OCTAL - 73)) | (1L << (HEX - 73)) | (1L << (INTEGER - 73)) | (1L << (DECIMAL - - 73)) | (1L << (STRING - 73)) | (1L << (REGEX - 73)) | (1L << (TRUE - 73)) | (1L << (FALSE - 73)) | (1L - << (NULL - 73)) | (1L << (ID - 73)))) != 0)) { + if (((_la) & ~0x3f) == 0 && ((1L << _la) & 1729382310068880032L) != 0 + || (((_la - 73)) & ~0x3f) == 0 && ((1L << (_la - 73)) & 2559L) != 0) { { setState(461); expression(); @@ -4495,6 +4606,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class ListinitializerContext extends ParserRuleContext { public TerminalNode LBRACE() { return getToken(PainlessParser.LBRACE, 0); @@ -4589,6 +4701,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class MapinitializerContext extends ParserRuleContext { public TerminalNode LBRACE() { return getToken(PainlessParser.LBRACE, 0); @@ -4689,6 +4802,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class MaptokenContext extends ParserRuleContext { public List expression() { return getRuleContexts(ExpressionContext.class); @@ -4741,6 +4855,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class ArgumentsContext extends ParserRuleContext { public TerminalNode LP() { return getToken(PainlessParser.LP, 0); @@ -4793,14 +4908,10 @@ class PainlessParser extends Parser { setState(515); match(LP); setState(524); + _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 - && ((1L << _la) & ((1L << LBRACE) | (1L << LP) | (1L << DOLLAR) | (1L << NEW) | (1L << THIS) | (1L << BOOLNOT) | (1L - << BWNOT) | (1L << ADD) | (1L << SUB) | (1L << INCR) | (1L << DECR))) != 0) - || ((((_la - 73)) & ~0x3f) == 0 - && ((1L << (_la - 73)) & ((1L << (OCTAL - 73)) | (1L << (HEX - 73)) | (1L << (INTEGER - 73)) | (1L << (DECIMAL - - 73)) | (1L << (STRING - 73)) | (1L << (REGEX - 73)) | (1L << (TRUE - 73)) | (1L << (FALSE - 73)) | (1L - << (NULL - 73)) | (1L << (PRIMITIVE - 73)) | (1L << (DEF - 73)) | (1L << (ID - 73)))) != 0)) { + if (((_la) & ~0x3f) == 0 && ((1L << _la) & 1729382310203097760L) != 0 + || (((_la - 73)) & ~0x3f) == 0 && ((1L << (_la - 73)) & 4095L) != 0) { { setState(516); argument(); @@ -4837,6 +4948,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class ArgumentContext extends ParserRuleContext { public ExpressionContext expression() { return getRuleContext(ExpressionContext.class, 0); @@ -4902,6 +5014,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class LambdaContext extends ParserRuleContext { public TerminalNode ARROW() { return getToken(PainlessParser.ARROW, 0); @@ -4963,6 +5076,7 @@ class PainlessParser extends Parser { enterOuterAlt(_localctx, 1); { setState(546); + _errHandler.sync(this); switch (_input.LA(1)) { case PRIMITIVE: case DEF: @@ -4975,9 +5089,9 @@ class PainlessParser extends Parser { setState(534); match(LP); setState(543); + _errHandler.sync(this); _la = _input.LA(1); - if (((((_la - 82)) & ~0x3f) == 0 - && ((1L << (_la - 82)) & ((1L << (PRIMITIVE - 82)) | (1L << (DEF - 82)) | (1L << (ID - 82)))) != 0)) { + if ((((_la - 82)) & ~0x3f) == 0 && ((1L << (_la - 82)) & 7L) != 0) { { setState(535); lamtype(); @@ -5010,6 +5124,7 @@ class PainlessParser extends Parser { setState(548); match(ARROW); setState(551); + _errHandler.sync(this); switch (_input.LA(1)) { case LBRACK: { setState(549); @@ -5054,6 +5169,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class LamtypeContext extends ParserRuleContext { public TerminalNode ID() { return getToken(PainlessParser.ID, 0); @@ -5107,6 +5223,7 @@ class PainlessParser extends Parser { return _localctx; } + @SuppressWarnings("CheckReturnValue") public static class FuncrefContext extends ParserRuleContext { public FuncrefContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -5124,6 +5241,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class ClassfuncrefContext extends FuncrefContext { public DecltypeContext decltype() { return getRuleContext(DecltypeContext.class, 0); @@ -5148,6 +5266,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class ConstructorfuncrefContext extends FuncrefContext { public DecltypeContext decltype() { return getRuleContext(DecltypeContext.class, 0); @@ -5174,6 +5293,7 @@ class PainlessParser extends Parser { } } + @SuppressWarnings("CheckReturnValue") public static class LocalfuncrefContext extends FuncrefContext { public TerminalNode THIS() { return getToken(PainlessParser.THIS, 0); @@ -5299,224 +5419,395 @@ class PainlessParser extends Parser { return true; } - public static final String _serializedATN = "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3X\u023e\4\2\t\2\4" - + "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t" - + "\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22" - + "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31" - + "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!" - + "\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\3\2\7\2R\n\2\f\2\16" - + "\2U\13\2\3\2\7\2X\n\2\f\2\16\2[\13\2\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\4\3" - + "\4\3\4\3\4\3\4\3\4\3\4\7\4k\n\4\f\4\16\4n\13\4\5\4p\n\4\3\4\3\4\3\5\3" - + "\5\3\5\3\5\5\5x\n\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\5\6\u0082\n\6\3\6" - + "\3\6\3\6\3\6\3\6\3\6\5\6\u008a\n\6\3\6\3\6\3\6\5\6\u008f\n\6\3\6\3\6\5" - + "\6\u0093\n\6\3\6\3\6\5\6\u0097\n\6\3\6\3\6\3\6\5\6\u009c\n\6\3\6\3\6\3" - + "\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6" - + "\6\6\u00b2\n\6\r\6\16\6\u00b3\5\6\u00b6\n\6\3\7\3\7\3\7\3\7\3\7\3\7\3" - + "\7\3\7\3\7\3\7\3\7\3\7\5\7\u00c4\n\7\3\7\3\7\3\7\5\7\u00c9\n\7\3\b\3\b" - + "\5\b\u00cd\n\b\3\t\3\t\7\t\u00d1\n\t\f\t\16\t\u00d4\13\t\3\t\5\t\u00d7" - + "\n\t\3\t\3\t\3\n\3\n\3\13\3\13\5\13\u00df\n\13\3\f\3\f\3\r\3\r\3\r\3\r" - + "\7\r\u00e7\n\r\f\r\16\r\u00ea\13\r\3\16\3\16\3\16\7\16\u00ef\n\16\f\16" - + "\16\16\u00f2\13\16\3\17\3\17\3\17\3\17\3\17\7\17\u00f9\n\17\f\17\16\17" - + "\u00fc\13\17\5\17\u00fe\n\17\3\20\3\20\3\20\5\20\u0103\n\20\3\21\3\21" - + "\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22" - + "\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22" - + "\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22" - + "\3\22\3\22\3\22\3\22\3\22\7\22\u0136\n\22\f\22\16\22\u0139\13\22\3\23" - + "\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\5\23\u0146\n\23\3\24" - + "\3\24\3\24\3\24\3\24\5\24\u014d\n\24\3\25\3\25\3\25\3\25\3\25\3\25\3\25" - + "\5\25\u0156\n\25\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\5\26" - + "\u0162\n\26\3\27\3\27\3\30\3\30\3\30\6\30\u0169\n\30\r\30\16\30\u016a" - + "\3\30\3\30\3\30\6\30\u0170\n\30\r\30\16\30\u0171\3\30\3\30\3\30\7\30\u0177" - + "\n\30\f\30\16\30\u017a\13\30\3\30\3\30\7\30\u017e\n\30\f\30\16\30\u0181" - + "\13\30\5\30\u0183\n\30\3\31\3\31\7\31\u0187\n\31\f\31\16\31\u018a\13\31" - + "\3\31\5\31\u018d\n\31\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32" - + "\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\5\32\u01a2\n\32\3\33\3\33" - + "\3\33\5\33\u01a7\n\33\3\34\3\34\5\34\u01ab\n\34\3\35\3\35\3\35\3\35\3" - + "\36\3\36\3\36\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3 \3 \6 \u01be\n \r \16" - + " \u01bf\3 \3 \7 \u01c4\n \f \16 \u01c7\13 \5 \u01c9\n \3 \3 \3 \3 \3 " - + "\3 \3 \3 \7 \u01d3\n \f \16 \u01d6\13 \5 \u01d8\n \3 \3 \7 \u01dc\n \f" - + " \16 \u01df\13 \5 \u01e1\n \3!\3!\3!\3!\7!\u01e7\n!\f!\16!\u01ea\13!\3" - + "!\3!\3!\3!\5!\u01f0\n!\3\"\3\"\3\"\3\"\7\"\u01f6\n\"\f\"\16\"\u01f9\13" - + "\"\3\"\3\"\3\"\3\"\3\"\5\"\u0200\n\"\3#\3#\3#\3#\3$\3$\3$\3$\7$\u020a" - + "\n$\f$\16$\u020d\13$\5$\u020f\n$\3$\3$\3%\3%\3%\5%\u0216\n%\3&\3&\3&\3" - + "&\3&\7&\u021d\n&\f&\16&\u0220\13&\5&\u0222\n&\3&\5&\u0225\n&\3&\3&\3&" - + "\5&\u022a\n&\3\'\5\'\u022d\n\'\3\'\3\'\3(\3(\3(\3(\3(\3(\3(\3(\3(\3(\3" - + "(\5(\u023c\n(\3(\2\3\")\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*" - + ",.\60\62\64\668:<>@BDFHJLN\2\21\3\3\17\17\3\2!#\3\2$%\3\2;<\3\2&(\3\2" - + "),\3\2-\60\3\2?J\3\2=>\3\2\37 \3\2TU\3\2KN\4\2\13\13VV\3\2\f\r\3\2WX\u0279" - + "\2S\3\2\2\2\4^\3\2\2\2\6c\3\2\2\2\bw\3\2\2\2\n\u00b5\3\2\2\2\f\u00c8\3" - + "\2\2\2\16\u00cc\3\2\2\2\20\u00ce\3\2\2\2\22\u00da\3\2\2\2\24\u00de\3\2" - + "\2\2\26\u00e0\3\2\2\2\30\u00e2\3\2\2\2\32\u00eb\3\2\2\2\34\u00fd\3\2\2" - + "\2\36\u00ff\3\2\2\2 \u0104\3\2\2\2\"\u010b\3\2\2\2$\u0145\3\2\2\2&\u014c" - + "\3\2\2\2(\u0155\3\2\2\2*\u0161\3\2\2\2,\u0163\3\2\2\2.\u0182\3\2\2\2\60" - + "\u018c\3\2\2\2\62\u01a1\3\2\2\2\64\u01a6\3\2\2\2\66\u01aa\3\2\2\28\u01ac" - + "\3\2\2\2:\u01b0\3\2\2\2<\u01b3\3\2\2\2>\u01e0\3\2\2\2@\u01ef\3\2\2\2B" - + "\u01ff\3\2\2\2D\u0201\3\2\2\2F\u0205\3\2\2\2H\u0215\3\2\2\2J\u0224\3\2" - + "\2\2L\u022c\3\2\2\2N\u023b\3\2\2\2PR\5\4\3\2QP\3\2\2\2RU\3\2\2\2SQ\3\2" - + "\2\2ST\3\2\2\2TY\3\2\2\2US\3\2\2\2VX\5\b\5\2WV\3\2\2\2X[\3\2\2\2YW\3\2" - + "\2\2YZ\3\2\2\2Z\\\3\2\2\2[Y\3\2\2\2\\]\7\2\2\3]\3\3\2\2\2^_\5\32\16\2" - + "_`\7V\2\2`a\5\6\4\2ab\5\20\t\2b\5\3\2\2\2co\7\t\2\2de\5\32\16\2el\7V\2" - + "\2fg\7\16\2\2gh\5\32\16\2hi\7V\2\2ik\3\2\2\2jf\3\2\2\2kn\3\2\2\2lj\3\2" - + "\2\2lm\3\2\2\2mp\3\2\2\2nl\3\2\2\2od\3\2\2\2op\3\2\2\2pq\3\2\2\2qr\7\n" - + "\2\2r\7\3\2\2\2sx\5\n\6\2tu\5\f\7\2uv\t\2\2\2vx\3\2\2\2ws\3\2\2\2wt\3" - + "\2\2\2x\t\3\2\2\2yz\7\20\2\2z{\7\t\2\2{|\5$\23\2|}\7\n\2\2}\u0081\5\16" - + "\b\2~\177\7\22\2\2\177\u0082\5\16\b\2\u0080\u0082\6\6\2\2\u0081~\3\2\2" - + "\2\u0081\u0080\3\2\2\2\u0082\u00b6\3\2\2\2\u0083\u0084\7\23\2\2\u0084" - + "\u0085\7\t\2\2\u0085\u0086\5$\23\2\u0086\u0089\7\n\2\2\u0087\u008a\5\16" - + "\b\2\u0088\u008a\5\22\n\2\u0089\u0087\3\2\2\2\u0089\u0088\3\2\2\2\u008a" - + "\u00b6\3\2\2\2\u008b\u008c\7\25\2\2\u008c\u008e\7\t\2\2\u008d\u008f\5" - + "\24\13\2\u008e\u008d\3\2\2\2\u008e\u008f\3\2\2\2\u008f\u0090\3\2\2\2\u0090" - + "\u0092\7\17\2\2\u0091\u0093\5$\23\2\u0092\u0091\3\2\2\2\u0092\u0093\3" - + "\2\2\2\u0093\u0094\3\2\2\2\u0094\u0096\7\17\2\2\u0095\u0097\5\26\f\2\u0096" - + "\u0095\3\2\2\2\u0096\u0097\3\2\2\2\u0097\u0098\3\2\2\2\u0098\u009b\7\n" - + "\2\2\u0099\u009c\5\16\b\2\u009a\u009c\5\22\n\2\u009b\u0099\3\2\2\2\u009b" - + "\u009a\3\2\2\2\u009c\u00b6\3\2\2\2\u009d\u009e\7\25\2\2\u009e\u009f\7" - + "\t\2\2\u009f\u00a0\5\32\16\2\u00a0\u00a1\7V\2\2\u00a1\u00a2\7\67\2\2\u00a2" - + "\u00a3\5$\23\2\u00a3\u00a4\7\n\2\2\u00a4\u00a5\5\16\b\2\u00a5\u00b6\3" - + "\2\2\2\u00a6\u00a7\7\25\2\2\u00a7\u00a8\7\t\2\2\u00a8\u00a9\7V\2\2\u00a9" - + "\u00aa\7\21\2\2\u00aa\u00ab\5$\23\2\u00ab\u00ac\7\n\2\2\u00ac\u00ad\5" - + "\16\b\2\u00ad\u00b6\3\2\2\2\u00ae\u00af\7\32\2\2\u00af\u00b1\5\20\t\2" - + "\u00b0\u00b2\5 \21\2\u00b1\u00b0\3\2\2\2\u00b2\u00b3\3\2\2\2\u00b3\u00b1" - + "\3\2\2\2\u00b3\u00b4\3\2\2\2\u00b4\u00b6\3\2\2\2\u00b5y\3\2\2\2\u00b5" - + "\u0083\3\2\2\2\u00b5\u008b\3\2\2\2\u00b5\u009d\3\2\2\2\u00b5\u00a6\3\2" - + "\2\2\u00b5\u00ae\3\2\2\2\u00b6\13\3\2\2\2\u00b7\u00b8\7\24\2\2\u00b8\u00b9" - + "\5\20\t\2\u00b9\u00ba\7\23\2\2\u00ba\u00bb\7\t\2\2\u00bb\u00bc\5$\23\2" - + "\u00bc\u00bd\7\n\2\2\u00bd\u00c9\3\2\2\2\u00be\u00c9\5\30\r\2\u00bf\u00c9" - + "\7\26\2\2\u00c0\u00c9\7\27\2\2\u00c1\u00c3\7\30\2\2\u00c2\u00c4\5$\23" - + "\2\u00c3\u00c2\3\2\2\2\u00c3\u00c4\3\2\2\2\u00c4\u00c9\3\2\2\2\u00c5\u00c6" - + "\7\34\2\2\u00c6\u00c9\5$\23\2\u00c7\u00c9\5$\23\2\u00c8\u00b7\3\2\2\2" - + "\u00c8\u00be\3\2\2\2\u00c8\u00bf\3\2\2\2\u00c8\u00c0\3\2\2\2\u00c8\u00c1" - + "\3\2\2\2\u00c8\u00c5\3\2\2\2\u00c8\u00c7\3\2\2\2\u00c9\r\3\2\2\2\u00ca" - + "\u00cd\5\20\t\2\u00cb\u00cd\5\b\5\2\u00cc\u00ca\3\2\2\2\u00cc\u00cb\3" - + "\2\2\2\u00cd\17\3\2\2\2\u00ce\u00d2\7\5\2\2\u00cf\u00d1\5\b\5\2\u00d0" - + "\u00cf\3\2\2\2\u00d1\u00d4\3\2\2\2\u00d2\u00d0\3\2\2\2\u00d2\u00d3\3\2" - + "\2\2\u00d3\u00d6\3\2\2\2\u00d4\u00d2\3\2\2\2\u00d5\u00d7\5\f\7\2\u00d6" - + "\u00d5\3\2\2\2\u00d6\u00d7\3\2\2\2\u00d7\u00d8\3\2\2\2\u00d8\u00d9\7\6" - + "\2\2\u00d9\21\3\2\2\2\u00da\u00db\7\17\2\2\u00db\23\3\2\2\2\u00dc\u00df" - + "\5\30\r\2\u00dd\u00df\5$\23\2\u00de\u00dc\3\2\2\2\u00de\u00dd\3\2\2\2" - + "\u00df\25\3\2\2\2\u00e0\u00e1\5$\23\2\u00e1\27\3\2\2\2\u00e2\u00e3\5\32" - + "\16\2\u00e3\u00e8\5\36\20\2\u00e4\u00e5\7\16\2\2\u00e5\u00e7\5\36\20\2" - + "\u00e6\u00e4\3\2\2\2\u00e7\u00ea\3\2\2\2\u00e8\u00e6\3\2\2\2\u00e8\u00e9" - + "\3\2\2\2\u00e9\31\3\2\2\2\u00ea\u00e8\3\2\2\2\u00eb\u00f0\5\34\17\2\u00ec" - + "\u00ed\7\7\2\2\u00ed\u00ef\7\b\2\2\u00ee\u00ec\3\2\2\2\u00ef\u00f2\3\2" - + "\2\2\u00f0\u00ee\3\2\2\2\u00f0\u00f1\3\2\2\2\u00f1\33\3\2\2\2\u00f2\u00f0" - + "\3\2\2\2\u00f3\u00fe\7U\2\2\u00f4\u00fe\7T\2\2\u00f5\u00fa\7V\2\2\u00f6" - + "\u00f7\7\f\2\2\u00f7\u00f9\7X\2\2\u00f8\u00f6\3\2\2\2\u00f9\u00fc\3\2" - + "\2\2\u00fa\u00f8\3\2\2\2\u00fa\u00fb\3\2\2\2\u00fb\u00fe\3\2\2\2\u00fc" - + "\u00fa\3\2\2\2\u00fd\u00f3\3\2\2\2\u00fd\u00f4\3\2\2\2\u00fd\u00f5\3\2" - + "\2\2\u00fe\35\3\2\2\2\u00ff\u0102\7V\2\2\u0100\u0101\7?\2\2\u0101\u0103" - + "\5$\23\2\u0102\u0100\3\2\2\2\u0102\u0103\3\2\2\2\u0103\37\3\2\2\2\u0104" - + "\u0105\7\33\2\2\u0105\u0106\7\t\2\2\u0106\u0107\5\34\17\2\u0107\u0108" - + "\7V\2\2\u0108\u0109\7\n\2\2\u0109\u010a\5\20\t\2\u010a!\3\2\2\2\u010b" - + "\u010c\b\22\1\2\u010c\u010d\5&\24\2\u010d\u0137\3\2\2\2\u010e\u010f\f" - + "\17\2\2\u010f\u0110\t\3\2\2\u0110\u0136\5\"\22\20\u0111\u0112\f\16\2\2" - + "\u0112\u0113\t\4\2\2\u0113\u0136\5\"\22\17\u0114\u0115\f\r\2\2\u0115\u0116" - + "\t\5\2\2\u0116\u0136\5\"\22\16\u0117\u0118\f\f\2\2\u0118\u0119\t\6\2\2" - + "\u0119\u0136\5\"\22\r\u011a\u011b\f\13\2\2\u011b\u011c\t\7\2\2\u011c\u0136" - + "\5\"\22\f\u011d\u011e\f\t\2\2\u011e\u011f\t\b\2\2\u011f\u0136\5\"\22\n" - + "\u0120\u0121\f\b\2\2\u0121\u0122\7\61\2\2\u0122\u0136\5\"\22\t\u0123\u0124" - + "\f\7\2\2\u0124\u0125\7\62\2\2\u0125\u0136\5\"\22\b\u0126\u0127\f\6\2\2" - + "\u0127\u0128\7\63\2\2\u0128\u0136\5\"\22\7\u0129\u012a\f\5\2\2\u012a\u012b" - + "\7\64\2\2\u012b\u0136\5\"\22\6\u012c\u012d\f\4\2\2\u012d\u012e\7\65\2" - + "\2\u012e\u0136\5\"\22\5\u012f\u0130\f\3\2\2\u0130\u0131\78\2\2\u0131\u0136" - + "\5\"\22\3\u0132\u0133\f\n\2\2\u0133\u0134\7\36\2\2\u0134\u0136\5\32\16" - + "\2\u0135\u010e\3\2\2\2\u0135\u0111\3\2\2\2\u0135\u0114\3\2\2\2\u0135\u0117" - + "\3\2\2\2\u0135\u011a\3\2\2\2\u0135\u011d\3\2\2\2\u0135\u0120\3\2\2\2\u0135" - + "\u0123\3\2\2\2\u0135\u0126\3\2\2\2\u0135\u0129\3\2\2\2\u0135\u012c\3\2" - + "\2\2\u0135\u012f\3\2\2\2\u0135\u0132\3\2\2\2\u0136\u0139\3\2\2\2\u0137" - + "\u0135\3\2\2\2\u0137\u0138\3\2\2\2\u0138#\3\2\2\2\u0139\u0137\3\2\2\2" - + "\u013a\u0146\5\"\22\2\u013b\u013c\5\"\22\2\u013c\u013d\7\66\2\2\u013d" - + "\u013e\5$\23\2\u013e\u013f\7\67\2\2\u013f\u0140\5$\23\2\u0140\u0146\3" - + "\2\2\2\u0141\u0142\5\"\22\2\u0142\u0143\t\t\2\2\u0143\u0144\5$\23\2\u0144" - + "\u0146\3\2\2\2\u0145\u013a\3\2\2\2\u0145\u013b\3\2\2\2\u0145\u0141\3\2" - + "\2\2\u0146%\3\2\2\2\u0147\u0148\t\n\2\2\u0148\u014d\5\60\31\2\u0149\u014a" - + "\t\4\2\2\u014a\u014d\5&\24\2\u014b\u014d\5(\25\2\u014c\u0147\3\2\2\2\u014c" - + "\u0149\3\2\2\2\u014c\u014b\3\2\2\2\u014d\'\3\2\2\2\u014e\u0156\5\60\31" - + "\2\u014f\u0150\5\60\31\2\u0150\u0151\t\n\2\2\u0151\u0156\3\2\2\2\u0152" - + "\u0153\t\13\2\2\u0153\u0156\5&\24\2\u0154\u0156\5*\26\2\u0155\u014e\3" - + "\2\2\2\u0155\u014f\3\2\2\2\u0155\u0152\3\2\2\2\u0155\u0154\3\2\2\2\u0156" - + ")\3\2\2\2\u0157\u0158\7\t\2\2\u0158\u0159\5,\27\2\u0159\u015a\7\n\2\2" - + "\u015a\u015b\5&\24\2\u015b\u0162\3\2\2\2\u015c\u015d\7\t\2\2\u015d\u015e" - + "\5.\30\2\u015e\u015f\7\n\2\2\u015f\u0160\5(\25\2\u0160\u0162\3\2\2\2\u0161" - + "\u0157\3\2\2\2\u0161\u015c\3\2\2\2\u0162+\3\2\2\2\u0163\u0164\t\f\2\2" - + "\u0164-\3\2\2\2\u0165\u0168\7U\2\2\u0166\u0167\7\7\2\2\u0167\u0169\7\b" - + "\2\2\u0168\u0166\3\2\2\2\u0169\u016a\3\2\2\2\u016a\u0168\3\2\2\2\u016a" - + "\u016b\3\2\2\2\u016b\u0183\3\2\2\2\u016c\u016f\7T\2\2\u016d\u016e\7\7" - + "\2\2\u016e\u0170\7\b\2\2\u016f\u016d\3\2\2\2\u0170\u0171\3\2\2\2\u0171" - + "\u016f\3\2\2\2\u0171\u0172\3\2\2\2\u0172\u0183\3\2\2\2\u0173\u0178\7V" - + "\2\2\u0174\u0175\7\f\2\2\u0175\u0177\7X\2\2\u0176\u0174\3\2\2\2\u0177" - + "\u017a\3\2\2\2\u0178\u0176\3\2\2\2\u0178\u0179\3\2\2\2\u0179\u017f\3\2" - + "\2\2\u017a\u0178\3\2\2\2\u017b\u017c\7\7\2\2\u017c\u017e\7\b\2\2\u017d" - + "\u017b\3\2\2\2\u017e\u0181\3\2\2\2\u017f\u017d\3\2\2\2\u017f\u0180\3\2" - + "\2\2\u0180\u0183\3\2\2\2\u0181\u017f\3\2\2\2\u0182\u0165\3\2\2\2\u0182" - + "\u016c\3\2\2\2\u0182\u0173\3\2\2\2\u0183/\3\2\2\2\u0184\u0188\5\62\32" - + "\2\u0185\u0187\5\64\33\2\u0186\u0185\3\2\2\2\u0187\u018a\3\2\2\2\u0188" - + "\u0186\3\2\2\2\u0188\u0189\3\2\2\2\u0189\u018d\3\2\2\2\u018a\u0188\3\2" - + "\2\2\u018b\u018d\5> \2\u018c\u0184\3\2\2\2\u018c\u018b\3\2\2\2\u018d\61" - + "\3\2\2\2\u018e\u018f\7\t\2\2\u018f\u0190\5$\23\2\u0190\u0191\7\n\2\2\u0191" - + "\u01a2\3\2\2\2\u0192\u01a2\t\r\2\2\u0193\u01a2\7Q\2\2\u0194\u01a2\7R\2" - + "\2\u0195\u01a2\7S\2\2\u0196\u01a2\7O\2\2\u0197\u01a2\7P\2\2\u0198\u01a2" - + "\5@!\2\u0199\u01a2\5B\"\2\u019a\u01a2\7V\2\2\u019b\u019c\t\16\2\2\u019c" - + "\u01a2\5F$\2\u019d\u019e\7\31\2\2\u019e\u019f\5\34\17\2\u019f\u01a0\5" - + "F$\2\u01a0\u01a2\3\2\2\2\u01a1\u018e\3\2\2\2\u01a1\u0192\3\2\2\2\u01a1" - + "\u0193\3\2\2\2\u01a1\u0194\3\2\2\2\u01a1\u0195\3\2\2\2\u01a1\u0196\3\2" - + "\2\2\u01a1\u0197\3\2\2\2\u01a1\u0198\3\2\2\2\u01a1\u0199\3\2\2\2\u01a1" - + "\u019a\3\2\2\2\u01a1\u019b\3\2\2\2\u01a1\u019d\3\2\2\2\u01a2\63\3\2\2" - + "\2\u01a3\u01a7\58\35\2\u01a4\u01a7\5:\36\2\u01a5\u01a7\5<\37\2\u01a6\u01a3" - + "\3\2\2\2\u01a6\u01a4\3\2\2\2\u01a6\u01a5\3\2\2\2\u01a7\65\3\2\2\2\u01a8" - + "\u01ab\58\35\2\u01a9\u01ab\5:\36\2\u01aa\u01a8\3\2\2\2\u01aa\u01a9\3\2" - + "\2\2\u01ab\67\3\2\2\2\u01ac\u01ad\t\17\2\2\u01ad\u01ae\7X\2\2\u01ae\u01af" - + "\5F$\2\u01af9\3\2\2\2\u01b0\u01b1\t\17\2\2\u01b1\u01b2\t\20\2\2\u01b2" - + ";\3\2\2\2\u01b3\u01b4\7\7\2\2\u01b4\u01b5\5$\23\2\u01b5\u01b6\7\b\2\2" - + "\u01b6=\3\2\2\2\u01b7\u01b8\7\31\2\2\u01b8\u01bd\5\34\17\2\u01b9\u01ba" - + "\7\7\2\2\u01ba\u01bb\5$\23\2\u01bb\u01bc\7\b\2\2\u01bc\u01be\3\2\2\2\u01bd" - + "\u01b9\3\2\2\2\u01be\u01bf\3\2\2\2\u01bf\u01bd\3\2\2\2\u01bf\u01c0\3\2" - + "\2\2\u01c0\u01c8\3\2\2\2\u01c1\u01c5\5\66\34\2\u01c2\u01c4\5\64\33\2\u01c3" - + "\u01c2\3\2\2\2\u01c4\u01c7\3\2\2\2\u01c5\u01c3\3\2\2\2\u01c5\u01c6\3\2" - + "\2\2\u01c6\u01c9\3\2\2\2\u01c7\u01c5\3\2\2\2\u01c8\u01c1\3\2\2\2\u01c8" - + "\u01c9\3\2\2\2\u01c9\u01e1\3\2\2\2\u01ca\u01cb\7\31\2\2\u01cb\u01cc\5" - + "\34\17\2\u01cc\u01cd\7\7\2\2\u01cd\u01ce\7\b\2\2\u01ce\u01d7\7\5\2\2\u01cf" - + "\u01d4\5$\23\2\u01d0\u01d1\7\16\2\2\u01d1\u01d3\5$\23\2\u01d2\u01d0\3" - + "\2\2\2\u01d3\u01d6\3\2\2\2\u01d4\u01d2\3\2\2\2\u01d4\u01d5\3\2\2\2\u01d5" - + "\u01d8\3\2\2\2\u01d6\u01d4\3\2\2\2\u01d7\u01cf\3\2\2\2\u01d7\u01d8\3\2" - + "\2\2\u01d8\u01d9\3\2\2\2\u01d9\u01dd\7\6\2\2\u01da\u01dc\5\64\33\2\u01db" - + "\u01da\3\2\2\2\u01dc\u01df\3\2\2\2\u01dd\u01db\3\2\2\2\u01dd\u01de\3\2" - + "\2\2\u01de\u01e1\3\2\2\2\u01df\u01dd\3\2\2\2\u01e0\u01b7\3\2\2\2\u01e0" - + "\u01ca\3\2\2\2\u01e1?\3\2\2\2\u01e2\u01e3\7\7\2\2\u01e3\u01e8\5$\23\2" - + "\u01e4\u01e5\7\16\2\2\u01e5\u01e7\5$\23\2\u01e6\u01e4\3\2\2\2\u01e7\u01ea" - + "\3\2\2\2\u01e8\u01e6\3\2\2\2\u01e8\u01e9\3\2\2\2\u01e9\u01eb\3\2\2\2\u01ea" - + "\u01e8\3\2\2\2\u01eb\u01ec\7\b\2\2\u01ec\u01f0\3\2\2\2\u01ed\u01ee\7\7" - + "\2\2\u01ee\u01f0\7\b\2\2\u01ef\u01e2\3\2\2\2\u01ef\u01ed\3\2\2\2\u01f0" - + "A\3\2\2\2\u01f1\u01f2\7\7\2\2\u01f2\u01f7\5D#\2\u01f3\u01f4\7\16\2\2\u01f4" - + "\u01f6\5D#\2\u01f5\u01f3\3\2\2\2\u01f6\u01f9\3\2\2\2\u01f7\u01f5\3\2\2" - + "\2\u01f7\u01f8\3\2\2\2\u01f8\u01fa\3\2\2\2\u01f9\u01f7\3\2\2\2\u01fa\u01fb" - + "\7\b\2\2\u01fb\u0200\3\2\2\2\u01fc\u01fd\7\7\2\2\u01fd\u01fe\7\67\2\2" - + "\u01fe\u0200\7\b\2\2\u01ff\u01f1\3\2\2\2\u01ff\u01fc\3\2\2\2\u0200C\3" - + "\2\2\2\u0201\u0202\5$\23\2\u0202\u0203\7\67\2\2\u0203\u0204\5$\23\2\u0204" - + "E\3\2\2\2\u0205\u020e\7\t\2\2\u0206\u020b\5H%\2\u0207\u0208\7\16\2\2\u0208" - + "\u020a\5H%\2\u0209\u0207\3\2\2\2\u020a\u020d\3\2\2\2\u020b\u0209\3\2\2" - + "\2\u020b\u020c\3\2\2\2\u020c\u020f\3\2\2\2\u020d\u020b\3\2\2\2\u020e\u0206" - + "\3\2\2\2\u020e\u020f\3\2\2\2\u020f\u0210\3\2\2\2\u0210\u0211\7\n\2\2\u0211" - + "G\3\2\2\2\u0212\u0216\5$\23\2\u0213\u0216\5J&\2\u0214\u0216\5N(\2\u0215" - + "\u0212\3\2\2\2\u0215\u0213\3\2\2\2\u0215\u0214\3\2\2\2\u0216I\3\2\2\2" - + "\u0217\u0225\5L\'\2\u0218\u0221\7\t\2\2\u0219\u021e\5L\'\2\u021a\u021b" - + "\7\16\2\2\u021b\u021d\5L\'\2\u021c\u021a\3\2\2\2\u021d\u0220\3\2\2\2\u021e" - + "\u021c\3\2\2\2\u021e\u021f\3\2\2\2\u021f\u0222\3\2\2\2\u0220\u021e\3\2" - + "\2\2\u0221\u0219\3\2\2\2\u0221\u0222\3\2\2\2\u0222\u0223\3\2\2\2\u0223" - + "\u0225\7\n\2\2\u0224\u0217\3\2\2\2\u0224\u0218\3\2\2\2\u0225\u0226\3\2" - + "\2\2\u0226\u0229\7:\2\2\u0227\u022a\5\20\t\2\u0228\u022a\5$\23\2\u0229" - + "\u0227\3\2\2\2\u0229\u0228\3\2\2\2\u022aK\3\2\2\2\u022b\u022d\5\32\16" - + "\2\u022c\u022b\3\2\2\2\u022c\u022d\3\2\2\2\u022d\u022e\3\2\2\2\u022e\u022f" - + "\7V\2\2\u022fM\3\2\2\2\u0230\u0231\5\32\16\2\u0231\u0232\79\2\2\u0232" - + "\u0233\7V\2\2\u0233\u023c\3\2\2\2\u0234\u0235\5\32\16\2\u0235\u0236\7" - + "9\2\2\u0236\u0237\7\31\2\2\u0237\u023c\3\2\2\2\u0238\u0239\7\35\2\2\u0239" - + "\u023a\79\2\2\u023a\u023c\7V\2\2\u023b\u0230\3\2\2\2\u023b\u0234\3\2\2" - + "\2\u023b\u0238\3\2\2\2\u023cO\3\2\2\2>SYlow\u0081\u0089\u008e\u0092\u0096" - + "\u009b\u00b3\u00b5\u00c3\u00c8\u00cc\u00d2\u00d6\u00de\u00e8\u00f0\u00fa" - + "\u00fd\u0102\u0135\u0137\u0145\u014c\u0155\u0161\u016a\u0171\u0178\u017f" - + "\u0182\u0188\u018c\u01a1\u01a6\u01aa\u01bf\u01c5\u01c8\u01d4\u01d7\u01dd" - + "\u01e0\u01e8\u01ef\u01f7\u01ff\u020b\u020e\u0215\u021e\u0221\u0224\u0229" - + "\u022c\u023b"; + public static final String _serializedATN = "\u0004\u0001V\u023c\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002" + + "\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002" + + "\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007\u0007\u0007\u0002" + + "\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b\u0007\u000b\u0002" + + "\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0002\u000f\u0007\u000f" + + "\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011\u0002\u0012\u0007\u0012" + + "\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014\u0002\u0015\u0007\u0015" + + "\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017\u0002\u0018\u0007\u0018" + + "\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a\u0002\u001b\u0007\u001b" + + "\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d\u0002\u001e\u0007\u001e" + + "\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!\u0007!\u0002\"\u0007\"\u0002" + + "#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002&\u0007&\u0001\u0000\u0005\u0000" + + "P\b\u0000\n\u0000\f\u0000S\t\u0000\u0001\u0000\u0005\u0000V\b\u0000\n" + + "\u0000\f\u0000Y\t\u0000\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001" + + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0002" + + "\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0005\u0002i\b\u0002" + + "\n\u0002\f\u0002l\t\u0002\u0003\u0002n\b\u0002\u0001\u0002\u0001\u0002" + + "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0003\u0003v\b\u0003" + + "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004" + + "\u0001\u0004\u0001\u0004\u0003\u0004\u0080\b\u0004\u0001\u0004\u0001\u0004" + + "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0003\u0004\u0088\b\u0004" + + "\u0001\u0004\u0001\u0004\u0001\u0004\u0003\u0004\u008d\b\u0004\u0001\u0004" + + "\u0001\u0004\u0003\u0004\u0091\b\u0004\u0001\u0004\u0001\u0004\u0003\u0004" + + "\u0095\b\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0003\u0004\u009a\b" + + "\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001" + + "\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001" + + "\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001" + + "\u0004\u0001\u0004\u0001\u0004\u0004\u0004\u00b0\b\u0004\u000b\u0004\f" + + "\u0004\u00b1\u0003\u0004\u00b4\b\u0004\u0001\u0005\u0001\u0005\u0001\u0005" + + "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005" + + "\u0001\u0005\u0001\u0005\u0001\u0005\u0003\u0005\u00c2\b\u0005\u0001\u0005" + + "\u0001\u0005\u0001\u0005\u0003\u0005\u00c7\b\u0005\u0001\u0006\u0001\u0006" + + "\u0003\u0006\u00cb\b\u0006\u0001\u0007\u0001\u0007\u0005\u0007\u00cf\b" + + "\u0007\n\u0007\f\u0007\u00d2\t\u0007\u0001\u0007\u0003\u0007\u00d5\b\u0007" + + "\u0001\u0007\u0001\u0007\u0001\b\u0001\b\u0001\t\u0001\t\u0003\t\u00dd" + + "\b\t\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0005" + + "\u000b\u00e5\b\u000b\n\u000b\f\u000b\u00e8\t\u000b\u0001\f\u0001\f\u0001" + + "\f\u0005\f\u00ed\b\f\n\f\f\f\u00f0\t\f\u0001\r\u0001\r\u0001\r\u0001\r" + + "\u0001\r\u0005\r\u00f7\b\r\n\r\f\r\u00fa\t\r\u0003\r\u00fc\b\r\u0001\u000e" + + "\u0001\u000e\u0001\u000e\u0003\u000e\u0101\b\u000e\u0001\u000f\u0001\u000f" + + "\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u0010" + + "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010" + + "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010" + + "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010" + + "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010" + + "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010" + + "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010" + + "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0005\u0010" + + "\u0134\b\u0010\n\u0010\f\u0010\u0137\t\u0010\u0001\u0011\u0001\u0011\u0001" + + "\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001" + + "\u0011\u0001\u0011\u0001\u0011\u0003\u0011\u0144\b\u0011\u0001\u0012\u0001" + + "\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0003\u0012\u014b\b\u0012\u0001" + + "\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001" + + "\u0013\u0003\u0013\u0154\b\u0013\u0001\u0014\u0001\u0014\u0001\u0014\u0001" + + "\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001" + + "\u0014\u0003\u0014\u0160\b\u0014\u0001\u0015\u0001\u0015\u0001\u0016\u0001" + + "\u0016\u0001\u0016\u0004\u0016\u0167\b\u0016\u000b\u0016\f\u0016\u0168" + + "\u0001\u0016\u0001\u0016\u0001\u0016\u0004\u0016\u016e\b\u0016\u000b\u0016" + + "\f\u0016\u016f\u0001\u0016\u0001\u0016\u0001\u0016\u0005\u0016\u0175\b" + + "\u0016\n\u0016\f\u0016\u0178\t\u0016\u0001\u0016\u0001\u0016\u0005\u0016" + + "\u017c\b\u0016\n\u0016\f\u0016\u017f\t\u0016\u0003\u0016\u0181\b\u0016" + + "\u0001\u0017\u0001\u0017\u0005\u0017\u0185\b\u0017\n\u0017\f\u0017\u0188" + + "\t\u0017\u0001\u0017\u0003\u0017\u018b\b\u0017\u0001\u0018\u0001\u0018" + + "\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018" + + "\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018" + + "\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0003\u0018" + + "\u01a0\b\u0018\u0001\u0019\u0001\u0019\u0001\u0019\u0003\u0019\u01a5\b" + + "\u0019\u0001\u001a\u0001\u001a\u0003\u001a\u01a9\b\u001a\u0001\u001b\u0001" + + "\u001b\u0001\u001b\u0001\u001b\u0001\u001c\u0001\u001c\u0001\u001c\u0001" + + "\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001e\u0001\u001e\u0001" + + "\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0004\u001e\u01bc\b\u001e\u000b" + + "\u001e\f\u001e\u01bd\u0001\u001e\u0001\u001e\u0005\u001e\u01c2\b\u001e" + + "\n\u001e\f\u001e\u01c5\t\u001e\u0003\u001e\u01c7\b\u001e\u0001\u001e\u0001" + + "\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0001" + + "\u001e\u0005\u001e\u01d1\b\u001e\n\u001e\f\u001e\u01d4\t\u001e\u0003\u001e" + + "\u01d6\b\u001e\u0001\u001e\u0001\u001e\u0005\u001e\u01da\b\u001e\n\u001e" + + "\f\u001e\u01dd\t\u001e\u0003\u001e\u01df\b\u001e\u0001\u001f\u0001\u001f" + + "\u0001\u001f\u0001\u001f\u0005\u001f\u01e5\b\u001f\n\u001f\f\u001f\u01e8" + + "\t\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0003\u001f\u01ee" + + "\b\u001f\u0001 \u0001 \u0001 \u0001 \u0005 \u01f4\b \n \f \u01f7\t \u0001" + + " \u0001 \u0001 \u0001 \u0001 \u0003 \u01fe\b \u0001!\u0001!\u0001!\u0001" + + "!\u0001\"\u0001\"\u0001\"\u0001\"\u0005\"\u0208\b\"\n\"\f\"\u020b\t\"" + + "\u0003\"\u020d\b\"\u0001\"\u0001\"\u0001#\u0001#\u0001#\u0003#\u0214\b" + + "#\u0001$\u0001$\u0001$\u0001$\u0001$\u0005$\u021b\b$\n$\f$\u021e\t$\u0003" + + "$\u0220\b$\u0001$\u0003$\u0223\b$\u0001$\u0001$\u0001$\u0003$\u0228\b" + + "$\u0001%\u0003%\u022b\b%\u0001%\u0001%\u0001&\u0001&\u0001&\u0001&\u0001" + + "&\u0001&\u0001&\u0001&\u0001&\u0001&\u0001&\u0003&\u023a\b&\u0001&\u0000" + + "\u0001 \'\u0000\u0002\u0004\u0006\b\n\f\u000e\u0010\u0012\u0014\u0016" + + "\u0018\u001a\u001c\u001e \"$&(*,.02468:<>@BDFHJL\u0000\u000f\u0001\u0001" + + "\r\r\u0001\u0000\u001f!\u0001\u0000\"#\u0001\u00009:\u0001\u0000$&\u0001" + + "\u0000\'*\u0001\u0000+.\u0001\u0000=H\u0001\u0000;<\u0001\u0000\u001d" + + "\u001e\u0001\u0000RS\u0001\u0000IL\u0002\u0000\t\tTT\u0001\u0000\n\u000b" + + "\u0001\u0000UV\u0277\u0000Q\u0001\u0000\u0000\u0000\u0002\\\u0001\u0000" + + "\u0000\u0000\u0004a\u0001\u0000\u0000\u0000\u0006u\u0001\u0000\u0000\u0000" + + "\b\u00b3\u0001\u0000\u0000\u0000\n\u00c6\u0001\u0000\u0000\u0000\f\u00ca" + + "\u0001\u0000\u0000\u0000\u000e\u00cc\u0001\u0000\u0000\u0000\u0010\u00d8" + + "\u0001\u0000\u0000\u0000\u0012\u00dc\u0001\u0000\u0000\u0000\u0014\u00de" + + "\u0001\u0000\u0000\u0000\u0016\u00e0\u0001\u0000\u0000\u0000\u0018\u00e9" + + "\u0001\u0000\u0000\u0000\u001a\u00fb\u0001\u0000\u0000\u0000\u001c\u00fd" + + "\u0001\u0000\u0000\u0000\u001e\u0102\u0001\u0000\u0000\u0000 \u0109\u0001" + + "\u0000\u0000\u0000\"\u0143\u0001\u0000\u0000\u0000$\u014a\u0001\u0000" + + "\u0000\u0000&\u0153\u0001\u0000\u0000\u0000(\u015f\u0001\u0000\u0000\u0000" + + "*\u0161\u0001\u0000\u0000\u0000,\u0180\u0001\u0000\u0000\u0000.\u018a" + + "\u0001\u0000\u0000\u00000\u019f\u0001\u0000\u0000\u00002\u01a4\u0001\u0000" + + "\u0000\u00004\u01a8\u0001\u0000\u0000\u00006\u01aa\u0001\u0000\u0000\u0000" + + "8\u01ae\u0001\u0000\u0000\u0000:\u01b1\u0001\u0000\u0000\u0000<\u01de" + + "\u0001\u0000\u0000\u0000>\u01ed\u0001\u0000\u0000\u0000@\u01fd\u0001\u0000" + + "\u0000\u0000B\u01ff\u0001\u0000\u0000\u0000D\u0203\u0001\u0000\u0000\u0000" + + "F\u0213\u0001\u0000\u0000\u0000H\u0222\u0001\u0000\u0000\u0000J\u022a" + + "\u0001\u0000\u0000\u0000L\u0239\u0001\u0000\u0000\u0000NP\u0003\u0002" + + "\u0001\u0000ON\u0001\u0000\u0000\u0000PS\u0001\u0000\u0000\u0000QO\u0001" + + "\u0000\u0000\u0000QR\u0001\u0000\u0000\u0000RW\u0001\u0000\u0000\u0000" + + "SQ\u0001\u0000\u0000\u0000TV\u0003\u0006\u0003\u0000UT\u0001\u0000\u0000" + + "\u0000VY\u0001\u0000\u0000\u0000WU\u0001\u0000\u0000\u0000WX\u0001\u0000" + + "\u0000\u0000XZ\u0001\u0000\u0000\u0000YW\u0001\u0000\u0000\u0000Z[\u0005" + + "\u0000\u0000\u0001[\u0001\u0001\u0000\u0000\u0000\\]\u0003\u0018\f\u0000" + + "]^\u0005T\u0000\u0000^_\u0003\u0004\u0002\u0000_`\u0003\u000e\u0007\u0000" + + "`\u0003\u0001\u0000\u0000\u0000am\u0005\u0007\u0000\u0000bc\u0003\u0018" + + "\f\u0000cj\u0005T\u0000\u0000de\u0005\f\u0000\u0000ef\u0003\u0018\f\u0000" + + "fg\u0005T\u0000\u0000gi\u0001\u0000\u0000\u0000hd\u0001\u0000\u0000\u0000" + + "il\u0001\u0000\u0000\u0000jh\u0001\u0000\u0000\u0000jk\u0001\u0000\u0000" + + "\u0000kn\u0001\u0000\u0000\u0000lj\u0001\u0000\u0000\u0000mb\u0001\u0000" + + "\u0000\u0000mn\u0001\u0000\u0000\u0000no\u0001\u0000\u0000\u0000op\u0005" + + "\b\u0000\u0000p\u0005\u0001\u0000\u0000\u0000qv\u0003\b\u0004\u0000rs" + + "\u0003\n\u0005\u0000st\u0007\u0000\u0000\u0000tv\u0001\u0000\u0000\u0000" + + "uq\u0001\u0000\u0000\u0000ur\u0001\u0000\u0000\u0000v\u0007\u0001\u0000" + + "\u0000\u0000wx\u0005\u000e\u0000\u0000xy\u0005\u0007\u0000\u0000yz\u0003" + + "\"\u0011\u0000z{\u0005\b\u0000\u0000{\u007f\u0003\f\u0006\u0000|}\u0005" + + "\u0010\u0000\u0000}\u0080\u0003\f\u0006\u0000~\u0080\u0004\u0004\u0000" + + "\u0000\u007f|\u0001\u0000\u0000\u0000\u007f~\u0001\u0000\u0000\u0000\u0080" + + "\u00b4\u0001\u0000\u0000\u0000\u0081\u0082\u0005\u0011\u0000\u0000\u0082" + + "\u0083\u0005\u0007\u0000\u0000\u0083\u0084\u0003\"\u0011\u0000\u0084\u0087" + + "\u0005\b\u0000\u0000\u0085\u0088\u0003\f\u0006\u0000\u0086\u0088\u0003" + + "\u0010\b\u0000\u0087\u0085\u0001\u0000\u0000\u0000\u0087\u0086\u0001\u0000" + + "\u0000\u0000\u0088\u00b4\u0001\u0000\u0000\u0000\u0089\u008a\u0005\u0013" + + "\u0000\u0000\u008a\u008c\u0005\u0007\u0000\u0000\u008b\u008d\u0003\u0012" + + "\t\u0000\u008c\u008b\u0001\u0000\u0000\u0000\u008c\u008d\u0001\u0000\u0000" + + "\u0000\u008d\u008e\u0001\u0000\u0000\u0000\u008e\u0090\u0005\r\u0000\u0000" + + "\u008f\u0091\u0003\"\u0011\u0000\u0090\u008f\u0001\u0000\u0000\u0000\u0090" + + "\u0091\u0001\u0000\u0000\u0000\u0091\u0092\u0001\u0000\u0000\u0000\u0092" + + "\u0094\u0005\r\u0000\u0000\u0093\u0095\u0003\u0014\n\u0000\u0094\u0093" + + "\u0001\u0000\u0000\u0000\u0094\u0095\u0001\u0000\u0000\u0000\u0095\u0096" + + "\u0001\u0000\u0000\u0000\u0096\u0099\u0005\b\u0000\u0000\u0097\u009a\u0003" + + "\f\u0006\u0000\u0098\u009a\u0003\u0010\b\u0000\u0099\u0097\u0001\u0000" + + "\u0000\u0000\u0099\u0098\u0001\u0000\u0000\u0000\u009a\u00b4\u0001\u0000" + + "\u0000\u0000\u009b\u009c\u0005\u0013\u0000\u0000\u009c\u009d\u0005\u0007" + + "\u0000\u0000\u009d\u009e\u0003\u0018\f\u0000\u009e\u009f\u0005T\u0000" + + "\u0000\u009f\u00a0\u00055\u0000\u0000\u00a0\u00a1\u0003\"\u0011\u0000" + + "\u00a1\u00a2\u0005\b\u0000\u0000\u00a2\u00a3\u0003\f\u0006\u0000\u00a3" + + "\u00b4\u0001\u0000\u0000\u0000\u00a4\u00a5\u0005\u0013\u0000\u0000\u00a5" + + "\u00a6\u0005\u0007\u0000\u0000\u00a6\u00a7\u0005T\u0000\u0000\u00a7\u00a8" + + "\u0005\u000f\u0000\u0000\u00a8\u00a9\u0003\"\u0011\u0000\u00a9\u00aa\u0005" + + "\b\u0000\u0000\u00aa\u00ab\u0003\f\u0006\u0000\u00ab\u00b4\u0001\u0000" + + "\u0000\u0000\u00ac\u00ad\u0005\u0018\u0000\u0000\u00ad\u00af\u0003\u000e" + + "\u0007\u0000\u00ae\u00b0\u0003\u001e\u000f\u0000\u00af\u00ae\u0001\u0000" + + "\u0000\u0000\u00b0\u00b1\u0001\u0000\u0000\u0000\u00b1\u00af\u0001\u0000" + + "\u0000\u0000\u00b1\u00b2\u0001\u0000\u0000\u0000\u00b2\u00b4\u0001\u0000" + + "\u0000\u0000\u00b3w\u0001\u0000\u0000\u0000\u00b3\u0081\u0001\u0000\u0000" + + "\u0000\u00b3\u0089\u0001\u0000\u0000\u0000\u00b3\u009b\u0001\u0000\u0000" + + "\u0000\u00b3\u00a4\u0001\u0000\u0000\u0000\u00b3\u00ac\u0001\u0000\u0000" + + "\u0000\u00b4\t\u0001\u0000\u0000\u0000\u00b5\u00b6\u0005\u0012\u0000\u0000" + + "\u00b6\u00b7\u0003\u000e\u0007\u0000\u00b7\u00b8\u0005\u0011\u0000\u0000" + + "\u00b8\u00b9\u0005\u0007\u0000\u0000\u00b9\u00ba\u0003\"\u0011\u0000\u00ba" + + "\u00bb\u0005\b\u0000\u0000\u00bb\u00c7\u0001\u0000\u0000\u0000\u00bc\u00c7" + + "\u0003\u0016\u000b\u0000\u00bd\u00c7\u0005\u0014\u0000\u0000\u00be\u00c7" + + "\u0005\u0015\u0000\u0000\u00bf\u00c1\u0005\u0016\u0000\u0000\u00c0\u00c2" + + "\u0003\"\u0011\u0000\u00c1\u00c0\u0001\u0000\u0000\u0000\u00c1\u00c2\u0001" + + "\u0000\u0000\u0000\u00c2\u00c7\u0001\u0000\u0000\u0000\u00c3\u00c4\u0005" + + "\u001a\u0000\u0000\u00c4\u00c7\u0003\"\u0011\u0000\u00c5\u00c7\u0003\"" + + "\u0011\u0000\u00c6\u00b5\u0001\u0000\u0000\u0000\u00c6\u00bc\u0001\u0000" + + "\u0000\u0000\u00c6\u00bd\u0001\u0000\u0000\u0000\u00c6\u00be\u0001\u0000" + + "\u0000\u0000\u00c6\u00bf\u0001\u0000\u0000\u0000\u00c6\u00c3\u0001\u0000" + + "\u0000\u0000\u00c6\u00c5\u0001\u0000\u0000\u0000\u00c7\u000b\u0001\u0000" + + "\u0000\u0000\u00c8\u00cb\u0003\u000e\u0007\u0000\u00c9\u00cb\u0003\u0006" + + "\u0003\u0000\u00ca\u00c8\u0001\u0000\u0000\u0000\u00ca\u00c9\u0001\u0000" + + "\u0000\u0000\u00cb\r\u0001\u0000\u0000\u0000\u00cc\u00d0\u0005\u0003\u0000" + + "\u0000\u00cd\u00cf\u0003\u0006\u0003\u0000\u00ce\u00cd\u0001\u0000\u0000" + + "\u0000\u00cf\u00d2\u0001\u0000\u0000\u0000\u00d0\u00ce\u0001\u0000\u0000" + + "\u0000\u00d0\u00d1\u0001\u0000\u0000\u0000\u00d1\u00d4\u0001\u0000\u0000" + + "\u0000\u00d2\u00d0\u0001\u0000\u0000\u0000\u00d3\u00d5\u0003\n\u0005\u0000" + + "\u00d4\u00d3\u0001\u0000\u0000\u0000\u00d4\u00d5\u0001\u0000\u0000\u0000" + + "\u00d5\u00d6\u0001\u0000\u0000\u0000\u00d6\u00d7\u0005\u0004\u0000\u0000" + + "\u00d7\u000f\u0001\u0000\u0000\u0000\u00d8\u00d9\u0005\r\u0000\u0000\u00d9" + + "\u0011\u0001\u0000\u0000\u0000\u00da\u00dd\u0003\u0016\u000b\u0000\u00db" + + "\u00dd\u0003\"\u0011\u0000\u00dc\u00da\u0001\u0000\u0000\u0000\u00dc\u00db" + + "\u0001\u0000\u0000\u0000\u00dd\u0013\u0001\u0000\u0000\u0000\u00de\u00df" + + "\u0003\"\u0011\u0000\u00df\u0015\u0001\u0000\u0000\u0000\u00e0\u00e1\u0003" + + "\u0018\f\u0000\u00e1\u00e6\u0003\u001c\u000e\u0000\u00e2\u00e3\u0005\f" + + "\u0000\u0000\u00e3\u00e5\u0003\u001c\u000e\u0000\u00e4\u00e2\u0001\u0000" + + "\u0000\u0000\u00e5\u00e8\u0001\u0000\u0000\u0000\u00e6\u00e4\u0001\u0000" + + "\u0000\u0000\u00e6\u00e7\u0001\u0000\u0000\u0000\u00e7\u0017\u0001\u0000" + + "\u0000\u0000\u00e8\u00e6\u0001\u0000\u0000\u0000\u00e9\u00ee\u0003\u001a" + + "\r\u0000\u00ea\u00eb\u0005\u0005\u0000\u0000\u00eb\u00ed\u0005\u0006\u0000" + + "\u0000\u00ec\u00ea\u0001\u0000\u0000\u0000\u00ed\u00f0\u0001\u0000\u0000" + + "\u0000\u00ee\u00ec\u0001\u0000\u0000\u0000\u00ee\u00ef\u0001\u0000\u0000" + + "\u0000\u00ef\u0019\u0001\u0000\u0000\u0000\u00f0\u00ee\u0001\u0000\u0000" + + "\u0000\u00f1\u00fc\u0005S\u0000\u0000\u00f2\u00fc\u0005R\u0000\u0000\u00f3" + + "\u00f8\u0005T\u0000\u0000\u00f4\u00f5\u0005\n\u0000\u0000\u00f5\u00f7" + + "\u0005V\u0000\u0000\u00f6\u00f4\u0001\u0000\u0000\u0000\u00f7\u00fa\u0001" + + "\u0000\u0000\u0000\u00f8\u00f6\u0001\u0000\u0000\u0000\u00f8\u00f9\u0001" + + "\u0000\u0000\u0000\u00f9\u00fc\u0001\u0000\u0000\u0000\u00fa\u00f8\u0001" + + "\u0000\u0000\u0000\u00fb\u00f1\u0001\u0000\u0000\u0000\u00fb\u00f2\u0001" + + "\u0000\u0000\u0000\u00fb\u00f3\u0001\u0000\u0000\u0000\u00fc\u001b\u0001" + + "\u0000\u0000\u0000\u00fd\u0100\u0005T\u0000\u0000\u00fe\u00ff\u0005=\u0000" + + "\u0000\u00ff\u0101\u0003\"\u0011\u0000\u0100\u00fe\u0001\u0000\u0000\u0000" + + "\u0100\u0101\u0001\u0000\u0000\u0000\u0101\u001d\u0001\u0000\u0000\u0000" + + "\u0102\u0103\u0005\u0019\u0000\u0000\u0103\u0104\u0005\u0007\u0000\u0000" + + "\u0104\u0105\u0003\u001a\r\u0000\u0105\u0106\u0005T\u0000\u0000\u0106" + + "\u0107\u0005\b\u0000\u0000\u0107\u0108\u0003\u000e\u0007\u0000\u0108\u001f" + + "\u0001\u0000\u0000\u0000\u0109\u010a\u0006\u0010\uffff\uffff\u0000\u010a" + + "\u010b\u0003$\u0012\u0000\u010b\u0135\u0001\u0000\u0000\u0000\u010c\u010d" + + "\n\r\u0000\u0000\u010d\u010e\u0007\u0001\u0000\u0000\u010e\u0134\u0003" + + " \u0010\u000e\u010f\u0110\n\f\u0000\u0000\u0110\u0111\u0007\u0002\u0000" + + "\u0000\u0111\u0134\u0003 \u0010\r\u0112\u0113\n\u000b\u0000\u0000\u0113" + + "\u0114\u0007\u0003\u0000\u0000\u0114\u0134\u0003 \u0010\f\u0115\u0116" + + "\n\n\u0000\u0000\u0116\u0117\u0007\u0004\u0000\u0000\u0117\u0134\u0003" + + " \u0010\u000b\u0118\u0119\n\t\u0000\u0000\u0119\u011a\u0007\u0005\u0000" + + "\u0000\u011a\u0134\u0003 \u0010\n\u011b\u011c\n\u0007\u0000\u0000\u011c" + + "\u011d\u0007\u0006\u0000\u0000\u011d\u0134\u0003 \u0010\b\u011e\u011f" + + "\n\u0006\u0000\u0000\u011f\u0120\u0005/\u0000\u0000\u0120\u0134\u0003" + + " \u0010\u0007\u0121\u0122\n\u0005\u0000\u0000\u0122\u0123\u00050\u0000" + + "\u0000\u0123\u0134\u0003 \u0010\u0006\u0124\u0125\n\u0004\u0000\u0000" + + "\u0125\u0126\u00051\u0000\u0000\u0126\u0134\u0003 \u0010\u0005\u0127\u0128" + + "\n\u0003\u0000\u0000\u0128\u0129\u00052\u0000\u0000\u0129\u0134\u0003" + + " \u0010\u0004\u012a\u012b\n\u0002\u0000\u0000\u012b\u012c\u00053\u0000" + + "\u0000\u012c\u0134\u0003 \u0010\u0003\u012d\u012e\n\u0001\u0000\u0000" + + "\u012e\u012f\u00056\u0000\u0000\u012f\u0134\u0003 \u0010\u0001\u0130\u0131" + + "\n\b\u0000\u0000\u0131\u0132\u0005\u001c\u0000\u0000\u0132\u0134\u0003" + + "\u0018\f\u0000\u0133\u010c\u0001\u0000\u0000\u0000\u0133\u010f\u0001\u0000" + + "\u0000\u0000\u0133\u0112\u0001\u0000\u0000\u0000\u0133\u0115\u0001\u0000" + + "\u0000\u0000\u0133\u0118\u0001\u0000\u0000\u0000\u0133\u011b\u0001\u0000" + + "\u0000\u0000\u0133\u011e\u0001\u0000\u0000\u0000\u0133\u0121\u0001\u0000" + + "\u0000\u0000\u0133\u0124\u0001\u0000\u0000\u0000\u0133\u0127\u0001\u0000" + + "\u0000\u0000\u0133\u012a\u0001\u0000\u0000\u0000\u0133\u012d\u0001\u0000" + + "\u0000\u0000\u0133\u0130\u0001\u0000\u0000\u0000\u0134\u0137\u0001\u0000" + + "\u0000\u0000\u0135\u0133\u0001\u0000\u0000\u0000\u0135\u0136\u0001\u0000" + + "\u0000\u0000\u0136!\u0001\u0000\u0000\u0000\u0137\u0135\u0001\u0000\u0000" + + "\u0000\u0138\u0144\u0003 \u0010\u0000\u0139\u013a\u0003 \u0010\u0000\u013a" + + "\u013b\u00054\u0000\u0000\u013b\u013c\u0003\"\u0011\u0000\u013c\u013d" + + "\u00055\u0000\u0000\u013d\u013e\u0003\"\u0011\u0000\u013e\u0144\u0001" + + "\u0000\u0000\u0000\u013f\u0140\u0003 \u0010\u0000\u0140\u0141\u0007\u0007" + + "\u0000\u0000\u0141\u0142\u0003\"\u0011\u0000\u0142\u0144\u0001\u0000\u0000" + + "\u0000\u0143\u0138\u0001\u0000\u0000\u0000\u0143\u0139\u0001\u0000\u0000" + + "\u0000\u0143\u013f\u0001\u0000\u0000\u0000\u0144#\u0001\u0000\u0000\u0000" + + "\u0145\u0146\u0007\b\u0000\u0000\u0146\u014b\u0003.\u0017\u0000\u0147" + + "\u0148\u0007\u0002\u0000\u0000\u0148\u014b\u0003$\u0012\u0000\u0149\u014b" + + "\u0003&\u0013\u0000\u014a\u0145\u0001\u0000\u0000\u0000\u014a\u0147\u0001" + + "\u0000\u0000\u0000\u014a\u0149\u0001\u0000\u0000\u0000\u014b%\u0001\u0000" + + "\u0000\u0000\u014c\u0154\u0003.\u0017\u0000\u014d\u014e\u0003.\u0017\u0000" + + "\u014e\u014f\u0007\b\u0000\u0000\u014f\u0154\u0001\u0000\u0000\u0000\u0150" + + "\u0151\u0007\t\u0000\u0000\u0151\u0154\u0003$\u0012\u0000\u0152\u0154" + + "\u0003(\u0014\u0000\u0153\u014c\u0001\u0000\u0000\u0000\u0153\u014d\u0001" + + "\u0000\u0000\u0000\u0153\u0150\u0001\u0000\u0000\u0000\u0153\u0152\u0001" + + "\u0000\u0000\u0000\u0154\'\u0001\u0000\u0000\u0000\u0155\u0156\u0005\u0007" + + "\u0000\u0000\u0156\u0157\u0003*\u0015\u0000\u0157\u0158\u0005\b\u0000" + + "\u0000\u0158\u0159\u0003$\u0012\u0000\u0159\u0160\u0001\u0000\u0000\u0000" + + "\u015a\u015b\u0005\u0007\u0000\u0000\u015b\u015c\u0003,\u0016\u0000\u015c" + + "\u015d\u0005\b\u0000\u0000\u015d\u015e\u0003&\u0013\u0000\u015e\u0160" + + "\u0001\u0000\u0000\u0000\u015f\u0155\u0001\u0000\u0000\u0000\u015f\u015a" + + "\u0001\u0000\u0000\u0000\u0160)\u0001\u0000\u0000\u0000\u0161\u0162\u0007" + + "\n\u0000\u0000\u0162+\u0001\u0000\u0000\u0000\u0163\u0166\u0005S\u0000" + + "\u0000\u0164\u0165\u0005\u0005\u0000\u0000\u0165\u0167\u0005\u0006\u0000" + + "\u0000\u0166\u0164\u0001\u0000\u0000\u0000\u0167\u0168\u0001\u0000\u0000" + + "\u0000\u0168\u0166\u0001\u0000\u0000\u0000\u0168\u0169\u0001\u0000\u0000" + + "\u0000\u0169\u0181\u0001\u0000\u0000\u0000\u016a\u016d\u0005R\u0000\u0000" + + "\u016b\u016c\u0005\u0005\u0000\u0000\u016c\u016e\u0005\u0006\u0000\u0000" + + "\u016d\u016b\u0001\u0000\u0000\u0000\u016e\u016f\u0001\u0000\u0000\u0000" + + "\u016f\u016d\u0001\u0000\u0000\u0000\u016f\u0170\u0001\u0000\u0000\u0000" + + "\u0170\u0181\u0001\u0000\u0000\u0000\u0171\u0176\u0005T\u0000\u0000\u0172" + + "\u0173\u0005\n\u0000\u0000\u0173\u0175\u0005V\u0000\u0000\u0174\u0172" + + "\u0001\u0000\u0000\u0000\u0175\u0178\u0001\u0000\u0000\u0000\u0176\u0174" + + "\u0001\u0000\u0000\u0000\u0176\u0177\u0001\u0000\u0000\u0000\u0177\u017d" + + "\u0001\u0000\u0000\u0000\u0178\u0176\u0001\u0000\u0000\u0000\u0179\u017a" + + "\u0005\u0005\u0000\u0000\u017a\u017c\u0005\u0006\u0000\u0000\u017b\u0179" + + "\u0001\u0000\u0000\u0000\u017c\u017f\u0001\u0000\u0000\u0000\u017d\u017b" + + "\u0001\u0000\u0000\u0000\u017d\u017e\u0001\u0000\u0000\u0000\u017e\u0181" + + "\u0001\u0000\u0000\u0000\u017f\u017d\u0001\u0000\u0000\u0000\u0180\u0163" + + "\u0001\u0000\u0000\u0000\u0180\u016a\u0001\u0000\u0000\u0000\u0180\u0171" + + "\u0001\u0000\u0000\u0000\u0181-\u0001\u0000\u0000\u0000\u0182\u0186\u0003" + + "0\u0018\u0000\u0183\u0185\u00032\u0019\u0000\u0184\u0183\u0001\u0000\u0000" + + "\u0000\u0185\u0188\u0001\u0000\u0000\u0000\u0186\u0184\u0001\u0000\u0000" + + "\u0000\u0186\u0187\u0001\u0000\u0000\u0000\u0187\u018b\u0001\u0000\u0000" + + "\u0000\u0188\u0186\u0001\u0000\u0000\u0000\u0189\u018b\u0003<\u001e\u0000" + + "\u018a\u0182\u0001\u0000\u0000\u0000\u018a\u0189\u0001\u0000\u0000\u0000" + + "\u018b/\u0001\u0000\u0000\u0000\u018c\u018d\u0005\u0007\u0000\u0000\u018d" + + "\u018e\u0003\"\u0011\u0000\u018e\u018f\u0005\b\u0000\u0000\u018f\u01a0" + + "\u0001\u0000\u0000\u0000\u0190\u01a0\u0007\u000b\u0000\u0000\u0191\u01a0" + + "\u0005O\u0000\u0000\u0192\u01a0\u0005P\u0000\u0000\u0193\u01a0\u0005Q" + + "\u0000\u0000\u0194\u01a0\u0005M\u0000\u0000\u0195\u01a0\u0005N\u0000\u0000" + + "\u0196\u01a0\u0003>\u001f\u0000\u0197\u01a0\u0003@ \u0000\u0198\u01a0" + + "\u0005T\u0000\u0000\u0199\u019a\u0007\f\u0000\u0000\u019a\u01a0\u0003" + + "D\"\u0000\u019b\u019c\u0005\u0017\u0000\u0000\u019c\u019d\u0003\u001a" + + "\r\u0000\u019d\u019e\u0003D\"\u0000\u019e\u01a0\u0001\u0000\u0000\u0000" + + "\u019f\u018c\u0001\u0000\u0000\u0000\u019f\u0190\u0001\u0000\u0000\u0000" + + "\u019f\u0191\u0001\u0000\u0000\u0000\u019f\u0192\u0001\u0000\u0000\u0000" + + "\u019f\u0193\u0001\u0000\u0000\u0000\u019f\u0194\u0001\u0000\u0000\u0000" + + "\u019f\u0195\u0001\u0000\u0000\u0000\u019f\u0196\u0001\u0000\u0000\u0000" + + "\u019f\u0197\u0001\u0000\u0000\u0000\u019f\u0198\u0001\u0000\u0000\u0000" + + "\u019f\u0199\u0001\u0000\u0000\u0000\u019f\u019b\u0001\u0000\u0000\u0000" + + "\u01a01\u0001\u0000\u0000\u0000\u01a1\u01a5\u00036\u001b\u0000\u01a2\u01a5" + + "\u00038\u001c\u0000\u01a3\u01a5\u0003:\u001d\u0000\u01a4\u01a1\u0001\u0000" + + "\u0000\u0000\u01a4\u01a2\u0001\u0000\u0000\u0000\u01a4\u01a3\u0001\u0000" + + "\u0000\u0000\u01a53\u0001\u0000\u0000\u0000\u01a6\u01a9\u00036\u001b\u0000" + + "\u01a7\u01a9\u00038\u001c\u0000\u01a8\u01a6\u0001\u0000\u0000\u0000\u01a8" + + "\u01a7\u0001\u0000\u0000\u0000\u01a95\u0001\u0000\u0000\u0000\u01aa\u01ab" + + "\u0007\r\u0000\u0000\u01ab\u01ac\u0005V\u0000\u0000\u01ac\u01ad\u0003" + + "D\"\u0000\u01ad7\u0001\u0000\u0000\u0000\u01ae\u01af\u0007\r\u0000\u0000" + + "\u01af\u01b0\u0007\u000e\u0000\u0000\u01b09\u0001\u0000\u0000\u0000\u01b1" + + "\u01b2\u0005\u0005\u0000\u0000\u01b2\u01b3\u0003\"\u0011\u0000\u01b3\u01b4" + + "\u0005\u0006\u0000\u0000\u01b4;\u0001\u0000\u0000\u0000\u01b5\u01b6\u0005" + + "\u0017\u0000\u0000\u01b6\u01bb\u0003\u001a\r\u0000\u01b7\u01b8\u0005\u0005" + + "\u0000\u0000\u01b8\u01b9\u0003\"\u0011\u0000\u01b9\u01ba\u0005\u0006\u0000" + + "\u0000\u01ba\u01bc\u0001\u0000\u0000\u0000\u01bb\u01b7\u0001\u0000\u0000" + + "\u0000\u01bc\u01bd\u0001\u0000\u0000\u0000\u01bd\u01bb\u0001\u0000\u0000" + + "\u0000\u01bd\u01be\u0001\u0000\u0000\u0000\u01be\u01c6\u0001\u0000\u0000" + + "\u0000\u01bf\u01c3\u00034\u001a\u0000\u01c0\u01c2\u00032\u0019\u0000\u01c1" + + "\u01c0\u0001\u0000\u0000\u0000\u01c2\u01c5\u0001\u0000\u0000\u0000\u01c3" + + "\u01c1\u0001\u0000\u0000\u0000\u01c3\u01c4\u0001\u0000\u0000\u0000\u01c4" + + "\u01c7\u0001\u0000\u0000\u0000\u01c5\u01c3\u0001\u0000\u0000\u0000\u01c6" + + "\u01bf\u0001\u0000\u0000\u0000\u01c6\u01c7\u0001\u0000\u0000\u0000\u01c7" + + "\u01df\u0001\u0000\u0000\u0000\u01c8\u01c9\u0005\u0017\u0000\u0000\u01c9" + + "\u01ca\u0003\u001a\r\u0000\u01ca\u01cb\u0005\u0005\u0000\u0000\u01cb\u01cc" + + "\u0005\u0006\u0000\u0000\u01cc\u01d5\u0005\u0003\u0000\u0000\u01cd\u01d2" + + "\u0003\"\u0011\u0000\u01ce\u01cf\u0005\f\u0000\u0000\u01cf\u01d1\u0003" + + "\"\u0011\u0000\u01d0\u01ce\u0001\u0000\u0000\u0000\u01d1\u01d4\u0001\u0000" + + "\u0000\u0000\u01d2\u01d0\u0001\u0000\u0000\u0000\u01d2\u01d3\u0001\u0000" + + "\u0000\u0000\u01d3\u01d6\u0001\u0000\u0000\u0000\u01d4\u01d2\u0001\u0000" + + "\u0000\u0000\u01d5\u01cd\u0001\u0000\u0000\u0000\u01d5\u01d6\u0001\u0000" + + "\u0000\u0000\u01d6\u01d7\u0001\u0000\u0000\u0000\u01d7\u01db\u0005\u0004" + + "\u0000\u0000\u01d8\u01da\u00032\u0019\u0000\u01d9\u01d8\u0001\u0000\u0000" + + "\u0000\u01da\u01dd\u0001\u0000\u0000\u0000\u01db\u01d9\u0001\u0000\u0000" + + "\u0000\u01db\u01dc\u0001\u0000\u0000\u0000\u01dc\u01df\u0001\u0000\u0000" + + "\u0000\u01dd\u01db\u0001\u0000\u0000\u0000\u01de\u01b5\u0001\u0000\u0000" + + "\u0000\u01de\u01c8\u0001\u0000\u0000\u0000\u01df=\u0001\u0000\u0000\u0000" + + "\u01e0\u01e1\u0005\u0005\u0000\u0000\u01e1\u01e6\u0003\"\u0011\u0000\u01e2" + + "\u01e3\u0005\f\u0000\u0000\u01e3\u01e5\u0003\"\u0011\u0000\u01e4\u01e2" + + "\u0001\u0000\u0000\u0000\u01e5\u01e8\u0001\u0000\u0000\u0000\u01e6\u01e4" + + "\u0001\u0000\u0000\u0000\u01e6\u01e7\u0001\u0000\u0000\u0000\u01e7\u01e9" + + "\u0001\u0000\u0000\u0000\u01e8\u01e6\u0001\u0000\u0000\u0000\u01e9\u01ea" + + "\u0005\u0006\u0000\u0000\u01ea\u01ee\u0001\u0000\u0000\u0000\u01eb\u01ec" + + "\u0005\u0005\u0000\u0000\u01ec\u01ee\u0005\u0006\u0000\u0000\u01ed\u01e0" + + "\u0001\u0000\u0000\u0000\u01ed\u01eb\u0001\u0000\u0000\u0000\u01ee?\u0001" + + "\u0000\u0000\u0000\u01ef\u01f0\u0005\u0005\u0000\u0000\u01f0\u01f5\u0003" + + "B!\u0000\u01f1\u01f2\u0005\f\u0000\u0000\u01f2\u01f4\u0003B!\u0000\u01f3" + + "\u01f1\u0001\u0000\u0000\u0000\u01f4\u01f7\u0001\u0000\u0000\u0000\u01f5" + + "\u01f3\u0001\u0000\u0000\u0000\u01f5\u01f6\u0001\u0000\u0000\u0000\u01f6" + + "\u01f8\u0001\u0000\u0000\u0000\u01f7\u01f5\u0001\u0000\u0000\u0000\u01f8" + + "\u01f9\u0005\u0006\u0000\u0000\u01f9\u01fe\u0001\u0000\u0000\u0000\u01fa" + + "\u01fb\u0005\u0005\u0000\u0000\u01fb\u01fc\u00055\u0000\u0000\u01fc\u01fe" + + "\u0005\u0006\u0000\u0000\u01fd\u01ef\u0001\u0000\u0000\u0000\u01fd\u01fa" + + "\u0001\u0000\u0000\u0000\u01feA\u0001\u0000\u0000\u0000\u01ff\u0200\u0003" + + "\"\u0011\u0000\u0200\u0201\u00055\u0000\u0000\u0201\u0202\u0003\"\u0011" + + "\u0000\u0202C\u0001\u0000\u0000\u0000\u0203\u020c\u0005\u0007\u0000\u0000" + + "\u0204\u0209\u0003F#\u0000\u0205\u0206\u0005\f\u0000\u0000\u0206\u0208" + + "\u0003F#\u0000\u0207\u0205\u0001\u0000\u0000\u0000\u0208\u020b\u0001\u0000" + + "\u0000\u0000\u0209\u0207\u0001\u0000\u0000\u0000\u0209\u020a\u0001\u0000" + + "\u0000\u0000\u020a\u020d\u0001\u0000\u0000\u0000\u020b\u0209\u0001\u0000" + + "\u0000\u0000\u020c\u0204\u0001\u0000\u0000\u0000\u020c\u020d\u0001\u0000" + + "\u0000\u0000\u020d\u020e\u0001\u0000\u0000\u0000\u020e\u020f\u0005\b\u0000" + + "\u0000\u020fE\u0001\u0000\u0000\u0000\u0210\u0214\u0003\"\u0011\u0000" + + "\u0211\u0214\u0003H$\u0000\u0212\u0214\u0003L&\u0000\u0213\u0210\u0001" + + "\u0000\u0000\u0000\u0213\u0211\u0001\u0000\u0000\u0000\u0213\u0212\u0001" + + "\u0000\u0000\u0000\u0214G\u0001\u0000\u0000\u0000\u0215\u0223\u0003J%" + + "\u0000\u0216\u021f\u0005\u0007\u0000\u0000\u0217\u021c\u0003J%\u0000\u0218" + + "\u0219\u0005\f\u0000\u0000\u0219\u021b\u0003J%\u0000\u021a\u0218\u0001" + + "\u0000\u0000\u0000\u021b\u021e\u0001\u0000\u0000\u0000\u021c\u021a\u0001" + + "\u0000\u0000\u0000\u021c\u021d\u0001\u0000\u0000\u0000\u021d\u0220\u0001" + + "\u0000\u0000\u0000\u021e\u021c\u0001\u0000\u0000\u0000\u021f\u0217\u0001" + + "\u0000\u0000\u0000\u021f\u0220\u0001\u0000\u0000\u0000\u0220\u0221\u0001" + + "\u0000\u0000\u0000\u0221\u0223\u0005\b\u0000\u0000\u0222\u0215\u0001\u0000" + + "\u0000\u0000\u0222\u0216\u0001\u0000\u0000\u0000\u0223\u0224\u0001\u0000" + + "\u0000\u0000\u0224\u0227\u00058\u0000\u0000\u0225\u0228\u0003\u000e\u0007" + + "\u0000\u0226\u0228\u0003\"\u0011\u0000\u0227\u0225\u0001\u0000\u0000\u0000" + + "\u0227\u0226\u0001\u0000\u0000\u0000\u0228I\u0001\u0000\u0000\u0000\u0229" + + "\u022b\u0003\u0018\f\u0000\u022a\u0229\u0001\u0000\u0000\u0000\u022a\u022b" + + "\u0001\u0000\u0000\u0000\u022b\u022c\u0001\u0000\u0000\u0000\u022c\u022d" + + "\u0005T\u0000\u0000\u022dK\u0001\u0000\u0000\u0000\u022e\u022f\u0003\u0018" + + "\f\u0000\u022f\u0230\u00057\u0000\u0000\u0230\u0231\u0005T\u0000\u0000" + + "\u0231\u023a\u0001\u0000\u0000\u0000\u0232\u0233\u0003\u0018\f\u0000\u0233" + + "\u0234\u00057\u0000\u0000\u0234\u0235\u0005\u0017\u0000\u0000\u0235\u023a" + + "\u0001\u0000\u0000\u0000\u0236\u0237\u0005\u001b\u0000\u0000\u0237\u0238" + + "\u00057\u0000\u0000\u0238\u023a\u0005T\u0000\u0000\u0239\u022e\u0001\u0000" + + "\u0000\u0000\u0239\u0232\u0001\u0000\u0000\u0000\u0239\u0236\u0001\u0000" + + "\u0000\u0000\u023aM\u0001\u0000\u0000\u0000 The return type of the visit operation. Use {@link Void} for * operations with no return type. */ +@SuppressWarnings("CheckReturnValue") class PainlessParserBaseVisitor extends AbstractParseTreeVisitor implements PainlessParserVisitor { /** * {@inheritDoc} diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/SuggestLexer.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/SuggestLexer.java index 0bad35d925f2..e9d89d0a9667 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/SuggestLexer.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/SuggestLexer.java @@ -1,17 +1,22 @@ // ANTLR GENERATED CODE: DO NOT EDIT package org.elasticsearch.painless.antlr; -import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.RuleContext; +import org.antlr.v4.runtime.RuntimeMetaData; +import org.antlr.v4.runtime.Vocabulary; +import org.antlr.v4.runtime.VocabularyImpl; +import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNDeserializer; +import org.antlr.v4.runtime.atn.LexerATNSimulator; +import org.antlr.v4.runtime.atn.PredictionContextCache; import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; -@SuppressWarnings({ "all", "warnings", "unchecked", "unused", "cast" }) +@SuppressWarnings({ "all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue" }) public abstract class SuggestLexer extends Lexer { static { - RuntimeMetaData.checkVersion("4.5.3", RuntimeMetaData.VERSION); + RuntimeMetaData.checkVersion("4.11.1", RuntimeMetaData.VERSION); } protected static final DFA[] _decisionToDFA; @@ -25,266 +30,281 @@ public abstract class SuggestLexer extends Lexer { 68, ALSH = 69, ARSH = 70, AUSH = 71, OCTAL = 72, HEX = 73, INTEGER = 74, DECIMAL = 75, STRING = 76, REGEX = 77, TRUE = 78, FALSE = 79, NULL = 80, ATYPE = 81, TYPE = 82, ID = 83, UNKNOWN = 84, DOTINTEGER = 85, DOTID = 86; public static final int AFTER_DOT = 1; + public static String[] channelNames = { "DEFAULT_TOKEN_CHANNEL", "HIDDEN" }; + public static String[] modeNames = { "DEFAULT_MODE", "AFTER_DOT" }; - public static final String[] ruleNames = { - "WS", - "COMMENT", - "LBRACK", - "RBRACK", - "LBRACE", - "RBRACE", - "LP", - "RP", - "DOT", - "NSDOT", - "COMMA", - "SEMICOLON", - "IF", - "IN", - "ELSE", - "WHILE", - "DO", - "FOR", - "CONTINUE", - "BREAK", - "RETURN", - "NEW", - "TRY", - "CATCH", - "THROW", - "THIS", - "INSTANCEOF", - "BOOLNOT", - "BWNOT", - "MUL", - "DIV", - "REM", - "ADD", - "SUB", - "LSH", - "RSH", - "USH", - "LT", - "LTE", - "GT", - "GTE", - "EQ", - "EQR", - "NE", - "NER", - "BWAND", - "XOR", - "BWOR", - "BOOLAND", - "BOOLOR", - "COND", - "COLON", - "ELVIS", - "REF", - "ARROW", - "FIND", - "MATCH", - "INCR", - "DECR", - "ASSIGN", - "AADD", - "ASUB", - "AMUL", - "ADIV", - "AREM", - "AAND", - "AXOR", - "AOR", - "ALSH", - "ARSH", - "AUSH", - "OCTAL", - "HEX", - "INTEGER", - "DECIMAL", - "STRING", - "REGEX", - "TRUE", - "FALSE", - "NULL", - "ATYPE", - "TYPE", - "ID", - "UNKNOWN", - "DOTINTEGER", - "DOTID" }; + private static String[] makeRuleNames() { + return new String[] { + "WS", + "COMMENT", + "LBRACK", + "RBRACK", + "LBRACE", + "RBRACE", + "LP", + "RP", + "DOT", + "NSDOT", + "COMMA", + "SEMICOLON", + "IF", + "IN", + "ELSE", + "WHILE", + "DO", + "FOR", + "CONTINUE", + "BREAK", + "RETURN", + "NEW", + "TRY", + "CATCH", + "THROW", + "THIS", + "INSTANCEOF", + "BOOLNOT", + "BWNOT", + "MUL", + "DIV", + "REM", + "ADD", + "SUB", + "LSH", + "RSH", + "USH", + "LT", + "LTE", + "GT", + "GTE", + "EQ", + "EQR", + "NE", + "NER", + "BWAND", + "XOR", + "BWOR", + "BOOLAND", + "BOOLOR", + "COND", + "COLON", + "ELVIS", + "REF", + "ARROW", + "FIND", + "MATCH", + "INCR", + "DECR", + "ASSIGN", + "AADD", + "ASUB", + "AMUL", + "ADIV", + "AREM", + "AAND", + "AXOR", + "AOR", + "ALSH", + "ARSH", + "AUSH", + "OCTAL", + "HEX", + "INTEGER", + "DECIMAL", + "STRING", + "REGEX", + "TRUE", + "FALSE", + "NULL", + "ATYPE", + "TYPE", + "ID", + "UNKNOWN", + "DOTINTEGER", + "DOTID" }; + } - private static final String[] _LITERAL_NAMES = { - null, - null, - null, - "'{'", - "'}'", - "'['", - "']'", - "'('", - "')'", - "'.'", - "'?.'", - "','", - "';'", - "'if'", - "'in'", - "'else'", - "'while'", - "'do'", - "'for'", - "'continue'", - "'break'", - "'return'", - "'new'", - "'try'", - "'catch'", - "'throw'", - "'this'", - "'instanceof'", - "'!'", - "'~'", - "'*'", - "'/'", - "'%'", - "'+'", - "'-'", - "'<<'", - "'>>'", - "'>>>'", - "'<'", - "'<='", - "'>'", - "'>='", - "'=='", - "'==='", - "'!='", - "'!=='", - "'&'", - "'^'", - "'|'", - "'&&'", - "'||'", - "'?'", - "':'", - "'?:'", - "'::'", - "'->'", - "'=~'", - "'==~'", - "'++'", - "'--'", - "'='", - "'+='", - "'-='", - "'*='", - "'/='", - "'%='", - "'&='", - "'^='", - "'|='", - "'<<='", - "'>>='", - "'>>>='", - null, - null, - null, - null, - null, - null, - "'true'", - "'false'", - "'null'" }; - private static final String[] _SYMBOLIC_NAMES = { - null, - "WS", - "COMMENT", - "LBRACK", - "RBRACK", - "LBRACE", - "RBRACE", - "LP", - "RP", - "DOT", - "NSDOT", - "COMMA", - "SEMICOLON", - "IF", - "IN", - "ELSE", - "WHILE", - "DO", - "FOR", - "CONTINUE", - "BREAK", - "RETURN", - "NEW", - "TRY", - "CATCH", - "THROW", - "THIS", - "INSTANCEOF", - "BOOLNOT", - "BWNOT", - "MUL", - "DIV", - "REM", - "ADD", - "SUB", - "LSH", - "RSH", - "USH", - "LT", - "LTE", - "GT", - "GTE", - "EQ", - "EQR", - "NE", - "NER", - "BWAND", - "XOR", - "BWOR", - "BOOLAND", - "BOOLOR", - "COND", - "COLON", - "ELVIS", - "REF", - "ARROW", - "FIND", - "MATCH", - "INCR", - "DECR", - "ASSIGN", - "AADD", - "ASUB", - "AMUL", - "ADIV", - "AREM", - "AAND", - "AXOR", - "AOR", - "ALSH", - "ARSH", - "AUSH", - "OCTAL", - "HEX", - "INTEGER", - "DECIMAL", - "STRING", - "REGEX", - "TRUE", - "FALSE", - "NULL", - "ATYPE", - "TYPE", - "ID", - "UNKNOWN", - "DOTINTEGER", - "DOTID" }; + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, + null, + null, + "'{'", + "'}'", + "'['", + "']'", + "'('", + "')'", + "'.'", + "'?.'", + "','", + "';'", + "'if'", + "'in'", + "'else'", + "'while'", + "'do'", + "'for'", + "'continue'", + "'break'", + "'return'", + "'new'", + "'try'", + "'catch'", + "'throw'", + "'this'", + "'instanceof'", + "'!'", + "'~'", + "'*'", + "'/'", + "'%'", + "'+'", + "'-'", + "'<<'", + "'>>'", + "'>>>'", + "'<'", + "'<='", + "'>'", + "'>='", + "'=='", + "'==='", + "'!='", + "'!=='", + "'&'", + "'^'", + "'|'", + "'&&'", + "'||'", + "'?'", + "':'", + "'?:'", + "'::'", + "'->'", + "'=~'", + "'==~'", + "'++'", + "'--'", + "'='", + "'+='", + "'-='", + "'*='", + "'/='", + "'%='", + "'&='", + "'^='", + "'|='", + "'<<='", + "'>>='", + "'>>>='", + null, + null, + null, + null, + null, + null, + "'true'", + "'false'", + "'null'" }; + } + + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + + private static String[] makeSymbolicNames() { + return new String[] { + null, + "WS", + "COMMENT", + "LBRACK", + "RBRACK", + "LBRACE", + "RBRACE", + "LP", + "RP", + "DOT", + "NSDOT", + "COMMA", + "SEMICOLON", + "IF", + "IN", + "ELSE", + "WHILE", + "DO", + "FOR", + "CONTINUE", + "BREAK", + "RETURN", + "NEW", + "TRY", + "CATCH", + "THROW", + "THIS", + "INSTANCEOF", + "BOOLNOT", + "BWNOT", + "MUL", + "DIV", + "REM", + "ADD", + "SUB", + "LSH", + "RSH", + "USH", + "LT", + "LTE", + "GT", + "GTE", + "EQ", + "EQR", + "NE", + "NER", + "BWAND", + "XOR", + "BWOR", + "BOOLAND", + "BOOLOR", + "COND", + "COLON", + "ELVIS", + "REF", + "ARROW", + "FIND", + "MATCH", + "INCR", + "DECR", + "ASSIGN", + "AADD", + "ASUB", + "AMUL", + "ADIV", + "AREM", + "AAND", + "AXOR", + "AOR", + "ALSH", + "ARSH", + "AUSH", + "OCTAL", + "HEX", + "INTEGER", + "DECIMAL", + "STRING", + "REGEX", + "TRUE", + "FALSE", + "NULL", + "ATYPE", + "TYPE", + "ID", + "UNKNOWN", + "DOTINTEGER", + "DOTID" }; + } + + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); /** @@ -343,6 +363,11 @@ public abstract class SuggestLexer extends Lexer { return _serializedATN; } + @Override + public String[] getChannelNames() { + return channelNames; + } + @Override public String[] getModeNames() { return modeNames; @@ -390,221 +415,394 @@ public abstract class SuggestLexer extends Lexer { return true; } - public static final String _serializedATN = "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2X\u0267\b\1\b\1\4" - + "\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n" - + "\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22" - + "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31" - + "\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t" - + " \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t" - + "+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64" - + "\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t" - + "=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4" - + "I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\t" - + "T\4U\tU\4V\tV\4W\tW\3\2\6\2\u00b2\n\2\r\2\16\2\u00b3\3\2\3\2\3\3\3\3\3" - + "\3\3\3\7\3\u00bc\n\3\f\3\16\3\u00bf\13\3\3\3\3\3\3\3\3\3\3\3\7\3\u00c6" - + "\n\3\f\3\16\3\u00c9\13\3\3\3\3\3\5\3\u00cd\n\3\3\3\3\3\3\4\3\4\3\5\3\5" - + "\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3" - + "\13\3\f\3\f\3\r\3\r\3\16\3\16\3\16\3\17\3\17\3\17\3\20\3\20\3\20\3\20" - + "\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\23\3\23\3\23\3\23" - + "\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25" - + "\3\25\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\30\3\30" - + "\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32" - + "\3\33\3\33\3\33\3\33\3\33\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34" - + "\3\34\3\34\3\35\3\35\3\36\3\36\3\37\3\37\3 \3 \3 \3!\3!\3\"\3\"\3#\3#" - + "\3$\3$\3$\3%\3%\3%\3&\3&\3&\3&\3\'\3\'\3(\3(\3(\3)\3)\3*\3*\3*\3+\3+\3" - + "+\3,\3,\3,\3,\3-\3-\3-\3.\3.\3.\3.\3/\3/\3\60\3\60\3\61\3\61\3\62\3\62" - + "\3\62\3\63\3\63\3\63\3\64\3\64\3\65\3\65\3\66\3\66\3\66\3\67\3\67\3\67" - + "\38\38\38\39\39\39\3:\3:\3:\3:\3;\3;\3;\3<\3<\3<\3=\3=\3>\3>\3>\3?\3?" - + "\3?\3@\3@\3@\3A\3A\3A\3B\3B\3B\3C\3C\3C\3D\3D\3D\3E\3E\3E\3F\3F\3F\3F" - + "\3G\3G\3G\3G\3H\3H\3H\3H\3H\3I\3I\6I\u01bc\nI\rI\16I\u01bd\3I\5I\u01c1" - + "\nI\3J\3J\3J\6J\u01c6\nJ\rJ\16J\u01c7\3J\5J\u01cb\nJ\3K\3K\3K\7K\u01d0" - + "\nK\fK\16K\u01d3\13K\5K\u01d5\nK\3K\5K\u01d8\nK\3L\3L\3L\7L\u01dd\nL\f" - + "L\16L\u01e0\13L\5L\u01e2\nL\3L\3L\6L\u01e6\nL\rL\16L\u01e7\5L\u01ea\n" - + "L\3L\3L\5L\u01ee\nL\3L\6L\u01f1\nL\rL\16L\u01f2\5L\u01f5\nL\3L\5L\u01f8" - + "\nL\3M\3M\3M\3M\3M\3M\7M\u0200\nM\fM\16M\u0203\13M\3M\3M\3M\3M\3M\3M\3" - + "M\7M\u020c\nM\fM\16M\u020f\13M\3M\5M\u0212\nM\3N\3N\3N\3N\6N\u0218\nN" - + "\rN\16N\u0219\3N\3N\7N\u021e\nN\fN\16N\u0221\13N\3N\3N\3O\3O\3O\3O\3O" - + "\3P\3P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\6R\u0239\nR\rR\16R\u023a" - + "\3S\3S\3S\3S\7S\u0241\nS\fS\16S\u0244\13S\3S\3S\3T\3T\7T\u024a\nT\fT\16" - + "T\u024d\13T\3U\3U\3U\3U\3V\3V\3V\7V\u0256\nV\fV\16V\u0259\13V\5V\u025b" - + "\nV\3V\3V\3W\3W\7W\u0261\nW\fW\16W\u0264\13W\3W\3W\7\u00bd\u00c7\u0201" - + "\u020d\u0219\2X\4\3\6\4\b\5\n\6\f\7\16\b\20\t\22\n\24\13\26\f\30\r\32" - + "\16\34\17\36\20 \21\"\22$\23&\24(\25*\26,\27.\30\60\31\62\32\64\33\66" - + "\348\35:\36<\37> @!B\"D#F$H%J&L\'N(P)R*T+V,X-Z.\\/^\60`\61b\62d\63f\64" - + "h\65j\66l\67n8p9r:t;v|?~@\u0080A\u0082B\u0084C\u0086D\u0088E\u008a" - + "F\u008cG\u008eH\u0090I\u0092J\u0094K\u0096L\u0098M\u009aN\u009cO\u009e" - + "P\u00a0Q\u00a2R\u00a4S\u00a6T\u00a8U\u00aaV\u00acW\u00aeX\4\2\3\25\5\2" - + "\13\f\17\17\"\"\4\2\f\f\17\17\3\2\629\4\2NNnn\4\2ZZzz\5\2\62;CHch\3\2" - + "\63;\3\2\62;\b\2FFHHNNffhhnn\4\2GGgg\4\2--//\6\2FFHHffhh\4\2$$^^\4\2)" - + ")^^\3\2\f\f\4\2\f\f\61\61\t\2WWeekknouuwwzz\5\2C\\aac|\6\2\62;C\\aac|" - + "\u0288\2\4\3\2\2\2\2\6\3\2\2\2\2\b\3\2\2\2\2\n\3\2\2\2\2\f\3\2\2\2\2\16" - + "\3\2\2\2\2\20\3\2\2\2\2\22\3\2\2\2\2\24\3\2\2\2\2\26\3\2\2\2\2\30\3\2" - + "\2\2\2\32\3\2\2\2\2\34\3\2\2\2\2\36\3\2\2\2\2 \3\2\2\2\2\"\3\2\2\2\2$" - + "\3\2\2\2\2&\3\2\2\2\2(\3\2\2\2\2*\3\2\2\2\2,\3\2\2\2\2.\3\2\2\2\2\60\3" - + "\2\2\2\2\62\3\2\2\2\2\64\3\2\2\2\2\66\3\2\2\2\28\3\2\2\2\2:\3\2\2\2\2" - + "<\3\2\2\2\2>\3\2\2\2\2@\3\2\2\2\2B\3\2\2\2\2D\3\2\2\2\2F\3\2\2\2\2H\3" - + "\2\2\2\2J\3\2\2\2\2L\3\2\2\2\2N\3\2\2\2\2P\3\2\2\2\2R\3\2\2\2\2T\3\2\2" - + "\2\2V\3\2\2\2\2X\3\2\2\2\2Z\3\2\2\2\2\\\3\2\2\2\2^\3\2\2\2\2`\3\2\2\2" - + "\2b\3\2\2\2\2d\3\2\2\2\2f\3\2\2\2\2h\3\2\2\2\2j\3\2\2\2\2l\3\2\2\2\2n" - + "\3\2\2\2\2p\3\2\2\2\2r\3\2\2\2\2t\3\2\2\2\2v\3\2\2\2\2x\3\2\2\2\2z\3\2" - + "\2\2\2|\3\2\2\2\2~\3\2\2\2\2\u0080\3\2\2\2\2\u0082\3\2\2\2\2\u0084\3\2" - + "\2\2\2\u0086\3\2\2\2\2\u0088\3\2\2\2\2\u008a\3\2\2\2\2\u008c\3\2\2\2\2" - + "\u008e\3\2\2\2\2\u0090\3\2\2\2\2\u0092\3\2\2\2\2\u0094\3\2\2\2\2\u0096" - + "\3\2\2\2\2\u0098\3\2\2\2\2\u009a\3\2\2\2\2\u009c\3\2\2\2\2\u009e\3\2\2" - + "\2\2\u00a0\3\2\2\2\2\u00a2\3\2\2\2\2\u00a4\3\2\2\2\2\u00a6\3\2\2\2\2\u00a8" - + "\3\2\2\2\2\u00aa\3\2\2\2\3\u00ac\3\2\2\2\3\u00ae\3\2\2\2\4\u00b1\3\2\2" - + "\2\6\u00cc\3\2\2\2\b\u00d0\3\2\2\2\n\u00d2\3\2\2\2\f\u00d4\3\2\2\2\16" - + "\u00d6\3\2\2\2\20\u00d8\3\2\2\2\22\u00da\3\2\2\2\24\u00dc\3\2\2\2\26\u00e0" - + "\3\2\2\2\30\u00e5\3\2\2\2\32\u00e7\3\2\2\2\34\u00e9\3\2\2\2\36\u00ec\3" - + "\2\2\2 \u00ef\3\2\2\2\"\u00f4\3\2\2\2$\u00fa\3\2\2\2&\u00fd\3\2\2\2(\u0101" - + "\3\2\2\2*\u010a\3\2\2\2,\u0110\3\2\2\2.\u0117\3\2\2\2\60\u011b\3\2\2\2" - + "\62\u011f\3\2\2\2\64\u0125\3\2\2\2\66\u012b\3\2\2\28\u0130\3\2\2\2:\u013b" - + "\3\2\2\2<\u013d\3\2\2\2>\u013f\3\2\2\2@\u0141\3\2\2\2B\u0144\3\2\2\2D" - + "\u0146\3\2\2\2F\u0148\3\2\2\2H\u014a\3\2\2\2J\u014d\3\2\2\2L\u0150\3\2" - + "\2\2N\u0154\3\2\2\2P\u0156\3\2\2\2R\u0159\3\2\2\2T\u015b\3\2\2\2V\u015e" - + "\3\2\2\2X\u0161\3\2\2\2Z\u0165\3\2\2\2\\\u0168\3\2\2\2^\u016c\3\2\2\2" - + "`\u016e\3\2\2\2b\u0170\3\2\2\2d\u0172\3\2\2\2f\u0175\3\2\2\2h\u0178\3" - + "\2\2\2j\u017a\3\2\2\2l\u017c\3\2\2\2n\u017f\3\2\2\2p\u0182\3\2\2\2r\u0185" - + "\3\2\2\2t\u0188\3\2\2\2v\u018c\3\2\2\2x\u018f\3\2\2\2z\u0192\3\2\2\2|" - + "\u0194\3\2\2\2~\u0197\3\2\2\2\u0080\u019a\3\2\2\2\u0082\u019d\3\2\2\2" - + "\u0084\u01a0\3\2\2\2\u0086\u01a3\3\2\2\2\u0088\u01a6\3\2\2\2\u008a\u01a9" - + "\3\2\2\2\u008c\u01ac\3\2\2\2\u008e\u01b0\3\2\2\2\u0090\u01b4\3\2\2\2\u0092" - + "\u01b9\3\2\2\2\u0094\u01c2\3\2\2\2\u0096\u01d4\3\2\2\2\u0098\u01e1\3\2" - + "\2\2\u009a\u0211\3\2\2\2\u009c\u0213\3\2\2\2\u009e\u0224\3\2\2\2\u00a0" - + "\u0229\3\2\2\2\u00a2\u022f\3\2\2\2\u00a4\u0234\3\2\2\2\u00a6\u023c\3\2" - + "\2\2\u00a8\u0247\3\2\2\2\u00aa\u024e\3\2\2\2\u00ac\u025a\3\2\2\2\u00ae" - + "\u025e\3\2\2\2\u00b0\u00b2\t\2\2\2\u00b1\u00b0\3\2\2\2\u00b2\u00b3\3\2" - + "\2\2\u00b3\u00b1\3\2\2\2\u00b3\u00b4\3\2\2\2\u00b4\u00b5\3\2\2\2\u00b5" - + "\u00b6\b\2\2\2\u00b6\5\3\2\2\2\u00b7\u00b8\7\61\2\2\u00b8\u00b9\7\61\2" - + "\2\u00b9\u00bd\3\2\2\2\u00ba\u00bc\13\2\2\2\u00bb\u00ba\3\2\2\2\u00bc" - + "\u00bf\3\2\2\2\u00bd\u00be\3\2\2\2\u00bd\u00bb\3\2\2\2\u00be\u00c0\3\2" - + "\2\2\u00bf\u00bd\3\2\2\2\u00c0\u00cd\t\3\2\2\u00c1\u00c2\7\61\2\2\u00c2" - + "\u00c3\7,\2\2\u00c3\u00c7\3\2\2\2\u00c4\u00c6\13\2\2\2\u00c5\u00c4\3\2" - + "\2\2\u00c6\u00c9\3\2\2\2\u00c7\u00c8\3\2\2\2\u00c7\u00c5\3\2\2\2\u00c8" - + "\u00ca\3\2\2\2\u00c9\u00c7\3\2\2\2\u00ca\u00cb\7,\2\2\u00cb\u00cd\7\61" - + "\2\2\u00cc\u00b7\3\2\2\2\u00cc\u00c1\3\2\2\2\u00cd\u00ce\3\2\2\2\u00ce" - + "\u00cf\b\3\2\2\u00cf\7\3\2\2\2\u00d0\u00d1\7}\2\2\u00d1\t\3\2\2\2\u00d2" - + "\u00d3\7\177\2\2\u00d3\13\3\2\2\2\u00d4\u00d5\7]\2\2\u00d5\r\3\2\2\2\u00d6" - + "\u00d7\7_\2\2\u00d7\17\3\2\2\2\u00d8\u00d9\7*\2\2\u00d9\21\3\2\2\2\u00da" - + "\u00db\7+\2\2\u00db\23\3\2\2\2\u00dc\u00dd\7\60\2\2\u00dd\u00de\3\2\2" - + "\2\u00de\u00df\b\n\3\2\u00df\25\3\2\2\2\u00e0\u00e1\7A\2\2\u00e1\u00e2" - + "\7\60\2\2\u00e2\u00e3\3\2\2\2\u00e3\u00e4\b\13\3\2\u00e4\27\3\2\2\2\u00e5" - + "\u00e6\7.\2\2\u00e6\31\3\2\2\2\u00e7\u00e8\7=\2\2\u00e8\33\3\2\2\2\u00e9" - + "\u00ea\7k\2\2\u00ea\u00eb\7h\2\2\u00eb\35\3\2\2\2\u00ec\u00ed\7k\2\2\u00ed" - + "\u00ee\7p\2\2\u00ee\37\3\2\2\2\u00ef\u00f0\7g\2\2\u00f0\u00f1\7n\2\2\u00f1" - + "\u00f2\7u\2\2\u00f2\u00f3\7g\2\2\u00f3!\3\2\2\2\u00f4\u00f5\7y\2\2\u00f5" - + "\u00f6\7j\2\2\u00f6\u00f7\7k\2\2\u00f7\u00f8\7n\2\2\u00f8\u00f9\7g\2\2" - + "\u00f9#\3\2\2\2\u00fa\u00fb\7f\2\2\u00fb\u00fc\7q\2\2\u00fc%\3\2\2\2\u00fd" - + "\u00fe\7h\2\2\u00fe\u00ff\7q\2\2\u00ff\u0100\7t\2\2\u0100\'\3\2\2\2\u0101" - + "\u0102\7e\2\2\u0102\u0103\7q\2\2\u0103\u0104\7p\2\2\u0104\u0105\7v\2\2" - + "\u0105\u0106\7k\2\2\u0106\u0107\7p\2\2\u0107\u0108\7w\2\2\u0108\u0109" - + "\7g\2\2\u0109)\3\2\2\2\u010a\u010b\7d\2\2\u010b\u010c\7t\2\2\u010c\u010d" - + "\7g\2\2\u010d\u010e\7c\2\2\u010e\u010f\7m\2\2\u010f+\3\2\2\2\u0110\u0111" - + "\7t\2\2\u0111\u0112\7g\2\2\u0112\u0113\7v\2\2\u0113\u0114\7w\2\2\u0114" - + "\u0115\7t\2\2\u0115\u0116\7p\2\2\u0116-\3\2\2\2\u0117\u0118\7p\2\2\u0118" - + "\u0119\7g\2\2\u0119\u011a\7y\2\2\u011a/\3\2\2\2\u011b\u011c\7v\2\2\u011c" - + "\u011d\7t\2\2\u011d\u011e\7{\2\2\u011e\61\3\2\2\2\u011f\u0120\7e\2\2\u0120" - + "\u0121\7c\2\2\u0121\u0122\7v\2\2\u0122\u0123\7e\2\2\u0123\u0124\7j\2\2" - + "\u0124\63\3\2\2\2\u0125\u0126\7v\2\2\u0126\u0127\7j\2\2\u0127\u0128\7" - + "t\2\2\u0128\u0129\7q\2\2\u0129\u012a\7y\2\2\u012a\65\3\2\2\2\u012b\u012c" - + "\7v\2\2\u012c\u012d\7j\2\2\u012d\u012e\7k\2\2\u012e\u012f\7u\2\2\u012f" - + "\67\3\2\2\2\u0130\u0131\7k\2\2\u0131\u0132\7p\2\2\u0132\u0133\7u\2\2\u0133" - + "\u0134\7v\2\2\u0134\u0135\7c\2\2\u0135\u0136\7p\2\2\u0136\u0137\7e\2\2" - + "\u0137\u0138\7g\2\2\u0138\u0139\7q\2\2\u0139\u013a\7h\2\2\u013a9\3\2\2" - + "\2\u013b\u013c\7#\2\2\u013c;\3\2\2\2\u013d\u013e\7\u0080\2\2\u013e=\3" - + "\2\2\2\u013f\u0140\7,\2\2\u0140?\3\2\2\2\u0141\u0142\7\61\2\2\u0142\u0143" - + "\6 \2\2\u0143A\3\2\2\2\u0144\u0145\7\'\2\2\u0145C\3\2\2\2\u0146\u0147" - + "\7-\2\2\u0147E\3\2\2\2\u0148\u0149\7/\2\2\u0149G\3\2\2\2\u014a\u014b\7" - + ">\2\2\u014b\u014c\7>\2\2\u014cI\3\2\2\2\u014d\u014e\7@\2\2\u014e\u014f" - + "\7@\2\2\u014fK\3\2\2\2\u0150\u0151\7@\2\2\u0151\u0152\7@\2\2\u0152\u0153" - + "\7@\2\2\u0153M\3\2\2\2\u0154\u0155\7>\2\2\u0155O\3\2\2\2\u0156\u0157\7" - + ">\2\2\u0157\u0158\7?\2\2\u0158Q\3\2\2\2\u0159\u015a\7@\2\2\u015aS\3\2" - + "\2\2\u015b\u015c\7@\2\2\u015c\u015d\7?\2\2\u015dU\3\2\2\2\u015e\u015f" - + "\7?\2\2\u015f\u0160\7?\2\2\u0160W\3\2\2\2\u0161\u0162\7?\2\2\u0162\u0163" - + "\7?\2\2\u0163\u0164\7?\2\2\u0164Y\3\2\2\2\u0165\u0166\7#\2\2\u0166\u0167" - + "\7?\2\2\u0167[\3\2\2\2\u0168\u0169\7#\2\2\u0169\u016a\7?\2\2\u016a\u016b" - + "\7?\2\2\u016b]\3\2\2\2\u016c\u016d\7(\2\2\u016d_\3\2\2\2\u016e\u016f\7" - + "`\2\2\u016fa\3\2\2\2\u0170\u0171\7~\2\2\u0171c\3\2\2\2\u0172\u0173\7(" - + "\2\2\u0173\u0174\7(\2\2\u0174e\3\2\2\2\u0175\u0176\7~\2\2\u0176\u0177" - + "\7~\2\2\u0177g\3\2\2\2\u0178\u0179\7A\2\2\u0179i\3\2\2\2\u017a\u017b\7" - + "<\2\2\u017bk\3\2\2\2\u017c\u017d\7A\2\2\u017d\u017e\7<\2\2\u017em\3\2" - + "\2\2\u017f\u0180\7<\2\2\u0180\u0181\7<\2\2\u0181o\3\2\2\2\u0182\u0183" - + "\7/\2\2\u0183\u0184\7@\2\2\u0184q\3\2\2\2\u0185\u0186\7?\2\2\u0186\u0187" - + "\7\u0080\2\2\u0187s\3\2\2\2\u0188\u0189\7?\2\2\u0189\u018a\7?\2\2\u018a" - + "\u018b\7\u0080\2\2\u018bu\3\2\2\2\u018c\u018d\7-\2\2\u018d\u018e\7-\2" - + "\2\u018ew\3\2\2\2\u018f\u0190\7/\2\2\u0190\u0191\7/\2\2\u0191y\3\2\2\2" - + "\u0192\u0193\7?\2\2\u0193{\3\2\2\2\u0194\u0195\7-\2\2\u0195\u0196\7?\2" - + "\2\u0196}\3\2\2\2\u0197\u0198\7/\2\2\u0198\u0199\7?\2\2\u0199\177\3\2" - + "\2\2\u019a\u019b\7,\2\2\u019b\u019c\7?\2\2\u019c\u0081\3\2\2\2\u019d\u019e" - + "\7\61\2\2\u019e\u019f\7?\2\2\u019f\u0083\3\2\2\2\u01a0\u01a1\7\'\2\2\u01a1" - + "\u01a2\7?\2\2\u01a2\u0085\3\2\2\2\u01a3\u01a4\7(\2\2\u01a4\u01a5\7?\2" - + "\2\u01a5\u0087\3\2\2\2\u01a6\u01a7\7`\2\2\u01a7\u01a8\7?\2\2\u01a8\u0089" - + "\3\2\2\2\u01a9\u01aa\7~\2\2\u01aa\u01ab\7?\2\2\u01ab\u008b\3\2\2\2\u01ac" - + "\u01ad\7>\2\2\u01ad\u01ae\7>\2\2\u01ae\u01af\7?\2\2\u01af\u008d\3\2\2" - + "\2\u01b0\u01b1\7@\2\2\u01b1\u01b2\7@\2\2\u01b2\u01b3\7?\2\2\u01b3\u008f" - + "\3\2\2\2\u01b4\u01b5\7@\2\2\u01b5\u01b6\7@\2\2\u01b6\u01b7\7@\2\2\u01b7" - + "\u01b8\7?\2\2\u01b8\u0091\3\2\2\2\u01b9\u01bb\7\62\2\2\u01ba\u01bc\t\4" - + "\2\2\u01bb\u01ba\3\2\2\2\u01bc\u01bd\3\2\2\2\u01bd\u01bb\3\2\2\2\u01bd" - + "\u01be\3\2\2\2\u01be\u01c0\3\2\2\2\u01bf\u01c1\t\5\2\2\u01c0\u01bf\3\2" - + "\2\2\u01c0\u01c1\3\2\2\2\u01c1\u0093\3\2\2\2\u01c2\u01c3\7\62\2\2\u01c3" - + "\u01c5\t\6\2\2\u01c4\u01c6\t\7\2\2\u01c5\u01c4\3\2\2\2\u01c6\u01c7\3\2" - + "\2\2\u01c7\u01c5\3\2\2\2\u01c7\u01c8\3\2\2\2\u01c8\u01ca\3\2\2\2\u01c9" - + "\u01cb\t\5\2\2\u01ca\u01c9\3\2\2\2\u01ca\u01cb\3\2\2\2\u01cb\u0095\3\2" - + "\2\2\u01cc\u01d5\7\62\2\2\u01cd\u01d1\t\b\2\2\u01ce\u01d0\t\t\2\2\u01cf" - + "\u01ce\3\2\2\2\u01d0\u01d3\3\2\2\2\u01d1\u01cf\3\2\2\2\u01d1\u01d2\3\2" - + "\2\2\u01d2\u01d5\3\2\2\2\u01d3\u01d1\3\2\2\2\u01d4\u01cc\3\2\2\2\u01d4" - + "\u01cd\3\2\2\2\u01d5\u01d7\3\2\2\2\u01d6\u01d8\t\n\2\2\u01d7\u01d6\3\2" - + "\2\2\u01d7\u01d8\3\2\2\2\u01d8\u0097\3\2\2\2\u01d9\u01e2\7\62\2\2\u01da" - + "\u01de\t\b\2\2\u01db\u01dd\t\t\2\2\u01dc\u01db\3\2\2\2\u01dd\u01e0\3\2" - + "\2\2\u01de\u01dc\3\2\2\2\u01de\u01df\3\2\2\2\u01df\u01e2\3\2\2\2\u01e0" - + "\u01de\3\2\2\2\u01e1\u01d9\3\2\2\2\u01e1\u01da\3\2\2\2\u01e2\u01e9\3\2" - + "\2\2\u01e3\u01e5\5\24\n\2\u01e4\u01e6\t\t\2\2\u01e5\u01e4\3\2\2\2\u01e6" - + "\u01e7\3\2\2\2\u01e7\u01e5\3\2\2\2\u01e7\u01e8\3\2\2\2\u01e8\u01ea\3\2" - + "\2\2\u01e9\u01e3\3\2\2\2\u01e9\u01ea\3\2\2\2\u01ea\u01f4\3\2\2\2\u01eb" - + "\u01ed\t\13\2\2\u01ec\u01ee\t\f\2\2\u01ed\u01ec\3\2\2\2\u01ed\u01ee\3" - + "\2\2\2\u01ee\u01f0\3\2\2\2\u01ef\u01f1\t\t\2\2\u01f0\u01ef\3\2\2\2\u01f1" - + "\u01f2\3\2\2\2\u01f2\u01f0\3\2\2\2\u01f2\u01f3\3\2\2\2\u01f3\u01f5\3\2" - + "\2\2\u01f4\u01eb\3\2\2\2\u01f4\u01f5\3\2\2\2\u01f5\u01f7\3\2\2\2\u01f6" - + "\u01f8\t\r\2\2\u01f7\u01f6\3\2\2\2\u01f7\u01f8\3\2\2\2\u01f8\u0099\3\2" - + "\2\2\u01f9\u0201\7$\2\2\u01fa\u01fb\7^\2\2\u01fb\u0200\7$\2\2\u01fc\u01fd" - + "\7^\2\2\u01fd\u0200\7^\2\2\u01fe\u0200\n\16\2\2\u01ff\u01fa\3\2\2\2\u01ff" - + "\u01fc\3\2\2\2\u01ff\u01fe\3\2\2\2\u0200\u0203\3\2\2\2\u0201\u0202\3\2" - + "\2\2\u0201\u01ff\3\2\2\2\u0202\u0204\3\2\2\2\u0203\u0201\3\2\2\2\u0204" - + "\u0212\7$\2\2\u0205\u020d\7)\2\2\u0206\u0207\7^\2\2\u0207\u020c\7)\2\2" - + "\u0208\u0209\7^\2\2\u0209\u020c\7^\2\2\u020a\u020c\n\17\2\2\u020b\u0206" - + "\3\2\2\2\u020b\u0208\3\2\2\2\u020b\u020a\3\2\2\2\u020c\u020f\3\2\2\2\u020d" - + "\u020e\3\2\2\2\u020d\u020b\3\2\2\2\u020e\u0210\3\2\2\2\u020f\u020d\3\2" - + "\2\2\u0210\u0212\7)\2\2\u0211\u01f9\3\2\2\2\u0211\u0205\3\2\2\2\u0212" - + "\u009b\3\2\2\2\u0213\u0217\7\61\2\2\u0214\u0215\7^\2\2\u0215\u0218\n\20" - + "\2\2\u0216\u0218\n\21\2\2\u0217\u0214\3\2\2\2\u0217\u0216\3\2\2\2\u0218" - + "\u0219\3\2\2\2\u0219\u021a\3\2\2\2\u0219\u0217\3\2\2\2\u021a\u021b\3\2" - + "\2\2\u021b\u021f\7\61\2\2\u021c\u021e\t\22\2\2\u021d\u021c\3\2\2\2\u021e" - + "\u0221\3\2\2\2\u021f\u021d\3\2\2\2\u021f\u0220\3\2\2\2\u0220\u0222\3\2" - + "\2\2\u0221\u021f\3\2\2\2\u0222\u0223\6N\3\2\u0223\u009d\3\2\2\2\u0224" - + "\u0225\7v\2\2\u0225\u0226\7t\2\2\u0226\u0227\7w\2\2\u0227\u0228\7g\2\2" - + "\u0228\u009f\3\2\2\2\u0229\u022a\7h\2\2\u022a\u022b\7c\2\2\u022b\u022c" - + "\7n\2\2\u022c\u022d\7u\2\2\u022d\u022e\7g\2\2\u022e\u00a1\3\2\2\2\u022f" - + "\u0230\7p\2\2\u0230\u0231\7w\2\2\u0231\u0232\7n\2\2\u0232\u0233\7n\2\2" - + "\u0233\u00a3\3\2\2\2\u0234\u0238\5\u00a6S\2\u0235\u0236\5\f\6\2\u0236" - + "\u0237\5\16\7\2\u0237\u0239\3\2\2\2\u0238\u0235\3\2\2\2\u0239\u023a\3" - + "\2\2\2\u023a\u0238\3\2\2\2\u023a\u023b\3\2\2\2\u023b\u00a5\3\2\2\2\u023c" - + "\u0242\5\u00a8T\2\u023d\u023e\5\24\n\2\u023e\u023f\5\u00a8T\2\u023f\u0241" - + "\3\2\2\2\u0240\u023d\3\2\2\2\u0241\u0244\3\2\2\2\u0242\u0240\3\2\2\2\u0242" - + "\u0243\3\2\2\2\u0243\u0245\3\2\2\2\u0244\u0242\3\2\2\2\u0245\u0246\6S" - + "\4\2\u0246\u00a7\3\2\2\2\u0247\u024b\t\23\2\2\u0248\u024a\t\24\2\2\u0249" - + "\u0248\3\2\2\2\u024a\u024d\3\2\2\2\u024b\u0249\3\2\2\2\u024b\u024c\3\2" - + "\2\2\u024c\u00a9\3\2\2\2\u024d\u024b\3\2\2\2\u024e\u024f\13\2\2\2\u024f" - + "\u0250\3\2\2\2\u0250\u0251\bU\2\2\u0251\u00ab\3\2\2\2\u0252\u025b\7\62" - + "\2\2\u0253\u0257\t\b\2\2\u0254\u0256\t\t\2\2\u0255\u0254\3\2\2\2\u0256" - + "\u0259\3\2\2\2\u0257\u0255\3\2\2\2\u0257\u0258\3\2\2\2\u0258\u025b\3\2" - + "\2\2\u0259\u0257\3\2\2\2\u025a\u0252\3\2\2\2\u025a\u0253\3\2\2\2\u025b" - + "\u025c\3\2\2\2\u025c\u025d\bV\4\2\u025d\u00ad\3\2\2\2\u025e\u0262\t\23" - + "\2\2\u025f\u0261\t\24\2\2\u0260\u025f\3\2\2\2\u0261\u0264\3\2\2\2\u0262" - + "\u0260\3\2\2\2\u0262\u0263\3\2\2\2\u0263\u0265\3\2\2\2\u0264\u0262\3\2" - + "\2\2\u0265\u0266\bW\4\2\u0266\u00af\3\2\2\2%\2\3\u00b3\u00bd\u00c7\u00cc" - + "\u01bd\u01c0\u01c7\u01ca\u01d1\u01d4\u01d7\u01de\u01e1\u01e7\u01e9\u01ed" - + "\u01f2\u01f4\u01f7\u01ff\u0201\u020b\u020d\u0211\u0217\u0219\u021f\u023a" - + "\u0242\u024b\u0257\u025a\u0262\5\b\2\2\4\3\2\4\2\2"; + public static final String _serializedATN = "\u0004\u0000V\u0265\u0006\uffff\uffff\u0006\uffff\uffff\u0002\u0000\u0007" + + "\u0000\u0002\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007" + + "\u0003\u0002\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007" + + "\u0006\u0002\u0007\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n" + + "\u0007\n\u0002\u000b\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002" + + "\u000e\u0007\u000e\u0002\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002" + + "\u0011\u0007\u0011\u0002\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002" + + "\u0014\u0007\u0014\u0002\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002" + + "\u0017\u0007\u0017\u0002\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002" + + "\u001a\u0007\u001a\u0002\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002" + + "\u001d\u0007\u001d\u0002\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002" + + " \u0007 \u0002!\u0007!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002" + + "%\u0007%\u0002&\u0007&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002" + + "*\u0007*\u0002+\u0007+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002" + + "/\u0007/\u00020\u00070\u00021\u00071\u00022\u00072\u00023\u00073\u0002" + + "4\u00074\u00025\u00075\u00026\u00076\u00027\u00077\u00028\u00078\u0002" + + "9\u00079\u0002:\u0007:\u0002;\u0007;\u0002<\u0007<\u0002=\u0007=\u0002" + + ">\u0007>\u0002?\u0007?\u0002@\u0007@\u0002A\u0007A\u0002B\u0007B\u0002" + + "C\u0007C\u0002D\u0007D\u0002E\u0007E\u0002F\u0007F\u0002G\u0007G\u0002" + + "H\u0007H\u0002I\u0007I\u0002J\u0007J\u0002K\u0007K\u0002L\u0007L\u0002" + + "M\u0007M\u0002N\u0007N\u0002O\u0007O\u0002P\u0007P\u0002Q\u0007Q\u0002" + + "R\u0007R\u0002S\u0007S\u0002T\u0007T\u0002U\u0007U\u0001\u0000\u0004\u0000" + + "\u00b0\b\u0000\u000b\u0000\f\u0000\u00b1\u0001\u0000\u0001\u0000\u0001" + + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0005\u0001\u00ba\b\u0001\n" + + "\u0001\f\u0001\u00bd\t\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001" + + "\u0001\u0001\u0001\u0005\u0001\u00c4\b\u0001\n\u0001\f\u0001\u00c7\t\u0001" + + "\u0001\u0001\u0001\u0001\u0003\u0001\u00cb\b\u0001\u0001\u0001\u0001\u0001" + + "\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004" + + "\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006\u0001\u0007\u0001\u0007" + + "\u0001\b\u0001\b\u0001\b\u0001\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001" + + "\t\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001\f\u0001\f\u0001\f\u0001" + + "\r\u0001\r\u0001\r\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001" + + "\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001" + + "\u000f\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001" + + "\u0011\u0001\u0011\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001" + + "\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0013\u0001" + + "\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0014\u0001" + + "\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001" + + "\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0016\u0001\u0016\u0001" + + "\u0016\u0001\u0016\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001" + + "\u0017\u0001\u0017\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001" + + "\u0018\u0001\u0018\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001" + + "\u0019\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001" + + "\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001" + + "\u001b\u0001\u001b\u0001\u001c\u0001\u001c\u0001\u001d\u0001\u001d\u0001" + + "\u001e\u0001\u001e\u0001\u001e\u0001\u001f\u0001\u001f\u0001 \u0001 \u0001" + + "!\u0001!\u0001\"\u0001\"\u0001\"\u0001#\u0001#\u0001#\u0001$\u0001$\u0001" + + "$\u0001$\u0001%\u0001%\u0001&\u0001&\u0001&\u0001\'\u0001\'\u0001(\u0001" + + "(\u0001(\u0001)\u0001)\u0001)\u0001*\u0001*\u0001*\u0001*\u0001+\u0001" + + "+\u0001+\u0001,\u0001,\u0001,\u0001,\u0001-\u0001-\u0001.\u0001.\u0001" + + "/\u0001/\u00010\u00010\u00010\u00011\u00011\u00011\u00012\u00012\u0001" + + "3\u00013\u00014\u00014\u00014\u00015\u00015\u00015\u00016\u00016\u0001" + + "6\u00017\u00017\u00017\u00018\u00018\u00018\u00018\u00019\u00019\u0001" + + "9\u0001:\u0001:\u0001:\u0001;\u0001;\u0001<\u0001<\u0001<\u0001=\u0001" + + "=\u0001=\u0001>\u0001>\u0001>\u0001?\u0001?\u0001?\u0001@\u0001@\u0001" + + "@\u0001A\u0001A\u0001A\u0001B\u0001B\u0001B\u0001C\u0001C\u0001C\u0001" + + "D\u0001D\u0001D\u0001D\u0001E\u0001E\u0001E\u0001E\u0001F\u0001F\u0001" + + "F\u0001F\u0001F\u0001G\u0001G\u0004G\u01ba\bG\u000bG\fG\u01bb\u0001G\u0003" + + "G\u01bf\bG\u0001H\u0001H\u0001H\u0004H\u01c4\bH\u000bH\fH\u01c5\u0001" + + "H\u0003H\u01c9\bH\u0001I\u0001I\u0001I\u0005I\u01ce\bI\nI\fI\u01d1\tI" + + "\u0003I\u01d3\bI\u0001I\u0003I\u01d6\bI\u0001J\u0001J\u0001J\u0005J\u01db" + + "\bJ\nJ\fJ\u01de\tJ\u0003J\u01e0\bJ\u0001J\u0001J\u0004J\u01e4\bJ\u000b" + + "J\fJ\u01e5\u0003J\u01e8\bJ\u0001J\u0001J\u0003J\u01ec\bJ\u0001J\u0004" + + "J\u01ef\bJ\u000bJ\fJ\u01f0\u0003J\u01f3\bJ\u0001J\u0003J\u01f6\bJ\u0001" + + "K\u0001K\u0001K\u0001K\u0001K\u0001K\u0005K\u01fe\bK\nK\fK\u0201\tK\u0001" + + "K\u0001K\u0001K\u0001K\u0001K\u0001K\u0001K\u0005K\u020a\bK\nK\fK\u020d" + + "\tK\u0001K\u0003K\u0210\bK\u0001L\u0001L\u0001L\u0001L\u0004L\u0216\b" + + "L\u000bL\fL\u0217\u0001L\u0001L\u0005L\u021c\bL\nL\fL\u021f\tL\u0001L" + + "\u0001L\u0001M\u0001M\u0001M\u0001M\u0001M\u0001N\u0001N\u0001N\u0001" + + "N\u0001N\u0001N\u0001O\u0001O\u0001O\u0001O\u0001O\u0001P\u0001P\u0001" + + "P\u0001P\u0004P\u0237\bP\u000bP\fP\u0238\u0001Q\u0001Q\u0001Q\u0001Q\u0005" + + "Q\u023f\bQ\nQ\fQ\u0242\tQ\u0001Q\u0001Q\u0001R\u0001R\u0005R\u0248\bR" + + "\nR\fR\u024b\tR\u0001S\u0001S\u0001S\u0001S\u0001T\u0001T\u0001T\u0005" + + "T\u0254\bT\nT\fT\u0257\tT\u0003T\u0259\bT\u0001T\u0001T\u0001U\u0001U" + + "\u0005U\u025f\bU\nU\fU\u0262\tU\u0001U\u0001U\u0005\u00bb\u00c5\u01ff" + + "\u020b\u0217\u0000V\u0002\u0001\u0004\u0002\u0006\u0003\b\u0004\n\u0005" + + "\f\u0006\u000e\u0007\u0010\b\u0012\t\u0014\n\u0016\u000b\u0018\f\u001a" + + "\r\u001c\u000e\u001e\u000f \u0010\"\u0011$\u0012&\u0013(\u0014*\u0015" + + ",\u0016.\u00170\u00182\u00194\u001a6\u001b8\u001c:\u001d<\u001e>\u001f" + + "@ B!D\"F#H$J%L&N\'P(R)T*V+X,Z-\\.^/`0b1d2f3h4j5l6n7p8r9t:v;x~?\u0080" + + "@\u0082A\u0084B\u0086C\u0088D\u008aE\u008cF\u008eG\u0090H\u0092I\u0094" + + "J\u0096K\u0098L\u009aM\u009cN\u009eO\u00a0P\u00a2Q\u00a4R\u00a6S\u00a8" + + "T\u00aaU\u00acV\u0002\u0000\u0001\u0013\u0003\u0000\t\n\r\r \u0002\u0000" + + "\n\n\r\r\u0001\u000007\u0002\u0000LLll\u0002\u0000XXxx\u0003\u000009A" + + "Faf\u0001\u000019\u0001\u000009\u0006\u0000DDFFLLddffll\u0002\u0000EE" + + "ee\u0002\u0000++--\u0004\u0000DDFFddff\u0002\u0000\"\"\\\\\u0002\u0000" + + "\'\'\\\\\u0001\u0000\n\n\u0002\u0000\n\n//\u0007\u0000UUcciilmssuuxx\u0003" + + "\u0000AZ__az\u0004\u000009AZ__az\u0286\u0000\u0002\u0001\u0000\u0000\u0000" + + "\u0000\u0004\u0001\u0000\u0000\u0000\u0000\u0006\u0001\u0000\u0000\u0000" + + "\u0000\b\u0001\u0000\u0000\u0000\u0000\n\u0001\u0000\u0000\u0000\u0000" + + "\f\u0001\u0000\u0000\u0000\u0000\u000e\u0001\u0000\u0000\u0000\u0000\u0010" + + "\u0001\u0000\u0000\u0000\u0000\u0012\u0001\u0000\u0000\u0000\u0000\u0014" + + "\u0001\u0000\u0000\u0000\u0000\u0016\u0001\u0000\u0000\u0000\u0000\u0018" + + "\u0001\u0000\u0000\u0000\u0000\u001a\u0001\u0000\u0000\u0000\u0000\u001c" + + "\u0001\u0000\u0000\u0000\u0000\u001e\u0001\u0000\u0000\u0000\u0000 \u0001" + + "\u0000\u0000\u0000\u0000\"\u0001\u0000\u0000\u0000\u0000$\u0001\u0000" + + "\u0000\u0000\u0000&\u0001\u0000\u0000\u0000\u0000(\u0001\u0000\u0000\u0000" + + "\u0000*\u0001\u0000\u0000\u0000\u0000,\u0001\u0000\u0000\u0000\u0000." + + "\u0001\u0000\u0000\u0000\u00000\u0001\u0000\u0000\u0000\u00002\u0001\u0000" + + "\u0000\u0000\u00004\u0001\u0000\u0000\u0000\u00006\u0001\u0000\u0000\u0000" + + "\u00008\u0001\u0000\u0000\u0000\u0000:\u0001\u0000\u0000\u0000\u0000<" + + "\u0001\u0000\u0000\u0000\u0000>\u0001\u0000\u0000\u0000\u0000@\u0001\u0000" + + "\u0000\u0000\u0000B\u0001\u0000\u0000\u0000\u0000D\u0001\u0000\u0000\u0000" + + "\u0000F\u0001\u0000\u0000\u0000\u0000H\u0001\u0000\u0000\u0000\u0000J" + + "\u0001\u0000\u0000\u0000\u0000L\u0001\u0000\u0000\u0000\u0000N\u0001\u0000" + + "\u0000\u0000\u0000P\u0001\u0000\u0000\u0000\u0000R\u0001\u0000\u0000\u0000" + + "\u0000T\u0001\u0000\u0000\u0000\u0000V\u0001\u0000\u0000\u0000\u0000X" + + "\u0001\u0000\u0000\u0000\u0000Z\u0001\u0000\u0000\u0000\u0000\\\u0001" + + "\u0000\u0000\u0000\u0000^\u0001\u0000\u0000\u0000\u0000`\u0001\u0000\u0000" + + "\u0000\u0000b\u0001\u0000\u0000\u0000\u0000d\u0001\u0000\u0000\u0000\u0000" + + "f\u0001\u0000\u0000\u0000\u0000h\u0001\u0000\u0000\u0000\u0000j\u0001" + + "\u0000\u0000\u0000\u0000l\u0001\u0000\u0000\u0000\u0000n\u0001\u0000\u0000" + + "\u0000\u0000p\u0001\u0000\u0000\u0000\u0000r\u0001\u0000\u0000\u0000\u0000" + + "t\u0001\u0000\u0000\u0000\u0000v\u0001\u0000\u0000\u0000\u0000x\u0001" + + "\u0000\u0000\u0000\u0000z\u0001\u0000\u0000\u0000\u0000|\u0001\u0000\u0000" + + "\u0000\u0000~\u0001\u0000\u0000\u0000\u0000\u0080\u0001\u0000\u0000\u0000" + + "\u0000\u0082\u0001\u0000\u0000\u0000\u0000\u0084\u0001\u0000\u0000\u0000" + + "\u0000\u0086\u0001\u0000\u0000\u0000\u0000\u0088\u0001\u0000\u0000\u0000" + + "\u0000\u008a\u0001\u0000\u0000\u0000\u0000\u008c\u0001\u0000\u0000\u0000" + + "\u0000\u008e\u0001\u0000\u0000\u0000\u0000\u0090\u0001\u0000\u0000\u0000" + + "\u0000\u0092\u0001\u0000\u0000\u0000\u0000\u0094\u0001\u0000\u0000\u0000" + + "\u0000\u0096\u0001\u0000\u0000\u0000\u0000\u0098\u0001\u0000\u0000\u0000" + + "\u0000\u009a\u0001\u0000\u0000\u0000\u0000\u009c\u0001\u0000\u0000\u0000" + + "\u0000\u009e\u0001\u0000\u0000\u0000\u0000\u00a0\u0001\u0000\u0000\u0000" + + "\u0000\u00a2\u0001\u0000\u0000\u0000\u0000\u00a4\u0001\u0000\u0000\u0000" + + "\u0000\u00a6\u0001\u0000\u0000\u0000\u0000\u00a8\u0001\u0000\u0000\u0000" + + "\u0001\u00aa\u0001\u0000\u0000\u0000\u0001\u00ac\u0001\u0000\u0000\u0000" + + "\u0002\u00af\u0001\u0000\u0000\u0000\u0004\u00ca\u0001\u0000\u0000\u0000" + + "\u0006\u00ce\u0001\u0000\u0000\u0000\b\u00d0\u0001\u0000\u0000\u0000\n" + + "\u00d2\u0001\u0000\u0000\u0000\f\u00d4\u0001\u0000\u0000\u0000\u000e\u00d6" + + "\u0001\u0000\u0000\u0000\u0010\u00d8\u0001\u0000\u0000\u0000\u0012\u00da" + + "\u0001\u0000\u0000\u0000\u0014\u00de\u0001\u0000\u0000\u0000\u0016\u00e3" + + "\u0001\u0000\u0000\u0000\u0018\u00e5\u0001\u0000\u0000\u0000\u001a\u00e7" + + "\u0001\u0000\u0000\u0000\u001c\u00ea\u0001\u0000\u0000\u0000\u001e\u00ed" + + "\u0001\u0000\u0000\u0000 \u00f2\u0001\u0000\u0000\u0000\"\u00f8\u0001" + + "\u0000\u0000\u0000$\u00fb\u0001\u0000\u0000\u0000&\u00ff\u0001\u0000\u0000" + + "\u0000(\u0108\u0001\u0000\u0000\u0000*\u010e\u0001\u0000\u0000\u0000," + + "\u0115\u0001\u0000\u0000\u0000.\u0119\u0001\u0000\u0000\u00000\u011d\u0001" + + "\u0000\u0000\u00002\u0123\u0001\u0000\u0000\u00004\u0129\u0001\u0000\u0000" + + "\u00006\u012e\u0001\u0000\u0000\u00008\u0139\u0001\u0000\u0000\u0000:" + + "\u013b\u0001\u0000\u0000\u0000<\u013d\u0001\u0000\u0000\u0000>\u013f\u0001" + + "\u0000\u0000\u0000@\u0142\u0001\u0000\u0000\u0000B\u0144\u0001\u0000\u0000" + + "\u0000D\u0146\u0001\u0000\u0000\u0000F\u0148\u0001\u0000\u0000\u0000H" + + "\u014b\u0001\u0000\u0000\u0000J\u014e\u0001\u0000\u0000\u0000L\u0152\u0001" + + "\u0000\u0000\u0000N\u0154\u0001\u0000\u0000\u0000P\u0157\u0001\u0000\u0000" + + "\u0000R\u0159\u0001\u0000\u0000\u0000T\u015c\u0001\u0000\u0000\u0000V" + + "\u015f\u0001\u0000\u0000\u0000X\u0163\u0001\u0000\u0000\u0000Z\u0166\u0001" + + "\u0000\u0000\u0000\\\u016a\u0001\u0000\u0000\u0000^\u016c\u0001\u0000" + + "\u0000\u0000`\u016e\u0001\u0000\u0000\u0000b\u0170\u0001\u0000\u0000\u0000" + + "d\u0173\u0001\u0000\u0000\u0000f\u0176\u0001\u0000\u0000\u0000h\u0178" + + "\u0001\u0000\u0000\u0000j\u017a\u0001\u0000\u0000\u0000l\u017d\u0001\u0000" + + "\u0000\u0000n\u0180\u0001\u0000\u0000\u0000p\u0183\u0001\u0000\u0000\u0000" + + "r\u0186\u0001\u0000\u0000\u0000t\u018a\u0001\u0000\u0000\u0000v\u018d" + + "\u0001\u0000\u0000\u0000x\u0190\u0001\u0000\u0000\u0000z\u0192\u0001\u0000" + + "\u0000\u0000|\u0195\u0001\u0000\u0000\u0000~\u0198\u0001\u0000\u0000\u0000" + + "\u0080\u019b\u0001\u0000\u0000\u0000\u0082\u019e\u0001\u0000\u0000\u0000" + + "\u0084\u01a1\u0001\u0000\u0000\u0000\u0086\u01a4\u0001\u0000\u0000\u0000" + + "\u0088\u01a7\u0001\u0000\u0000\u0000\u008a\u01aa\u0001\u0000\u0000\u0000" + + "\u008c\u01ae\u0001\u0000\u0000\u0000\u008e\u01b2\u0001\u0000\u0000\u0000" + + "\u0090\u01b7\u0001\u0000\u0000\u0000\u0092\u01c0\u0001\u0000\u0000\u0000" + + "\u0094\u01d2\u0001\u0000\u0000\u0000\u0096\u01df\u0001\u0000\u0000\u0000" + + "\u0098\u020f\u0001\u0000\u0000\u0000\u009a\u0211\u0001\u0000\u0000\u0000" + + "\u009c\u0222\u0001\u0000\u0000\u0000\u009e\u0227\u0001\u0000\u0000\u0000" + + "\u00a0\u022d\u0001\u0000\u0000\u0000\u00a2\u0232\u0001\u0000\u0000\u0000" + + "\u00a4\u023a\u0001\u0000\u0000\u0000\u00a6\u0245\u0001\u0000\u0000\u0000" + + "\u00a8\u024c\u0001\u0000\u0000\u0000\u00aa\u0258\u0001\u0000\u0000\u0000" + + "\u00ac\u025c\u0001\u0000\u0000\u0000\u00ae\u00b0\u0007\u0000\u0000\u0000" + + "\u00af\u00ae\u0001\u0000\u0000\u0000\u00b0\u00b1\u0001\u0000\u0000\u0000" + + "\u00b1\u00af\u0001\u0000\u0000\u0000\u00b1\u00b2\u0001\u0000\u0000\u0000" + + "\u00b2\u00b3\u0001\u0000\u0000\u0000\u00b3\u00b4\u0006\u0000\u0000\u0000" + + "\u00b4\u0003\u0001\u0000\u0000\u0000\u00b5\u00b6\u0005/\u0000\u0000\u00b6" + + "\u00b7\u0005/\u0000\u0000\u00b7\u00bb\u0001\u0000\u0000\u0000\u00b8\u00ba" + + "\t\u0000\u0000\u0000\u00b9\u00b8\u0001\u0000\u0000\u0000\u00ba\u00bd\u0001" + + "\u0000\u0000\u0000\u00bb\u00bc\u0001\u0000\u0000\u0000\u00bb\u00b9\u0001" + + "\u0000\u0000\u0000\u00bc\u00be\u0001\u0000\u0000\u0000\u00bd\u00bb\u0001" + + "\u0000\u0000\u0000\u00be\u00cb\u0007\u0001\u0000\u0000\u00bf\u00c0\u0005" + + "/\u0000\u0000\u00c0\u00c1\u0005*\u0000\u0000\u00c1\u00c5\u0001\u0000\u0000" + + "\u0000\u00c2\u00c4\t\u0000\u0000\u0000\u00c3\u00c2\u0001\u0000\u0000\u0000" + + "\u00c4\u00c7\u0001\u0000\u0000\u0000\u00c5\u00c6\u0001\u0000\u0000\u0000" + + "\u00c5\u00c3\u0001\u0000\u0000\u0000\u00c6\u00c8\u0001\u0000\u0000\u0000" + + "\u00c7\u00c5\u0001\u0000\u0000\u0000\u00c8\u00c9\u0005*\u0000\u0000\u00c9" + + "\u00cb\u0005/\u0000\u0000\u00ca\u00b5\u0001\u0000\u0000\u0000\u00ca\u00bf" + + "\u0001\u0000\u0000\u0000\u00cb\u00cc\u0001\u0000\u0000\u0000\u00cc\u00cd" + + "\u0006\u0001\u0000\u0000\u00cd\u0005\u0001\u0000\u0000\u0000\u00ce\u00cf" + + "\u0005{\u0000\u0000\u00cf\u0007\u0001\u0000\u0000\u0000\u00d0\u00d1\u0005" + + "}\u0000\u0000\u00d1\t\u0001\u0000\u0000\u0000\u00d2\u00d3\u0005[\u0000" + + "\u0000\u00d3\u000b\u0001\u0000\u0000\u0000\u00d4\u00d5\u0005]\u0000\u0000" + + "\u00d5\r\u0001\u0000\u0000\u0000\u00d6\u00d7\u0005(\u0000\u0000\u00d7" + + "\u000f\u0001\u0000\u0000\u0000\u00d8\u00d9\u0005)\u0000\u0000\u00d9\u0011" + + "\u0001\u0000\u0000\u0000\u00da\u00db\u0005.\u0000\u0000\u00db\u00dc\u0001" + + "\u0000\u0000\u0000\u00dc\u00dd\u0006\b\u0001\u0000\u00dd\u0013\u0001\u0000" + + "\u0000\u0000\u00de\u00df\u0005?\u0000\u0000\u00df\u00e0\u0005.\u0000\u0000" + + "\u00e0\u00e1\u0001\u0000\u0000\u0000\u00e1\u00e2\u0006\t\u0001\u0000\u00e2" + + "\u0015\u0001\u0000\u0000\u0000\u00e3\u00e4\u0005,\u0000\u0000\u00e4\u0017" + + "\u0001\u0000\u0000\u0000\u00e5\u00e6\u0005;\u0000\u0000\u00e6\u0019\u0001" + + "\u0000\u0000\u0000\u00e7\u00e8\u0005i\u0000\u0000\u00e8\u00e9\u0005f\u0000" + + "\u0000\u00e9\u001b\u0001\u0000\u0000\u0000\u00ea\u00eb\u0005i\u0000\u0000" + + "\u00eb\u00ec\u0005n\u0000\u0000\u00ec\u001d\u0001\u0000\u0000\u0000\u00ed" + + "\u00ee\u0005e\u0000\u0000\u00ee\u00ef\u0005l\u0000\u0000\u00ef\u00f0\u0005" + + "s\u0000\u0000\u00f0\u00f1\u0005e\u0000\u0000\u00f1\u001f\u0001\u0000\u0000" + + "\u0000\u00f2\u00f3\u0005w\u0000\u0000\u00f3\u00f4\u0005h\u0000\u0000\u00f4" + + "\u00f5\u0005i\u0000\u0000\u00f5\u00f6\u0005l\u0000\u0000\u00f6\u00f7\u0005" + + "e\u0000\u0000\u00f7!\u0001\u0000\u0000\u0000\u00f8\u00f9\u0005d\u0000" + + "\u0000\u00f9\u00fa\u0005o\u0000\u0000\u00fa#\u0001\u0000\u0000\u0000\u00fb" + + "\u00fc\u0005f\u0000\u0000\u00fc\u00fd\u0005o\u0000\u0000\u00fd\u00fe\u0005" + + "r\u0000\u0000\u00fe%\u0001\u0000\u0000\u0000\u00ff\u0100\u0005c\u0000" + + "\u0000\u0100\u0101\u0005o\u0000\u0000\u0101\u0102\u0005n\u0000\u0000\u0102" + + "\u0103\u0005t\u0000\u0000\u0103\u0104\u0005i\u0000\u0000\u0104\u0105\u0005" + + "n\u0000\u0000\u0105\u0106\u0005u\u0000\u0000\u0106\u0107\u0005e\u0000" + + "\u0000\u0107\'\u0001\u0000\u0000\u0000\u0108\u0109\u0005b\u0000\u0000" + + "\u0109\u010a\u0005r\u0000\u0000\u010a\u010b\u0005e\u0000\u0000\u010b\u010c" + + "\u0005a\u0000\u0000\u010c\u010d\u0005k\u0000\u0000\u010d)\u0001\u0000" + + "\u0000\u0000\u010e\u010f\u0005r\u0000\u0000\u010f\u0110\u0005e\u0000\u0000" + + "\u0110\u0111\u0005t\u0000\u0000\u0111\u0112\u0005u\u0000\u0000\u0112\u0113" + + "\u0005r\u0000\u0000\u0113\u0114\u0005n\u0000\u0000\u0114+\u0001\u0000" + + "\u0000\u0000\u0115\u0116\u0005n\u0000\u0000\u0116\u0117\u0005e\u0000\u0000" + + "\u0117\u0118\u0005w\u0000\u0000\u0118-\u0001\u0000\u0000\u0000\u0119\u011a" + + "\u0005t\u0000\u0000\u011a\u011b\u0005r\u0000\u0000\u011b\u011c\u0005y" + + "\u0000\u0000\u011c/\u0001\u0000\u0000\u0000\u011d\u011e\u0005c\u0000\u0000" + + "\u011e\u011f\u0005a\u0000\u0000\u011f\u0120\u0005t\u0000\u0000\u0120\u0121" + + "\u0005c\u0000\u0000\u0121\u0122\u0005h\u0000\u0000\u01221\u0001\u0000" + + "\u0000\u0000\u0123\u0124\u0005t\u0000\u0000\u0124\u0125\u0005h\u0000\u0000" + + "\u0125\u0126\u0005r\u0000\u0000\u0126\u0127\u0005o\u0000\u0000\u0127\u0128" + + "\u0005w\u0000\u0000\u01283\u0001\u0000\u0000\u0000\u0129\u012a\u0005t" + + "\u0000\u0000\u012a\u012b\u0005h\u0000\u0000\u012b\u012c\u0005i\u0000\u0000" + + "\u012c\u012d\u0005s\u0000\u0000\u012d5\u0001\u0000\u0000\u0000\u012e\u012f" + + "\u0005i\u0000\u0000\u012f\u0130\u0005n\u0000\u0000\u0130\u0131\u0005s" + + "\u0000\u0000\u0131\u0132\u0005t\u0000\u0000\u0132\u0133\u0005a\u0000\u0000" + + "\u0133\u0134\u0005n\u0000\u0000\u0134\u0135\u0005c\u0000\u0000\u0135\u0136" + + "\u0005e\u0000\u0000\u0136\u0137\u0005o\u0000\u0000\u0137\u0138\u0005f" + + "\u0000\u0000\u01387\u0001\u0000\u0000\u0000\u0139\u013a\u0005!\u0000\u0000" + + "\u013a9\u0001\u0000\u0000\u0000\u013b\u013c\u0005~\u0000\u0000\u013c;" + + "\u0001\u0000\u0000\u0000\u013d\u013e\u0005*\u0000\u0000\u013e=\u0001\u0000" + + "\u0000\u0000\u013f\u0140\u0005/\u0000\u0000\u0140\u0141\u0004\u001e\u0000" + + "\u0000\u0141?\u0001\u0000\u0000\u0000\u0142\u0143\u0005%\u0000\u0000\u0143" + + "A\u0001\u0000\u0000\u0000\u0144\u0145\u0005+\u0000\u0000\u0145C\u0001" + + "\u0000\u0000\u0000\u0146\u0147\u0005-\u0000\u0000\u0147E\u0001\u0000\u0000" + + "\u0000\u0148\u0149\u0005<\u0000\u0000\u0149\u014a\u0005<\u0000\u0000\u014a" + + "G\u0001\u0000\u0000\u0000\u014b\u014c\u0005>\u0000\u0000\u014c\u014d\u0005" + + ">\u0000\u0000\u014dI\u0001\u0000\u0000\u0000\u014e\u014f\u0005>\u0000" + + "\u0000\u014f\u0150\u0005>\u0000\u0000\u0150\u0151\u0005>\u0000\u0000\u0151" + + "K\u0001\u0000\u0000\u0000\u0152\u0153\u0005<\u0000\u0000\u0153M\u0001" + + "\u0000\u0000\u0000\u0154\u0155\u0005<\u0000\u0000\u0155\u0156\u0005=\u0000" + + "\u0000\u0156O\u0001\u0000\u0000\u0000\u0157\u0158\u0005>\u0000\u0000\u0158" + + "Q\u0001\u0000\u0000\u0000\u0159\u015a\u0005>\u0000\u0000\u015a\u015b\u0005" + + "=\u0000\u0000\u015bS\u0001\u0000\u0000\u0000\u015c\u015d\u0005=\u0000" + + "\u0000\u015d\u015e\u0005=\u0000\u0000\u015eU\u0001\u0000\u0000\u0000\u015f" + + "\u0160\u0005=\u0000\u0000\u0160\u0161\u0005=\u0000\u0000\u0161\u0162\u0005" + + "=\u0000\u0000\u0162W\u0001\u0000\u0000\u0000\u0163\u0164\u0005!\u0000" + + "\u0000\u0164\u0165\u0005=\u0000\u0000\u0165Y\u0001\u0000\u0000\u0000\u0166" + + "\u0167\u0005!\u0000\u0000\u0167\u0168\u0005=\u0000\u0000\u0168\u0169\u0005" + + "=\u0000\u0000\u0169[\u0001\u0000\u0000\u0000\u016a\u016b\u0005&\u0000" + + "\u0000\u016b]\u0001\u0000\u0000\u0000\u016c\u016d\u0005^\u0000\u0000\u016d" + + "_\u0001\u0000\u0000\u0000\u016e\u016f\u0005|\u0000\u0000\u016fa\u0001" + + "\u0000\u0000\u0000\u0170\u0171\u0005&\u0000\u0000\u0171\u0172\u0005&\u0000" + + "\u0000\u0172c\u0001\u0000\u0000\u0000\u0173\u0174\u0005|\u0000\u0000\u0174" + + "\u0175\u0005|\u0000\u0000\u0175e\u0001\u0000\u0000\u0000\u0176\u0177\u0005" + + "?\u0000\u0000\u0177g\u0001\u0000\u0000\u0000\u0178\u0179\u0005:\u0000" + + "\u0000\u0179i\u0001\u0000\u0000\u0000\u017a\u017b\u0005?\u0000\u0000\u017b" + + "\u017c\u0005:\u0000\u0000\u017ck\u0001\u0000\u0000\u0000\u017d\u017e\u0005" + + ":\u0000\u0000\u017e\u017f\u0005:\u0000\u0000\u017fm\u0001\u0000\u0000" + + "\u0000\u0180\u0181\u0005-\u0000\u0000\u0181\u0182\u0005>\u0000\u0000\u0182" + + "o\u0001\u0000\u0000\u0000\u0183\u0184\u0005=\u0000\u0000\u0184\u0185\u0005" + + "~\u0000\u0000\u0185q\u0001\u0000\u0000\u0000\u0186\u0187\u0005=\u0000" + + "\u0000\u0187\u0188\u0005=\u0000\u0000\u0188\u0189\u0005~\u0000\u0000\u0189" + + "s\u0001\u0000\u0000\u0000\u018a\u018b\u0005+\u0000\u0000\u018b\u018c\u0005" + + "+\u0000\u0000\u018cu\u0001\u0000\u0000\u0000\u018d\u018e\u0005-\u0000" + + "\u0000\u018e\u018f\u0005-\u0000\u0000\u018fw\u0001\u0000\u0000\u0000\u0190" + + "\u0191\u0005=\u0000\u0000\u0191y\u0001\u0000\u0000\u0000\u0192\u0193\u0005" + + "+\u0000\u0000\u0193\u0194\u0005=\u0000\u0000\u0194{\u0001\u0000\u0000" + + "\u0000\u0195\u0196\u0005-\u0000\u0000\u0196\u0197\u0005=\u0000\u0000\u0197" + + "}\u0001\u0000\u0000\u0000\u0198\u0199\u0005*\u0000\u0000\u0199\u019a\u0005" + + "=\u0000\u0000\u019a\u007f\u0001\u0000\u0000\u0000\u019b\u019c\u0005/\u0000" + + "\u0000\u019c\u019d\u0005=\u0000\u0000\u019d\u0081\u0001\u0000\u0000\u0000" + + "\u019e\u019f\u0005%\u0000\u0000\u019f\u01a0\u0005=\u0000\u0000\u01a0\u0083" + + "\u0001\u0000\u0000\u0000\u01a1\u01a2\u0005&\u0000\u0000\u01a2\u01a3\u0005" + + "=\u0000\u0000\u01a3\u0085\u0001\u0000\u0000\u0000\u01a4\u01a5\u0005^\u0000" + + "\u0000\u01a5\u01a6\u0005=\u0000\u0000\u01a6\u0087\u0001\u0000\u0000\u0000" + + "\u01a7\u01a8\u0005|\u0000\u0000\u01a8\u01a9\u0005=\u0000\u0000\u01a9\u0089" + + "\u0001\u0000\u0000\u0000\u01aa\u01ab\u0005<\u0000\u0000\u01ab\u01ac\u0005" + + "<\u0000\u0000\u01ac\u01ad\u0005=\u0000\u0000\u01ad\u008b\u0001\u0000\u0000" + + "\u0000\u01ae\u01af\u0005>\u0000\u0000\u01af\u01b0\u0005>\u0000\u0000\u01b0" + + "\u01b1\u0005=\u0000\u0000\u01b1\u008d\u0001\u0000\u0000\u0000\u01b2\u01b3" + + "\u0005>\u0000\u0000\u01b3\u01b4\u0005>\u0000\u0000\u01b4\u01b5\u0005>" + + "\u0000\u0000\u01b5\u01b6\u0005=\u0000\u0000\u01b6\u008f\u0001\u0000\u0000" + + "\u0000\u01b7\u01b9\u00050\u0000\u0000\u01b8\u01ba\u0007\u0002\u0000\u0000" + + "\u01b9\u01b8\u0001\u0000\u0000\u0000\u01ba\u01bb\u0001\u0000\u0000\u0000" + + "\u01bb\u01b9\u0001\u0000\u0000\u0000\u01bb\u01bc\u0001\u0000\u0000\u0000" + + "\u01bc\u01be\u0001\u0000\u0000\u0000\u01bd\u01bf\u0007\u0003\u0000\u0000" + + "\u01be\u01bd\u0001\u0000\u0000\u0000\u01be\u01bf\u0001\u0000\u0000\u0000" + + "\u01bf\u0091\u0001\u0000\u0000\u0000\u01c0\u01c1\u00050\u0000\u0000\u01c1" + + "\u01c3\u0007\u0004\u0000\u0000\u01c2\u01c4\u0007\u0005\u0000\u0000\u01c3" + + "\u01c2\u0001\u0000\u0000\u0000\u01c4\u01c5\u0001\u0000\u0000\u0000\u01c5" + + "\u01c3\u0001\u0000\u0000\u0000\u01c5\u01c6\u0001\u0000\u0000\u0000\u01c6" + + "\u01c8\u0001\u0000\u0000\u0000\u01c7\u01c9\u0007\u0003\u0000\u0000\u01c8" + + "\u01c7\u0001\u0000\u0000\u0000\u01c8\u01c9\u0001\u0000\u0000\u0000\u01c9" + + "\u0093\u0001\u0000\u0000\u0000\u01ca\u01d3\u00050\u0000\u0000\u01cb\u01cf" + + "\u0007\u0006\u0000\u0000\u01cc\u01ce\u0007\u0007\u0000\u0000\u01cd\u01cc" + + "\u0001\u0000\u0000\u0000\u01ce\u01d1\u0001\u0000\u0000\u0000\u01cf\u01cd" + + "\u0001\u0000\u0000\u0000\u01cf\u01d0\u0001\u0000\u0000\u0000\u01d0\u01d3" + + "\u0001\u0000\u0000\u0000\u01d1\u01cf\u0001\u0000\u0000\u0000\u01d2\u01ca" + + "\u0001\u0000\u0000\u0000\u01d2\u01cb\u0001\u0000\u0000\u0000\u01d3\u01d5" + + "\u0001\u0000\u0000\u0000\u01d4\u01d6\u0007\b\u0000\u0000\u01d5\u01d4\u0001" + + "\u0000\u0000\u0000\u01d5\u01d6\u0001\u0000\u0000\u0000\u01d6\u0095\u0001" + + "\u0000\u0000\u0000\u01d7\u01e0\u00050\u0000\u0000\u01d8\u01dc\u0007\u0006" + + "\u0000\u0000\u01d9\u01db\u0007\u0007\u0000\u0000\u01da\u01d9\u0001\u0000" + + "\u0000\u0000\u01db\u01de\u0001\u0000\u0000\u0000\u01dc\u01da\u0001\u0000" + + "\u0000\u0000\u01dc\u01dd\u0001\u0000\u0000\u0000\u01dd\u01e0\u0001\u0000" + + "\u0000\u0000\u01de\u01dc\u0001\u0000\u0000\u0000\u01df\u01d7\u0001\u0000" + + "\u0000\u0000\u01df\u01d8\u0001\u0000\u0000\u0000\u01e0\u01e7\u0001\u0000" + + "\u0000\u0000\u01e1\u01e3\u0003\u0012\b\u0000\u01e2\u01e4\u0007\u0007\u0000" + + "\u0000\u01e3\u01e2\u0001\u0000\u0000\u0000\u01e4\u01e5\u0001\u0000\u0000" + + "\u0000\u01e5\u01e3\u0001\u0000\u0000\u0000\u01e5\u01e6\u0001\u0000\u0000" + + "\u0000\u01e6\u01e8\u0001\u0000\u0000\u0000\u01e7\u01e1\u0001\u0000\u0000" + + "\u0000\u01e7\u01e8\u0001\u0000\u0000\u0000\u01e8\u01f2\u0001\u0000\u0000" + + "\u0000\u01e9\u01eb\u0007\t\u0000\u0000\u01ea\u01ec\u0007\n\u0000\u0000" + + "\u01eb\u01ea\u0001\u0000\u0000\u0000\u01eb\u01ec\u0001\u0000\u0000\u0000" + + "\u01ec\u01ee\u0001\u0000\u0000\u0000\u01ed\u01ef\u0007\u0007\u0000\u0000" + + "\u01ee\u01ed\u0001\u0000\u0000\u0000\u01ef\u01f0\u0001\u0000\u0000\u0000" + + "\u01f0\u01ee\u0001\u0000\u0000\u0000\u01f0\u01f1\u0001\u0000\u0000\u0000" + + "\u01f1\u01f3\u0001\u0000\u0000\u0000\u01f2\u01e9\u0001\u0000\u0000\u0000" + + "\u01f2\u01f3\u0001\u0000\u0000\u0000\u01f3\u01f5\u0001\u0000\u0000\u0000" + + "\u01f4\u01f6\u0007\u000b\u0000\u0000\u01f5\u01f4\u0001\u0000\u0000\u0000" + + "\u01f5\u01f6\u0001\u0000\u0000\u0000\u01f6\u0097\u0001\u0000\u0000\u0000" + + "\u01f7\u01ff\u0005\"\u0000\u0000\u01f8\u01f9\u0005\\\u0000\u0000\u01f9" + + "\u01fe\u0005\"\u0000\u0000\u01fa\u01fb\u0005\\\u0000\u0000\u01fb\u01fe" + + "\u0005\\\u0000\u0000\u01fc\u01fe\b\f\u0000\u0000\u01fd\u01f8\u0001\u0000" + + "\u0000\u0000\u01fd\u01fa\u0001\u0000\u0000\u0000\u01fd\u01fc\u0001\u0000" + + "\u0000\u0000\u01fe\u0201\u0001\u0000\u0000\u0000\u01ff\u0200\u0001\u0000" + + "\u0000\u0000\u01ff\u01fd\u0001\u0000\u0000\u0000\u0200\u0202\u0001\u0000" + + "\u0000\u0000\u0201\u01ff\u0001\u0000\u0000\u0000\u0202\u0210\u0005\"\u0000" + + "\u0000\u0203\u020b\u0005\'\u0000\u0000\u0204\u0205\u0005\\\u0000\u0000" + + "\u0205\u020a\u0005\'\u0000\u0000\u0206\u0207\u0005\\\u0000\u0000\u0207" + + "\u020a\u0005\\\u0000\u0000\u0208\u020a\b\r\u0000\u0000\u0209\u0204\u0001" + + "\u0000\u0000\u0000\u0209\u0206\u0001\u0000\u0000\u0000\u0209\u0208\u0001" + + "\u0000\u0000\u0000\u020a\u020d\u0001\u0000\u0000\u0000\u020b\u020c\u0001" + + "\u0000\u0000\u0000\u020b\u0209\u0001\u0000\u0000\u0000\u020c\u020e\u0001" + + "\u0000\u0000\u0000\u020d\u020b\u0001\u0000\u0000\u0000\u020e\u0210\u0005" + + "\'\u0000\u0000\u020f\u01f7\u0001\u0000\u0000\u0000\u020f\u0203\u0001\u0000" + + "\u0000\u0000\u0210\u0099\u0001\u0000\u0000\u0000\u0211\u0215\u0005/\u0000" + + "\u0000\u0212\u0213\u0005\\\u0000\u0000\u0213\u0216\b\u000e\u0000\u0000" + + "\u0214\u0216\b\u000f\u0000\u0000\u0215\u0212\u0001\u0000\u0000\u0000\u0215" + + "\u0214\u0001\u0000\u0000\u0000\u0216\u0217\u0001\u0000\u0000\u0000\u0217" + + "\u0218\u0001\u0000\u0000\u0000\u0217\u0215\u0001\u0000\u0000\u0000\u0218" + + "\u0219\u0001\u0000\u0000\u0000\u0219\u021d\u0005/\u0000\u0000\u021a\u021c" + + "\u0007\u0010\u0000\u0000\u021b\u021a\u0001\u0000\u0000\u0000\u021c\u021f" + + "\u0001\u0000\u0000\u0000\u021d\u021b\u0001\u0000\u0000\u0000\u021d\u021e" + + "\u0001\u0000\u0000\u0000\u021e\u0220\u0001\u0000\u0000\u0000\u021f\u021d" + + "\u0001\u0000\u0000\u0000\u0220\u0221\u0004L\u0001\u0000\u0221\u009b\u0001" + + "\u0000\u0000\u0000\u0222\u0223\u0005t\u0000\u0000\u0223\u0224\u0005r\u0000" + + "\u0000\u0224\u0225\u0005u\u0000\u0000\u0225\u0226\u0005e\u0000\u0000\u0226" + + "\u009d\u0001\u0000\u0000\u0000\u0227\u0228\u0005f\u0000\u0000\u0228\u0229" + + "\u0005a\u0000\u0000\u0229\u022a\u0005l\u0000\u0000\u022a\u022b\u0005s" + + "\u0000\u0000\u022b\u022c\u0005e\u0000\u0000\u022c\u009f\u0001\u0000\u0000" + + "\u0000\u022d\u022e\u0005n\u0000\u0000\u022e\u022f\u0005u\u0000\u0000\u022f" + + "\u0230\u0005l\u0000\u0000\u0230\u0231\u0005l\u0000\u0000\u0231\u00a1\u0001" + + "\u0000\u0000\u0000\u0232\u0236\u0003\u00a4Q\u0000\u0233\u0234\u0003\n" + + "\u0004\u0000\u0234\u0235\u0003\f\u0005\u0000\u0235\u0237\u0001\u0000\u0000" + + "\u0000\u0236\u0233\u0001\u0000\u0000\u0000\u0237\u0238\u0001\u0000\u0000" + + "\u0000\u0238\u0236\u0001\u0000\u0000\u0000\u0238\u0239\u0001\u0000\u0000" + + "\u0000\u0239\u00a3\u0001\u0000\u0000\u0000\u023a\u0240\u0003\u00a6R\u0000" + + "\u023b\u023c\u0003\u0012\b\u0000\u023c\u023d\u0003\u00a6R\u0000\u023d" + + "\u023f\u0001\u0000\u0000\u0000\u023e\u023b\u0001\u0000\u0000\u0000\u023f" + + "\u0242\u0001\u0000\u0000\u0000\u0240\u023e\u0001\u0000\u0000\u0000\u0240" + + "\u0241\u0001\u0000\u0000\u0000\u0241\u0243\u0001\u0000\u0000\u0000\u0242" + + "\u0240\u0001\u0000\u0000\u0000\u0243\u0244\u0004Q\u0002\u0000\u0244\u00a5" + + "\u0001\u0000\u0000\u0000\u0245\u0249\u0007\u0011\u0000\u0000\u0246\u0248" + + "\u0007\u0012\u0000\u0000\u0247\u0246\u0001\u0000\u0000\u0000\u0248\u024b" + + "\u0001\u0000\u0000\u0000\u0249\u0247\u0001\u0000\u0000\u0000\u0249\u024a" + + "\u0001\u0000\u0000\u0000\u024a\u00a7\u0001\u0000\u0000\u0000\u024b\u0249" + + "\u0001\u0000\u0000\u0000\u024c\u024d\t\u0000\u0000\u0000\u024d\u024e\u0001" + + "\u0000\u0000\u0000\u024e\u024f\u0006S\u0000\u0000\u024f\u00a9\u0001\u0000" + + "\u0000\u0000\u0250\u0259\u00050\u0000\u0000\u0251\u0255\u0007\u0006\u0000" + + "\u0000\u0252\u0254\u0007\u0007\u0000\u0000\u0253\u0252\u0001\u0000\u0000" + + "\u0000\u0254\u0257\u0001\u0000\u0000\u0000\u0255\u0253\u0001\u0000\u0000" + + "\u0000\u0255\u0256\u0001\u0000\u0000\u0000\u0256\u0259\u0001\u0000\u0000" + + "\u0000\u0257\u0255\u0001\u0000\u0000\u0000\u0258\u0250\u0001\u0000\u0000" + + "\u0000\u0258\u0251\u0001\u0000\u0000\u0000\u0259\u025a\u0001\u0000\u0000" + + "\u0000\u025a\u025b\u0006T\u0002\u0000\u025b\u00ab\u0001\u0000\u0000\u0000" + + "\u025c\u0260\u0007\u0011\u0000\u0000\u025d\u025f\u0007\u0012\u0000\u0000" + + "\u025e\u025d\u0001\u0000\u0000\u0000\u025f\u0262\u0001\u0000\u0000\u0000" + + "\u0260\u025e\u0001\u0000\u0000\u0000\u0260\u0261\u0001\u0000\u0000\u0000" + + "\u0261\u0263\u0001\u0000\u0000\u0000\u0262\u0260\u0001\u0000\u0000\u0000" + + "\u0263\u0264\u0006U\u0002\u0000\u0264\u00ad\u0001\u0000\u0000\u0000#\u0000" + + "\u0001\u00b1\u00bb\u00c5\u00ca\u01bb\u01be\u01c5\u01c8\u01cf\u01d2\u01d5" + + "\u01dc\u01df\u01e5\u01e7\u01eb\u01f0\u01f2\u01f5\u01fd\u01ff\u0209\u020b" + + "\u020f\u0215\u0217\u021d\u0238\u0240\u0249\u0255\u0258\u0260\u0003\u0006" + + "\u0000\u0000\u0002\u0001\u0000\u0002\u0000\u0000"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; diff --git a/server/src/main/java/org/elasticsearch/Version.java b/server/src/main/java/org/elasticsearch/Version.java index f5dad1e51a5e..8a5e4b340ed5 100644 --- a/server/src/main/java/org/elasticsearch/Version.java +++ b/server/src/main/java/org/elasticsearch/Version.java @@ -131,7 +131,8 @@ public class Version implements Comparable, ToXContentFragment { public static final Version V_8_5_4 = new Version(8_05_04_99, TransportVersion.V_8_5_4, org.apache.lucene.util.Version.LUCENE_9_4_2); public static final Version V_8_6_0 = new Version(8_06_00_99, TransportVersion.V_8_6_0, org.apache.lucene.util.Version.LUCENE_9_4_2); public static final Version V_8_6_1 = new Version(8_06_01_99, TransportVersion.V_8_6_1, org.apache.lucene.util.Version.LUCENE_9_4_2); - public static final Version V_8_7_0 = new Version(8_07_00_99, TransportVersion.V_8_7_0, org.apache.lucene.util.Version.LUCENE_9_4_2); + public static final Version V_8_7_0 = new Version(8_07_00_99, TransportVersion.V_8_7_0, org.apache.lucene.util.Version.LUCENE_9_5_0); + public static final Version CURRENT = V_8_7_0; private static final Map VERSION_IDS; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/diskusage/IndexDiskUsageAnalyzer.java b/server/src/main/java/org/elasticsearch/action/admin/indices/diskusage/IndexDiskUsageAnalyzer.java index ba47c28c869d..ebf68ffdb403 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/diskusage/IndexDiskUsageAnalyzer.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/diskusage/IndexDiskUsageAnalyzer.java @@ -20,6 +20,7 @@ import org.apache.lucene.codecs.StoredFieldsReader; import org.apache.lucene.codecs.TermVectorsReader; import org.apache.lucene.codecs.lucene90.Lucene90PostingsFormat; import org.apache.lucene.index.BinaryDocValues; +import org.apache.lucene.index.ByteVectorValues; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.DocValuesType; import org.apache.lucene.index.FieldInfo; @@ -137,7 +138,7 @@ final class IndexDiskUsageAnalyzer { final int skipMask = 0x1FF; // 511 while (docID < reader.maxDoc()) { cancellationChecker.logEvent(); - storedFieldsReader.visitDocument(docID, visitor); + storedFieldsReader.document(docID, visitor); // As we already estimate the size of stored fields, we can trade off the accuracy for the speed of the estimate. // Here we only visit 1/11 documents instead of all documents. Ideally, we should visit 1 doc then skip 10 docs // to avoid missing many skew documents. But, documents are stored in chunks in compressed format and a chunk can @@ -525,23 +526,47 @@ final class IndexDiskUsageAnalyzer { cancellationChecker.checkForCancellation(); directory.resetBytesRead(); if (field.getVectorDimension() > 0) { - iterateDocValues(reader.maxDoc(), () -> vectorReader.getVectorValues(field.name), vectors -> { - cancellationChecker.logEvent(); - vectors.vectorValue(); - }); + switch (field.getVectorEncoding()) { + case BYTE -> { + iterateDocValues(reader.maxDoc(), () -> vectorReader.getByteVectorValues(field.name), vectors -> { + cancellationChecker.logEvent(); + vectors.vectorValue(); + }); - // do a couple of randomized searches to figure out min and max offsets of index file - VectorValues vectorValues = vectorReader.getVectorValues(field.name); - int numDocsToVisit = reader.maxDoc() < 10 ? reader.maxDoc() : 10 * (int) Math.log10(reader.maxDoc()); - int skipFactor = Math.max(reader.maxDoc() / numDocsToVisit, 1); - for (int i = 0; i < reader.maxDoc(); i += skipFactor) { - if ((i = vectorValues.advance(i)) == DocIdSetIterator.NO_MORE_DOCS) { - break; + // do a couple of randomized searches to figure out min and max offsets of index file + ByteVectorValues vectorValues = vectorReader.getByteVectorValues(field.name); + int numDocsToVisit = reader.maxDoc() < 10 ? reader.maxDoc() : 10 * (int) Math.log10(reader.maxDoc()); + int skipFactor = Math.max(reader.maxDoc() / numDocsToVisit, 1); + for (int i = 0; i < reader.maxDoc(); i += skipFactor) { + if ((i = vectorValues.advance(i)) == DocIdSetIterator.NO_MORE_DOCS) { + break; + } + cancellationChecker.checkForCancellation(); + vectorReader.search(field.name, vectorValues.vectorValue(), 100, null, Integer.MAX_VALUE); + } + stats.addKnnVectors(field.name, directory.getBytesRead()); + } + case FLOAT32 -> { + iterateDocValues(reader.maxDoc(), () -> vectorReader.getVectorValues(field.name), vectors -> { + cancellationChecker.logEvent(); + vectors.vectorValue(); + }); + + // do a couple of randomized searches to figure out min and max offsets of index file + VectorValues vectorValues = vectorReader.getVectorValues(field.name); + int numDocsToVisit = reader.maxDoc() < 10 ? reader.maxDoc() : 10 * (int) Math.log10(reader.maxDoc()); + int skipFactor = Math.max(reader.maxDoc() / numDocsToVisit, 1); + for (int i = 0; i < reader.maxDoc(); i += skipFactor) { + if ((i = vectorValues.advance(i)) == DocIdSetIterator.NO_MORE_DOCS) { + break; + } + cancellationChecker.checkForCancellation(); + vectorReader.search(field.name, vectorValues.vectorValue(), 100, null, Integer.MAX_VALUE); + } + stats.addKnnVectors(field.name, directory.getBytesRead()); } - cancellationChecker.checkForCancellation(); - vectorReader.search(field.name, vectorValues.vectorValue(), 100, null, Integer.MAX_VALUE); } - stats.addKnnVectors(field.name, directory.getBytesRead()); + } } } diff --git a/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java b/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java index cf31d3ff1005..a660730bfb02 100644 --- a/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java +++ b/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java @@ -86,7 +86,7 @@ import java.util.List; import java.util.Map; public class Lucene { - public static final String LATEST_CODEC = "Lucene94"; + public static final String LATEST_CODEC = "Lucene95"; public static final String SOFT_DELETES_FIELD = "__soft_deletes"; diff --git a/server/src/main/java/org/elasticsearch/common/lucene/search/MultiPhrasePrefixQuery.java b/server/src/main/java/org/elasticsearch/common/lucene/search/MultiPhrasePrefixQuery.java index 5c411c7b397c..1293c59486e7 100644 --- a/server/src/main/java/org/elasticsearch/common/lucene/search/MultiPhrasePrefixQuery.java +++ b/server/src/main/java/org/elasticsearch/common/lucene/search/MultiPhrasePrefixQuery.java @@ -299,7 +299,29 @@ public class MultiPhrasePrefixQuery extends Query { @Override public void visit(QueryVisitor visitor) { if (visitor.acceptField(field)) { - visitor.visitLeaf(this); // TODO implement term visiting + visitor = visitor.getSubVisitor(BooleanClause.Occur.MUST, this); + for (int i = 0; i < termArrays.size() - 1; i++) { + if (termArrays.get(i).length == 1) { + visitor.consumeTerms(this, termArrays.get(i)[0]); + } else { + QueryVisitor shouldVisitor = visitor.getSubVisitor(BooleanClause.Occur.SHOULD, this); + shouldVisitor.consumeTerms(this, termArrays.get(i)); + } + } + /* We don't report automata here because this breaks the unified highlighter, + which extracts automata separately from phrases. MPPQ gets rewritten to a + SpanMTQQuery by the PhraseHelper in any case, so highlighting is taken + care of there instead. If we extract automata here then the trailing prefix + word will be highlighted wherever it appears in the document, instead of only + as part of a phrase. This can be re-instated once we switch to using Matches + to highlight. + for (Term prefixTerm : termArrays.get(termArrays.size() - 1)) { + visitor.consumeTermsMatching(this, field, () -> { + CompiledAutomaton ca = new CompiledAutomaton(PrefixQuery.toAutomaton(prefixTerm.bytes())); + return ca.runAutomaton; + }); + } + */ } } } diff --git a/server/src/main/java/org/elasticsearch/index/codec/CodecService.java b/server/src/main/java/org/elasticsearch/index/codec/CodecService.java index 0daf88610fbe..990d44f5baef 100644 --- a/server/src/main/java/org/elasticsearch/index/codec/CodecService.java +++ b/server/src/main/java/org/elasticsearch/index/codec/CodecService.java @@ -9,7 +9,7 @@ package org.elasticsearch.index.codec; import org.apache.lucene.codecs.Codec; -import org.apache.lucene.codecs.lucene94.Lucene94Codec; +import org.apache.lucene.codecs.lucene95.Lucene95Codec; import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.core.Nullable; import org.elasticsearch.index.mapper.MapperService; @@ -35,11 +35,11 @@ public class CodecService { public CodecService(@Nullable MapperService mapperService, BigArrays bigArrays) { final var codecs = new HashMap(); if (mapperService == null) { - codecs.put(DEFAULT_CODEC, new Lucene94Codec()); - codecs.put(BEST_COMPRESSION_CODEC, new Lucene94Codec(Lucene94Codec.Mode.BEST_COMPRESSION)); + codecs.put(DEFAULT_CODEC, new Lucene95Codec()); + codecs.put(BEST_COMPRESSION_CODEC, new Lucene95Codec(Lucene95Codec.Mode.BEST_COMPRESSION)); } else { - codecs.put(DEFAULT_CODEC, new PerFieldMapperCodec(Lucene94Codec.Mode.BEST_SPEED, mapperService, bigArrays)); - codecs.put(BEST_COMPRESSION_CODEC, new PerFieldMapperCodec(Lucene94Codec.Mode.BEST_COMPRESSION, mapperService, bigArrays)); + codecs.put(DEFAULT_CODEC, new PerFieldMapperCodec(Lucene95Codec.Mode.BEST_SPEED, mapperService, bigArrays)); + codecs.put(BEST_COMPRESSION_CODEC, new PerFieldMapperCodec(Lucene95Codec.Mode.BEST_COMPRESSION, mapperService, bigArrays)); } codecs.put(LUCENE_DEFAULT_CODEC, Codec.getDefault()); for (String codec : Codec.availableCodecs()) { diff --git a/server/src/main/java/org/elasticsearch/index/codec/PerFieldMapperCodec.java b/server/src/main/java/org/elasticsearch/index/codec/PerFieldMapperCodec.java index a847909baca7..95dd202a86e4 100644 --- a/server/src/main/java/org/elasticsearch/index/codec/PerFieldMapperCodec.java +++ b/server/src/main/java/org/elasticsearch/index/codec/PerFieldMapperCodec.java @@ -13,7 +13,7 @@ import org.apache.lucene.codecs.DocValuesFormat; import org.apache.lucene.codecs.KnnVectorsFormat; import org.apache.lucene.codecs.PostingsFormat; import org.apache.lucene.codecs.lucene90.Lucene90DocValuesFormat; -import org.apache.lucene.codecs.lucene94.Lucene94Codec; +import org.apache.lucene.codecs.lucene95.Lucene95Codec; import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.index.IndexMode; @@ -37,7 +37,7 @@ import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper; * per index in real time via the mapping API. If no specific postings format or vector format is * configured for a specific field the default postings or vector format is used. */ -public class PerFieldMapperCodec extends Lucene94Codec { +public class PerFieldMapperCodec extends Lucene95Codec { private final MapperService mapperService; private final DocValuesFormat docValuesFormat = new Lucene90DocValuesFormat(); diff --git a/server/src/main/java/org/elasticsearch/index/engine/IdStoredFieldLoader.java b/server/src/main/java/org/elasticsearch/index/engine/IdStoredFieldLoader.java index 734678417c6b..61f9f2c0f24d 100644 --- a/server/src/main/java/org/elasticsearch/index/engine/IdStoredFieldLoader.java +++ b/server/src/main/java/org/elasticsearch/index/engine/IdStoredFieldLoader.java @@ -35,7 +35,7 @@ final class IdStoredFieldLoader { private static CheckedBiConsumer getStoredFieldsReader(LeafReader in) { if (in instanceof SequentialStoredFieldsLeafReader) { - return (((SequentialStoredFieldsLeafReader) in).getSequentialStoredFieldsReader())::visitDocument; + return (((SequentialStoredFieldsLeafReader) in).getSequentialStoredFieldsReader())::document; } throw new IllegalArgumentException("Requires a SequentialStoredFieldsReader, got " + in.getClass()); } diff --git a/server/src/main/java/org/elasticsearch/index/engine/LuceneChangesSnapshot.java b/server/src/main/java/org/elasticsearch/index/engine/LuceneChangesSnapshot.java index f673b693df6c..b81709aae8cb 100644 --- a/server/src/main/java/org/elasticsearch/index/engine/LuceneChangesSnapshot.java +++ b/server/src/main/java/org/elasticsearch/index/engine/LuceneChangesSnapshot.java @@ -338,7 +338,7 @@ final class LuceneChangesSnapshot implements Translog.Snapshot { assert singleConsumer : "Sequential access optimization must not be enabled for multiple consumers"; assert parallelArray.useSequentialStoredFieldsReader; assert storedFieldsReaderOrd == leaf.ord : storedFieldsReaderOrd + " != " + leaf.ord; - storedFieldsReader.visitDocument(segmentDocID, fields); + storedFieldsReader.document(segmentDocID, fields); } else { leaf.reader().document(segmentDocID, fields); } diff --git a/server/src/main/java/org/elasticsearch/index/engine/RecoverySourcePruneMergePolicy.java b/server/src/main/java/org/elasticsearch/index/engine/RecoverySourcePruneMergePolicy.java index 1a0b8531d7fb..05c5031edbdd 100644 --- a/server/src/main/java/org/elasticsearch/index/engine/RecoverySourcePruneMergePolicy.java +++ b/server/src/main/java/org/elasticsearch/index/engine/RecoverySourcePruneMergePolicy.java @@ -195,8 +195,8 @@ final class RecoverySourcePruneMergePolicy extends OneMergeWrappingMergePolicy { } @Override - public void visitDocument(int docID, StoredFieldVisitor visitor) throws IOException { - in.visitDocument(docID, visitor); + public void document(int docID, StoredFieldVisitor visitor) throws IOException { + in.document(docID, visitor); } @Override @@ -220,11 +220,11 @@ final class RecoverySourcePruneMergePolicy extends OneMergeWrappingMergePolicy { } @Override - public void visitDocument(int docID, StoredFieldVisitor visitor) throws IOException { + public void document(int docID, StoredFieldVisitor visitor) throws IOException { if (recoverySourceToKeep != null && recoverySourceToKeep.get(docID)) { - super.visitDocument(docID, visitor); + super.document(docID, visitor); } else { - super.visitDocument(docID, new FilterStoredFieldVisitor(visitor) { + super.document(docID, new FilterStoredFieldVisitor(visitor) { @Override public Status needsField(FieldInfo fieldInfo) throws IOException { if (recoverySourceField.equals(fieldInfo.name)) { diff --git a/server/src/main/java/org/elasticsearch/index/engine/TranslogDirectoryReader.java b/server/src/main/java/org/elasticsearch/index/engine/TranslogDirectoryReader.java index c377fdd73f3d..e3afc895b338 100644 --- a/server/src/main/java/org/elasticsearch/index/engine/TranslogDirectoryReader.java +++ b/server/src/main/java/org/elasticsearch/index/engine/TranslogDirectoryReader.java @@ -11,6 +11,7 @@ package org.elasticsearch.index.engine; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.index.BaseTermsEnum; import org.apache.lucene.index.BinaryDocValues; +import org.apache.lucene.index.ByteVectorValues; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.DocValuesType; import org.apache.lucene.index.FieldInfo; @@ -30,6 +31,8 @@ import org.apache.lucene.index.SortedDocValues; import org.apache.lucene.index.SortedNumericDocValues; import org.apache.lucene.index.SortedSetDocValues; import org.apache.lucene.index.StoredFieldVisitor; +import org.apache.lucene.index.StoredFields; +import org.apache.lucene.index.TermVectors; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.VectorEncoding; @@ -349,11 +352,21 @@ final class TranslogDirectoryReader extends DirectoryReader { return getDelegate().getVectorValues(field); } + @Override + public ByteVectorValues getByteVectorValues(String field) throws IOException { + return getDelegate().getByteVectorValues(field); + } + @Override public TopDocs searchNearestVectors(String field, float[] target, int k, Bits acceptDocs, int visitedLimit) throws IOException { return getDelegate().searchNearestVectors(field, target, k, acceptDocs, visitedLimit); } + @Override + public TopDocs searchNearestVectors(String field, BytesRef target, int k, Bits acceptDocs, int visitedLimit) throws IOException { + return getDelegate().searchNearestVectors(field, target, k, acceptDocs, visitedLimit); + } + @Override public FieldInfos getFieldInfos() { return getDelegate().getFieldInfos(); @@ -382,6 +395,16 @@ final class TranslogDirectoryReader extends DirectoryReader { return getDelegate().getTermVectors(docID); } + @Override + public TermVectors termVectors() throws IOException { + return getDelegate().termVectors(); + } + + @Override + public StoredFields storedFields() throws IOException { + return getDelegate().storedFields(); + } + @Override public int numDocs() { return 1; diff --git a/server/src/main/java/org/elasticsearch/index/fieldvisitor/StoredFieldLoader.java b/server/src/main/java/org/elasticsearch/index/fieldvisitor/StoredFieldLoader.java index 1326127c58de..bbb5f40431e6 100644 --- a/server/src/main/java/org/elasticsearch/index/fieldvisitor/StoredFieldLoader.java +++ b/server/src/main/java/org/elasticsearch/index/fieldvisitor/StoredFieldLoader.java @@ -108,7 +108,7 @@ public abstract class StoredFieldLoader { private static CheckedBiConsumer sequentialReader(LeafReaderContext ctx) { LeafReader leafReader = ctx.reader(); if (leafReader instanceof SequentialStoredFieldsLeafReader lf) { - return lf.getSequentialStoredFieldsReader()::visitDocument; + return lf.getSequentialStoredFieldsReader()::document; } return leafReader::document; } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java index 79218051c807..04d3eac53ee8 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java @@ -17,8 +17,8 @@ import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.PointValues; import org.apache.lucene.index.SortedNumericDocValues; -import org.apache.lucene.sandbox.search.IndexSortSortedNumericDocValuesRangeQuery; import org.apache.lucene.search.IndexOrDocValuesQuery; +import org.apache.lucene.search.IndexSortSortedNumericDocValuesRangeQuery; import org.apache.lucene.search.Query; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.Version; diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DocumentLeafReader.java b/server/src/main/java/org/elasticsearch/index/mapper/DocumentLeafReader.java index e2a8feb30fa7..e2c8a1c84ebb 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/DocumentLeafReader.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/DocumentLeafReader.java @@ -9,6 +9,7 @@ package org.elasticsearch.index.mapper; import org.apache.lucene.index.BinaryDocValues; +import org.apache.lucene.index.ByteVectorValues; import org.apache.lucene.index.DocValuesType; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.FieldInfos; @@ -24,6 +25,8 @@ import org.apache.lucene.index.SortedDocValues; import org.apache.lucene.index.SortedNumericDocValues; import org.apache.lucene.index.SortedSetDocValues; import org.apache.lucene.index.StoredFieldVisitor; +import org.apache.lucene.index.StoredFields; +import org.apache.lucene.index.TermVectors; import org.apache.lucene.index.Terms; import org.apache.lucene.index.VectorEncoding; import org.apache.lucene.index.VectorSimilarityFunction; @@ -46,10 +49,9 @@ import java.util.function.Consumer; /** * A {@link LeafReader} over a lucene document that exposes doc values and stored fields. * Note that unlike lucene's {@link MemoryIndex} implementation, this holds no state and - * does not attempt to do any analysis on text fields. It also supports stored - * fields where MemoryIndex does not. It is used to back index-time scripts that - * reference field data and stored fields from a document that has not yet been - * indexed. + * does not attempt to do any analysis on text fields. It is used to back index-time + * scripts that reference field data and stored fields from a document that has not yet + * been indexed. */ class DocumentLeafReader extends LeafReader { @@ -175,6 +177,11 @@ class DocumentLeafReader extends LeafReader { } } + @Override + public StoredFields storedFields() throws IOException { + throw new UnsupportedOperationException(); + } + @Override public CacheHelper getCoreCacheHelper() { throw new UnsupportedOperationException(); @@ -240,6 +247,21 @@ class DocumentLeafReader extends LeafReader { throw new UnsupportedOperationException(); } + @Override + public ByteVectorValues getByteVectorValues(String field) { + throw new UnsupportedOperationException(); + } + + @Override + public TopDocs searchNearestVectors(String field, BytesRef target, int k, Bits acceptDocs, int visitedLimit) { + throw new UnsupportedOperationException(); + } + + @Override + public TermVectors termVectors() throws IOException { + throw new UnsupportedOperationException(); + } + @Override public CacheHelper getReaderCacheHelper() { throw new UnsupportedOperationException(); diff --git a/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java index 237ee081d177..5125c4614aee 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java @@ -17,8 +17,8 @@ import org.apache.lucene.document.StoredField; import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.sandbox.document.HalfFloatPoint; -import org.apache.lucene.sandbox.search.IndexSortSortedNumericDocValuesRangeQuery; import org.apache.lucene.search.IndexOrDocValuesQuery; +import org.apache.lucene.search.IndexSortSortedNumericDocValuesRangeQuery; import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.Query; import org.apache.lucene.util.BytesRef; diff --git a/server/src/main/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapper.java index e5f1537813d1..7896950ab1f7 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapper.java @@ -9,19 +9,21 @@ package org.elasticsearch.index.mapper.vectors; import org.apache.lucene.codecs.KnnVectorsFormat; -import org.apache.lucene.codecs.lucene94.Lucene94HnswVectorsFormat; +import org.apache.lucene.codecs.lucene95.Lucene95HnswVectorsFormat; import org.apache.lucene.document.BinaryDocValuesField; import org.apache.lucene.document.Field; +import org.apache.lucene.document.KnnByteVectorField; import org.apache.lucene.document.KnnVectorField; import org.apache.lucene.index.BinaryDocValues; +import org.apache.lucene.index.ByteVectorValues; import org.apache.lucene.index.LeafReader; import org.apache.lucene.index.VectorSimilarityFunction; import org.apache.lucene.index.VectorValues; import org.apache.lucene.search.FieldExistsQuery; +import org.apache.lucene.search.KnnByteVectorQuery; import org.apache.lucene.search.KnnVectorQuery; import org.apache.lucene.search.Query; import org.apache.lucene.util.BytesRef; -import org.apache.lucene.util.VectorUtil; import org.elasticsearch.Version; import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.index.fielddata.FieldDataContext; @@ -43,6 +45,7 @@ import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; import org.elasticsearch.xcontent.ToXContent; import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xcontent.XContentParser; import org.elasticsearch.xcontent.XContentParser.Token; import java.io.IOException; @@ -51,6 +54,7 @@ import java.time.ZoneId; import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.function.Function; import java.util.stream.Stream; import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; @@ -178,13 +182,18 @@ public class DenseVectorFieldMapper extends FieldMapper { } @Override - public float readValue(ByteBuffer byteBuffer) { - return byteBuffer.get(); + public void readAndWriteValue(ByteBuffer byteBuffer, XContentBuilder b) throws IOException { + b.value(byteBuffer.get()); + } + + @Override + KnnByteVectorField createKnnVectorField(String name, BytesRef vector, VectorSimilarityFunction function) { + return new KnnByteVectorField(name, vector, function); } @Override KnnVectorField createKnnVectorField(String name, float[] vector, VectorSimilarityFunction function) { - return new KnnVectorField(name, VectorUtil.toBytesRef(vector), function); + throw new IllegalArgumentException("cannot create a float vector field from byte"); } @Override @@ -245,7 +254,11 @@ public class DenseVectorFieldMapper extends FieldMapper { } @Override - void checkVectorMagnitude(VectorSimilarity similarity, float[] vector, float squaredMagnitude) { + void checkVectorMagnitude( + VectorSimilarity similarity, + Function appender, + float squaredMagnitude + ) { StringBuilder errorBuilder = null; if (similarity == VectorSimilarity.COSINE && Math.sqrt(squaredMagnitude) == 0.0f) { @@ -255,9 +268,91 @@ public class DenseVectorFieldMapper extends FieldMapper { } if (errorBuilder != null) { - throw new IllegalArgumentException(appendErrorElements(errorBuilder, vector).toString()); + throw new IllegalArgumentException(appender.apply(errorBuilder).toString()); } } + + @Override + public Field parseKnnVector(DocumentParserContext context, DenseVectorFieldMapper fieldMapper) throws IOException { + int index = 0; + byte[] vector = new byte[fieldMapper.dims]; + float squaredMagnitude = 0; + for (Token token = context.parser().nextToken(); token != Token.END_ARRAY; token = context.parser().nextToken()) { + fieldMapper.checkDimensionExceeded(index, context); + ensureExpectedToken(Token.VALUE_NUMBER, token, context.parser()); + final int value; + if (context.parser().numberType() != XContentParser.NumberType.INT) { + float floatValue = context.parser().floatValue(true); + if (floatValue % 1.0f != 0.0f) { + throw new IllegalArgumentException( + "element_type [" + + this + + "] vectors only support non-decimal values but found decimal value [" + + floatValue + + "] at dim [" + + index + + "];" + ); + } + value = (int) floatValue; + } else { + value = context.parser().intValue(true); + } + if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) { + throw new IllegalArgumentException( + "element_type [" + + this + + "] vectors only support integers between [" + + Byte.MIN_VALUE + + ", " + + Byte.MAX_VALUE + + "] but found [" + + value + + "] at dim [" + + index + + "];" + ); + } + vector[index++] = (byte) value; + squaredMagnitude += value * value; + } + fieldMapper.checkDimensionMatches(index, context); + BytesRef bytesVector = new BytesRef(vector); + checkVectorMagnitude(fieldMapper.similarity, errorByteElementsAppender(bytesVector), squaredMagnitude); + return createKnnVectorField(fieldMapper.fieldType().name(), bytesVector, fieldMapper.similarity.function); + } + + @Override + double parseKnnVectorToByteBuffer(DocumentParserContext context, DenseVectorFieldMapper fieldMapper, ByteBuffer byteBuffer) + throws IOException { + double dotProduct = 0f; + int index = 0; + for (Token token = context.parser().nextToken(); token != Token.END_ARRAY; token = context.parser().nextToken()) { + fieldMapper.checkDimensionExceeded(index, context); + ensureExpectedToken(Token.VALUE_NUMBER, token, context.parser()); + int value = context.parser().intValue(true); + if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) { + throw new IllegalArgumentException( + "element_type [" + + this + + "] vectors only support integers between [" + + Byte.MIN_VALUE + + ", " + + Byte.MAX_VALUE + + "] but found [" + + value + + "] at dim [" + + index + + "];" + ); + } + byteBuffer.put((byte) value); + dotProduct += value * value; + index++; + } + fieldMapper.checkDimensionMatches(index, context); + return dotProduct; + } }, FLOAT(4) { @@ -273,8 +368,8 @@ public class DenseVectorFieldMapper extends FieldMapper { } @Override - public float readValue(ByteBuffer byteBuffer) { - return byteBuffer.getFloat(); + public void readAndWriteValue(ByteBuffer byteBuffer, XContentBuilder b) throws IOException { + b.value(byteBuffer.getFloat()); } @Override @@ -282,6 +377,11 @@ public class DenseVectorFieldMapper extends FieldMapper { return new KnnVectorField(name, vector, function); } + @Override + KnnByteVectorField createKnnVectorField(String name, BytesRef vector, VectorSimilarityFunction function) { + throw new IllegalArgumentException("cannot create a byte vector field from float"); + } + @Override IndexFieldData.Builder fielddataBuilder(DenseVectorFieldType denseVectorFieldType, FieldDataContext fieldDataContext) { return new VectorIndexFieldData.Builder( @@ -300,7 +400,11 @@ public class DenseVectorFieldMapper extends FieldMapper { } @Override - void checkVectorMagnitude(VectorSimilarity similarity, float[] vector, float squaredMagnitude) { + void checkVectorMagnitude( + VectorSimilarity similarity, + Function appender, + float squaredMagnitude + ) { StringBuilder errorBuilder = null; if (similarity == VectorSimilarity.DOT_PRODUCT && Math.abs(squaredMagnitude - 1.0f) > 1e-4f) { @@ -314,9 +418,48 @@ public class DenseVectorFieldMapper extends FieldMapper { } if (errorBuilder != null) { - throw new IllegalArgumentException(appendErrorElements(errorBuilder, vector).toString()); + throw new IllegalArgumentException(appender.apply(errorBuilder).toString()); } } + + @Override + public Field parseKnnVector(DocumentParserContext context, DenseVectorFieldMapper fieldMapper) throws IOException { + int index = 0; + float[] vector = new float[fieldMapper.dims]; + float squaredMagnitude = 0; + for (Token token = context.parser().nextToken(); token != Token.END_ARRAY; token = context.parser().nextToken()) { + fieldMapper.checkDimensionExceeded(index, context); + ensureExpectedToken(Token.VALUE_NUMBER, token, context.parser()); + + float value = context.parser().floatValue(true); + vector[index++] = value; + squaredMagnitude += value * value; + } + fieldMapper.checkDimensionMatches(index, context); + checkVectorBounds(vector); + checkVectorMagnitude(fieldMapper.similarity, errorFloatElementsAppender(vector), squaredMagnitude); + return createKnnVectorField(fieldMapper.fieldType().name(), vector, fieldMapper.similarity.function); + } + + @Override + double parseKnnVectorToByteBuffer(DocumentParserContext context, DenseVectorFieldMapper fieldMapper, ByteBuffer byteBuffer) + throws IOException { + double dotProduct = 0f; + int index = 0; + float[] vector = new float[fieldMapper.dims]; + for (Token token = context.parser().nextToken(); token != Token.END_ARRAY; token = context.parser().nextToken()) { + fieldMapper.checkDimensionExceeded(index, context); + ensureExpectedToken(Token.VALUE_NUMBER, token, context.parser()); + float value = context.parser().floatValue(true); + vector[index] = value; + byteBuffer.putFloat(value); + dotProduct += value * value; + index++; + } + fieldMapper.checkDimensionMatches(index, context); + checkVectorBounds(vector); + return dotProduct; + } }; final int elementBytes; @@ -327,15 +470,26 @@ public class DenseVectorFieldMapper extends FieldMapper { public abstract void writeValue(ByteBuffer byteBuffer, float value); - public abstract float readValue(ByteBuffer byteBuffer); + public abstract void readAndWriteValue(ByteBuffer byteBuffer, XContentBuilder b) throws IOException; abstract KnnVectorField createKnnVectorField(String name, float[] vector, VectorSimilarityFunction function); + abstract KnnByteVectorField createKnnVectorField(String name, BytesRef vector, VectorSimilarityFunction function); + abstract IndexFieldData.Builder fielddataBuilder(DenseVectorFieldType denseVectorFieldType, FieldDataContext fieldDataContext); + abstract Field parseKnnVector(DocumentParserContext context, DenseVectorFieldMapper fieldMapper) throws IOException; + + abstract double parseKnnVectorToByteBuffer(DocumentParserContext context, DenseVectorFieldMapper fieldMapper, ByteBuffer byteBuffer) + throws IOException; + public abstract void checkVectorBounds(float[] vector); - abstract void checkVectorMagnitude(VectorSimilarity similarity, float[] vector, float squaredMagnitude); + abstract void checkVectorMagnitude( + VectorSimilarity similarity, + Function errorElementsAppender, + float squaredMagnitude + ); void checkNanAndInfinite(float[] vector) { StringBuilder errorBuilder = null; @@ -384,6 +538,30 @@ public class DenseVectorFieldMapper extends FieldMapper { errorBuilder.append("]"); return errorBuilder; } + + StringBuilder appendErrorElements(StringBuilder errorBuilder, BytesRef vector) { + // Include the first five elements of the invalid vector in the error message + errorBuilder.append(" Preview of invalid vector: ["); + for (int i = vector.offset; i < vector.offset + Math.min(5, vector.length); i++) { + if (i > vector.offset) { + errorBuilder.append(", "); + } + errorBuilder.append(vector.bytes[i]); + } + if (vector.length >= 5) { + errorBuilder.append(", ..."); + } + errorBuilder.append("]"); + return errorBuilder; + } + + Function errorFloatElementsAppender(float[] vector) { + return sb -> appendErrorElements(sb, vector); + } + + Function errorByteElementsAppender(BytesRef vector) { + return sb -> appendErrorElements(sb, vector); + } } static final Map namesToElementType = Map.of( @@ -546,7 +724,7 @@ public class DenseVectorFieldMapper extends FieldMapper { throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support term queries"); } - public KnnVectorQuery createKnnQuery(float[] queryVector, int numCands, Query filter) { + public Query createKnnQuery(BytesRef queryVector, int numCands, Query filter) { if (isIndexed() == false) { throw new IllegalArgumentException( "to perform knn search on field [" + name() + "], its mapping must have [index] set to [true]" @@ -559,6 +737,35 @@ public class DenseVectorFieldMapper extends FieldMapper { ); } + if (elementType != ElementType.BYTE) { + throw new IllegalArgumentException( + "only [" + ElementType.BYTE + "] elements are supported when querying field [" + name() + "]" + ); + } + + if (similarity == VectorSimilarity.DOT_PRODUCT || similarity == VectorSimilarity.COSINE) { + float squaredMagnitude = 0.0f; + for (int i = queryVector.offset; i < queryVector.offset + queryVector.length; i++) { + squaredMagnitude += queryVector.bytes[i] * queryVector.bytes[i]; + } + elementType.checkVectorMagnitude(similarity, elementType.errorByteElementsAppender(queryVector), squaredMagnitude); + } + + return new KnnByteVectorQuery(name(), queryVector, numCands, filter); + } + + public Query createKnnQuery(float[] queryVector, int numCands, Query filter) { + if (isIndexed() == false) { + throw new IllegalArgumentException( + "to perform knn search on field [" + name() + "], its mapping must have [index] set to [true]" + ); + } + + if (queryVector.length != dims) { + throw new IllegalArgumentException( + "the query vector has a different dimension [" + queryVector.length + "] than the index vectors [" + dims + "]" + ); + } elementType.checkVectorBounds(queryVector); if (similarity == VectorSimilarity.DOT_PRODUCT || similarity == VectorSimilarity.COSINE) { @@ -566,10 +773,18 @@ public class DenseVectorFieldMapper extends FieldMapper { for (float e : queryVector) { squaredMagnitude += e * e; } - elementType.checkVectorMagnitude(similarity, queryVector, squaredMagnitude); + elementType.checkVectorMagnitude(similarity, elementType.errorFloatElementsAppender(queryVector), squaredMagnitude); } - - return new KnnVectorQuery(name(), queryVector, numCands, filter); + return switch (elementType) { + case BYTE -> { + byte[] bytes = new byte[queryVector.length]; + for (int i = 0; i < queryVector.length; i++) { + bytes[i] = (byte) queryVector[i]; + } + yield new KnnByteVectorQuery(name(), new BytesRef(bytes), numCands, filter); + } + case FLOAT -> new KnnVectorQuery(name(), queryVector, numCands, filter); + }; } } @@ -628,21 +843,7 @@ public class DenseVectorFieldMapper extends FieldMapper { } private Field parseKnnVector(DocumentParserContext context) throws IOException { - float[] vector = new float[dims]; - float squaredMagnitude = 0.0f; - int index = 0; - for (Token token = context.parser().nextToken(); token != Token.END_ARRAY; token = context.parser().nextToken()) { - checkDimensionExceeded(index, context); - ensureExpectedToken(Token.VALUE_NUMBER, token, context.parser()); - - float value = context.parser().floatValue(true); - vector[index++] = value; - squaredMagnitude += value * value; - } - checkDimensionMatches(index, context); - elementType.checkVectorBounds(vector); - elementType.checkVectorMagnitude(similarity, vector, squaredMagnitude); - return elementType.createKnnVectorField(fieldType().name(), vector, similarity.function); + return elementType.parseKnnVector(context, this); } private Field parseBinaryDocValuesVector(DocumentParserContext context) throws IOException { @@ -653,22 +854,7 @@ public class DenseVectorFieldMapper extends FieldMapper { : new byte[dims * elementType.elementBytes]; ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); - double dotProduct = 0f; - - int index = 0; - float[] vector = new float[dims]; - for (Token token = context.parser().nextToken(); token != Token.END_ARRAY; token = context.parser().nextToken()) { - checkDimensionExceeded(index, context); - ensureExpectedToken(Token.VALUE_NUMBER, token, context.parser()); - float value = context.parser().floatValue(true); - vector[index] = value; - elementType.writeValue(byteBuffer, value); - dotProduct += value * value; - index++; - } - checkDimensionMatches(index, context); - elementType.checkVectorBounds(vector); - + double dotProduct = elementType.parseKnnVectorToByteBuffer(context, this, byteBuffer); if (indexCreatedVersion.onOrAfter(Version.V_7_5_0)) { // encode vector magnitude at the end float vectorMagnitude = (float) Math.sqrt(dotProduct); @@ -759,7 +945,7 @@ public class DenseVectorFieldMapper extends FieldMapper { return null; // use default format } else { HnswIndexOptions hnswIndexOptions = (HnswIndexOptions) indexOptions; - return new Lucene94HnswVectorsFormat(hnswIndexOptions.m, hnswIndexOptions.efConstruction); + return new Lucene95HnswVectorsFormat(hnswIndexOptions.m, hnswIndexOptions.efConstruction); } } @@ -778,6 +964,7 @@ public class DenseVectorFieldMapper extends FieldMapper { private class IndexedSyntheticFieldLoader implements SourceLoader.SyntheticFieldLoader { private VectorValues values; + private ByteVectorValues byteVectorValues; private boolean hasValue; @Override @@ -788,13 +975,20 @@ public class DenseVectorFieldMapper extends FieldMapper { @Override public DocValuesLoader docValuesLoader(LeafReader leafReader, int[] docIdsInLeaf) throws IOException { values = leafReader.getVectorValues(name()); - if (values == null) { - return null; + if (values != null) { + return docId -> { + hasValue = docId == values.advance(docId); + return hasValue; + }; } - return docId -> { - hasValue = docId == values.advance(docId); - return hasValue; - }; + byteVectorValues = leafReader.getByteVectorValues(name()); + if (byteVectorValues != null) { + return docId -> { + hasValue = docId == byteVectorValues.advance(docId); + return hasValue; + }; + } + return null; } @Override @@ -808,8 +1002,15 @@ public class DenseVectorFieldMapper extends FieldMapper { return; } b.startArray(simpleName()); - for (float v : values.vectorValue()) { - b.value(v); + if (values != null) { + for (float v : values.vectorValue()) { + b.value(v); + } + } else if (byteVectorValues != null) { + BytesRef vectorValue = byteVectorValues.vectorValue(); + for (int i = vectorValue.offset; i < vectorValue.offset + vectorValue.length; i++) { + b.value(vectorValue.bytes[i]); + } } b.endArray(); } @@ -850,7 +1051,7 @@ public class DenseVectorFieldMapper extends FieldMapper { BytesRef ref = values.binaryValue(); ByteBuffer byteBuffer = ByteBuffer.wrap(ref.bytes, ref.offset, ref.length); for (int dim = 0; dim < dims; dim++) { - b.value(elementType.readValue(byteBuffer)); + elementType.readAndWriteValue(byteBuffer, b); } b.endArray(); } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/vectors/VectorDVLeafFieldData.java b/server/src/main/java/org/elasticsearch/index/mapper/vectors/VectorDVLeafFieldData.java index 736a5bdf275b..a3ee9945035b 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/vectors/VectorDVLeafFieldData.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/vectors/VectorDVLeafFieldData.java @@ -11,7 +11,6 @@ package org.elasticsearch.index.mapper.vectors; import org.apache.lucene.index.BinaryDocValues; import org.apache.lucene.index.DocValues; import org.apache.lucene.index.LeafReader; -import org.apache.lucene.index.VectorValues; import org.elasticsearch.Version; import org.elasticsearch.index.fielddata.LeafFieldData; import org.elasticsearch.index.fielddata.SortedBinaryDocValues; @@ -56,15 +55,9 @@ final class VectorDVLeafFieldData implements LeafFieldData { public DocValuesScriptFieldFactory getScriptFieldFactory(String name) { try { if (indexed) { - VectorValues values = reader.getVectorValues(field); - if (values == VectorValues.EMPTY) { - // There's no way for KnnDenseVectorDocValuesField to reliably differentiate between VectorValues.EMPTY and - // values that can be iterated through. Since VectorValues.EMPTY throws on docID(), pass a null instead. - values = null; - } return switch (elementType) { - case BYTE -> new ByteKnnDenseVectorDocValuesField(values, name, elementType, dims); - case FLOAT -> new KnnDenseVectorDocValuesField(values, name, elementType, dims); + case BYTE -> new ByteKnnDenseVectorDocValuesField(reader.getByteVectorValues(field), name, dims); + case FLOAT -> new KnnDenseVectorDocValuesField(reader.getVectorValues(field), name, dims); }; } else { BinaryDocValues values = DocValues.getBinary(reader, field); diff --git a/server/src/main/java/org/elasticsearch/index/query/CombinedFieldsQueryBuilder.java b/server/src/main/java/org/elasticsearch/index/query/CombinedFieldsQueryBuilder.java index 52741a88e056..1e8ce792e52a 100644 --- a/server/src/main/java/org/elasticsearch/index/query/CombinedFieldsQueryBuilder.java +++ b/server/src/main/java/org/elasticsearch/index/query/CombinedFieldsQueryBuilder.java @@ -407,11 +407,11 @@ public class CombinedFieldsQueryBuilder extends AbstractQueryBuilder new TermAndBoost(t, BoostAttribute.DEFAULT_BOOST)) + .map(t -> new TermAndBoost(t.bytes(), BoostAttribute.DEFAULT_BOOST)) .toArray(TermAndBoost[]::new); - q.add(newSynonymQuery(termAndBoosts), operator); + q.add(newSynonymQuery(field, termAndBoosts), operator); } } @@ -648,9 +648,9 @@ public class MatchQueryParser { } else { // We don't apply prefix on synonyms final TermAndBoost[] termAndBoosts = Arrays.stream(terms) - .map(t -> new TermAndBoost(t, BoostAttribute.DEFAULT_BOOST)) + .map(t -> new TermAndBoost(t.bytes(), BoostAttribute.DEFAULT_BOOST)) .toArray(TermAndBoost[]::new); - queryPos = newSynonymQuery(termAndBoosts); + queryPos = newSynonymQuery(field, termAndBoosts); } } if (queryPos != null) { diff --git a/server/src/main/java/org/elasticsearch/index/search/MultiMatchQueryParser.java b/server/src/main/java/org/elasticsearch/index/search/MultiMatchQueryParser.java index 1220aeb9e96a..4c3020bdcd9d 100644 --- a/server/src/main/java/org/elasticsearch/index/search/MultiMatchQueryParser.java +++ b/server/src/main/java/org/elasticsearch/index/search/MultiMatchQueryParser.java @@ -196,10 +196,10 @@ public class MultiMatchQueryParser extends MatchQueryParser { } @Override - protected Query newSynonymQuery(TermAndBoost[] terms) { + protected Query newSynonymQuery(String field, TermAndBoost[] terms) { BytesRef[] values = new BytesRef[terms.length]; for (int i = 0; i < terms.length; i++) { - values[i] = terms[i].term.bytes(); + values[i] = terms[i].term; } return blendTerms(context, values, tieBreaker, lenient, blendedFields); } diff --git a/server/src/main/java/org/elasticsearch/script/VectorScoreScriptUtils.java b/server/src/main/java/org/elasticsearch/script/VectorScoreScriptUtils.java index 78efbaa373b3..ab3b12434f86 100644 --- a/server/src/main/java/org/elasticsearch/script/VectorScoreScriptUtils.java +++ b/server/src/main/java/org/elasticsearch/script/VectorScoreScriptUtils.java @@ -52,18 +52,18 @@ public class VectorScoreScriptUtils { public ByteDenseVectorFunction(ScoreScript scoreScript, DenseVectorDocValuesField field, List queryVector) { super(scoreScript, field); DenseVector.checkDimensions(field.get().getDims(), queryVector.size()); - - float[] vector = new float[queryVector.size()]; this.queryVector = new byte[queryVector.size()]; + float[] validateValues = new float[queryVector.size()]; int queryMagnitude = 0; for (int i = 0; i < queryVector.size(); i++) { - float value = queryVector.get(i).floatValue(); - vector[i] = value; - this.queryVector[i] = (byte) value; + final Number number = queryVector.get(i); + byte value = number.byteValue(); + this.queryVector[i] = value; queryMagnitude += value * value; + validateValues[i] = number.floatValue(); } this.qvMagnitude = (float) Math.sqrt(queryMagnitude); - field.getElementType().checkVectorBounds(vector); + field.getElementType().checkVectorBounds(validateValues); } } diff --git a/server/src/main/java/org/elasticsearch/script/field/vectors/ByteKnnDenseVector.java b/server/src/main/java/org/elasticsearch/script/field/vectors/ByteKnnDenseVector.java index 3b0817bcf230..864c32ae43a4 100644 --- a/server/src/main/java/org/elasticsearch/script/field/vectors/ByteKnnDenseVector.java +++ b/server/src/main/java/org/elasticsearch/script/field/vectors/ByteKnnDenseVector.java @@ -27,6 +27,7 @@ public class ByteKnnDenseVector implements DenseVector { @Override public float[] getVector() { + // TODO it would be really nice if we didn't transform the `byte[]` arrays to `float[]` if (floatDocVector == null) { floatDocVector = new float[docVector.length]; diff --git a/server/src/main/java/org/elasticsearch/script/field/vectors/ByteKnnDenseVectorDocValuesField.java b/server/src/main/java/org/elasticsearch/script/field/vectors/ByteKnnDenseVectorDocValuesField.java index 4c071301ce3c..18557c94dc73 100644 --- a/server/src/main/java/org/elasticsearch/script/field/vectors/ByteKnnDenseVectorDocValuesField.java +++ b/server/src/main/java/org/elasticsearch/script/field/vectors/ByteKnnDenseVectorDocValuesField.java @@ -8,7 +8,7 @@ package org.elasticsearch.script.field.vectors; -import org.apache.lucene.index.VectorValues; +import org.apache.lucene.index.ByteVectorValues; import org.apache.lucene.util.BytesRef; import org.elasticsearch.core.Nullable; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.ElementType; @@ -19,12 +19,12 @@ import java.io.IOException; import static org.apache.lucene.search.DocIdSetIterator.NO_MORE_DOCS; public class ByteKnnDenseVectorDocValuesField extends DenseVectorDocValuesField { - protected VectorValues input; // null if no vectors + protected ByteVectorValues input; // null if no vectors protected BytesRef vector; protected final int dims; - public ByteKnnDenseVectorDocValuesField(@Nullable VectorValues input, String name, ElementType elementType, int dims) { - super(name, elementType); + public ByteKnnDenseVectorDocValuesField(@Nullable ByteVectorValues input, String name, int dims) { + super(name, ElementType.BYTE); this.dims = dims; this.input = input; } @@ -38,11 +38,11 @@ public class ByteKnnDenseVectorDocValuesField extends DenseVectorDocValuesField if (currentDoc == NO_MORE_DOCS || docId < currentDoc) { vector = null; } else if (docId == currentDoc) { - vector = input.binaryValue(); + vector = input.vectorValue(); } else { currentDoc = input.advance(docId); if (currentDoc == docId) { - vector = input.binaryValue(); + vector = input.vectorValue(); } else { vector = null; } diff --git a/server/src/main/java/org/elasticsearch/script/field/vectors/KnnDenseVectorDocValuesField.java b/server/src/main/java/org/elasticsearch/script/field/vectors/KnnDenseVectorDocValuesField.java index ad9d0c7df78b..5400e402c64a 100644 --- a/server/src/main/java/org/elasticsearch/script/field/vectors/KnnDenseVectorDocValuesField.java +++ b/server/src/main/java/org/elasticsearch/script/field/vectors/KnnDenseVectorDocValuesField.java @@ -22,8 +22,8 @@ public class KnnDenseVectorDocValuesField extends DenseVectorDocValuesField { protected float[] vector; protected final int dims; - public KnnDenseVectorDocValuesField(@Nullable VectorValues input, String name, ElementType elementType, int dims) { - super(name, elementType); + public KnnDenseVectorDocValuesField(@Nullable VectorValues input, String name, int dims) { + super(name, ElementType.FLOAT); this.dims = dims; this.input = input; } diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/QueryToFilterAdapter.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/QueryToFilterAdapter.java index 9189fd6c636d..4e5d92b191bc 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/QueryToFilterAdapter.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/QueryToFilterAdapter.java @@ -9,13 +9,13 @@ package org.elasticsearch.search.aggregations.bucket.filter; import org.apache.lucene.index.LeafReaderContext; -import org.apache.lucene.sandbox.search.IndexSortSortedNumericDocValuesRangeQuery; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BulkScorer; import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.IndexOrDocValuesQuery; import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.IndexSortSortedNumericDocValuesRangeQuery; import org.apache.lucene.search.LeafCollector; import org.apache.lucene.search.PointRangeQuery; import org.apache.lucene.search.Query; diff --git a/server/src/main/java/org/elasticsearch/search/internal/ExitableDirectoryReader.java b/server/src/main/java/org/elasticsearch/search/internal/ExitableDirectoryReader.java index 1bf5ffa615a5..0951fa30b60c 100644 --- a/server/src/main/java/org/elasticsearch/search/internal/ExitableDirectoryReader.java +++ b/server/src/main/java/org/elasticsearch/search/internal/ExitableDirectoryReader.java @@ -9,6 +9,7 @@ package org.elasticsearch.search.internal; import org.apache.lucene.codecs.StoredFieldsReader; +import org.apache.lucene.index.ByteVectorValues; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.FilterDirectoryReader; import org.apache.lucene.index.FilterLeafReader; @@ -126,6 +127,45 @@ class ExitableDirectoryReader extends FilterDirectoryReader { return reader; } + @Override + public ByteVectorValues getByteVectorValues(String field) throws IOException { + ByteVectorValues vectorValues = in.getByteVectorValues(field); + if (vectorValues == null) { + return null; + } + return queryCancellation.isEnabled() ? new ExitableByteVectorValues(queryCancellation, vectorValues) : vectorValues; + } + + @Override + public TopDocs searchNearestVectors(String field, BytesRef target, int k, Bits acceptDocs, int visitedLimit) throws IOException { + if (queryCancellation.isEnabled() == false) { + return in.searchNearestVectors(field, target, k, acceptDocs, visitedLimit); + } + // when acceptDocs is null due to no doc deleted, we will instantiate a new one that would + // match all docs to allow timeout checking. + final Bits updatedAcceptDocs = acceptDocs == null ? new Bits.MatchAllBits(maxDoc()) : acceptDocs; + Bits timeoutCheckingAcceptDocs = new Bits() { + private static final int MAX_CALLS_BEFORE_QUERY_TIMEOUT_CHECK = 10; + private int calls; + + @Override + public boolean get(int index) { + if (calls++ % MAX_CALLS_BEFORE_QUERY_TIMEOUT_CHECK == 0) { + queryCancellation.checkCancelled(); + } + + return updatedAcceptDocs.get(index); + } + + @Override + public int length() { + return updatedAcceptDocs.length(); + } + }; + + return in.searchNearestVectors(field, target, k, timeoutCheckingAcceptDocs, visitedLimit); + } + @Override public VectorValues getVectorValues(String field) throws IOException { VectorValues vectorValues = in.getVectorValues(field); @@ -433,6 +473,57 @@ class ExitableDirectoryReader extends FilterDirectoryReader { } } + private static class ExitableByteVectorValues extends ByteVectorValues { + private int calls; + private final QueryCancellation queryCancellation; + private final ByteVectorValues in; + + private ExitableByteVectorValues(QueryCancellation queryCancellation, ByteVectorValues in) { + this.queryCancellation = queryCancellation; + this.in = in; + } + + @Override + public int dimension() { + return in.dimension(); + } + + @Override + public int size() { + return in.size(); + } + + @Override + public BytesRef vectorValue() throws IOException { + return in.vectorValue(); + } + + @Override + public int docID() { + return in.docID(); + } + + @Override + public int nextDoc() throws IOException { + final int nextDoc = in.nextDoc(); + checkAndThrowWithSampling(); + return nextDoc; + } + + @Override + public int advance(int target) throws IOException { + final int advance = in.advance(target); + checkAndThrowWithSampling(); + return advance; + } + + private void checkAndThrowWithSampling() { + if ((calls++ & ExitableIntersectVisitor.MAX_CALLS_BEFORE_QUERY_TIMEOUT_CHECK) == 0) { + this.queryCancellation.checkCancelled(); + } + } + } + private static class ExitableVectorValues extends FilterVectorValues { private int calls; private final QueryCancellation queryCancellation; diff --git a/server/src/main/java/org/elasticsearch/search/internal/FieldUsageTrackingDirectoryReader.java b/server/src/main/java/org/elasticsearch/search/internal/FieldUsageTrackingDirectoryReader.java index af8c53a04a83..2feba72dce4b 100644 --- a/server/src/main/java/org/elasticsearch/search/internal/FieldUsageTrackingDirectoryReader.java +++ b/server/src/main/java/org/elasticsearch/search/internal/FieldUsageTrackingDirectoryReader.java @@ -10,6 +10,7 @@ package org.elasticsearch.search.internal; import org.apache.lucene.codecs.StoredFieldsReader; import org.apache.lucene.index.BinaryDocValues; +import org.apache.lucene.index.ByteVectorValues; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.Fields; @@ -23,6 +24,8 @@ import org.apache.lucene.index.SortedDocValues; import org.apache.lucene.index.SortedNumericDocValues; import org.apache.lucene.index.SortedSetDocValues; import org.apache.lucene.index.StoredFieldVisitor; +import org.apache.lucene.index.StoredFields; +import org.apache.lucene.index.TermVectors; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.VectorValues; @@ -108,6 +111,21 @@ public class FieldUsageTrackingDirectoryReader extends FilterDirectoryReader { return f; } + @Override + public TermVectors termVectors() throws IOException { + TermVectors termVectors = super.termVectors(); + return new TermVectors() { + @Override + public Fields get(int doc) throws IOException { + Fields f = termVectors.get(doc); + if (f != null) { + f = new FieldUsageTrackingTermVectorFields(f); + } + return f; + } + }; + } + @Override public PointValues getPointValues(String field) throws IOException { PointValues pointValues = super.getPointValues(field); @@ -126,6 +144,21 @@ public class FieldUsageTrackingDirectoryReader extends FilterDirectoryReader { } } + @Override + public StoredFields storedFields() throws IOException { + StoredFields storedFields = super.storedFields(); + return new StoredFields() { + @Override + public void document(int docID, StoredFieldVisitor visitor) throws IOException { + if (visitor instanceof FieldNamesProvidingStoredFieldsVisitor) { + storedFields.document(docID, new FieldUsageFieldsVisitor((FieldNamesProvidingStoredFieldsVisitor) visitor)); + } else { + storedFields.document(docID, new FieldUsageStoredFieldVisitor(visitor)); + } + } + }; + } + @Override public Terms terms(String field) throws IOException { Terms terms = super.terms(field); @@ -195,6 +228,24 @@ public class FieldUsageTrackingDirectoryReader extends FilterDirectoryReader { return vectorValues; } + @Override + public ByteVectorValues getByteVectorValues(String field) throws IOException { + ByteVectorValues vectorValues = super.getByteVectorValues(field); + if (vectorValues != null) { + notifier.onKnnVectorsUsed(field); + } + return vectorValues; + } + + @Override + public TopDocs searchNearestVectors(String field, BytesRef target, int k, Bits acceptDocs, int visitedLimit) throws IOException { + TopDocs topDocs = super.searchNearestVectors(field, target, k, acceptDocs, visitedLimit); + if (topDocs != null) { + notifier.onKnnVectorsUsed(field); + } + return topDocs; + } + @Override public TopDocs searchNearestVectors(String field, float[] target, int k, Bits acceptDocs, int visitedLimit) throws IOException { TopDocs topDocs = super.searchNearestVectors(field, target, k, acceptDocs, visitedLimit); @@ -223,8 +274,8 @@ public class FieldUsageTrackingDirectoryReader extends FilterDirectoryReader { } @Override - public void visitDocument(int docID, StoredFieldVisitor visitor) throws IOException { - reader.visitDocument(docID, new FieldUsageStoredFieldVisitor(visitor)); + public void document(int docID, StoredFieldVisitor visitor) throws IOException { + reader.document(docID, new FieldUsageStoredFieldVisitor(visitor)); } @Override diff --git a/server/src/main/java/org/elasticsearch/search/vectors/KnnSearchBuilder.java b/server/src/main/java/org/elasticsearch/search/vectors/KnnSearchBuilder.java index a4679b6f891c..bed980e53113 100644 --- a/server/src/main/java/org/elasticsearch/search/vectors/KnnSearchBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/vectors/KnnSearchBuilder.java @@ -44,6 +44,7 @@ public class KnnSearchBuilder implements Writeable, ToXContentFragment, Rewritea private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("knn", args -> { @SuppressWarnings("unchecked") + // TODO optimize parsing for when BYTE values are provided List vector = (List) args[1]; float[] vectorArray = new float[vector.size()]; for (int i = 0; i < vector.size(); i++) { diff --git a/server/src/main/java/org/elasticsearch/search/vectors/KnnVectorQueryBuilder.java b/server/src/main/java/org/elasticsearch/search/vectors/KnnVectorQueryBuilder.java index 116ef025c15e..22bd0f0cfeec 100644 --- a/server/src/main/java/org/elasticsearch/search/vectors/KnnVectorQueryBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/vectors/KnnVectorQueryBuilder.java @@ -12,9 +12,11 @@ import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.KnnVectorQuery; import org.apache.lucene.search.Query; +import org.apache.lucene.util.BytesRef; import org.elasticsearch.Version; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.core.Nullable; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.DenseVectorFieldType; @@ -41,12 +43,22 @@ public class KnnVectorQueryBuilder extends AbstractQueryBuilder filterQueries; public KnnVectorQueryBuilder(String fieldName, float[] queryVector, int numCands) { this.fieldName = fieldName; - this.queryVector = queryVector; + this.queryVector = Objects.requireNonNull(queryVector); + this.byteQueryVector = null; + this.numCands = numCands; + this.filterQueries = new ArrayList<>(); + } + + public KnnVectorQueryBuilder(String fieldName, byte[] queryVector, int numCands) { + this.fieldName = fieldName; + this.queryVector = null; + this.byteQueryVector = Objects.requireNonNull(queryVector); this.numCands = numCands; this.filterQueries = new ArrayList<>(); } @@ -55,7 +67,13 @@ public class KnnVectorQueryBuilder extends AbstractQueryBuilder(); } else { @@ -67,10 +85,16 @@ public class KnnVectorQueryBuilder extends AbstractQueryBuilder {}); logger.info("--> stats {}", stats); - int dataBytes = numDocs * dimension * Float.BYTES; // size of flat vector data - int indexBytesEstimate = numDocs * Integer.BYTES * Lucene94HnswVectorsFormat.DEFAULT_MAX_CONN * 2; // rough size of HNSW graph - assertTrue(stats.total().getKnnVectorsBytes() > dataBytes + indexBytesEstimate); + long dataBytes = (long) numDocs * dimension * Float.BYTES; // size of flat vector data + long indexBytesEstimate = (long) numDocs * (Lucene95HnswVectorsFormat.DEFAULT_MAX_CONN / 2); // rough size of HNSW graph + assertThat(stats.total().getKnnVectorsBytes(), greaterThan(dataBytes)); + long connectionOverhead = stats.total().getKnnVectorsBytes() - dataBytes; + assertThat(connectionOverhead, greaterThan(indexBytesEstimate)); } } @@ -323,7 +326,7 @@ public class IndexDiskUsageAnalyzerTests extends ESTestCase { public void testCompletionField() throws Exception { IndexWriterConfig config = new IndexWriterConfig().setCommitOnClose(true) .setUseCompoundFile(false) - .setCodec(new Lucene94Codec(Lucene94Codec.Mode.BEST_SPEED) { + .setCodec(new Lucene95Codec(Lucene95Codec.Mode.BEST_SPEED) { @Override public PostingsFormat getPostingsFormatForField(String field) { if (field.startsWith("suggest_")) { @@ -410,25 +413,25 @@ public class IndexDiskUsageAnalyzerTests extends ESTestCase { enum CodecMode { BEST_SPEED { @Override - Lucene94Codec.Mode mode() { - return Lucene94Codec.Mode.BEST_SPEED; + Lucene95Codec.Mode mode() { + return Lucene95Codec.Mode.BEST_SPEED; } }, BEST_COMPRESSION { @Override - Lucene94Codec.Mode mode() { - return Lucene94Codec.Mode.BEST_COMPRESSION; + Lucene95Codec.Mode mode() { + return Lucene95Codec.Mode.BEST_COMPRESSION; } }; - abstract Lucene94Codec.Mode mode(); + abstract Lucene95Codec.Mode mode(); } static void indexRandomly(Directory directory, CodecMode codecMode, int numDocs, Consumer addFields) throws IOException { IndexWriterConfig config = new IndexWriterConfig().setCommitOnClose(true) .setUseCompoundFile(randomBoolean()) - .setCodec(new Lucene94Codec(codecMode.mode())); + .setCodec(new Lucene95Codec(codecMode.mode())); try (IndexWriter writer = new IndexWriter(directory, config)) { for (int i = 0; i < numDocs; i++) { final Document doc = new Document(); @@ -636,7 +639,7 @@ public class IndexDiskUsageAnalyzerTests extends ESTestCase { try (DirectoryReader reader = DirectoryReader.open(source)) { IndexWriterConfig config = new IndexWriterConfig().setSoftDeletesField(Lucene.SOFT_DELETES_FIELD) .setUseCompoundFile(randomBoolean()) - .setCodec(new Lucene94Codec(mode.mode()) { + .setCodec(new Lucene95Codec(mode.mode()) { @Override public PostingsFormat getPostingsFormatForField(String field) { return new Lucene90PostingsFormat(); @@ -649,7 +652,7 @@ public class IndexDiskUsageAnalyzerTests extends ESTestCase { @Override public KnnVectorsFormat getKnnVectorsFormatForField(String field) { - return new Lucene94HnswVectorsFormat(); + return new Lucene95HnswVectorsFormat(); } @Override diff --git a/server/src/test/java/org/elasticsearch/index/codec/CodecTests.java b/server/src/test/java/org/elasticsearch/index/codec/CodecTests.java index 9d8ee36d3dd7..df39f06c88da 100644 --- a/server/src/test/java/org/elasticsearch/index/codec/CodecTests.java +++ b/server/src/test/java/org/elasticsearch/index/codec/CodecTests.java @@ -10,7 +10,7 @@ package org.elasticsearch.index.codec; import org.apache.lucene.codecs.Codec; import org.apache.lucene.codecs.lucene90.Lucene90StoredFieldsFormat; -import org.apache.lucene.codecs.lucene94.Lucene94Codec; +import org.apache.lucene.codecs.lucene95.Lucene95Codec; import org.apache.lucene.document.Document; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexWriter; @@ -42,21 +42,21 @@ public class CodecTests extends ESTestCase { public void testResolveDefaultCodecs() throws Exception { CodecService codecService = createCodecService(); assertThat(codecService.codec("default"), instanceOf(PerFieldMapperCodec.class)); - assertThat(codecService.codec("default"), instanceOf(Lucene94Codec.class)); + assertThat(codecService.codec("default"), instanceOf(Lucene95Codec.class)); } public void testDefault() throws Exception { Codec codec = createCodecService().codec("default"); - assertStoredFieldsCompressionEquals(Lucene94Codec.Mode.BEST_SPEED, codec); + assertStoredFieldsCompressionEquals(Lucene95Codec.Mode.BEST_SPEED, codec); } public void testBestCompression() throws Exception { Codec codec = createCodecService().codec("best_compression"); - assertStoredFieldsCompressionEquals(Lucene94Codec.Mode.BEST_COMPRESSION, codec); + assertStoredFieldsCompressionEquals(Lucene95Codec.Mode.BEST_COMPRESSION, codec); } // write some docs with it, inspect .si to see this was the used compression - private void assertStoredFieldsCompressionEquals(Lucene94Codec.Mode expected, Codec actual) throws Exception { + private void assertStoredFieldsCompressionEquals(Lucene95Codec.Mode expected, Codec actual) throws Exception { Directory dir = newDirectory(); IndexWriterConfig iwc = newIndexWriterConfig(null); iwc.setCodec(actual); @@ -68,7 +68,7 @@ public class CodecTests extends ESTestCase { SegmentReader sr = (SegmentReader) ir.leaves().get(0).reader(); String v = sr.getSegmentInfo().info.getAttribute(Lucene90StoredFieldsFormat.MODE_KEY); assertNotNull(v); - assertEquals(expected, Lucene94Codec.Mode.valueOf(v)); + assertEquals(expected, Lucene95Codec.Mode.valueOf(v)); ir.close(); dir.close(); } diff --git a/server/src/test/java/org/elasticsearch/index/codec/PerFieldMapperCodecTests.java b/server/src/test/java/org/elasticsearch/index/codec/PerFieldMapperCodecTests.java index 75eb5d1abb52..42299c6c6baf 100644 --- a/server/src/test/java/org/elasticsearch/index/codec/PerFieldMapperCodecTests.java +++ b/server/src/test/java/org/elasticsearch/index/codec/PerFieldMapperCodecTests.java @@ -8,7 +8,7 @@ package org.elasticsearch.index.codec; -import org.apache.lucene.codecs.lucene94.Lucene94Codec; +import org.apache.lucene.codecs.lucene95.Lucene95Codec; import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.settings.Settings; @@ -74,7 +74,7 @@ public class PerFieldMapperCodecTests extends ESTestCase { """; mapperService.merge("type", new CompressedXContent(mapping), MapperService.MergeReason.MAPPING_UPDATE); } - return new PerFieldMapperCodec(Lucene94Codec.Mode.BEST_SPEED, mapperService, BigArrays.NON_RECYCLING_INSTANCE); + return new PerFieldMapperCodec(Lucene95Codec.Mode.BEST_SPEED, mapperService, BigArrays.NON_RECYCLING_INSTANCE); } } diff --git a/server/src/test/java/org/elasticsearch/index/engine/CompletionStatsCacheTests.java b/server/src/test/java/org/elasticsearch/index/engine/CompletionStatsCacheTests.java index 6ff58b260ac6..7f13629cf31e 100644 --- a/server/src/test/java/org/elasticsearch/index/engine/CompletionStatsCacheTests.java +++ b/server/src/test/java/org/elasticsearch/index/engine/CompletionStatsCacheTests.java @@ -8,7 +8,7 @@ package org.elasticsearch.index.engine; import org.apache.lucene.codecs.PostingsFormat; -import org.apache.lucene.codecs.lucene94.Lucene94Codec; +import org.apache.lucene.codecs.lucene95.Lucene95Codec; import org.apache.lucene.document.Document; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexWriter; @@ -45,7 +45,7 @@ public class CompletionStatsCacheTests extends ESTestCase { public void testCompletionStatsCache() throws IOException, InterruptedException { final IndexWriterConfig indexWriterConfig = newIndexWriterConfig(); final PostingsFormat postingsFormat = new Completion90PostingsFormat(); - indexWriterConfig.setCodec(new Lucene94Codec() { + indexWriterConfig.setCodec(new Lucene95Codec() { @Override public PostingsFormat getPostingsFormatForField(String field) { return postingsFormat; // all fields are suggest fields diff --git a/server/src/test/java/org/elasticsearch/index/mapper/DateFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/DateFieldTypeTests.java index 05f80a812d93..14c48348fcd4 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/DateFieldTypeTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/DateFieldTypeTests.java @@ -16,9 +16,9 @@ import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.MultiReader; import org.apache.lucene.index.SortedNumericDocValues; -import org.apache.lucene.sandbox.search.IndexSortSortedNumericDocValuesRangeQuery; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.IndexOrDocValuesQuery; +import org.apache.lucene.search.IndexSortSortedNumericDocValuesRangeQuery; import org.apache.lucene.search.Query; import org.apache.lucene.store.Directory; import org.elasticsearch.Version; diff --git a/server/src/test/java/org/elasticsearch/index/mapper/NumberFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/NumberFieldTypeTests.java index 2a9fbb199059..167f6e358320 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/NumberFieldTypeTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/NumberFieldTypeTests.java @@ -20,9 +20,9 @@ import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.sandbox.document.HalfFloatPoint; -import org.apache.lucene.sandbox.search.IndexSortSortedNumericDocValuesRangeQuery; import org.apache.lucene.search.IndexOrDocValuesQuery; import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.IndexSortSortedNumericDocValuesRangeQuery; import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.Sort; diff --git a/server/src/test/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapperTests.java b/server/src/test/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapperTests.java index e8ca7fb8b206..98ce8363f3ce 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapperTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapperTests.java @@ -12,8 +12,9 @@ import com.carrotsearch.randomizedtesting.generators.RandomPicks; import org.apache.lucene.codecs.Codec; import org.apache.lucene.codecs.KnnVectorsFormat; -import org.apache.lucene.codecs.lucene94.Lucene94HnswVectorsFormat; +import org.apache.lucene.codecs.lucene95.Lucene95HnswVectorsFormat; import org.apache.lucene.document.BinaryDocValuesField; +import org.apache.lucene.document.KnnByteVectorField; import org.apache.lucene.document.KnnVectorField; import org.apache.lucene.index.IndexableField; import org.apache.lucene.search.FieldExistsQuery; @@ -42,8 +43,8 @@ import java.nio.ByteBuffer; import java.util.Arrays; import java.util.List; -import static org.apache.lucene.codecs.lucene94.Lucene94HnswVectorsFormat.DEFAULT_BEAM_WIDTH; -import static org.apache.lucene.codecs.lucene94.Lucene94HnswVectorsFormat.DEFAULT_MAX_CONN; +import static org.apache.lucene.codecs.lucene95.Lucene95HnswVectorsFormat.DEFAULT_BEAM_WIDTH; +import static org.apache.lucene.codecs.lucene95.Lucene95HnswVectorsFormat.DEFAULT_MAX_CONN; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; @@ -250,19 +251,19 @@ public class DenseVectorFieldMapperTests extends MapperTestCase { ) ); - float[] vector = { (byte) -1, (byte) 1, (byte) 127 }; + byte[] vector = { (byte) -1, (byte) 1, (byte) 127 }; ParsedDocument doc1 = mapper.parse(source(b -> b.array("field", vector))); IndexableField[] fields = doc1.rootDoc().getFields("field"); assertEquals(1, fields.length); - assertThat(fields[0], instanceOf(KnnVectorField.class)); + assertThat(fields[0], instanceOf(KnnByteVectorField.class)); - KnnVectorField vectorField = (KnnVectorField) fields[0]; - vectorField.binaryValue(); + KnnByteVectorField vectorField = (KnnByteVectorField) fields[0]; + vectorField.vectorValue(); assertEquals( "Parsed vector is not equal to original.", new BytesRef(new byte[] { (byte) -1, (byte) 1, (byte) 127 }), - vectorField.binaryValue() + vectorField.vectorValue() ); assertEquals(similarity.function, vectorField.fieldType().vectorSimilarityFunction()); } @@ -332,9 +333,7 @@ public class DenseVectorFieldMapperTests extends MapperTestCase { assertNotNull(e.getCause()); assertThat( e.getCause().getMessage(), - containsString( - "The [cosine] similarity does not support vectors with zero magnitude. Preview of invalid vector: [-0.0, 0.0, 0.0]" - ) + containsString("The [cosine] similarity does not support vectors with zero magnitude. Preview of invalid vector: [0, 0, 0]") ); } @@ -544,7 +543,13 @@ public class DenseVectorFieldMapperTests extends MapperTestCase { ); assertThat( e.getCause().getMessage(), - containsString("element_type [byte] vectors only support integers between [-128, 127] but found [128.0] at dim [0];") + containsString("element_type [byte] vectors only support integers between [-128, 127] but found [128] at dim [0];") + ); + + e = expectThrows(MapperParsingException.class, () -> mapper.parse(source(b -> b.array("field", new float[] { 18.2f, 0, 0 })))); + assertThat( + e.getCause().getMessage(), + containsString("element_type [byte] vectors only support non-decimal values but found decimal value [18.2] at dim [0];") ); e = expectThrows( @@ -553,7 +558,7 @@ public class DenseVectorFieldMapperTests extends MapperTestCase { ); assertThat( e.getCause().getMessage(), - containsString("element_type [byte] vectors only support integers between [-128, 127] but found [-129.0] at dim [2];") + containsString("element_type [byte] vectors only support integers between [-128, 127] but found [-129] at dim [2];") ); } @@ -693,8 +698,8 @@ public class DenseVectorFieldMapperTests extends MapperTestCase { Codec codec = codecService.codec("default"); assertThat(codec, instanceOf(PerFieldMapperCodec.class)); KnnVectorsFormat knnVectorsFormat = ((PerFieldMapperCodec) codec).getKnnVectorsFormatForField("field"); - assertThat(knnVectorsFormat, instanceOf(Lucene94HnswVectorsFormat.class)); - String expectedString = "Lucene94HnswVectorsFormat(name=Lucene94HnswVectorsFormat, maxConn=" + assertThat(knnVectorsFormat, instanceOf(Lucene95HnswVectorsFormat.class)); + String expectedString = "Lucene95HnswVectorsFormat(name=Lucene95HnswVectorsFormat, maxConn=" + m + ", beamWidth=" + efConstruction @@ -725,14 +730,12 @@ public class DenseVectorFieldMapperTests extends MapperTestCase { @Override public SyntheticSourceExample example(int maxValues) throws IOException { - List value = randomList(dims, dims, this::randomValue); + Object value = elementType == ElementType.BYTE + ? randomList(dims, dims, ESTestCase::randomByte) + : randomList(dims, dims, ESTestCase::randomFloat); return new SyntheticSourceExample(value, value, this::mapping); } - private float randomValue() { - return elementType == ElementType.BYTE ? ESTestCase.randomByte() : ESTestCase.randomFloat(); - } - private void mapping(XContentBuilder b) throws IOException { b.field("type", "dense_vector"); b.field("dims", dims); @@ -753,7 +756,7 @@ public class DenseVectorFieldMapperTests extends MapperTestCase { } @Override - public List invalidExample() throws IOException { + public List invalidExample() { return List.of(); } } diff --git a/server/src/test/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldTypeTests.java index 6f7e7a477ccf..cf7605663635 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldTypeTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldTypeTests.java @@ -8,6 +8,7 @@ package org.elasticsearch.index.mapper.vectors; +import org.apache.lucene.util.BytesRef; import org.elasticsearch.Version; import org.elasticsearch.index.fielddata.FieldDataContext; import org.elasticsearch.index.mapper.FieldTypeTestCase; @@ -174,5 +175,8 @@ public class DenseVectorFieldTypeTests extends FieldTypeTestCase { ); e = expectThrows(IllegalArgumentException.class, () -> cosineField.createKnnQuery(new float[] { 0.0f, 0.0f, 0.0f }, 10, null)); assertThat(e.getMessage(), containsString("The [cosine] similarity does not support vectors with zero magnitude.")); + + e = expectThrows(IllegalArgumentException.class, () -> cosineField.createKnnQuery(new BytesRef(new byte[] { 0, 0, 0 }), 10, null)); + assertThat(e.getMessage(), containsString("The [cosine] similarity does not support vectors with zero magnitude.")); } } diff --git a/server/src/test/java/org/elasticsearch/index/mapper/vectors/KnnDenseVectorScriptDocValuesTests.java b/server/src/test/java/org/elasticsearch/index/mapper/vectors/KnnDenseVectorScriptDocValuesTests.java index 51ef11618537..7629e6952824 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/vectors/KnnDenseVectorScriptDocValuesTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/vectors/KnnDenseVectorScriptDocValuesTests.java @@ -8,9 +8,9 @@ package org.elasticsearch.index.mapper.vectors; +import org.apache.lucene.index.ByteVectorValues; import org.apache.lucene.index.VectorValues; import org.apache.lucene.util.BytesRef; -import org.apache.lucene.util.VectorUtil; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.ElementType; import org.elasticsearch.script.field.vectors.ByteKnnDenseVectorDocValuesField; import org.elasticsearch.script.field.vectors.DenseVector; @@ -30,12 +30,7 @@ public class KnnDenseVectorScriptDocValuesTests extends ESTestCase { float[][] vectors = { { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 3 } }; float[] expectedMagnitudes = { 1.7320f, 2.4495f, 3.3166f }; - DenseVectorDocValuesField field = new KnnDenseVectorDocValuesField( - wrap(vectors, ElementType.FLOAT), - "test", - ElementType.FLOAT, - dims - ); + DenseVectorDocValuesField field = new KnnDenseVectorDocValuesField(wrap(vectors), "test", dims); DenseVectorScriptDocValues scriptDocValues = field.toScriptDocValues(); for (int i = 0; i < vectors.length; i++) { field.setNextDocId(i); @@ -51,12 +46,7 @@ public class KnnDenseVectorScriptDocValuesTests extends ESTestCase { float[][] vectors = { { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 3 } }; float[] expectedMagnitudes = { 1.7320f, 2.4495f, 3.3166f }; - DenseVectorDocValuesField field = new ByteKnnDenseVectorDocValuesField( - wrap(vectors, ElementType.BYTE), - "test", - ElementType.BYTE, - dims - ); + DenseVectorDocValuesField field = new ByteKnnDenseVectorDocValuesField(wrapBytes(vectors), "test", dims); DenseVectorScriptDocValues scriptDocValues = field.toScriptDocValues(); for (int i = 0; i < vectors.length; i++) { field.setNextDocId(i); @@ -70,12 +60,7 @@ public class KnnDenseVectorScriptDocValuesTests extends ESTestCase { public void testFloatMetadataAndIterator() throws IOException { int dims = 3; float[][] vectors = fill(new float[randomIntBetween(1, 5)][dims], ElementType.FLOAT); - DenseVectorDocValuesField field = new KnnDenseVectorDocValuesField( - wrap(vectors, ElementType.FLOAT), - "test", - ElementType.FLOAT, - dims - ); + DenseVectorDocValuesField field = new KnnDenseVectorDocValuesField(wrap(vectors), "test", dims); for (int i = 0; i < vectors.length; i++) { field.setNextDocId(i); DenseVector dv = field.get(); @@ -94,12 +79,7 @@ public class KnnDenseVectorScriptDocValuesTests extends ESTestCase { public void testByteMetadataAndIterator() throws IOException { int dims = 3; float[][] vectors = fill(new float[randomIntBetween(1, 5)][dims], ElementType.BYTE); - DenseVectorDocValuesField field = new ByteKnnDenseVectorDocValuesField( - wrap(vectors, ElementType.BYTE), - "test", - ElementType.BYTE, - dims - ); + DenseVectorDocValuesField field = new ByteKnnDenseVectorDocValuesField(wrapBytes(vectors), "test", dims); for (int i = 0; i < vectors.length; i++) { field.setNextDocId(i); DenseVector dv = field.get(); @@ -127,12 +107,7 @@ public class KnnDenseVectorScriptDocValuesTests extends ESTestCase { public void testFloatMissingValues() throws IOException { int dims = 3; float[][] vectors = { { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 3 } }; - DenseVectorDocValuesField field = new KnnDenseVectorDocValuesField( - wrap(vectors, ElementType.FLOAT), - "test", - ElementType.FLOAT, - dims - ); + DenseVectorDocValuesField field = new KnnDenseVectorDocValuesField(wrap(vectors), "test", dims); DenseVectorScriptDocValues scriptDocValues = field.toScriptDocValues(); field.setNextDocId(3); @@ -146,12 +121,7 @@ public class KnnDenseVectorScriptDocValuesTests extends ESTestCase { public void testByteMissingValues() throws IOException { int dims = 3; float[][] vectors = { { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 3 } }; - DenseVectorDocValuesField field = new ByteKnnDenseVectorDocValuesField( - wrap(vectors, ElementType.BYTE), - "test", - ElementType.BYTE, - dims - ); + DenseVectorDocValuesField field = new ByteKnnDenseVectorDocValuesField(wrapBytes(vectors), "test", dims); DenseVectorScriptDocValues scriptDocValues = field.toScriptDocValues(); field.setNextDocId(3); @@ -165,12 +135,7 @@ public class KnnDenseVectorScriptDocValuesTests extends ESTestCase { public void testFloatGetFunctionIsNotAccessible() throws IOException { int dims = 3; float[][] vectors = { { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 3 } }; - DenseVectorDocValuesField field = new KnnDenseVectorDocValuesField( - wrap(vectors, ElementType.FLOAT), - "test", - ElementType.FLOAT, - dims - ); + DenseVectorDocValuesField field = new KnnDenseVectorDocValuesField(wrap(vectors), "test", dims); DenseVectorScriptDocValues scriptDocValues = field.toScriptDocValues(); field.setNextDocId(0); @@ -186,12 +151,7 @@ public class KnnDenseVectorScriptDocValuesTests extends ESTestCase { public void testByteGetFunctionIsNotAccessible() throws IOException { int dims = 3; float[][] vectors = { { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 3 } }; - DenseVectorDocValuesField field = new ByteKnnDenseVectorDocValuesField( - wrap(vectors, ElementType.BYTE), - "test", - ElementType.BYTE, - dims - ); + DenseVectorDocValuesField field = new ByteKnnDenseVectorDocValuesField(wrapBytes(vectors), "test", dims); DenseVectorScriptDocValues scriptDocValues = field.toScriptDocValues(); field.setNextDocId(0); @@ -206,7 +166,7 @@ public class KnnDenseVectorScriptDocValuesTests extends ESTestCase { public void testFloatMissingVectorValues() throws IOException { int dims = 7; - DenseVectorDocValuesField emptyKnn = new KnnDenseVectorDocValuesField(null, "test", ElementType.FLOAT, dims); + DenseVectorDocValuesField emptyKnn = new KnnDenseVectorDocValuesField(null, "test", dims); emptyKnn.setNextDocId(0); assertEquals(0, emptyKnn.toScriptDocValues().size()); @@ -220,7 +180,7 @@ public class KnnDenseVectorScriptDocValuesTests extends ESTestCase { public void testByteMissingVectorValues() throws IOException { int dims = 7; - DenseVectorDocValuesField emptyKnn = new ByteKnnDenseVectorDocValuesField(null, "test", ElementType.BYTE, dims); + DenseVectorDocValuesField emptyKnn = new ByteKnnDenseVectorDocValuesField(null, "test", dims); emptyKnn.setNextDocId(0); assertEquals(0, emptyKnn.toScriptDocValues().size()); @@ -232,7 +192,50 @@ public class KnnDenseVectorScriptDocValuesTests extends ESTestCase { assertEquals("Cannot iterate over single valued dense_vector field, use get() instead", e.getMessage()); } - public static VectorValues wrap(float[][] vectors, ElementType elementType) { + public static ByteVectorValues wrapBytes(float[][] vectors) { + return new ByteVectorValues() { + int index = 0; + byte[] byteVector = new byte[vectors[0].length]; + + @Override + public int dimension() { + return 0; + } + + @Override + public int size() { + return vectors.length; + } + + @Override + public BytesRef vectorValue() { + for (int i = 0; i < byteVector.length; i++) { + byteVector[i] = (byte) vectors[index][i]; + } + return new BytesRef(byteVector); + } + + @Override + public int docID() { + return index; + } + + @Override + public int nextDoc() { + throw new UnsupportedOperationException(); + } + + @Override + public int advance(int target) { + if (target >= size()) { + return NO_MORE_DOCS; + } + return index = target; + } + }; + } + + public static VectorValues wrap(float[][] vectors) { return new VectorValues() { int index = 0; @@ -253,17 +256,11 @@ public class KnnDenseVectorScriptDocValuesTests extends ESTestCase { @Override public BytesRef binaryValue() { - if (elementType == ElementType.FLOAT) { - ByteBuffer byteBuffer = ByteBuffer.allocate(elementType.elementBytes * vectors[index].length); - for (float value : vectors[index]) { - elementType.writeValue(byteBuffer, value); - } - return new BytesRef(byteBuffer.array()); - } else if (elementType == ElementType.BYTE) { - return VectorUtil.toBytesRef(vectors[index]); - } else { - throw new IllegalStateException("unknown element_type [" + elementType + "]"); + ByteBuffer byteBuffer = ByteBuffer.allocate(ElementType.FLOAT.elementBytes * vectors[index].length); + for (float value : vectors[index]) { + ElementType.FLOAT.writeValue(byteBuffer, value); } + return new BytesRef(byteBuffer.array()); } @Override @@ -283,11 +280,6 @@ public class KnnDenseVectorScriptDocValuesTests extends ESTestCase { } return index = target; } - - @Override - public long cost() { - return size(); - } }; } } diff --git a/server/src/test/java/org/elasticsearch/script/VectorScoreScriptUtilsTests.java b/server/src/test/java/org/elasticsearch/script/VectorScoreScriptUtilsTests.java index 1dc29532e9de..841a80927ba8 100644 --- a/server/src/test/java/org/elasticsearch/script/VectorScoreScriptUtilsTests.java +++ b/server/src/test/java/org/elasticsearch/script/VectorScoreScriptUtilsTests.java @@ -55,12 +55,7 @@ public class VectorScoreScriptUtilsTests extends ESTestCase { dims, Version.CURRENT ), - new KnnDenseVectorDocValuesField( - KnnDenseVectorScriptDocValuesTests.wrap(new float[][] { docVector }, ElementType.FLOAT), - "test", - ElementType.FLOAT, - dims - ) + new KnnDenseVectorDocValuesField(KnnDenseVectorScriptDocValuesTests.wrap(new float[][] { docVector }), "test", dims) ); for (DenseVectorDocValuesField field : fields) { field.setNextDocId(0); @@ -140,12 +135,7 @@ public class VectorScoreScriptUtilsTests extends ESTestCase { ElementType.BYTE, dims ), - new ByteKnnDenseVectorDocValuesField( - KnnDenseVectorScriptDocValuesTests.wrap(new float[][] { docVector }, ElementType.BYTE), - "test", - ElementType.BYTE, - dims - ) + new ByteKnnDenseVectorDocValuesField(KnnDenseVectorScriptDocValuesTests.wrapBytes(new float[][] { docVector }), "test", dims) ); for (DenseVectorDocValuesField field : fields) { field.setNextDocId(0); @@ -233,24 +223,14 @@ public class VectorScoreScriptUtilsTests extends ESTestCase { dims, Version.CURRENT ), - new KnnDenseVectorDocValuesField( - KnnDenseVectorScriptDocValuesTests.wrap(new float[][] { docVector }, ElementType.FLOAT), - "field2", - ElementType.FLOAT, - dims - ), + new KnnDenseVectorDocValuesField(KnnDenseVectorScriptDocValuesTests.wrap(new float[][] { docVector }), "field2", dims), new ByteBinaryDenseVectorDocValuesField( BinaryDenseVectorScriptDocValuesTests.wrap(new float[][] { docVector }, ElementType.BYTE, Version.CURRENT), "field3", ElementType.BYTE, dims ), - new ByteKnnDenseVectorDocValuesField( - KnnDenseVectorScriptDocValuesTests.wrap(new float[][] { docVector }, ElementType.BYTE), - "field4", - ElementType.BYTE, - dims - ) + new ByteKnnDenseVectorDocValuesField(KnnDenseVectorScriptDocValuesTests.wrapBytes(new float[][] { docVector }), "field4", dims) ); for (DenseVectorDocValuesField field : fields) { field.setNextDocId(0); @@ -388,12 +368,7 @@ public class VectorScoreScriptUtilsTests extends ESTestCase { ElementType.BYTE, dims ), - new ByteKnnDenseVectorDocValuesField( - KnnDenseVectorScriptDocValuesTests.wrap(new float[][] { docVector }, ElementType.BYTE), - "test", - ElementType.BYTE, - dims - ) + new ByteKnnDenseVectorDocValuesField(KnnDenseVectorScriptDocValuesTests.wrapBytes(new float[][] { docVector }), "test", dims) ); for (DenseVectorDocValuesField field : fields) { diff --git a/server/src/test/java/org/elasticsearch/search/vectors/AbstractKnnVectorQueryBuilderTestCase.java b/server/src/test/java/org/elasticsearch/search/vectors/AbstractKnnVectorQueryBuilderTestCase.java new file mode 100644 index 000000000000..f2617998045e --- /dev/null +++ b/server/src/test/java/org/elasticsearch/search/vectors/AbstractKnnVectorQueryBuilderTestCase.java @@ -0,0 +1,245 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.search.vectors; + +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.KnnByteVectorQuery; +import org.apache.lucene.search.KnnVectorQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.Version; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.compress.CompressedXContent; +import org.elasticsearch.common.io.stream.BytesStreamOutput; +import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.core.Tuple; +import org.elasticsearch.index.mapper.MapperService; +import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper; +import org.elasticsearch.index.query.MatchNoneQueryBuilder; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.index.query.SearchExecutionContext; +import org.elasticsearch.index.query.TermQueryBuilder; +import org.elasticsearch.test.AbstractBuilderTestCase; +import org.elasticsearch.test.AbstractQueryTestCase; +import org.elasticsearch.test.VersionUtils; +import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xcontent.XContentFactory; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; + +abstract class AbstractKnnVectorQueryBuilderTestCase extends AbstractQueryTestCase { + private static final String VECTOR_FIELD = "vector"; + private static final String VECTOR_ALIAS_FIELD = "vector_alias"; + private static final int VECTOR_DIMENSION = 3; + + abstract DenseVectorFieldMapper.ElementType elementType(); + + @Override + protected void initializeAdditionalMappings(MapperService mapperService) throws IOException { + XContentBuilder builder = XContentFactory.jsonBuilder() + .startObject() + .startObject("properties") + .startObject(VECTOR_FIELD) + .field("type", "dense_vector") + .field("dims", VECTOR_DIMENSION) + .field("index", true) + .field("similarity", "l2_norm") + .field("element_type", elementType()) + .endObject() + .startObject(VECTOR_ALIAS_FIELD) + .field("type", "alias") + .field("path", VECTOR_FIELD) + .endObject() + .endObject() + .endObject(); + mapperService.merge( + MapperService.SINGLE_MAPPING_NAME, + new CompressedXContent(Strings.toString(builder)), + MapperService.MergeReason.MAPPING_UPDATE + ); + } + + @Override + protected KnnVectorQueryBuilder doCreateTestQueryBuilder() { + String fieldName = randomBoolean() ? VECTOR_FIELD : VECTOR_ALIAS_FIELD; + byte[] byteVector = new byte[VECTOR_DIMENSION]; + float[] vector = new float[VECTOR_DIMENSION]; + for (int i = 0; i < vector.length; i++) { + vector[i] = randomFloat(); + byteVector[i] = randomByte(); + } + int numCands = randomIntBetween(1, 1000); + + KnnVectorQueryBuilder queryBuilder = switch (elementType()) { + case BYTE -> new KnnVectorQueryBuilder(fieldName, byteVector, numCands); + case FLOAT -> new KnnVectorQueryBuilder(fieldName, vector, numCands); + }; + + if (randomBoolean()) { + List filters = new ArrayList<>(); + int numFilters = randomIntBetween(1, 5); + for (int i = 0; i < numFilters; i++) { + String filterFieldName = randomBoolean() ? KEYWORD_FIELD_NAME : TEXT_FIELD_NAME; + filters.add(QueryBuilders.termQuery(filterFieldName, randomAlphaOfLength(10))); + } + queryBuilder.addFilterQueries(filters); + } + return queryBuilder; + } + + @Override + protected void doAssertLuceneQuery(KnnVectorQueryBuilder queryBuilder, Query query, SearchExecutionContext context) throws IOException { + switch (elementType()) { + case FLOAT -> assertTrue(query instanceof KnnVectorQuery); + case BYTE -> assertTrue(query instanceof KnnByteVectorQuery); + } + + BooleanQuery.Builder builder = new BooleanQuery.Builder(); + for (QueryBuilder qb : queryBuilder.filterQueries()) { + builder.add(qb.toQuery(context), BooleanClause.Occur.FILTER); + } + BooleanQuery booleanQuery = builder.build(); + Query filterQuery = booleanQuery.clauses().isEmpty() ? null : booleanQuery; + // The field should always be resolved to the concrete field + Query knnVectorQueryBuilt = switch (elementType()) { + case BYTE -> new KnnByteVectorQuery( + VECTOR_FIELD, + new BytesRef(queryBuilder.getByteQueryVector()), + queryBuilder.numCands(), + filterQuery + ); + case FLOAT -> new KnnVectorQuery(VECTOR_FIELD, queryBuilder.queryVector(), queryBuilder.numCands(), filterQuery); + }; + assertEquals(query, knnVectorQueryBuilt); + } + + public void testWrongDimension() { + SearchExecutionContext context = createSearchExecutionContext(); + KnnVectorQueryBuilder query = new KnnVectorQueryBuilder(VECTOR_FIELD, new float[] { 1.0f, 2.0f }, 10); + IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> query.doToQuery(context)); + assertThat(e.getMessage(), containsString("the query vector has a different dimension [2] than the index vectors [3]")); + } + + public void testNonexistentField() { + SearchExecutionContext context = createSearchExecutionContext(); + KnnVectorQueryBuilder query = new KnnVectorQueryBuilder("nonexistent", new float[] { 1.0f, 1.0f, 1.0f }, 10); + IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> query.doToQuery(context)); + assertThat(e.getMessage(), containsString("field [nonexistent] does not exist in the mapping")); + } + + public void testWrongFieldType() { + SearchExecutionContext context = createSearchExecutionContext(); + KnnVectorQueryBuilder query = new KnnVectorQueryBuilder( + AbstractBuilderTestCase.KEYWORD_FIELD_NAME, + new float[] { 1.0f, 1.0f, 1.0f }, + 10 + ); + IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> query.doToQuery(context)); + assertThat(e.getMessage(), containsString("[knn] queries are only supported on [dense_vector] fields")); + } + + @Override + public void testValidOutput() { + KnnVectorQueryBuilder query = new KnnVectorQueryBuilder(VECTOR_FIELD, new float[] { 1.0f, 2.0f, 3.0f }, 10); + String expected = """ + { + "knn" : { + "field" : "vector", + "vector" : [ + 1.0, + 2.0, + 3.0 + ], + "num_candidates" : 10 + } + }"""; + assertEquals(expected, query.toString()); + } + + @Override + public void testMustRewrite() throws IOException { + SearchExecutionContext context = createSearchExecutionContext(); + context.setAllowUnmappedFields(true); + TermQueryBuilder termQuery = new TermQueryBuilder("unmapped_field", 42); + KnnVectorQueryBuilder query = new KnnVectorQueryBuilder(VECTOR_FIELD, new float[] { 1.0f, 2.0f, 3.0f }, VECTOR_DIMENSION); + query.addFilterQuery(termQuery); + + IllegalStateException e = expectThrows(IllegalStateException.class, () -> query.toQuery(context)); + assertEquals("Rewrite first", e.getMessage()); + + QueryBuilder rewrittenQuery = query.rewrite(context); + assertThat(rewrittenQuery, instanceOf(MatchNoneQueryBuilder.class)); + } + + public void testBWCVersionSerialization() throws IOException { + float[] bwcFloat = new float[VECTOR_DIMENSION]; + KnnVectorQueryBuilder query = createTestQueryBuilder(); + if (query.queryVector() != null) { + bwcFloat = query.queryVector(); + } else { + for (int i = 0; i < query.getByteQueryVector().length; i++) { + bwcFloat[i] = query.getByteQueryVector()[i]; + } + } + KnnVectorQueryBuilder queryWithNoFilters = new KnnVectorQueryBuilder(query.getFieldName(), bwcFloat, query.numCands()).queryName( + query.queryName() + ).boost(query.boost()); + + KnnVectorQueryBuilder queryNoByteQuery = new KnnVectorQueryBuilder(query.getFieldName(), bwcFloat, query.numCands()).queryName( + query.queryName() + ).boost(query.boost()).addFilterQueries(query.filterQueries()); + + Version newVersion = VersionUtils.randomVersionBetween(random(), Version.V_8_7_0, Version.CURRENT); + Version beforeByteQueryVersion = VersionUtils.randomVersionBetween(random(), Version.V_8_2_0, Version.V_8_6_0); + Version beforeFilterVersion = VersionUtils.randomVersionBetween(random(), Version.V_8_0_0, Version.V_8_1_0); + + assertSerialization(query, newVersion); + assertSerialization(queryNoByteQuery, beforeByteQueryVersion); + assertSerialization(queryWithNoFilters, beforeFilterVersion); + + for (var tuple : List.of( + Tuple.tuple(beforeByteQueryVersion, queryNoByteQuery), + Tuple.tuple(beforeFilterVersion, queryWithNoFilters) + )) { + try (BytesStreamOutput output = new BytesStreamOutput()) { + output.setVersion(tuple.v1()); + output.writeNamedWriteable(query); + try (StreamInput in = new NamedWriteableAwareStreamInput(output.bytes().streamInput(), namedWriteableRegistry())) { + in.setVersion(tuple.v1()); + KnnVectorQueryBuilder deserializedQuery = (KnnVectorQueryBuilder) in.readNamedWriteable(QueryBuilder.class); + assertEquals(tuple.v2(), deserializedQuery); + assertEquals(tuple.v2().hashCode(), deserializedQuery.hashCode()); + } + } + } + } + + @Override + public void testUnknownObjectException() { + assumeTrue("Test isn't relevant, since query is never parsed from xContent", false); + } + + @Override + public void testFromXContent() { + assumeTrue("Test isn't relevant, since query is never parsed from xContent", false); + } + + @Override + public void testUnknownField() { + assumeTrue("Test isn't relevant, since query is never parsed from xContent", false); + } +} diff --git a/server/src/test/java/org/elasticsearch/search/vectors/KnnByteVectorQueryBuilderTests.java b/server/src/test/java/org/elasticsearch/search/vectors/KnnByteVectorQueryBuilderTests.java new file mode 100644 index 000000000000..3bf92a60275d --- /dev/null +++ b/server/src/test/java/org/elasticsearch/search/vectors/KnnByteVectorQueryBuilderTests.java @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.search.vectors; + +import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper; + +public class KnnByteVectorQueryBuilderTests extends AbstractKnnVectorQueryBuilderTestCase { + @Override + DenseVectorFieldMapper.ElementType elementType() { + return DenseVectorFieldMapper.ElementType.BYTE; + } +} diff --git a/server/src/test/java/org/elasticsearch/search/vectors/KnnVectorQueryBuilderTests.java b/server/src/test/java/org/elasticsearch/search/vectors/KnnVectorQueryBuilderTests.java index d52cafc8e685..6b1166cdd16d 100644 --- a/server/src/test/java/org/elasticsearch/search/vectors/KnnVectorQueryBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/search/vectors/KnnVectorQueryBuilderTests.java @@ -8,196 +8,11 @@ package org.elasticsearch.search.vectors; -import org.apache.lucene.search.BooleanClause; -import org.apache.lucene.search.BooleanQuery; -import org.apache.lucene.search.KnnVectorQuery; -import org.apache.lucene.search.Query; -import org.elasticsearch.Version; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.compress.CompressedXContent; -import org.elasticsearch.common.io.stream.BytesStreamOutput; -import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.index.mapper.MapperService; -import org.elasticsearch.index.query.MatchNoneQueryBuilder; -import org.elasticsearch.index.query.QueryBuilder; -import org.elasticsearch.index.query.QueryBuilders; -import org.elasticsearch.index.query.SearchExecutionContext; -import org.elasticsearch.index.query.TermQueryBuilder; -import org.elasticsearch.test.AbstractBuilderTestCase; -import org.elasticsearch.test.AbstractQueryTestCase; -import org.elasticsearch.test.VersionUtils; -import org.elasticsearch.xcontent.XContentBuilder; -import org.elasticsearch.xcontent.XContentFactory; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.instanceOf; - -public class KnnVectorQueryBuilderTests extends AbstractQueryTestCase { - private static final String VECTOR_FIELD = "vector"; - private static final String VECTOR_ALIAS_FIELD = "vector_alias"; - private static final int VECTOR_DIMENSION = 3; +import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper; +public class KnnVectorQueryBuilderTests extends AbstractKnnVectorQueryBuilderTestCase { @Override - protected void initializeAdditionalMappings(MapperService mapperService) throws IOException { - XContentBuilder builder = XContentFactory.jsonBuilder() - .startObject() - .startObject("properties") - .startObject(VECTOR_FIELD) - .field("type", "dense_vector") - .field("dims", VECTOR_DIMENSION) - .field("index", true) - .field("similarity", "l2_norm") - .endObject() - .startObject(VECTOR_ALIAS_FIELD) - .field("type", "alias") - .field("path", VECTOR_FIELD) - .endObject() - .endObject() - .endObject(); - mapperService.merge( - MapperService.SINGLE_MAPPING_NAME, - new CompressedXContent(Strings.toString(builder)), - MapperService.MergeReason.MAPPING_UPDATE - ); - } - - @Override - protected KnnVectorQueryBuilder doCreateTestQueryBuilder() { - String fieldName = randomBoolean() ? VECTOR_FIELD : VECTOR_ALIAS_FIELD; - float[] vector = new float[VECTOR_DIMENSION]; - for (int i = 0; i < vector.length; i++) { - vector[i] = randomFloat(); - } - int numCands = randomIntBetween(1, 1000); - - KnnVectorQueryBuilder queryBuilder = new KnnVectorQueryBuilder(fieldName, vector, numCands); - - if (randomBoolean()) { - List filters = new ArrayList<>(); - int numFilters = randomIntBetween(1, 5); - for (int i = 0; i < numFilters; i++) { - String filterFieldName = randomBoolean() ? KEYWORD_FIELD_NAME : TEXT_FIELD_NAME; - filters.add(QueryBuilders.termQuery(filterFieldName, randomAlphaOfLength(10))); - } - queryBuilder.addFilterQueries(filters); - } - return queryBuilder; - } - - @Override - protected void doAssertLuceneQuery(KnnVectorQueryBuilder queryBuilder, Query query, SearchExecutionContext context) throws IOException { - assertTrue(query instanceof KnnVectorQuery); - KnnVectorQuery knnVectorQuery = (KnnVectorQuery) query; - - BooleanQuery.Builder builder = new BooleanQuery.Builder(); - for (QueryBuilder qb : queryBuilder.filterQueries()) { - builder.add(qb.toQuery(context), BooleanClause.Occur.FILTER); - } - BooleanQuery booleanQuery = builder.build(); - Query filterQuery = booleanQuery.clauses().isEmpty() ? null : booleanQuery; - // The field should always be resolved to the concrete field - Query knnVectorQueryBuilt = new KnnVectorQuery(VECTOR_FIELD, queryBuilder.queryVector(), queryBuilder.numCands(), filterQuery); - assertEquals(knnVectorQuery, knnVectorQueryBuilt); - } - - public void testWrongDimension() { - SearchExecutionContext context = createSearchExecutionContext(); - KnnVectorQueryBuilder query = new KnnVectorQueryBuilder(VECTOR_FIELD, new float[] { 1.0f, 2.0f }, 10); - IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> query.doToQuery(context)); - assertThat(e.getMessage(), containsString("the query vector has a different dimension [2] than the index vectors [3]")); - } - - public void testNonexistentField() { - SearchExecutionContext context = createSearchExecutionContext(); - KnnVectorQueryBuilder query = new KnnVectorQueryBuilder("nonexistent", new float[] { 1.0f, 1.0f, 1.0f }, 10); - IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> query.doToQuery(context)); - assertThat(e.getMessage(), containsString("field [nonexistent] does not exist in the mapping")); - } - - public void testWrongFieldType() { - SearchExecutionContext context = createSearchExecutionContext(); - KnnVectorQueryBuilder query = new KnnVectorQueryBuilder( - AbstractBuilderTestCase.KEYWORD_FIELD_NAME, - new float[] { 1.0f, 1.0f, 1.0f }, - 10 - ); - IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> query.doToQuery(context)); - assertThat(e.getMessage(), containsString("[knn] queries are only supported on [dense_vector] fields")); - } - - @Override - public void testValidOutput() { - KnnVectorQueryBuilder query = new KnnVectorQueryBuilder(VECTOR_FIELD, new float[] { 1.0f, 2.0f, 3.0f }, 10); - String expected = """ - { - "knn" : { - "field" : "vector", - "vector" : [ - 1.0, - 2.0, - 3.0 - ], - "num_candidates" : 10 - } - }"""; - assertEquals(expected, query.toString()); - } - - @Override - public void testMustRewrite() throws IOException { - SearchExecutionContext context = createSearchExecutionContext(); - context.setAllowUnmappedFields(true); - TermQueryBuilder termQuery = new TermQueryBuilder("unmapped_field", 42); - KnnVectorQueryBuilder query = new KnnVectorQueryBuilder(VECTOR_FIELD, new float[] { 1.0f, 2.0f, 3.0f }, VECTOR_DIMENSION); - query.addFilterQuery(termQuery); - - IllegalStateException e = expectThrows(IllegalStateException.class, () -> query.toQuery(context)); - assertEquals("Rewrite first", e.getMessage()); - - QueryBuilder rewrittenQuery = query.rewrite(context); - assertThat(rewrittenQuery, instanceOf(MatchNoneQueryBuilder.class)); - } - - public void testOldVersionSerialization() throws IOException { - KnnVectorQueryBuilder query = createTestQueryBuilder(); - KnnVectorQueryBuilder queryWithNoFilters = new KnnVectorQueryBuilder(query.getFieldName(), query.queryVector(), query.numCands()); - queryWithNoFilters.queryName(query.queryName()).boost(query.boost()); - - Version newVersion = VersionUtils.randomVersionBetween(random(), Version.V_8_2_0, Version.CURRENT); - Version oldVersion = VersionUtils.randomVersionBetween(random(), Version.V_8_0_0, Version.V_8_1_0); - - assertSerialization(query, newVersion); - assertSerialization(queryWithNoFilters, oldVersion); - - try (BytesStreamOutput output = new BytesStreamOutput()) { - output.setVersion(newVersion); - output.writeNamedWriteable(query); - try (StreamInput in = new NamedWriteableAwareStreamInput(output.bytes().streamInput(), namedWriteableRegistry())) { - in.setVersion(oldVersion); - KnnVectorQueryBuilder deserializedQuery = (KnnVectorQueryBuilder) in.readNamedWriteable(QueryBuilder.class); - assertEquals(queryWithNoFilters, deserializedQuery); - assertEquals(queryWithNoFilters.hashCode(), deserializedQuery.hashCode()); - } - } - } - - @Override - public void testUnknownObjectException() throws IOException { - // Test isn't relevant, since query is never parsed from xContent - } - - @Override - public void testFromXContent() throws IOException { - // Test isn't relevant, since query is never parsed from xContent - } - - @Override - public void testUnknownField() throws IOException { - // Test isn't relevant, since query is never parsed from xContent + DenseVectorFieldMapper.ElementType elementType() { + return DenseVectorFieldMapper.ElementType.FLOAT; } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/index/engine/frozen/RewriteCachingDirectoryReader.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/index/engine/frozen/RewriteCachingDirectoryReader.java index a3f081882b09..a76bfdce77c1 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/index/engine/frozen/RewriteCachingDirectoryReader.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/index/engine/frozen/RewriteCachingDirectoryReader.java @@ -7,6 +7,7 @@ package org.elasticsearch.index.engine.frozen; import org.apache.lucene.index.BinaryDocValues; +import org.apache.lucene.index.ByteVectorValues; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.FieldInfos; @@ -22,11 +23,14 @@ import org.apache.lucene.index.SortedDocValues; import org.apache.lucene.index.SortedNumericDocValues; import org.apache.lucene.index.SortedSetDocValues; import org.apache.lucene.index.StoredFieldVisitor; +import org.apache.lucene.index.StoredFields; +import org.apache.lucene.index.TermVectors; import org.apache.lucene.index.Terms; import org.apache.lucene.index.VectorValues; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; import org.apache.lucene.util.Bits; +import org.apache.lucene.util.BytesRef; import java.io.IOException; import java.util.Comparator; @@ -216,11 +220,21 @@ final class RewriteCachingDirectoryReader extends DirectoryReader { throw new UnsupportedOperationException(); } + @Override + public ByteVectorValues getByteVectorValues(String field) throws IOException { + throw new UnsupportedOperationException(); + } + @Override public TopDocs searchNearestVectors(String field, float[] target, int k, Bits acceptDocs, int visitedLimit) throws IOException { throw new UnsupportedOperationException(); } + @Override + public TopDocs searchNearestVectors(String field, BytesRef target, int k, Bits acceptDocs, int visitedLimit) throws IOException { + throw new UnsupportedOperationException(); + } + @Override public FieldInfos getFieldInfos() { return fieldInfos; @@ -249,6 +263,16 @@ final class RewriteCachingDirectoryReader extends DirectoryReader { throw new UnsupportedOperationException(); } + @Override + public TermVectors termVectors() throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public StoredFields storedFields() throws IOException { + throw new UnsupportedOperationException(); + } + @Override public int numDocs() { return numDocs; diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/accesscontrol/FieldSubsetReader.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/accesscontrol/FieldSubsetReader.java index 38e4fd274060..706ba8d3eb87 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/accesscontrol/FieldSubsetReader.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/accesscontrol/FieldSubsetReader.java @@ -8,6 +8,7 @@ package org.elasticsearch.xpack.core.security.authz.accesscontrol; import org.apache.lucene.codecs.StoredFieldsReader; import org.apache.lucene.index.BinaryDocValues; +import org.apache.lucene.index.ByteVectorValues; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.FieldInfos; @@ -21,7 +22,9 @@ import org.apache.lucene.index.SortedDocValues; import org.apache.lucene.index.SortedNumericDocValues; import org.apache.lucene.index.SortedSetDocValues; import org.apache.lucene.index.StoredFieldVisitor; +import org.apache.lucene.index.StoredFields; import org.apache.lucene.index.TermState; +import org.apache.lucene.index.TermVectors; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.VectorValues; @@ -162,6 +165,34 @@ public final class FieldSubsetReader extends SequentialStoredFieldsLeafReader { return f.iterator().hasNext() ? f : null; } + @Override + public TermVectors termVectors() throws IOException { + TermVectors termVectors = super.termVectors(); + return new TermVectors() { + @Override + public Fields get(int doc) throws IOException { + Fields f = termVectors.get(doc); + if (f == null) { + return null; + } + f = new FieldFilterFields(f); + // we need to check for emptyness, so we can return null: + return f.iterator().hasNext() ? f : null; + } + }; + } + + @Override + public StoredFields storedFields() throws IOException { + StoredFields storedFields = super.storedFields(); + return new StoredFields() { + @Override + public void document(int docID, StoredFieldVisitor visitor) throws IOException { + storedFields.document(docID, new FieldSubsetStoredFieldVisitor(visitor)); + } + }; + } + /** Filter a map by a {@link CharacterRunAutomaton} that defines the fields to retain. */ @SuppressWarnings("unchecked") static Map filter(Map map, CharacterRunAutomaton includeAutomaton, int initialState) { @@ -287,6 +318,16 @@ public final class FieldSubsetReader extends SequentialStoredFieldsLeafReader { return hasField(field) ? super.searchNearestVectors(field, target, k, acceptDocs, visitedLimit) : null; } + @Override + public ByteVectorValues getByteVectorValues(String field) throws IOException { + return hasField(field) ? super.getByteVectorValues(field) : null; + } + + @Override + public TopDocs searchNearestVectors(String field, BytesRef target, int k, Bits acceptDocs, int visitedLimit) throws IOException { + return hasField(field) ? super.searchNearestVectors(field, target, k, acceptDocs, visitedLimit) : null; + } + // we share core cache keys (for e.g. fielddata) @Override @@ -310,8 +351,8 @@ public final class FieldSubsetReader extends SequentialStoredFieldsLeafReader { } @Override - public void visitDocument(int docID, StoredFieldVisitor visitor) throws IOException { - reader.visitDocument(docID, new FieldSubsetStoredFieldVisitor(visitor)); + public void document(int docID, StoredFieldVisitor visitor) throws IOException { + reader.document(docID, new FieldSubsetStoredFieldVisitor(visitor)); } @Override diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/accesscontrol/FieldSubsetReaderTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/accesscontrol/FieldSubsetReaderTests.java index ef061b25212b..9463ca71662d 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/accesscontrol/FieldSubsetReaderTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/accesscontrol/FieldSubsetReaderTests.java @@ -11,6 +11,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.FieldType; import org.apache.lucene.document.IntPoint; +import org.apache.lucene.document.KnnByteVectorField; import org.apache.lucene.document.KnnVectorField; import org.apache.lucene.document.NumericDocValuesField; import org.apache.lucene.document.SortedDocValuesField; @@ -20,6 +21,7 @@ import org.apache.lucene.document.StoredField; import org.apache.lucene.document.StringField; import org.apache.lucene.document.TextField; import org.apache.lucene.index.BinaryDocValues; +import org.apache.lucene.index.ByteVectorValues; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.FieldInfos; @@ -214,6 +216,39 @@ public class FieldSubsetReaderTests extends ESTestCase { IOUtils.close(ir, iw, dir); } + public void testKnnByteVectors() throws Exception { + Directory dir = newDirectory(); + IndexWriterConfig iwc = new IndexWriterConfig(null); + IndexWriter iw = new IndexWriter(dir, iwc); + + Document doc = new Document(); + doc.add(new KnnByteVectorField("fieldA", new BytesRef(new byte[] { 1, 2, 3 }))); + doc.add(new KnnByteVectorField("fieldB", new BytesRef(new byte[] { 3, 2, 1 }))); + iw.addDocument(doc); + + DirectoryReader ir = FieldSubsetReader.wrap(DirectoryReader.open(iw), new CharacterRunAutomaton(Automata.makeString("fieldA"))); + LeafReader leafReader = ir.leaves().get(0).reader(); + + // Check that fieldA behaves as normal + ByteVectorValues vectorValues = leafReader.getByteVectorValues("fieldA"); + assertEquals(3, vectorValues.dimension()); + assertEquals(1, vectorValues.size()); + assertEquals(0, vectorValues.nextDoc()); + assertNotNull(vectorValues.binaryValue()); + assertNotNull(vectorValues.vectorValue()); + + TopDocs topDocs = leafReader.searchNearestVectors("fieldA", new BytesRef(new byte[] { 1, 1, 1 }), 5, null, Integer.MAX_VALUE); + assertNotNull(topDocs); + assertEquals(1, topDocs.scoreDocs.length); + + // Check that we can't see fieldB + assertNull(leafReader.getByteVectorValues("fieldB")); + assertNull(leafReader.searchNearestVectors("fieldB", new BytesRef(new byte[] { 1, 1, 1 }), 5, null, Integer.MAX_VALUE)); + + TestUtil.checkReader(ir); + IOUtils.close(ir, iw, dir); + } + /** * test filtering two stored fields (string) */ @@ -232,10 +267,16 @@ public class FieldSubsetReaderTests extends ESTestCase { DirectoryReader ir = FieldSubsetReader.wrap(DirectoryReader.open(iw), new CharacterRunAutomaton(Automata.makeString("fieldA"))); // see only one field - Document d2 = ir.document(0); - assertEquals(1, d2.getFields().size()); - assertEquals("testA", d2.get("fieldA")); - + { + Document d2 = ir.document(0); + assertEquals(1, d2.getFields().size()); + assertEquals("testA", d2.get("fieldA")); + } + { + Document d2 = ir.storedFields().document(0); + assertEquals(1, d2.getFields().size()); + assertEquals("testA", d2.get("fieldA")); + } TestUtil.checkReader(ir); IOUtils.close(ir, iw, dir); } @@ -258,10 +299,16 @@ public class FieldSubsetReaderTests extends ESTestCase { DirectoryReader ir = FieldSubsetReader.wrap(DirectoryReader.open(iw), new CharacterRunAutomaton(Automata.makeString("fieldA"))); // see only one field - Document d2 = ir.document(0); - assertEquals(1, d2.getFields().size()); - assertEquals(new BytesRef("testA"), d2.getBinaryValue("fieldA")); - + { + Document d2 = ir.document(0); + assertEquals(1, d2.getFields().size()); + assertEquals(new BytesRef("testA"), d2.getBinaryValue("fieldA")); + } + { + Document d2 = ir.storedFields().document(0); + assertEquals(1, d2.getFields().size()); + assertEquals(new BytesRef("testA"), d2.getBinaryValue("fieldA")); + } TestUtil.checkReader(ir); IOUtils.close(ir, iw, dir); } @@ -284,10 +331,16 @@ public class FieldSubsetReaderTests extends ESTestCase { DirectoryReader ir = FieldSubsetReader.wrap(DirectoryReader.open(iw), new CharacterRunAutomaton(Automata.makeString("fieldA"))); // see only one field - Document d2 = ir.document(0); - assertEquals(1, d2.getFields().size()); - assertEquals(1, d2.getField("fieldA").numericValue()); - + { + Document d2 = ir.document(0); + assertEquals(1, d2.getFields().size()); + assertEquals(1, d2.getField("fieldA").numericValue()); + } + { + Document d2 = ir.storedFields().document(0); + assertEquals(1, d2.getFields().size()); + assertEquals(1, d2.getField("fieldA").numericValue()); + } TestUtil.checkReader(ir); IOUtils.close(ir, iw, dir); } @@ -310,10 +363,16 @@ public class FieldSubsetReaderTests extends ESTestCase { DirectoryReader ir = FieldSubsetReader.wrap(DirectoryReader.open(iw), new CharacterRunAutomaton(Automata.makeString("fieldA"))); // see only one field - Document d2 = ir.document(0); - assertEquals(1, d2.getFields().size()); - assertEquals(1L, d2.getField("fieldA").numericValue()); - + { + Document d2 = ir.document(0); + assertEquals(1, d2.getFields().size()); + assertEquals(1L, d2.getField("fieldA").numericValue()); + } + { + Document d2 = ir.storedFields().document(0); + assertEquals(1, d2.getFields().size()); + assertEquals(1L, d2.getField("fieldA").numericValue()); + } TestUtil.checkReader(ir); IOUtils.close(ir, iw, dir); } @@ -336,10 +395,16 @@ public class FieldSubsetReaderTests extends ESTestCase { DirectoryReader ir = FieldSubsetReader.wrap(DirectoryReader.open(iw), new CharacterRunAutomaton(Automata.makeString("fieldA"))); // see only one field - Document d2 = ir.document(0); - assertEquals(1, d2.getFields().size()); - assertEquals(1F, d2.getField("fieldA").numericValue()); - + { + Document d2 = ir.document(0); + assertEquals(1, d2.getFields().size()); + assertEquals(1F, d2.getField("fieldA").numericValue()); + } + { + Document d2 = ir.storedFields().document(0); + assertEquals(1, d2.getFields().size()); + assertEquals(1F, d2.getField("fieldA").numericValue()); + } TestUtil.checkReader(ir); IOUtils.close(ir, iw, dir); } @@ -362,10 +427,16 @@ public class FieldSubsetReaderTests extends ESTestCase { DirectoryReader ir = FieldSubsetReader.wrap(DirectoryReader.open(iw), new CharacterRunAutomaton(Automata.makeString("fieldA"))); // see only one field - Document d2 = ir.document(0); - assertEquals(1, d2.getFields().size()); - assertEquals(1D, d2.getField("fieldA").numericValue()); - + { + Document d2 = ir.document(0); + assertEquals(1, d2.getFields().size()); + assertEquals(1D, d2.getField("fieldA").numericValue()); + } + { + Document d2 = ir.storedFields().document(0); + assertEquals(1, d2.getFields().size()); + assertEquals(1D, d2.getField("fieldA").numericValue()); + } TestUtil.checkReader(ir); IOUtils.close(ir, iw, dir); } @@ -624,10 +695,16 @@ public class FieldSubsetReaderTests extends ESTestCase { DirectoryReader ir = FieldSubsetReader.wrap(DirectoryReader.open(iw), new CharacterRunAutomaton(automaton)); // see only one field - Document d2 = ir.document(0); - assertEquals(1, d2.getFields().size()); - assertEquals("{\"fieldA\":\"testA\"}", d2.getBinaryValue(SourceFieldMapper.NAME).utf8ToString()); - + { + Document d2 = ir.document(0); + assertEquals(1, d2.getFields().size()); + assertEquals("{\"fieldA\":\"testA\"}", d2.getBinaryValue(SourceFieldMapper.NAME).utf8ToString()); + } + { + Document d2 = ir.storedFields().document(0); + assertEquals(1, d2.getFields().size()); + assertEquals("{\"fieldA\":\"testA\"}", d2.getBinaryValue(SourceFieldMapper.NAME).utf8ToString()); + } TestUtil.checkReader(ir); IOUtils.close(ir, iw, dir); } @@ -1025,11 +1102,17 @@ public class FieldSubsetReaderTests extends ESTestCase { // see no vectors assertNull(segmentReader.getTermVectors(0)); + assertNull(segmentReader.termVectors().get(0)); // see no stored fields - Document document = segmentReader.document(0); - assertEquals(0, document.getFields().size()); - + { + Document document = segmentReader.document(0); + assertEquals(0, document.getFields().size()); + } + { + Document document = segmentReader.storedFields().document(0); + assertEquals(0, document.getFields().size()); + } TestUtil.checkReader(ir); IOUtils.close(ir, iw, dir); } diff --git a/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongFieldMapper.java b/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongFieldMapper.java index 53ec9d665110..8a21eb928920 100644 --- a/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongFieldMapper.java +++ b/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongFieldMapper.java @@ -11,8 +11,8 @@ import org.apache.lucene.document.Field; import org.apache.lucene.document.LongPoint; import org.apache.lucene.document.SortedNumericDocValuesField; import org.apache.lucene.document.StoredField; -import org.apache.lucene.sandbox.search.IndexSortSortedNumericDocValuesRangeQuery; import org.apache.lucene.search.IndexOrDocValuesQuery; +import org.apache.lucene.search.IndexSortSortedNumericDocValuesRangeQuery; import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.Query; import org.apache.lucene.util.BytesRef;