From 645a21ff4fe6f633c428126df3c49267aba0d608 Mon Sep 17 00:00:00 2001
From: Armin Braun
Date: Wed, 16 Aug 2023 17:16:29 +0200
Subject: [PATCH 01/21] Refactor InboundHandler into smaller Methods (#98444)
I tried to go through this code with someone and it became evident that
the massive method for request handling is very hard to grok. I split it
up into its logical constituents here and fixed some redundant passing
around of `message` and `header`. This at least makes it so we only have
one layer of ref count handling per method and it is a little easier to
follow where forking happens. Also, this removes a weirdly long
multi-second compile task from C2 for whatever that's worth :)
Also: * fixed `assertRemoteVersion` to be a proper assertion method *
extracted `verifyRequestReadFully` since it's not essential to the logic
just like we have `verifyResponseReadFully`
---
.../transport/InboundHandler.java | 366 ++++++++++--------
.../transport/TransportLogger.java | 2 +-
2 files changed, 202 insertions(+), 166 deletions(-)
diff --git a/server/src/main/java/org/elasticsearch/transport/InboundHandler.java b/server/src/main/java/org/elasticsearch/transport/InboundHandler.java
index 4bbdb7a3dd779..2080f89d25ccc 100644
--- a/server/src/main/java/org/elasticsearch/transport/InboundHandler.java
+++ b/server/src/main/java/org/elasticsearch/transport/InboundHandler.java
@@ -106,46 +106,20 @@ private void messageReceived(TcpChannel channel, InboundMessage message, long st
assert header.needsToReadVariableHeader() == false;
TransportResponseHandler> responseHandler = null;
- final boolean isRequest = message.getHeader().isRequest();
-
ThreadContext threadContext = threadPool.getThreadContext();
try (ThreadContext.StoredContext existing = threadContext.stashContext()) {
// Place the context with the headers from the message
threadContext.setHeaders(header.getHeaders());
threadContext.putTransient("_remote_address", remoteAddress);
- if (isRequest) {
- handleRequest(channel, header, message);
+ if (header.isRequest()) {
+ handleRequest(channel, message);
} else {
// Responses do not support short circuiting currently
assert message.isShortCircuit() == false;
- long requestId = header.getRequestId();
- if (header.isHandshake()) {
- responseHandler = handshaker.removeHandlerForHandshake(requestId);
- } else {
- final TransportResponseHandler extends TransportResponse> theHandler = responseHandlers.onResponseReceived(
- requestId,
- messageListener
- );
- if (theHandler == null && header.isError()) {
- responseHandler = handshaker.removeHandlerForHandshake(requestId);
- } else {
- responseHandler = theHandler;
- }
- }
+ responseHandler = findResponseHandler(header);
// ignore if its null, the service logs it
if (responseHandler != null) {
- if (message.getContentLength() > 0 || header.getVersion().equals(TransportVersion.current()) == false) {
- final StreamInput streamInput = namedWriteableStream(message.openOrGetStreamInput());
- assertRemoteVersion(streamInput, header.getVersion());
- if (header.isError()) {
- handlerResponseError(streamInput, message, responseHandler);
- } else {
- handleResponse(remoteAddress, streamInput, responseHandler, message);
- }
- } else {
- assert header.isError() == false;
- handleResponse(remoteAddress, EMPTY_STREAM_INPUT, responseHandler, message);
- }
+ executeResponseHandler(message, responseHandler, remoteAddress);
}
}
} finally {
@@ -153,23 +127,75 @@ private void messageReceived(TcpChannel channel, InboundMessage message, long st
handlingTimeTracker.addHandlingTime(took);
final long logThreshold = slowLogThresholdMs;
if (logThreshold > 0 && took > logThreshold) {
- if (isRequest) {
- logger.warn(
- "handling request [{}] took [{}ms] which is above the warn threshold of [{}ms]",
- message,
- took,
- logThreshold
- );
- } else {
- logger.warn(
- "handling response [{}] on handler [{}] took [{}ms] which is above the warn threshold of [{}ms]",
- message,
- responseHandler,
- took,
- logThreshold
- );
- }
+ logSlowMessage(message, took, logThreshold, responseHandler);
+ }
+ }
+ }
+
+ private void executeResponseHandler(
+ InboundMessage message,
+ TransportResponseHandler> responseHandler,
+ InetSocketAddress remoteAddress
+ ) throws IOException {
+ final var header = message.getHeader();
+ if (message.getContentLength() > 0 || header.getVersion().equals(TransportVersion.current()) == false) {
+ final StreamInput streamInput = namedWriteableStream(message.openOrGetStreamInput());
+ assert assertRemoteVersion(streamInput, header.getVersion());
+ if (header.isError()) {
+ handlerResponseError(streamInput, message, responseHandler);
+ } else {
+ handleResponse(remoteAddress, streamInput, responseHandler, message);
}
+ } else {
+ assert header.isError() == false;
+ handleResponse(remoteAddress, EMPTY_STREAM_INPUT, responseHandler, message);
+ }
+ }
+
+ private TransportResponseHandler> findResponseHandler(Header header) {
+ if (header.isHandshake()) {
+ return handshaker.removeHandlerForHandshake(header.getRequestId());
+ }
+ final TransportResponseHandler extends TransportResponse> theHandler = responseHandlers.onResponseReceived(
+ header.getRequestId(),
+ messageListener
+ );
+ if (theHandler == null && header.isError()) {
+ return handshaker.removeHandlerForHandshake(header.getRequestId());
+ } else {
+ return theHandler;
+ }
+ }
+
+ private static void logSlowMessage(InboundMessage message, long took, long logThreshold, TransportResponseHandler> responseHandler) {
+ if (message.getHeader().isRequest()) {
+ logger.warn("handling request [{}] took [{}ms] which is above the warn threshold of [{}ms]", message, took, logThreshold);
+ } else {
+ logger.warn(
+ "handling response [{}] on handler [{}] took [{}ms] which is above the warn threshold of [{}ms]",
+ message,
+ responseHandler,
+ took,
+ logThreshold
+ );
+ }
+ }
+
+ private void verifyRequestReadFully(StreamInput stream, long requestId, String action) throws IOException {
+ final int nextByte = stream.read();
+ // calling read() is useful to make sure the message is fully read, even if there some kind of EOS marker
+ if (nextByte != -1) {
+ final IllegalStateException exception = new IllegalStateException(
+ "Message not fully read (request) for requestId ["
+ + requestId
+ + "], action ["
+ + action
+ + "], available ["
+ + stream.available()
+ + "]; resetting"
+ );
+ assert ignoreDeserializationErrors : exception;
+ throw exception;
}
}
@@ -193,139 +219,148 @@ private void verifyResponseReadFully(Header header, TransportResponseHandler>
}
}
- private void handleRequest(TcpChannel channel, Header header, InboundMessage message) throws IOException {
+ private void handleRequest(TcpChannel channel, InboundMessage message) throws IOException {
+ final Header header = message.getHeader();
+ if (header.isHandshake()) {
+ handleHandshakeRequest(channel, message);
+ return;
+ }
+
final String action = header.getActionName();
final long requestId = header.getRequestId();
- final TransportVersion version = header.getVersion();
- if (header.isHandshake()) {
+ final RequestHandlerRegistry reg = requestHandlers.getHandler(action);
+ assert message.isShortCircuit() || reg != null : action;
+ final TransportChannel transportChannel = new TcpTransportChannel(
+ outboundHandler,
+ channel,
+ action,
+ requestId,
+ header.getVersion(),
+ header.getCompressionScheme(),
+ reg == null ? ResponseStatsConsumer.NONE : reg,
+ false,
+ message.takeBreakerReleaseControl()
+ );
+
+ try {
messageListener.onRequestReceived(requestId, action);
- // Cannot short circuit handshakes
- assert message.isShortCircuit() == false;
+ if (reg != null) {
+ reg.addRequestStats(header.getNetworkMessageSize() + TcpHeader.BYTES_REQUIRED_FOR_MESSAGE_SIZE);
+ }
+
+ if (message.isShortCircuit()) {
+ sendErrorResponse(action, transportChannel, message.getException());
+ return;
+ }
+
+ assert reg != null;
final StreamInput stream = namedWriteableStream(message.openOrGetStreamInput());
- assertRemoteVersion(stream, header.getVersion());
- final TransportChannel transportChannel = new TcpTransportChannel(
- outboundHandler,
- channel,
- action,
- requestId,
- version,
- header.getCompressionScheme(),
- ResponseStatsConsumer.NONE,
- header.isHandshake(),
- message.takeBreakerReleaseControl()
- );
+ assert assertRemoteVersion(stream, header.getVersion());
+ final T request;
try {
- handshaker.handleHandshake(transportChannel, requestId, stream);
+ request = reg.newRequest(stream);
} catch (Exception e) {
- logger.warn(() -> "error processing handshake version [" + version + "] received on [" + channel + "], closing channel", e);
- channel.close();
+ assert ignoreDeserializationErrors : e;
+ throw e;
}
- } else {
- final RequestHandlerRegistry reg = requestHandlers.getHandler(action);
- assert message.isShortCircuit() || reg != null : action;
- final TransportChannel transportChannel = new TcpTransportChannel(
- outboundHandler,
- channel,
- action,
- requestId,
- version,
- header.getCompressionScheme(),
- reg == null ? ResponseStatsConsumer.NONE : reg,
- header.isHandshake(),
- message.takeBreakerReleaseControl()
- );
-
try {
- messageListener.onRequestReceived(requestId, action);
- if (reg != null) {
- reg.addRequestStats(header.getNetworkMessageSize() + TcpHeader.BYTES_REQUIRED_FOR_MESSAGE_SIZE);
+ request.remoteAddress(channel.getRemoteAddress());
+ assert requestId > 0;
+ request.setRequestId(requestId);
+ verifyRequestReadFully(stream, requestId, action);
+ if (ThreadPool.Names.SAME.equals(reg.getExecutor())) {
+ try (var ignored = threadPool.getThreadContext().newTraceContext()) {
+ doHandleRequest(reg, request, transportChannel);
+ }
+ } else {
+ handleRequestForking(request, reg, transportChannel);
}
+ } finally {
+ request.decRef();
+ }
+ } catch (Exception e) {
+ sendErrorResponse(action, transportChannel, e);
+ }
+ }
- if (message.isShortCircuit()) {
- sendErrorResponse(action, transportChannel, message.getException());
- } else {
- assert reg != null;
- final StreamInput stream = namedWriteableStream(message.openOrGetStreamInput());
- assertRemoteVersion(stream, header.getVersion());
- final T request;
- try {
- request = reg.newRequest(stream);
- } catch (Exception e) {
- assert ignoreDeserializationErrors : e;
- throw e;
- }
- try {
- request.remoteAddress(channel.getRemoteAddress());
- assert requestId > 0;
- request.setRequestId(requestId);
- // in case we throw an exception, i.e. when the limit is hit, we don't want to verify
- final int nextByte = stream.read();
- // calling read() is useful to make sure the message is fully read, even if there some kind of EOS marker
- if (nextByte != -1) {
- final IllegalStateException exception = new IllegalStateException(
- "Message not fully read (request) for requestId ["
- + requestId
- + "], action ["
- + action
- + "], available ["
- + stream.available()
- + "]; resetting"
- );
- assert ignoreDeserializationErrors : exception;
- throw exception;
- }
- final String executor = reg.getExecutor();
- if (ThreadPool.Names.SAME.equals(executor)) {
- try (var ignored = threadPool.getThreadContext().newTraceContext()) {
- try {
- reg.processMessageReceived(request, transportChannel);
- } catch (Exception e) {
- sendErrorResponse(reg.getAction(), transportChannel, e);
- }
- }
- } else {
- boolean success = false;
- request.incRef();
- try {
- threadPool.executor(executor)
- .execute(threadPool.getThreadContext().preserveContextWithTracing(new AbstractRunnable() {
- @Override
- protected void doRun() throws Exception {
- reg.processMessageReceived(request, transportChannel);
- }
-
- @Override
- public boolean isForceExecution() {
- return reg.isForceExecution();
- }
-
- @Override
- public void onFailure(Exception e) {
- sendErrorResponse(reg.getAction(), transportChannel, e);
- }
-
- @Override
- public void onAfter() {
- request.decRef();
- }
- }));
- success = true;
- } finally {
- if (success == false) {
- request.decRef();
- }
- }
- }
- } finally {
- request.decRef();
- }
+ private static void doHandleRequest(RequestHandlerRegistry reg, T request, TransportChannel channel) {
+ try {
+ reg.processMessageReceived(request, channel);
+ } catch (Exception e) {
+ sendErrorResponse(reg.getAction(), channel, e);
+ }
+ }
+
+ private void handleRequestForking(T request, RequestHandlerRegistry reg, TransportChannel channel) {
+ boolean success = false;
+ request.incRef();
+ try {
+ threadPool.executor(reg.getExecutor()).execute(threadPool.getThreadContext().preserveContextWithTracing(new AbstractRunnable() {
+ @Override
+ protected void doRun() {
+ doHandleRequest(reg, request, channel);
}
- } catch (Exception e) {
- sendErrorResponse(action, transportChannel, e);
+
+ @Override
+ public boolean isForceExecution() {
+ return reg.isForceExecution();
+ }
+
+ @Override
+ public void onRejection(Exception e) {
+ sendErrorResponse(reg.getAction(), channel, e);
+ }
+
+ @Override
+ public void onFailure(Exception e) {
+ assert false : e; // shouldn't get here ever, no failures other than rejection by the thread-pool expected
+ sendErrorResponse(reg.getAction(), channel, e);
+ }
+
+ @Override
+ public void onAfter() {
+ request.decRef();
+ }
+ }));
+ success = true;
+ } finally {
+ if (success == false) {
+ request.decRef();
}
}
}
+ private void handleHandshakeRequest(TcpChannel channel, InboundMessage message) throws IOException {
+ var header = message.getHeader();
+ assert header.actionName.equals(TransportHandshaker.HANDSHAKE_ACTION_NAME);
+ final long requestId = header.getRequestId();
+ messageListener.onRequestReceived(requestId, TransportHandshaker.HANDSHAKE_ACTION_NAME);
+ // Cannot short circuit handshakes
+ assert message.isShortCircuit() == false;
+ final StreamInput stream = namedWriteableStream(message.openOrGetStreamInput());
+ assert assertRemoteVersion(stream, header.getVersion());
+ final TransportChannel transportChannel = new TcpTransportChannel(
+ outboundHandler,
+ channel,
+ TransportHandshaker.HANDSHAKE_ACTION_NAME,
+ requestId,
+ header.getVersion(),
+ header.getCompressionScheme(),
+ ResponseStatsConsumer.NONE,
+ true,
+ message.takeBreakerReleaseControl()
+ );
+ try {
+ handshaker.handleHandshake(transportChannel, requestId, stream);
+ } catch (Exception e) {
+ logger.warn(
+ () -> "error processing handshake version [" + header.getVersion() + "] received on [" + channel + "], closing channel",
+ e
+ );
+ channel.close();
+ }
+ }
+
private static void sendErrorResponse(String actionName, TransportChannel transportChannel, Exception e) {
try {
transportChannel.sendResponse(e);
@@ -448,8 +483,9 @@ private StreamInput namedWriteableStream(StreamInput delegate) {
return new NamedWriteableAwareStreamInput(delegate, namedWriteableRegistry);
}
- static void assertRemoteVersion(StreamInput in, TransportVersion version) {
+ static boolean assertRemoteVersion(StreamInput in, TransportVersion version) {
assert version.equals(in.getTransportVersion())
: "Stream version [" + in.getTransportVersion() + "] does not match version [" + version + "]";
+ return true;
}
}
diff --git a/server/src/main/java/org/elasticsearch/transport/TransportLogger.java b/server/src/main/java/org/elasticsearch/transport/TransportLogger.java
index c4b0381ef4523..2d06d53b4dba0 100644
--- a/server/src/main/java/org/elasticsearch/transport/TransportLogger.java
+++ b/server/src/main/java/org/elasticsearch/transport/TransportLogger.java
@@ -88,7 +88,7 @@ private static String format(TcpChannel channel, BytesReference message, String
sb.append(", header size: ").append(streamInput.readInt()).append('B');
} else {
streamInput = decompressingStream(status, streamInput);
- InboundHandler.assertRemoteVersion(streamInput, version);
+ assert InboundHandler.assertRemoteVersion(streamInput, version);
}
// read and discard headers
From 014bd33f456469ce9246aa65fb04fff71e9112e6 Mon Sep 17 00:00:00 2001
From: Andrei Stefan
Date: Wed, 16 Aug 2023 20:19:40 +0300
Subject: [PATCH 02/21] ESQL: replace the is_null function with IS NULL and IS
NOT NULL predicates (#98412)
---
docs/reference/esql/esql-functions.asciidoc | 2 -
docs/reference/esql/esql-syntax.asciidoc | 16 +
.../reference/esql/functions/is_null.asciidoc | 23 -
.../resources/blog-ignoreCsvTests.csv-spec | 2 +-
.../src/main/resources/boolean.csv-spec | 4 +-
.../src/main/resources/conditional.csv-spec | 36 +-
.../src/main/resources/docs.csv-spec | 32 -
.../src/main/resources/eval.csv-spec | 7 +
.../src/main/resources/ints.csv-spec | 2 +-
.../src/main/resources/ip.csv-spec | 4 +-
.../src/main/resources/row.csv-spec | 7 +
.../src/main/resources/show.csv-spec | 2 -
.../src/main/resources/version.csv-spec | 8 +-
.../esql/src/main/antlr/EsqlBaseLexer.g4 | 1 +
.../esql/src/main/antlr/EsqlBaseLexer.tokens | 134 +-
.../esql/src/main/antlr/EsqlBaseParser.g4 | 2 +-
.../esql/src/main/antlr/EsqlBaseParser.tokens | 134 +-
.../function/EsqlFunctionRegistry.java | 3 +-
.../xpack/esql/parser/EsqlBaseLexer.interp | 5 +-
.../xpack/esql/parser/EsqlBaseLexer.java | 933 ++++++------
.../xpack/esql/parser/EsqlBaseParser.interp | 4 +-
.../xpack/esql/parser/EsqlBaseParser.java | 1248 +++++++++--------
.../parser/EsqlBaseParserBaseListener.java | 12 +
.../parser/EsqlBaseParserBaseVisitor.java | 7 +
.../esql/parser/EsqlBaseParserListener.java | 12 +
.../esql/parser/EsqlBaseParserVisitor.java | 7 +
.../xpack/esql/parser/EsqlParser.java | 18 +
.../xpack/esql/parser/ExpressionBuilder.java | 9 +
.../optimizer/LogicalPlanOptimizerTests.java | 2 +-
.../esql/parser/StatementParserTests.java | 11 +
30 files changed, 1415 insertions(+), 1272 deletions(-)
delete mode 100644 docs/reference/esql/functions/is_null.asciidoc
diff --git a/docs/reference/esql/esql-functions.asciidoc b/docs/reference/esql/esql-functions.asciidoc
index 6b656202f04b5..2a4b64331390b 100644
--- a/docs/reference/esql/esql-functions.asciidoc
+++ b/docs/reference/esql/esql-functions.asciidoc
@@ -28,7 +28,6 @@ these functions:
* <>
* <>
* <>
-* <>
* <>
* <>
* <>
@@ -84,7 +83,6 @@ include::functions/floor.asciidoc[]
include::functions/is_finite.asciidoc[]
include::functions/is_infinite.asciidoc[]
include::functions/is_nan.asciidoc[]
-include::functions/is_null.asciidoc[]
include::functions/length.asciidoc[]
include::functions/log10.asciidoc[]
include::functions/mv_avg.asciidoc[]
diff --git a/docs/reference/esql/esql-syntax.asciidoc b/docs/reference/esql/esql-syntax.asciidoc
index 80a2596e4def3..53d80b9e29ab7 100644
--- a/docs/reference/esql/esql-syntax.asciidoc
+++ b/docs/reference/esql/esql-syntax.asciidoc
@@ -114,6 +114,22 @@ The following boolean operators are supported:
* `OR`
* `NOT`
+[discrete]
+[[esql-predicates]]
+=== Predicates
+
+For NULL comparison use the `IS NULL` and `IS NOT NULL` predicates:
+
+[source,esql]
+----
+include::{esql-specs}/conditional.csv-spec[tag=is-null]
+----
+
+[source,esql]
+----
+include::{esql-specs}/conditional.csv-spec[tag=is-not-null]
+----
+
[discrete]
[[esql-timespan-literals]]
=== Timespan literals
diff --git a/docs/reference/esql/functions/is_null.asciidoc b/docs/reference/esql/functions/is_null.asciidoc
deleted file mode 100644
index 1376288eaaebe..0000000000000
--- a/docs/reference/esql/functions/is_null.asciidoc
+++ /dev/null
@@ -1,23 +0,0 @@
-[[esql-is_null]]
-=== `IS_NULL`
-Returns a boolean that indicates whether its input is `null`.
-
-[source.merge.styled,esql]
-----
-include::{esql-specs}/docs.csv-spec[tag=isNull]
-----
-[%header.monospaced.styled,format=dsv,separator=|]
-|===
-include::{esql-specs}/docs.csv-spec[tag=isNull-result]
-|===
-
-Combine this function with `NOT` to filter out any `null` data:
-
-[source.merge.styled,esql]
-----
-include::{esql-specs}/docs.csv-spec[tag=notIsNull]
-----
-[%header.monospaced.styled,format=dsv,separator=|]
-|===
-include::{esql-specs}/docs.csv-spec[tag=notIsNull-result]
-|===
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/blog-ignoreCsvTests.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/blog-ignoreCsvTests.csv-spec
index 5c0d00262b61e..f670738bd3c49 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/blog-ignoreCsvTests.csv-spec
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/blog-ignoreCsvTests.csv-spec
@@ -7,7 +7,7 @@
| EVAL avg_salary = ROUND(avg_salary)
| EVAL lang_code = TO_STRING(languages)
| ENRICH languages_policy ON lang_code WITH lang = language_name
-| WHERE NOT IS_NULL(lang)
+| WHERE lang IS NOT NULL
| KEEP avg_salary, lang
| SORT avg_salary ASC
| LIMIT 3
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/boolean.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/boolean.csv-spec
index b3367b473ee48..6489d363ed77d 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/boolean.csv-spec
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/boolean.csv-spec
@@ -34,14 +34,14 @@ avg(salary):double | still_hired:boolean
;
statsByAlwaysTrue
-from employees | where not(is_null(first_name)) | eval always_true = starts_with(first_name, "") | stats avg(salary) by always_true;
+from employees | where first_name is not null | eval always_true = starts_with(first_name, "") | stats avg(salary) by always_true;
avg(salary):double | always_true:boolean
48353.72222222222 | true
;
statsByAlwaysFalse
-from employees | where not(is_null(first_name)) | eval always_false = starts_with(first_name, "nonestartwiththis") | stats avg(salary) by always_false;
+from employees | where first_name is not null | eval always_false = starts_with(first_name, "nonestartwiththis") | stats avg(salary) by always_false;
avg(salary):double | always_false:boolean
48353.72222222222 | false
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/conditional.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/conditional.csv-spec
index 712f5637411ba..7bc5f4b13ae0e 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/conditional.csv-spec
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/conditional.csv-spec
@@ -92,7 +92,7 @@ M |10
isNull
from employees
-| where is_null(gender)
+| where gender is null
| sort first_name
| keep first_name, gender
| limit 3;
@@ -105,7 +105,7 @@ Duangkaew |null
notIsNull
from employees
-| where not is_null(gender)
+| where gender is not null
| sort first_name
| keep first_name, gender
| limit 3;
@@ -115,3 +115,35 @@ Alejandro |F
Amabile |M
Anneke |F
;
+
+isNullForDocs
+// tag::is-null[]
+FROM employees
+| WHERE birth_date IS NULL
+| KEEP first_name, last_name
+| SORT first_name
+| LIMIT 3
+// end::is-null[]
+;
+
+// tag::is-null-result[]
+first_name:keyword|last_name:keyword
+Basil |Tramer
+Florian |Syrotiuk
+Lucien |Rosenbaum
+// end::is-null-result[]
+;
+
+isNotNullForDocs
+// tag::is-not-null[]
+FROM employees
+| WHERE is_rehired IS NOT NULL
+| STATS count(emp_no)
+// end::is-not-null[]
+;
+
+// tag::is-not-null-result[]
+count(emp_no):long
+84
+// end::is-not-null-result[]
+;
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/docs.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/docs.csv-spec
index 97bd7de53fc47..b386e546f9cb8 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/docs.csv-spec
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/docs.csv-spec
@@ -399,38 +399,6 @@ Saniya |Kalloufi |2.1 |6.9
// end::round-result[]
;
-docsIsNull
-// tag::isNull[]
-FROM employees
-| KEEP first_name, last_name
-| WHERE IS_NULL(first_name)
-// end::isNull[]
-| LIMIT 3;
-
-// tag::isNull-result[]
-first_name:keyword | last_name:keyword
-null |Demeyer
-null |Joslin
-null |Reistad
-// end::isNull-result[]
-;
-
-docsNotIsNull
-// tag::notIsNull[]
-FROM employees
-| KEEP first_name, last_name
-| WHERE NOT IS_NULL(first_name)
-// end::notIsNull[]
-| LIMIT 3;
-
-// tag::notIsNull-result[]
-first_name:keyword | last_name:keyword
-Georgi |Facello
-Bezalel |Simmel
-Parto |Bamford
-// end::notIsNull-result[]
-;
-
dateParse
// tag::dateParse[]
ROW date_string = "2022-05-06"
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/eval.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/eval.csv-spec
index 52e38794595db..ba89685716059 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/eval.csv-spec
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/eval.csv-spec
@@ -101,3 +101,10 @@ Tse
Udi
Uri
;
+
+evalWithIsNullIsNotNull
+from employees | eval true_bool = null is null, false_bool = null is not null, negated_true = not(null is null), negated_false = not(null is not null) | sort emp_no | limit 1 | keep *true*, *false*, first_name, last_name;
+
+true_bool:boolean | negated_true:boolean | false_bool:boolean | negated_false:boolean | first_name:keyword | last_name:keyword
+true | false | false | true | Georgi | Facello
+;
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/ints.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/ints.csv-spec
index 37a1ae34b1a81..0c73e24136a0f 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/ints.csv-spec
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/ints.csv-spec
@@ -25,7 +25,7 @@ emp_no:integer |languages.byte:byte |avg_worked_seconds:long |height:double
// `<= 10030` insures going over records where is_null(languages)==true; `in (.., emp_no)` prevents pushing the IN to Lucene
inOverNulls
-from employees | keep emp_no, languages | where is_null(languages) or emp_no <= 10030 | where languages in (2, 3, emp_no);
+from employees | keep emp_no, languages | where languages is null or emp_no <= 10030 | where languages in (2, 3, emp_no);
emp_no:integer |languages:integer
10001 |2
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/ip.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/ip.csv-spec
index d19f9a110383a..d69be91cd2f22 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/ip.csv-spec
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/ip.csv-spec
@@ -105,7 +105,7 @@ eth2 |epsilon |[fe81::cae2:65ff:fece:feb9, fe82::cae2:65ff:fece
;
isNull
-from hosts | where is_null(ip0) | keep ip0, ip1;
+from hosts | where ip0 is null | keep ip0, ip1;
ip0:ip |ip1:ip
null |[127.0.0.1, 127.0.0.2, 127.0.0.3]
@@ -149,7 +149,7 @@ eth1 |beta |127.0.0.1 |127.0.0.2
;
cidrMatchNullField
-from hosts | where is_null(cidr_match(ip0, "127.0.0.2/32")) | keep card, host, ip0, ip1;
+from hosts | where cidr_match(ip0, "127.0.0.2/32") is null | keep card, host, ip0, ip1;
card:keyword |host:keyword |ip0:ip |ip1:ip
eth0 |epsilon |[fe80::cae2:65ff:fece:feb9, fe80::cae2:65ff:fece:fec0, fe80::cae2:65ff:fece:fec1]|fe80::cae2:65ff:fece:fec1
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/row.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/row.csv-spec
index 256c11889950e..0c5026413fce9 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/row.csv-spec
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/row.csv-spec
@@ -324,3 +324,10 @@ row integers = [+ 1, -2, -300, -2147483648], longs = [1, - 2, -214748
integers:integer | longs:long | longs2:long | doubles:double
[1, -2, -300, -2147483648] | [1, -2, -2147483649] | [1, -2, -9223372036854775808] | [1, -0.455, -2.43, 3.4, -0.12, 8]
;
+
+isNullIsNotNull
+row true_bool = null is null, false_bool = null is not null, negated_true = not(null is null), negated_false = not(null is not null);
+
+true_bool:boolean | false_bool:boolean | negated_true:boolean | negated_false:boolean
+true | false | false | true
+;
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/show.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/show.csv-spec
index ea8cf53384ecf..99991d39cf8d3 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/show.csv-spec
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/show.csv-spec
@@ -32,7 +32,6 @@ floor |floor(arg1)
is_finite |is_finite(arg1)
is_infinite |is_infinite(arg1)
is_nan |is_nan(arg1)
-is_null |is_null(arg1)
length |length(arg1)
log10 |log10(arg1)
max |max(arg1)
@@ -91,5 +90,4 @@ show functions | where starts_with(name, "is_");
is_finite |is_finite(arg1)
is_infinite |is_infinite(arg1)
is_nan |is_nan(arg1)
-is_null |is_null(arg1)
;
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/version.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/version.csv-spec
index 0ef16d648c505..b7b3ca1c99d3c 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/version.csv-spec
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/version.csv-spec
@@ -194,7 +194,7 @@ c:l |maxid:i |version:v
;
groupOrderLimit
-FROM apps | WHERE not is_null(version) | STATS c = COUNT(version) BY version | SORT version DESC | DROP c | LIMIT 3;
+FROM apps | WHERE version is not null | STATS c = COUNT(version) BY version | SORT version DESC | DROP c | LIMIT 3;
version:v
bad
@@ -289,14 +289,14 @@ idx:i |version:v
case
FROM apps
| EVAL version_text = TO_STR(version)
-| WHERE IS_NULL(version) OR version_text LIKE "1*"
+| WHERE version IS NULL OR version_text LIKE "1*"
| EVAL v = TO_VER(CONCAT("123", TO_STR(version)))
| EVAL m = CASE(version > TO_VER("1.1"), 1, 0)
| EVAL g = CASE(version > TO_VER("1.3.0"), version, TO_VER("1.3.0"))
-| EVAL i = CASE(IS_NULL(version), TO_VER("0.1"), version)
+| EVAL i = CASE(version IS NULL, TO_VER("0.1"), version)
| EVAL c = CASE(
version > TO_VER("1.1"), "high",
- IS_NULL(version), "none",
+ version IS NULL, "none",
"low")
| SORT version DESC NULLS LAST, id DESC
| KEEP v, version, version_text, id, m, g, i, c;
diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4 b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4
index abd2f2de4f6a0..747c1fdcd1921 100644
--- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4
+++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4
@@ -93,6 +93,7 @@ FIRST : 'first';
LAST : 'last';
LP : '(';
IN: 'in';
+IS: 'is';
LIKE: 'like';
NOT : 'not';
NULL : 'null';
diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens
index e8040376185f5..d8761f5eb0d73 100644
--- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens
+++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens
@@ -39,45 +39,46 @@ FIRST=38
LAST=39
LP=40
IN=41
-LIKE=42
-NOT=43
-NULL=44
-NULLS=45
-OR=46
-PARAM=47
-RLIKE=48
-RP=49
-TRUE=50
-INFO=51
-FUNCTIONS=52
-EQ=53
-NEQ=54
-LT=55
-LTE=56
-GT=57
-GTE=58
-PLUS=59
-MINUS=60
-ASTERISK=61
-SLASH=62
-PERCENT=63
-OPENING_BRACKET=64
-CLOSING_BRACKET=65
-UNQUOTED_IDENTIFIER=66
-QUOTED_IDENTIFIER=67
-EXPR_LINE_COMMENT=68
-EXPR_MULTILINE_COMMENT=69
-EXPR_WS=70
-AS=71
-METADATA=72
-ON=73
-WITH=74
-SRC_UNQUOTED_IDENTIFIER=75
-SRC_QUOTED_IDENTIFIER=76
-SRC_LINE_COMMENT=77
-SRC_MULTILINE_COMMENT=78
-SRC_WS=79
-EXPLAIN_PIPE=80
+IS=42
+LIKE=43
+NOT=44
+NULL=45
+NULLS=46
+OR=47
+PARAM=48
+RLIKE=49
+RP=50
+TRUE=51
+INFO=52
+FUNCTIONS=53
+EQ=54
+NEQ=55
+LT=56
+LTE=57
+GT=58
+GTE=59
+PLUS=60
+MINUS=61
+ASTERISK=62
+SLASH=63
+PERCENT=64
+OPENING_BRACKET=65
+CLOSING_BRACKET=66
+UNQUOTED_IDENTIFIER=67
+QUOTED_IDENTIFIER=68
+EXPR_LINE_COMMENT=69
+EXPR_MULTILINE_COMMENT=70
+EXPR_WS=71
+AS=72
+METADATA=73
+ON=74
+WITH=75
+SRC_UNQUOTED_IDENTIFIER=76
+SRC_QUOTED_IDENTIFIER=77
+SRC_LINE_COMMENT=78
+SRC_MULTILINE_COMMENT=79
+SRC_WS=80
+EXPLAIN_PIPE=81
'dissect'=1
'drop'=2
'enrich'=3
@@ -106,30 +107,31 @@ EXPLAIN_PIPE=80
'last'=39
'('=40
'in'=41
-'like'=42
-'not'=43
-'null'=44
-'nulls'=45
-'or'=46
-'?'=47
-'rlike'=48
-')'=49
-'true'=50
-'info'=51
-'functions'=52
-'=='=53
-'!='=54
-'<'=55
-'<='=56
-'>'=57
-'>='=58
-'+'=59
-'-'=60
-'*'=61
-'/'=62
-'%'=63
-']'=65
-'as'=71
-'metadata'=72
-'on'=73
-'with'=74
+'is'=42
+'like'=43
+'not'=44
+'null'=45
+'nulls'=46
+'or'=47
+'?'=48
+'rlike'=49
+')'=50
+'true'=51
+'info'=52
+'functions'=53
+'=='=54
+'!='=55
+'<'=56
+'<='=57
+'>'=58
+'>='=59
+'+'=60
+'-'=61
+'*'=62
+'/'=63
+'%'=64
+']'=66
+'as'=72
+'metadata'=73
+'on'=74
+'with'=75
diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4 b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4
index 61fb9ab8e1b46..8f07a8a5dcdea 100644
--- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4
+++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4
@@ -53,6 +53,7 @@ booleanExpression
| left=booleanExpression operator=AND right=booleanExpression #logicalBinary
| left=booleanExpression operator=OR right=booleanExpression #logicalBinary
| valueExpression (NOT)? IN LP valueExpression (COMMA valueExpression)* RP #logicalIn
+ | valueExpression IS NOT? NULL #isNull
;
regexBooleanExpression
@@ -237,6 +238,5 @@ enrichCommand
;
enrichWithClause
-
: (newName=sourceIdentifier ASSIGN)? enrichField=sourceIdentifier
;
diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens
index e8040376185f5..d8761f5eb0d73 100644
--- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens
+++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens
@@ -39,45 +39,46 @@ FIRST=38
LAST=39
LP=40
IN=41
-LIKE=42
-NOT=43
-NULL=44
-NULLS=45
-OR=46
-PARAM=47
-RLIKE=48
-RP=49
-TRUE=50
-INFO=51
-FUNCTIONS=52
-EQ=53
-NEQ=54
-LT=55
-LTE=56
-GT=57
-GTE=58
-PLUS=59
-MINUS=60
-ASTERISK=61
-SLASH=62
-PERCENT=63
-OPENING_BRACKET=64
-CLOSING_BRACKET=65
-UNQUOTED_IDENTIFIER=66
-QUOTED_IDENTIFIER=67
-EXPR_LINE_COMMENT=68
-EXPR_MULTILINE_COMMENT=69
-EXPR_WS=70
-AS=71
-METADATA=72
-ON=73
-WITH=74
-SRC_UNQUOTED_IDENTIFIER=75
-SRC_QUOTED_IDENTIFIER=76
-SRC_LINE_COMMENT=77
-SRC_MULTILINE_COMMENT=78
-SRC_WS=79
-EXPLAIN_PIPE=80
+IS=42
+LIKE=43
+NOT=44
+NULL=45
+NULLS=46
+OR=47
+PARAM=48
+RLIKE=49
+RP=50
+TRUE=51
+INFO=52
+FUNCTIONS=53
+EQ=54
+NEQ=55
+LT=56
+LTE=57
+GT=58
+GTE=59
+PLUS=60
+MINUS=61
+ASTERISK=62
+SLASH=63
+PERCENT=64
+OPENING_BRACKET=65
+CLOSING_BRACKET=66
+UNQUOTED_IDENTIFIER=67
+QUOTED_IDENTIFIER=68
+EXPR_LINE_COMMENT=69
+EXPR_MULTILINE_COMMENT=70
+EXPR_WS=71
+AS=72
+METADATA=73
+ON=74
+WITH=75
+SRC_UNQUOTED_IDENTIFIER=76
+SRC_QUOTED_IDENTIFIER=77
+SRC_LINE_COMMENT=78
+SRC_MULTILINE_COMMENT=79
+SRC_WS=80
+EXPLAIN_PIPE=81
'dissect'=1
'drop'=2
'enrich'=3
@@ -106,30 +107,31 @@ EXPLAIN_PIPE=80
'last'=39
'('=40
'in'=41
-'like'=42
-'not'=43
-'null'=44
-'nulls'=45
-'or'=46
-'?'=47
-'rlike'=48
-')'=49
-'true'=50
-'info'=51
-'functions'=52
-'=='=53
-'!='=54
-'<'=55
-'<='=56
-'>'=57
-'>='=58
-'+'=59
-'-'=60
-'*'=61
-'/'=62
-'%'=63
-']'=65
-'as'=71
-'metadata'=72
-'on'=73
-'with'=74
+'is'=42
+'like'=43
+'not'=44
+'null'=45
+'nulls'=46
+'or'=47
+'?'=48
+'rlike'=49
+')'=50
+'true'=51
+'info'=52
+'functions'=53
+'=='=54
+'!='=55
+'<'=56
+'<='=57
+'>'=58
+'>='=59
+'+'=60
+'-'=61
+'*'=62
+'/'=63
+'%'=64
+']'=66
+'as'=72
+'metadata'=73
+'on'=74
+'with'=75
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java
index 605d1f8d193af..9a16435684648 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java
@@ -73,7 +73,6 @@
import org.elasticsearch.xpack.esql.expression.function.scalar.string.Trim;
import org.elasticsearch.xpack.ql.expression.function.FunctionDefinition;
import org.elasticsearch.xpack.ql.expression.function.FunctionRegistry;
-import org.elasticsearch.xpack.ql.expression.predicate.nulls.IsNull;
import java.util.Locale;
@@ -140,7 +139,7 @@ private FunctionDefinition[][] functions() {
def(DateTrunc.class, DateTrunc::new, "date_trunc"),
def(Now.class, Now::new, "now") },
// conditional
- new FunctionDefinition[] { def(Case.class, Case::new, "case"), def(IsNull.class, IsNull::new, "is_null"), },
+ new FunctionDefinition[] { def(Case.class, Case::new, "case") },
// IP
new FunctionDefinition[] { def(CIDRMatch.class, CIDRMatch::new, "cidr_match") },
// conversion functions
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp
index cba4b4514d38a..12542878c3ed3 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp
@@ -41,6 +41,7 @@ null
'last'
'('
'in'
+'is'
'like'
'not'
'null'
@@ -124,6 +125,7 @@ FIRST
LAST
LP
IN
+IS
LIKE
NOT
NULL
@@ -213,6 +215,7 @@ FIRST
LAST
LP
IN
+IS
LIKE
NOT
NULL
@@ -269,4 +272,4 @@ EXPRESSION
SOURCE_IDENTIFIERS
atn:
-[4, 0, 80, 759, 6, -1, 6, -1, 6, -1, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 4, 18, 343, 8, 18, 11, 18, 12, 18, 344, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 5, 19, 353, 8, 19, 10, 19, 12, 19, 356, 9, 19, 1, 19, 3, 19, 359, 8, 19, 1, 19, 3, 19, 362, 8, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 5, 20, 371, 8, 20, 10, 20, 12, 20, 374, 9, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 4, 21, 382, 8, 21, 11, 21, 12, 21, 383, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 32, 1, 32, 3, 32, 425, 8, 32, 1, 32, 4, 32, 428, 8, 32, 11, 32, 12, 32, 429, 1, 33, 1, 33, 1, 33, 5, 33, 435, 8, 33, 10, 33, 12, 33, 438, 9, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 5, 33, 446, 8, 33, 10, 33, 12, 33, 449, 9, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 3, 33, 456, 8, 33, 1, 33, 3, 33, 459, 8, 33, 3, 33, 461, 8, 33, 1, 34, 4, 34, 464, 8, 34, 11, 34, 12, 34, 465, 1, 35, 4, 35, 469, 8, 35, 11, 35, 12, 35, 470, 1, 35, 1, 35, 5, 35, 475, 8, 35, 10, 35, 12, 35, 478, 9, 35, 1, 35, 1, 35, 4, 35, 482, 8, 35, 11, 35, 12, 35, 483, 1, 35, 4, 35, 487, 8, 35, 11, 35, 12, 35, 488, 1, 35, 1, 35, 5, 35, 493, 8, 35, 10, 35, 12, 35, 496, 9, 35, 3, 35, 498, 8, 35, 1, 35, 1, 35, 1, 35, 1, 35, 4, 35, 504, 8, 35, 11, 35, 12, 35, 505, 1, 35, 1, 35, 3, 35, 510, 8, 35, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, 66, 1, 66, 1, 67, 1, 67, 1, 68, 1, 68, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 5, 72, 649, 8, 72, 10, 72, 12, 72, 652, 9, 72, 1, 72, 1, 72, 1, 72, 1, 72, 4, 72, 658, 8, 72, 11, 72, 12, 72, 659, 3, 72, 662, 8, 72, 1, 73, 1, 73, 1, 73, 1, 73, 5, 73, 668, 8, 73, 10, 73, 12, 73, 671, 9, 73, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 84, 1, 84, 1, 84, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 86, 4, 86, 733, 8, 86, 11, 86, 12, 86, 734, 1, 87, 4, 87, 738, 8, 87, 11, 87, 12, 87, 739, 1, 87, 1, 87, 3, 87, 744, 8, 87, 1, 88, 1, 88, 1, 89, 1, 89, 1, 89, 1, 89, 1, 90, 1, 90, 1, 90, 1, 90, 1, 91, 1, 91, 1, 91, 1, 91, 2, 372, 447, 0, 92, 4, 1, 6, 2, 8, 3, 10, 4, 12, 5, 14, 6, 16, 7, 18, 8, 20, 9, 22, 10, 24, 11, 26, 12, 28, 13, 30, 14, 32, 15, 34, 16, 36, 17, 38, 18, 40, 19, 42, 20, 44, 21, 46, 22, 48, 0, 50, 80, 52, 23, 54, 24, 56, 25, 58, 26, 60, 0, 62, 0, 64, 0, 66, 0, 68, 0, 70, 27, 72, 28, 74, 29, 76, 30, 78, 31, 80, 32, 82, 33, 84, 34, 86, 35, 88, 36, 90, 37, 92, 38, 94, 39, 96, 40, 98, 41, 100, 42, 102, 43, 104, 44, 106, 45, 108, 46, 110, 47, 112, 48, 114, 49, 116, 50, 118, 51, 120, 52, 122, 53, 124, 54, 126, 55, 128, 56, 130, 57, 132, 58, 134, 59, 136, 60, 138, 61, 140, 62, 142, 63, 144, 64, 146, 65, 148, 66, 150, 67, 152, 68, 154, 69, 156, 70, 158, 0, 160, 0, 162, 0, 164, 0, 166, 0, 168, 71, 170, 72, 172, 73, 174, 74, 176, 75, 178, 0, 180, 76, 182, 77, 184, 78, 186, 79, 4, 0, 1, 2, 3, 13, 6, 0, 9, 10, 13, 13, 32, 32, 47, 47, 91, 91, 93, 93, 2, 0, 10, 10, 13, 13, 3, 0, 9, 10, 13, 13, 32, 32, 1, 0, 48, 57, 2, 0, 65, 90, 97, 122, 5, 0, 34, 34, 92, 92, 110, 110, 114, 114, 116, 116, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 2, 0, 64, 64, 95, 95, 1, 0, 96, 96, 10, 0, 9, 10, 13, 13, 32, 32, 44, 44, 47, 47, 61, 61, 91, 91, 93, 93, 96, 96, 124, 124, 2, 0, 42, 42, 47, 47, 787, 0, 4, 1, 0, 0, 0, 0, 6, 1, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, 10, 1, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 14, 1, 0, 0, 0, 0, 16, 1, 0, 0, 0, 0, 18, 1, 0, 0, 0, 0, 20, 1, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 24, 1, 0, 0, 0, 0, 26, 1, 0, 0, 0, 0, 28, 1, 0, 0, 0, 0, 30, 1, 0, 0, 0, 0, 32, 1, 0, 0, 0, 0, 34, 1, 0, 0, 0, 0, 36, 1, 0, 0, 0, 0, 38, 1, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 42, 1, 0, 0, 0, 0, 44, 1, 0, 0, 0, 0, 46, 1, 0, 0, 0, 1, 48, 1, 0, 0, 0, 1, 50, 1, 0, 0, 0, 1, 52, 1, 0, 0, 0, 1, 54, 1, 0, 0, 0, 1, 56, 1, 0, 0, 0, 2, 58, 1, 0, 0, 0, 2, 70, 1, 0, 0, 0, 2, 72, 1, 0, 0, 0, 2, 74, 1, 0, 0, 0, 2, 76, 1, 0, 0, 0, 2, 78, 1, 0, 0, 0, 2, 80, 1, 0, 0, 0, 2, 82, 1, 0, 0, 0, 2, 84, 1, 0, 0, 0, 2, 86, 1, 0, 0, 0, 2, 88, 1, 0, 0, 0, 2, 90, 1, 0, 0, 0, 2, 92, 1, 0, 0, 0, 2, 94, 1, 0, 0, 0, 2, 96, 1, 0, 0, 0, 2, 98, 1, 0, 0, 0, 2, 100, 1, 0, 0, 0, 2, 102, 1, 0, 0, 0, 2, 104, 1, 0, 0, 0, 2, 106, 1, 0, 0, 0, 2, 108, 1, 0, 0, 0, 2, 110, 1, 0, 0, 0, 2, 112, 1, 0, 0, 0, 2, 114, 1, 0, 0, 0, 2, 116, 1, 0, 0, 0, 2, 118, 1, 0, 0, 0, 2, 120, 1, 0, 0, 0, 2, 122, 1, 0, 0, 0, 2, 124, 1, 0, 0, 0, 2, 126, 1, 0, 0, 0, 2, 128, 1, 0, 0, 0, 2, 130, 1, 0, 0, 0, 2, 132, 1, 0, 0, 0, 2, 134, 1, 0, 0, 0, 2, 136, 1, 0, 0, 0, 2, 138, 1, 0, 0, 0, 2, 140, 1, 0, 0, 0, 2, 142, 1, 0, 0, 0, 2, 144, 1, 0, 0, 0, 2, 146, 1, 0, 0, 0, 2, 148, 1, 0, 0, 0, 2, 150, 1, 0, 0, 0, 2, 152, 1, 0, 0, 0, 2, 154, 1, 0, 0, 0, 2, 156, 1, 0, 0, 0, 3, 158, 1, 0, 0, 0, 3, 160, 1, 0, 0, 0, 3, 162, 1, 0, 0, 0, 3, 164, 1, 0, 0, 0, 3, 166, 1, 0, 0, 0, 3, 168, 1, 0, 0, 0, 3, 170, 1, 0, 0, 0, 3, 172, 1, 0, 0, 0, 3, 174, 1, 0, 0, 0, 3, 176, 1, 0, 0, 0, 3, 180, 1, 0, 0, 0, 3, 182, 1, 0, 0, 0, 3, 184, 1, 0, 0, 0, 3, 186, 1, 0, 0, 0, 4, 188, 1, 0, 0, 0, 6, 198, 1, 0, 0, 0, 8, 205, 1, 0, 0, 0, 10, 214, 1, 0, 0, 0, 12, 221, 1, 0, 0, 0, 14, 231, 1, 0, 0, 0, 16, 238, 1, 0, 0, 0, 18, 245, 1, 0, 0, 0, 20, 259, 1, 0, 0, 0, 22, 266, 1, 0, 0, 0, 24, 274, 1, 0, 0, 0, 26, 286, 1, 0, 0, 0, 28, 296, 1, 0, 0, 0, 30, 305, 1, 0, 0, 0, 32, 311, 1, 0, 0, 0, 34, 318, 1, 0, 0, 0, 36, 325, 1, 0, 0, 0, 38, 333, 1, 0, 0, 0, 40, 342, 1, 0, 0, 0, 42, 348, 1, 0, 0, 0, 44, 365, 1, 0, 0, 0, 46, 381, 1, 0, 0, 0, 48, 387, 1, 0, 0, 0, 50, 392, 1, 0, 0, 0, 52, 397, 1, 0, 0, 0, 54, 401, 1, 0, 0, 0, 56, 405, 1, 0, 0, 0, 58, 409, 1, 0, 0, 0, 60, 413, 1, 0, 0, 0, 62, 415, 1, 0, 0, 0, 64, 417, 1, 0, 0, 0, 66, 420, 1, 0, 0, 0, 68, 422, 1, 0, 0, 0, 70, 460, 1, 0, 0, 0, 72, 463, 1, 0, 0, 0, 74, 509, 1, 0, 0, 0, 76, 511, 1, 0, 0, 0, 78, 514, 1, 0, 0, 0, 80, 518, 1, 0, 0, 0, 82, 522, 1, 0, 0, 0, 84, 524, 1, 0, 0, 0, 86, 526, 1, 0, 0, 0, 88, 531, 1, 0, 0, 0, 90, 533, 1, 0, 0, 0, 92, 539, 1, 0, 0, 0, 94, 545, 1, 0, 0, 0, 96, 550, 1, 0, 0, 0, 98, 552, 1, 0, 0, 0, 100, 555, 1, 0, 0, 0, 102, 560, 1, 0, 0, 0, 104, 564, 1, 0, 0, 0, 106, 569, 1, 0, 0, 0, 108, 575, 1, 0, 0, 0, 110, 578, 1, 0, 0, 0, 112, 580, 1, 0, 0, 0, 114, 586, 1, 0, 0, 0, 116, 588, 1, 0, 0, 0, 118, 593, 1, 0, 0, 0, 120, 598, 1, 0, 0, 0, 122, 608, 1, 0, 0, 0, 124, 611, 1, 0, 0, 0, 126, 614, 1, 0, 0, 0, 128, 616, 1, 0, 0, 0, 130, 619, 1, 0, 0, 0, 132, 621, 1, 0, 0, 0, 134, 624, 1, 0, 0, 0, 136, 626, 1, 0, 0, 0, 138, 628, 1, 0, 0, 0, 140, 630, 1, 0, 0, 0, 142, 632, 1, 0, 0, 0, 144, 634, 1, 0, 0, 0, 146, 639, 1, 0, 0, 0, 148, 661, 1, 0, 0, 0, 150, 663, 1, 0, 0, 0, 152, 674, 1, 0, 0, 0, 154, 678, 1, 0, 0, 0, 156, 682, 1, 0, 0, 0, 158, 686, 1, 0, 0, 0, 160, 691, 1, 0, 0, 0, 162, 697, 1, 0, 0, 0, 164, 703, 1, 0, 0, 0, 166, 707, 1, 0, 0, 0, 168, 711, 1, 0, 0, 0, 170, 714, 1, 0, 0, 0, 172, 723, 1, 0, 0, 0, 174, 726, 1, 0, 0, 0, 176, 732, 1, 0, 0, 0, 178, 743, 1, 0, 0, 0, 180, 745, 1, 0, 0, 0, 182, 747, 1, 0, 0, 0, 184, 751, 1, 0, 0, 0, 186, 755, 1, 0, 0, 0, 188, 189, 5, 100, 0, 0, 189, 190, 5, 105, 0, 0, 190, 191, 5, 115, 0, 0, 191, 192, 5, 115, 0, 0, 192, 193, 5, 101, 0, 0, 193, 194, 5, 99, 0, 0, 194, 195, 5, 116, 0, 0, 195, 196, 1, 0, 0, 0, 196, 197, 6, 0, 0, 0, 197, 5, 1, 0, 0, 0, 198, 199, 5, 100, 0, 0, 199, 200, 5, 114, 0, 0, 200, 201, 5, 111, 0, 0, 201, 202, 5, 112, 0, 0, 202, 203, 1, 0, 0, 0, 203, 204, 6, 1, 1, 0, 204, 7, 1, 0, 0, 0, 205, 206, 5, 101, 0, 0, 206, 207, 5, 110, 0, 0, 207, 208, 5, 114, 0, 0, 208, 209, 5, 105, 0, 0, 209, 210, 5, 99, 0, 0, 210, 211, 5, 104, 0, 0, 211, 212, 1, 0, 0, 0, 212, 213, 6, 2, 1, 0, 213, 9, 1, 0, 0, 0, 214, 215, 5, 101, 0, 0, 215, 216, 5, 118, 0, 0, 216, 217, 5, 97, 0, 0, 217, 218, 5, 108, 0, 0, 218, 219, 1, 0, 0, 0, 219, 220, 6, 3, 0, 0, 220, 11, 1, 0, 0, 0, 221, 222, 5, 101, 0, 0, 222, 223, 5, 120, 0, 0, 223, 224, 5, 112, 0, 0, 224, 225, 5, 108, 0, 0, 225, 226, 5, 97, 0, 0, 226, 227, 5, 105, 0, 0, 227, 228, 5, 110, 0, 0, 228, 229, 1, 0, 0, 0, 229, 230, 6, 4, 2, 0, 230, 13, 1, 0, 0, 0, 231, 232, 5, 102, 0, 0, 232, 233, 5, 114, 0, 0, 233, 234, 5, 111, 0, 0, 234, 235, 5, 109, 0, 0, 235, 236, 1, 0, 0, 0, 236, 237, 6, 5, 1, 0, 237, 15, 1, 0, 0, 0, 238, 239, 5, 103, 0, 0, 239, 240, 5, 114, 0, 0, 240, 241, 5, 111, 0, 0, 241, 242, 5, 107, 0, 0, 242, 243, 1, 0, 0, 0, 243, 244, 6, 6, 0, 0, 244, 17, 1, 0, 0, 0, 245, 246, 5, 105, 0, 0, 246, 247, 5, 110, 0, 0, 247, 248, 5, 108, 0, 0, 248, 249, 5, 105, 0, 0, 249, 250, 5, 110, 0, 0, 250, 251, 5, 101, 0, 0, 251, 252, 5, 115, 0, 0, 252, 253, 5, 116, 0, 0, 253, 254, 5, 97, 0, 0, 254, 255, 5, 116, 0, 0, 255, 256, 5, 115, 0, 0, 256, 257, 1, 0, 0, 0, 257, 258, 6, 7, 0, 0, 258, 19, 1, 0, 0, 0, 259, 260, 5, 107, 0, 0, 260, 261, 5, 101, 0, 0, 261, 262, 5, 101, 0, 0, 262, 263, 5, 112, 0, 0, 263, 264, 1, 0, 0, 0, 264, 265, 6, 8, 1, 0, 265, 21, 1, 0, 0, 0, 266, 267, 5, 108, 0, 0, 267, 268, 5, 105, 0, 0, 268, 269, 5, 109, 0, 0, 269, 270, 5, 105, 0, 0, 270, 271, 5, 116, 0, 0, 271, 272, 1, 0, 0, 0, 272, 273, 6, 9, 0, 0, 273, 23, 1, 0, 0, 0, 274, 275, 5, 109, 0, 0, 275, 276, 5, 118, 0, 0, 276, 277, 5, 95, 0, 0, 277, 278, 5, 101, 0, 0, 278, 279, 5, 120, 0, 0, 279, 280, 5, 112, 0, 0, 280, 281, 5, 97, 0, 0, 281, 282, 5, 110, 0, 0, 282, 283, 5, 100, 0, 0, 283, 284, 1, 0, 0, 0, 284, 285, 6, 10, 1, 0, 285, 25, 1, 0, 0, 0, 286, 287, 5, 112, 0, 0, 287, 288, 5, 114, 0, 0, 288, 289, 5, 111, 0, 0, 289, 290, 5, 106, 0, 0, 290, 291, 5, 101, 0, 0, 291, 292, 5, 99, 0, 0, 292, 293, 5, 116, 0, 0, 293, 294, 1, 0, 0, 0, 294, 295, 6, 11, 1, 0, 295, 27, 1, 0, 0, 0, 296, 297, 5, 114, 0, 0, 297, 298, 5, 101, 0, 0, 298, 299, 5, 110, 0, 0, 299, 300, 5, 97, 0, 0, 300, 301, 5, 109, 0, 0, 301, 302, 5, 101, 0, 0, 302, 303, 1, 0, 0, 0, 303, 304, 6, 12, 1, 0, 304, 29, 1, 0, 0, 0, 305, 306, 5, 114, 0, 0, 306, 307, 5, 111, 0, 0, 307, 308, 5, 119, 0, 0, 308, 309, 1, 0, 0, 0, 309, 310, 6, 13, 0, 0, 310, 31, 1, 0, 0, 0, 311, 312, 5, 115, 0, 0, 312, 313, 5, 104, 0, 0, 313, 314, 5, 111, 0, 0, 314, 315, 5, 119, 0, 0, 315, 316, 1, 0, 0, 0, 316, 317, 6, 14, 0, 0, 317, 33, 1, 0, 0, 0, 318, 319, 5, 115, 0, 0, 319, 320, 5, 111, 0, 0, 320, 321, 5, 114, 0, 0, 321, 322, 5, 116, 0, 0, 322, 323, 1, 0, 0, 0, 323, 324, 6, 15, 0, 0, 324, 35, 1, 0, 0, 0, 325, 326, 5, 115, 0, 0, 326, 327, 5, 116, 0, 0, 327, 328, 5, 97, 0, 0, 328, 329, 5, 116, 0, 0, 329, 330, 5, 115, 0, 0, 330, 331, 1, 0, 0, 0, 331, 332, 6, 16, 0, 0, 332, 37, 1, 0, 0, 0, 333, 334, 5, 119, 0, 0, 334, 335, 5, 104, 0, 0, 335, 336, 5, 101, 0, 0, 336, 337, 5, 114, 0, 0, 337, 338, 5, 101, 0, 0, 338, 339, 1, 0, 0, 0, 339, 340, 6, 17, 0, 0, 340, 39, 1, 0, 0, 0, 341, 343, 8, 0, 0, 0, 342, 341, 1, 0, 0, 0, 343, 344, 1, 0, 0, 0, 344, 342, 1, 0, 0, 0, 344, 345, 1, 0, 0, 0, 345, 346, 1, 0, 0, 0, 346, 347, 6, 18, 0, 0, 347, 41, 1, 0, 0, 0, 348, 349, 5, 47, 0, 0, 349, 350, 5, 47, 0, 0, 350, 354, 1, 0, 0, 0, 351, 353, 8, 1, 0, 0, 352, 351, 1, 0, 0, 0, 353, 356, 1, 0, 0, 0, 354, 352, 1, 0, 0, 0, 354, 355, 1, 0, 0, 0, 355, 358, 1, 0, 0, 0, 356, 354, 1, 0, 0, 0, 357, 359, 5, 13, 0, 0, 358, 357, 1, 0, 0, 0, 358, 359, 1, 0, 0, 0, 359, 361, 1, 0, 0, 0, 360, 362, 5, 10, 0, 0, 361, 360, 1, 0, 0, 0, 361, 362, 1, 0, 0, 0, 362, 363, 1, 0, 0, 0, 363, 364, 6, 19, 3, 0, 364, 43, 1, 0, 0, 0, 365, 366, 5, 47, 0, 0, 366, 367, 5, 42, 0, 0, 367, 372, 1, 0, 0, 0, 368, 371, 3, 44, 20, 0, 369, 371, 9, 0, 0, 0, 370, 368, 1, 0, 0, 0, 370, 369, 1, 0, 0, 0, 371, 374, 1, 0, 0, 0, 372, 373, 1, 0, 0, 0, 372, 370, 1, 0, 0, 0, 373, 375, 1, 0, 0, 0, 374, 372, 1, 0, 0, 0, 375, 376, 5, 42, 0, 0, 376, 377, 5, 47, 0, 0, 377, 378, 1, 0, 0, 0, 378, 379, 6, 20, 3, 0, 379, 45, 1, 0, 0, 0, 380, 382, 7, 2, 0, 0, 381, 380, 1, 0, 0, 0, 382, 383, 1, 0, 0, 0, 383, 381, 1, 0, 0, 0, 383, 384, 1, 0, 0, 0, 384, 385, 1, 0, 0, 0, 385, 386, 6, 21, 3, 0, 386, 47, 1, 0, 0, 0, 387, 388, 5, 91, 0, 0, 388, 389, 1, 0, 0, 0, 389, 390, 6, 22, 4, 0, 390, 391, 6, 22, 5, 0, 391, 49, 1, 0, 0, 0, 392, 393, 5, 124, 0, 0, 393, 394, 1, 0, 0, 0, 394, 395, 6, 23, 6, 0, 395, 396, 6, 23, 7, 0, 396, 51, 1, 0, 0, 0, 397, 398, 3, 46, 21, 0, 398, 399, 1, 0, 0, 0, 399, 400, 6, 24, 3, 0, 400, 53, 1, 0, 0, 0, 401, 402, 3, 42, 19, 0, 402, 403, 1, 0, 0, 0, 403, 404, 6, 25, 3, 0, 404, 55, 1, 0, 0, 0, 405, 406, 3, 44, 20, 0, 406, 407, 1, 0, 0, 0, 407, 408, 6, 26, 3, 0, 408, 57, 1, 0, 0, 0, 409, 410, 5, 124, 0, 0, 410, 411, 1, 0, 0, 0, 411, 412, 6, 27, 7, 0, 412, 59, 1, 0, 0, 0, 413, 414, 7, 3, 0, 0, 414, 61, 1, 0, 0, 0, 415, 416, 7, 4, 0, 0, 416, 63, 1, 0, 0, 0, 417, 418, 5, 92, 0, 0, 418, 419, 7, 5, 0, 0, 419, 65, 1, 0, 0, 0, 420, 421, 8, 6, 0, 0, 421, 67, 1, 0, 0, 0, 422, 424, 7, 7, 0, 0, 423, 425, 7, 8, 0, 0, 424, 423, 1, 0, 0, 0, 424, 425, 1, 0, 0, 0, 425, 427, 1, 0, 0, 0, 426, 428, 3, 60, 28, 0, 427, 426, 1, 0, 0, 0, 428, 429, 1, 0, 0, 0, 429, 427, 1, 0, 0, 0, 429, 430, 1, 0, 0, 0, 430, 69, 1, 0, 0, 0, 431, 436, 5, 34, 0, 0, 432, 435, 3, 64, 30, 0, 433, 435, 3, 66, 31, 0, 434, 432, 1, 0, 0, 0, 434, 433, 1, 0, 0, 0, 435, 438, 1, 0, 0, 0, 436, 434, 1, 0, 0, 0, 436, 437, 1, 0, 0, 0, 437, 439, 1, 0, 0, 0, 438, 436, 1, 0, 0, 0, 439, 461, 5, 34, 0, 0, 440, 441, 5, 34, 0, 0, 441, 442, 5, 34, 0, 0, 442, 443, 5, 34, 0, 0, 443, 447, 1, 0, 0, 0, 444, 446, 8, 1, 0, 0, 445, 444, 1, 0, 0, 0, 446, 449, 1, 0, 0, 0, 447, 448, 1, 0, 0, 0, 447, 445, 1, 0, 0, 0, 448, 450, 1, 0, 0, 0, 449, 447, 1, 0, 0, 0, 450, 451, 5, 34, 0, 0, 451, 452, 5, 34, 0, 0, 452, 453, 5, 34, 0, 0, 453, 455, 1, 0, 0, 0, 454, 456, 5, 34, 0, 0, 455, 454, 1, 0, 0, 0, 455, 456, 1, 0, 0, 0, 456, 458, 1, 0, 0, 0, 457, 459, 5, 34, 0, 0, 458, 457, 1, 0, 0, 0, 458, 459, 1, 0, 0, 0, 459, 461, 1, 0, 0, 0, 460, 431, 1, 0, 0, 0, 460, 440, 1, 0, 0, 0, 461, 71, 1, 0, 0, 0, 462, 464, 3, 60, 28, 0, 463, 462, 1, 0, 0, 0, 464, 465, 1, 0, 0, 0, 465, 463, 1, 0, 0, 0, 465, 466, 1, 0, 0, 0, 466, 73, 1, 0, 0, 0, 467, 469, 3, 60, 28, 0, 468, 467, 1, 0, 0, 0, 469, 470, 1, 0, 0, 0, 470, 468, 1, 0, 0, 0, 470, 471, 1, 0, 0, 0, 471, 472, 1, 0, 0, 0, 472, 476, 3, 88, 42, 0, 473, 475, 3, 60, 28, 0, 474, 473, 1, 0, 0, 0, 475, 478, 1, 0, 0, 0, 476, 474, 1, 0, 0, 0, 476, 477, 1, 0, 0, 0, 477, 510, 1, 0, 0, 0, 478, 476, 1, 0, 0, 0, 479, 481, 3, 88, 42, 0, 480, 482, 3, 60, 28, 0, 481, 480, 1, 0, 0, 0, 482, 483, 1, 0, 0, 0, 483, 481, 1, 0, 0, 0, 483, 484, 1, 0, 0, 0, 484, 510, 1, 0, 0, 0, 485, 487, 3, 60, 28, 0, 486, 485, 1, 0, 0, 0, 487, 488, 1, 0, 0, 0, 488, 486, 1, 0, 0, 0, 488, 489, 1, 0, 0, 0, 489, 497, 1, 0, 0, 0, 490, 494, 3, 88, 42, 0, 491, 493, 3, 60, 28, 0, 492, 491, 1, 0, 0, 0, 493, 496, 1, 0, 0, 0, 494, 492, 1, 0, 0, 0, 494, 495, 1, 0, 0, 0, 495, 498, 1, 0, 0, 0, 496, 494, 1, 0, 0, 0, 497, 490, 1, 0, 0, 0, 497, 498, 1, 0, 0, 0, 498, 499, 1, 0, 0, 0, 499, 500, 3, 68, 32, 0, 500, 510, 1, 0, 0, 0, 501, 503, 3, 88, 42, 0, 502, 504, 3, 60, 28, 0, 503, 502, 1, 0, 0, 0, 504, 505, 1, 0, 0, 0, 505, 503, 1, 0, 0, 0, 505, 506, 1, 0, 0, 0, 506, 507, 1, 0, 0, 0, 507, 508, 3, 68, 32, 0, 508, 510, 1, 0, 0, 0, 509, 468, 1, 0, 0, 0, 509, 479, 1, 0, 0, 0, 509, 486, 1, 0, 0, 0, 509, 501, 1, 0, 0, 0, 510, 75, 1, 0, 0, 0, 511, 512, 5, 98, 0, 0, 512, 513, 5, 121, 0, 0, 513, 77, 1, 0, 0, 0, 514, 515, 5, 97, 0, 0, 515, 516, 5, 110, 0, 0, 516, 517, 5, 100, 0, 0, 517, 79, 1, 0, 0, 0, 518, 519, 5, 97, 0, 0, 519, 520, 5, 115, 0, 0, 520, 521, 5, 99, 0, 0, 521, 81, 1, 0, 0, 0, 522, 523, 5, 61, 0, 0, 523, 83, 1, 0, 0, 0, 524, 525, 5, 44, 0, 0, 525, 85, 1, 0, 0, 0, 526, 527, 5, 100, 0, 0, 527, 528, 5, 101, 0, 0, 528, 529, 5, 115, 0, 0, 529, 530, 5, 99, 0, 0, 530, 87, 1, 0, 0, 0, 531, 532, 5, 46, 0, 0, 532, 89, 1, 0, 0, 0, 533, 534, 5, 102, 0, 0, 534, 535, 5, 97, 0, 0, 535, 536, 5, 108, 0, 0, 536, 537, 5, 115, 0, 0, 537, 538, 5, 101, 0, 0, 538, 91, 1, 0, 0, 0, 539, 540, 5, 102, 0, 0, 540, 541, 5, 105, 0, 0, 541, 542, 5, 114, 0, 0, 542, 543, 5, 115, 0, 0, 543, 544, 5, 116, 0, 0, 544, 93, 1, 0, 0, 0, 545, 546, 5, 108, 0, 0, 546, 547, 5, 97, 0, 0, 547, 548, 5, 115, 0, 0, 548, 549, 5, 116, 0, 0, 549, 95, 1, 0, 0, 0, 550, 551, 5, 40, 0, 0, 551, 97, 1, 0, 0, 0, 552, 553, 5, 105, 0, 0, 553, 554, 5, 110, 0, 0, 554, 99, 1, 0, 0, 0, 555, 556, 5, 108, 0, 0, 556, 557, 5, 105, 0, 0, 557, 558, 5, 107, 0, 0, 558, 559, 5, 101, 0, 0, 559, 101, 1, 0, 0, 0, 560, 561, 5, 110, 0, 0, 561, 562, 5, 111, 0, 0, 562, 563, 5, 116, 0, 0, 563, 103, 1, 0, 0, 0, 564, 565, 5, 110, 0, 0, 565, 566, 5, 117, 0, 0, 566, 567, 5, 108, 0, 0, 567, 568, 5, 108, 0, 0, 568, 105, 1, 0, 0, 0, 569, 570, 5, 110, 0, 0, 570, 571, 5, 117, 0, 0, 571, 572, 5, 108, 0, 0, 572, 573, 5, 108, 0, 0, 573, 574, 5, 115, 0, 0, 574, 107, 1, 0, 0, 0, 575, 576, 5, 111, 0, 0, 576, 577, 5, 114, 0, 0, 577, 109, 1, 0, 0, 0, 578, 579, 5, 63, 0, 0, 579, 111, 1, 0, 0, 0, 580, 581, 5, 114, 0, 0, 581, 582, 5, 108, 0, 0, 582, 583, 5, 105, 0, 0, 583, 584, 5, 107, 0, 0, 584, 585, 5, 101, 0, 0, 585, 113, 1, 0, 0, 0, 586, 587, 5, 41, 0, 0, 587, 115, 1, 0, 0, 0, 588, 589, 5, 116, 0, 0, 589, 590, 5, 114, 0, 0, 590, 591, 5, 117, 0, 0, 591, 592, 5, 101, 0, 0, 592, 117, 1, 0, 0, 0, 593, 594, 5, 105, 0, 0, 594, 595, 5, 110, 0, 0, 595, 596, 5, 102, 0, 0, 596, 597, 5, 111, 0, 0, 597, 119, 1, 0, 0, 0, 598, 599, 5, 102, 0, 0, 599, 600, 5, 117, 0, 0, 600, 601, 5, 110, 0, 0, 601, 602, 5, 99, 0, 0, 602, 603, 5, 116, 0, 0, 603, 604, 5, 105, 0, 0, 604, 605, 5, 111, 0, 0, 605, 606, 5, 110, 0, 0, 606, 607, 5, 115, 0, 0, 607, 121, 1, 0, 0, 0, 608, 609, 5, 61, 0, 0, 609, 610, 5, 61, 0, 0, 610, 123, 1, 0, 0, 0, 611, 612, 5, 33, 0, 0, 612, 613, 5, 61, 0, 0, 613, 125, 1, 0, 0, 0, 614, 615, 5, 60, 0, 0, 615, 127, 1, 0, 0, 0, 616, 617, 5, 60, 0, 0, 617, 618, 5, 61, 0, 0, 618, 129, 1, 0, 0, 0, 619, 620, 5, 62, 0, 0, 620, 131, 1, 0, 0, 0, 621, 622, 5, 62, 0, 0, 622, 623, 5, 61, 0, 0, 623, 133, 1, 0, 0, 0, 624, 625, 5, 43, 0, 0, 625, 135, 1, 0, 0, 0, 626, 627, 5, 45, 0, 0, 627, 137, 1, 0, 0, 0, 628, 629, 5, 42, 0, 0, 629, 139, 1, 0, 0, 0, 630, 631, 5, 47, 0, 0, 631, 141, 1, 0, 0, 0, 632, 633, 5, 37, 0, 0, 633, 143, 1, 0, 0, 0, 634, 635, 5, 91, 0, 0, 635, 636, 1, 0, 0, 0, 636, 637, 6, 70, 0, 0, 637, 638, 6, 70, 0, 0, 638, 145, 1, 0, 0, 0, 639, 640, 5, 93, 0, 0, 640, 641, 1, 0, 0, 0, 641, 642, 6, 71, 7, 0, 642, 643, 6, 71, 7, 0, 643, 147, 1, 0, 0, 0, 644, 650, 3, 62, 29, 0, 645, 649, 3, 62, 29, 0, 646, 649, 3, 60, 28, 0, 647, 649, 5, 95, 0, 0, 648, 645, 1, 0, 0, 0, 648, 646, 1, 0, 0, 0, 648, 647, 1, 0, 0, 0, 649, 652, 1, 0, 0, 0, 650, 648, 1, 0, 0, 0, 650, 651, 1, 0, 0, 0, 651, 662, 1, 0, 0, 0, 652, 650, 1, 0, 0, 0, 653, 657, 7, 9, 0, 0, 654, 658, 3, 62, 29, 0, 655, 658, 3, 60, 28, 0, 656, 658, 5, 95, 0, 0, 657, 654, 1, 0, 0, 0, 657, 655, 1, 0, 0, 0, 657, 656, 1, 0, 0, 0, 658, 659, 1, 0, 0, 0, 659, 657, 1, 0, 0, 0, 659, 660, 1, 0, 0, 0, 660, 662, 1, 0, 0, 0, 661, 644, 1, 0, 0, 0, 661, 653, 1, 0, 0, 0, 662, 149, 1, 0, 0, 0, 663, 669, 5, 96, 0, 0, 664, 668, 8, 10, 0, 0, 665, 666, 5, 96, 0, 0, 666, 668, 5, 96, 0, 0, 667, 664, 1, 0, 0, 0, 667, 665, 1, 0, 0, 0, 668, 671, 1, 0, 0, 0, 669, 667, 1, 0, 0, 0, 669, 670, 1, 0, 0, 0, 670, 672, 1, 0, 0, 0, 671, 669, 1, 0, 0, 0, 672, 673, 5, 96, 0, 0, 673, 151, 1, 0, 0, 0, 674, 675, 3, 42, 19, 0, 675, 676, 1, 0, 0, 0, 676, 677, 6, 74, 3, 0, 677, 153, 1, 0, 0, 0, 678, 679, 3, 44, 20, 0, 679, 680, 1, 0, 0, 0, 680, 681, 6, 75, 3, 0, 681, 155, 1, 0, 0, 0, 682, 683, 3, 46, 21, 0, 683, 684, 1, 0, 0, 0, 684, 685, 6, 76, 3, 0, 685, 157, 1, 0, 0, 0, 686, 687, 5, 124, 0, 0, 687, 688, 1, 0, 0, 0, 688, 689, 6, 77, 6, 0, 689, 690, 6, 77, 7, 0, 690, 159, 1, 0, 0, 0, 691, 692, 5, 91, 0, 0, 692, 693, 1, 0, 0, 0, 693, 694, 6, 78, 4, 0, 694, 695, 6, 78, 1, 0, 695, 696, 6, 78, 1, 0, 696, 161, 1, 0, 0, 0, 697, 698, 5, 93, 0, 0, 698, 699, 1, 0, 0, 0, 699, 700, 6, 79, 7, 0, 700, 701, 6, 79, 7, 0, 701, 702, 6, 79, 8, 0, 702, 163, 1, 0, 0, 0, 703, 704, 5, 44, 0, 0, 704, 705, 1, 0, 0, 0, 705, 706, 6, 80, 9, 0, 706, 165, 1, 0, 0, 0, 707, 708, 5, 61, 0, 0, 708, 709, 1, 0, 0, 0, 709, 710, 6, 81, 10, 0, 710, 167, 1, 0, 0, 0, 711, 712, 5, 97, 0, 0, 712, 713, 5, 115, 0, 0, 713, 169, 1, 0, 0, 0, 714, 715, 5, 109, 0, 0, 715, 716, 5, 101, 0, 0, 716, 717, 5, 116, 0, 0, 717, 718, 5, 97, 0, 0, 718, 719, 5, 100, 0, 0, 719, 720, 5, 97, 0, 0, 720, 721, 5, 116, 0, 0, 721, 722, 5, 97, 0, 0, 722, 171, 1, 0, 0, 0, 723, 724, 5, 111, 0, 0, 724, 725, 5, 110, 0, 0, 725, 173, 1, 0, 0, 0, 726, 727, 5, 119, 0, 0, 727, 728, 5, 105, 0, 0, 728, 729, 5, 116, 0, 0, 729, 730, 5, 104, 0, 0, 730, 175, 1, 0, 0, 0, 731, 733, 3, 178, 87, 0, 732, 731, 1, 0, 0, 0, 733, 734, 1, 0, 0, 0, 734, 732, 1, 0, 0, 0, 734, 735, 1, 0, 0, 0, 735, 177, 1, 0, 0, 0, 736, 738, 8, 11, 0, 0, 737, 736, 1, 0, 0, 0, 738, 739, 1, 0, 0, 0, 739, 737, 1, 0, 0, 0, 739, 740, 1, 0, 0, 0, 740, 744, 1, 0, 0, 0, 741, 742, 5, 47, 0, 0, 742, 744, 8, 12, 0, 0, 743, 737, 1, 0, 0, 0, 743, 741, 1, 0, 0, 0, 744, 179, 1, 0, 0, 0, 745, 746, 3, 150, 73, 0, 746, 181, 1, 0, 0, 0, 747, 748, 3, 42, 19, 0, 748, 749, 1, 0, 0, 0, 749, 750, 6, 89, 3, 0, 750, 183, 1, 0, 0, 0, 751, 752, 3, 44, 20, 0, 752, 753, 1, 0, 0, 0, 753, 754, 6, 90, 3, 0, 754, 185, 1, 0, 0, 0, 755, 756, 3, 46, 21, 0, 756, 757, 1, 0, 0, 0, 757, 758, 6, 91, 3, 0, 758, 187, 1, 0, 0, 0, 38, 0, 1, 2, 3, 344, 354, 358, 361, 370, 372, 383, 424, 429, 434, 436, 447, 455, 458, 460, 465, 470, 476, 483, 488, 494, 497, 505, 509, 648, 650, 657, 659, 661, 667, 669, 734, 739, 743, 11, 5, 2, 0, 5, 3, 0, 5, 1, 0, 0, 1, 0, 7, 64, 0, 5, 0, 0, 7, 26, 0, 4, 0, 0, 7, 65, 0, 7, 34, 0, 7, 33, 0]
\ No newline at end of file
+[4, 0, 81, 764, 6, -1, 6, -1, 6, -1, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 4, 18, 345, 8, 18, 11, 18, 12, 18, 346, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 5, 19, 355, 8, 19, 10, 19, 12, 19, 358, 9, 19, 1, 19, 3, 19, 361, 8, 19, 1, 19, 3, 19, 364, 8, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 5, 20, 373, 8, 20, 10, 20, 12, 20, 376, 9, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 4, 21, 384, 8, 21, 11, 21, 12, 21, 385, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 32, 1, 32, 3, 32, 427, 8, 32, 1, 32, 4, 32, 430, 8, 32, 11, 32, 12, 32, 431, 1, 33, 1, 33, 1, 33, 5, 33, 437, 8, 33, 10, 33, 12, 33, 440, 9, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 5, 33, 448, 8, 33, 10, 33, 12, 33, 451, 9, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 3, 33, 458, 8, 33, 1, 33, 3, 33, 461, 8, 33, 3, 33, 463, 8, 33, 1, 34, 4, 34, 466, 8, 34, 11, 34, 12, 34, 467, 1, 35, 4, 35, 471, 8, 35, 11, 35, 12, 35, 472, 1, 35, 1, 35, 5, 35, 477, 8, 35, 10, 35, 12, 35, 480, 9, 35, 1, 35, 1, 35, 4, 35, 484, 8, 35, 11, 35, 12, 35, 485, 1, 35, 4, 35, 489, 8, 35, 11, 35, 12, 35, 490, 1, 35, 1, 35, 5, 35, 495, 8, 35, 10, 35, 12, 35, 498, 9, 35, 3, 35, 500, 8, 35, 1, 35, 1, 35, 1, 35, 1, 35, 4, 35, 506, 8, 35, 11, 35, 12, 35, 507, 1, 35, 1, 35, 3, 35, 512, 8, 35, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 67, 1, 67, 1, 68, 1, 68, 1, 69, 1, 69, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 1, 73, 5, 73, 654, 8, 73, 10, 73, 12, 73, 657, 9, 73, 1, 73, 1, 73, 1, 73, 1, 73, 4, 73, 663, 8, 73, 11, 73, 12, 73, 664, 3, 73, 667, 8, 73, 1, 74, 1, 74, 1, 74, 1, 74, 5, 74, 673, 8, 74, 10, 74, 12, 74, 676, 9, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 1, 77, 1, 77, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83, 1, 83, 1, 83, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 85, 1, 85, 1, 85, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 87, 4, 87, 738, 8, 87, 11, 87, 12, 87, 739, 1, 88, 4, 88, 743, 8, 88, 11, 88, 12, 88, 744, 1, 88, 1, 88, 3, 88, 749, 8, 88, 1, 89, 1, 89, 1, 90, 1, 90, 1, 90, 1, 90, 1, 91, 1, 91, 1, 91, 1, 91, 1, 92, 1, 92, 1, 92, 1, 92, 2, 374, 449, 0, 93, 4, 1, 6, 2, 8, 3, 10, 4, 12, 5, 14, 6, 16, 7, 18, 8, 20, 9, 22, 10, 24, 11, 26, 12, 28, 13, 30, 14, 32, 15, 34, 16, 36, 17, 38, 18, 40, 19, 42, 20, 44, 21, 46, 22, 48, 0, 50, 81, 52, 23, 54, 24, 56, 25, 58, 26, 60, 0, 62, 0, 64, 0, 66, 0, 68, 0, 70, 27, 72, 28, 74, 29, 76, 30, 78, 31, 80, 32, 82, 33, 84, 34, 86, 35, 88, 36, 90, 37, 92, 38, 94, 39, 96, 40, 98, 41, 100, 42, 102, 43, 104, 44, 106, 45, 108, 46, 110, 47, 112, 48, 114, 49, 116, 50, 118, 51, 120, 52, 122, 53, 124, 54, 126, 55, 128, 56, 130, 57, 132, 58, 134, 59, 136, 60, 138, 61, 140, 62, 142, 63, 144, 64, 146, 65, 148, 66, 150, 67, 152, 68, 154, 69, 156, 70, 158, 71, 160, 0, 162, 0, 164, 0, 166, 0, 168, 0, 170, 72, 172, 73, 174, 74, 176, 75, 178, 76, 180, 0, 182, 77, 184, 78, 186, 79, 188, 80, 4, 0, 1, 2, 3, 13, 6, 0, 9, 10, 13, 13, 32, 32, 47, 47, 91, 91, 93, 93, 2, 0, 10, 10, 13, 13, 3, 0, 9, 10, 13, 13, 32, 32, 1, 0, 48, 57, 2, 0, 65, 90, 97, 122, 5, 0, 34, 34, 92, 92, 110, 110, 114, 114, 116, 116, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 2, 0, 64, 64, 95, 95, 1, 0, 96, 96, 10, 0, 9, 10, 13, 13, 32, 32, 44, 44, 47, 47, 61, 61, 91, 91, 93, 93, 96, 96, 124, 124, 2, 0, 42, 42, 47, 47, 792, 0, 4, 1, 0, 0, 0, 0, 6, 1, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, 10, 1, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 14, 1, 0, 0, 0, 0, 16, 1, 0, 0, 0, 0, 18, 1, 0, 0, 0, 0, 20, 1, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 24, 1, 0, 0, 0, 0, 26, 1, 0, 0, 0, 0, 28, 1, 0, 0, 0, 0, 30, 1, 0, 0, 0, 0, 32, 1, 0, 0, 0, 0, 34, 1, 0, 0, 0, 0, 36, 1, 0, 0, 0, 0, 38, 1, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 42, 1, 0, 0, 0, 0, 44, 1, 0, 0, 0, 0, 46, 1, 0, 0, 0, 1, 48, 1, 0, 0, 0, 1, 50, 1, 0, 0, 0, 1, 52, 1, 0, 0, 0, 1, 54, 1, 0, 0, 0, 1, 56, 1, 0, 0, 0, 2, 58, 1, 0, 0, 0, 2, 70, 1, 0, 0, 0, 2, 72, 1, 0, 0, 0, 2, 74, 1, 0, 0, 0, 2, 76, 1, 0, 0, 0, 2, 78, 1, 0, 0, 0, 2, 80, 1, 0, 0, 0, 2, 82, 1, 0, 0, 0, 2, 84, 1, 0, 0, 0, 2, 86, 1, 0, 0, 0, 2, 88, 1, 0, 0, 0, 2, 90, 1, 0, 0, 0, 2, 92, 1, 0, 0, 0, 2, 94, 1, 0, 0, 0, 2, 96, 1, 0, 0, 0, 2, 98, 1, 0, 0, 0, 2, 100, 1, 0, 0, 0, 2, 102, 1, 0, 0, 0, 2, 104, 1, 0, 0, 0, 2, 106, 1, 0, 0, 0, 2, 108, 1, 0, 0, 0, 2, 110, 1, 0, 0, 0, 2, 112, 1, 0, 0, 0, 2, 114, 1, 0, 0, 0, 2, 116, 1, 0, 0, 0, 2, 118, 1, 0, 0, 0, 2, 120, 1, 0, 0, 0, 2, 122, 1, 0, 0, 0, 2, 124, 1, 0, 0, 0, 2, 126, 1, 0, 0, 0, 2, 128, 1, 0, 0, 0, 2, 130, 1, 0, 0, 0, 2, 132, 1, 0, 0, 0, 2, 134, 1, 0, 0, 0, 2, 136, 1, 0, 0, 0, 2, 138, 1, 0, 0, 0, 2, 140, 1, 0, 0, 0, 2, 142, 1, 0, 0, 0, 2, 144, 1, 0, 0, 0, 2, 146, 1, 0, 0, 0, 2, 148, 1, 0, 0, 0, 2, 150, 1, 0, 0, 0, 2, 152, 1, 0, 0, 0, 2, 154, 1, 0, 0, 0, 2, 156, 1, 0, 0, 0, 2, 158, 1, 0, 0, 0, 3, 160, 1, 0, 0, 0, 3, 162, 1, 0, 0, 0, 3, 164, 1, 0, 0, 0, 3, 166, 1, 0, 0, 0, 3, 168, 1, 0, 0, 0, 3, 170, 1, 0, 0, 0, 3, 172, 1, 0, 0, 0, 3, 174, 1, 0, 0, 0, 3, 176, 1, 0, 0, 0, 3, 178, 1, 0, 0, 0, 3, 182, 1, 0, 0, 0, 3, 184, 1, 0, 0, 0, 3, 186, 1, 0, 0, 0, 3, 188, 1, 0, 0, 0, 4, 190, 1, 0, 0, 0, 6, 200, 1, 0, 0, 0, 8, 207, 1, 0, 0, 0, 10, 216, 1, 0, 0, 0, 12, 223, 1, 0, 0, 0, 14, 233, 1, 0, 0, 0, 16, 240, 1, 0, 0, 0, 18, 247, 1, 0, 0, 0, 20, 261, 1, 0, 0, 0, 22, 268, 1, 0, 0, 0, 24, 276, 1, 0, 0, 0, 26, 288, 1, 0, 0, 0, 28, 298, 1, 0, 0, 0, 30, 307, 1, 0, 0, 0, 32, 313, 1, 0, 0, 0, 34, 320, 1, 0, 0, 0, 36, 327, 1, 0, 0, 0, 38, 335, 1, 0, 0, 0, 40, 344, 1, 0, 0, 0, 42, 350, 1, 0, 0, 0, 44, 367, 1, 0, 0, 0, 46, 383, 1, 0, 0, 0, 48, 389, 1, 0, 0, 0, 50, 394, 1, 0, 0, 0, 52, 399, 1, 0, 0, 0, 54, 403, 1, 0, 0, 0, 56, 407, 1, 0, 0, 0, 58, 411, 1, 0, 0, 0, 60, 415, 1, 0, 0, 0, 62, 417, 1, 0, 0, 0, 64, 419, 1, 0, 0, 0, 66, 422, 1, 0, 0, 0, 68, 424, 1, 0, 0, 0, 70, 462, 1, 0, 0, 0, 72, 465, 1, 0, 0, 0, 74, 511, 1, 0, 0, 0, 76, 513, 1, 0, 0, 0, 78, 516, 1, 0, 0, 0, 80, 520, 1, 0, 0, 0, 82, 524, 1, 0, 0, 0, 84, 526, 1, 0, 0, 0, 86, 528, 1, 0, 0, 0, 88, 533, 1, 0, 0, 0, 90, 535, 1, 0, 0, 0, 92, 541, 1, 0, 0, 0, 94, 547, 1, 0, 0, 0, 96, 552, 1, 0, 0, 0, 98, 554, 1, 0, 0, 0, 100, 557, 1, 0, 0, 0, 102, 560, 1, 0, 0, 0, 104, 565, 1, 0, 0, 0, 106, 569, 1, 0, 0, 0, 108, 574, 1, 0, 0, 0, 110, 580, 1, 0, 0, 0, 112, 583, 1, 0, 0, 0, 114, 585, 1, 0, 0, 0, 116, 591, 1, 0, 0, 0, 118, 593, 1, 0, 0, 0, 120, 598, 1, 0, 0, 0, 122, 603, 1, 0, 0, 0, 124, 613, 1, 0, 0, 0, 126, 616, 1, 0, 0, 0, 128, 619, 1, 0, 0, 0, 130, 621, 1, 0, 0, 0, 132, 624, 1, 0, 0, 0, 134, 626, 1, 0, 0, 0, 136, 629, 1, 0, 0, 0, 138, 631, 1, 0, 0, 0, 140, 633, 1, 0, 0, 0, 142, 635, 1, 0, 0, 0, 144, 637, 1, 0, 0, 0, 146, 639, 1, 0, 0, 0, 148, 644, 1, 0, 0, 0, 150, 666, 1, 0, 0, 0, 152, 668, 1, 0, 0, 0, 154, 679, 1, 0, 0, 0, 156, 683, 1, 0, 0, 0, 158, 687, 1, 0, 0, 0, 160, 691, 1, 0, 0, 0, 162, 696, 1, 0, 0, 0, 164, 702, 1, 0, 0, 0, 166, 708, 1, 0, 0, 0, 168, 712, 1, 0, 0, 0, 170, 716, 1, 0, 0, 0, 172, 719, 1, 0, 0, 0, 174, 728, 1, 0, 0, 0, 176, 731, 1, 0, 0, 0, 178, 737, 1, 0, 0, 0, 180, 748, 1, 0, 0, 0, 182, 750, 1, 0, 0, 0, 184, 752, 1, 0, 0, 0, 186, 756, 1, 0, 0, 0, 188, 760, 1, 0, 0, 0, 190, 191, 5, 100, 0, 0, 191, 192, 5, 105, 0, 0, 192, 193, 5, 115, 0, 0, 193, 194, 5, 115, 0, 0, 194, 195, 5, 101, 0, 0, 195, 196, 5, 99, 0, 0, 196, 197, 5, 116, 0, 0, 197, 198, 1, 0, 0, 0, 198, 199, 6, 0, 0, 0, 199, 5, 1, 0, 0, 0, 200, 201, 5, 100, 0, 0, 201, 202, 5, 114, 0, 0, 202, 203, 5, 111, 0, 0, 203, 204, 5, 112, 0, 0, 204, 205, 1, 0, 0, 0, 205, 206, 6, 1, 1, 0, 206, 7, 1, 0, 0, 0, 207, 208, 5, 101, 0, 0, 208, 209, 5, 110, 0, 0, 209, 210, 5, 114, 0, 0, 210, 211, 5, 105, 0, 0, 211, 212, 5, 99, 0, 0, 212, 213, 5, 104, 0, 0, 213, 214, 1, 0, 0, 0, 214, 215, 6, 2, 1, 0, 215, 9, 1, 0, 0, 0, 216, 217, 5, 101, 0, 0, 217, 218, 5, 118, 0, 0, 218, 219, 5, 97, 0, 0, 219, 220, 5, 108, 0, 0, 220, 221, 1, 0, 0, 0, 221, 222, 6, 3, 0, 0, 222, 11, 1, 0, 0, 0, 223, 224, 5, 101, 0, 0, 224, 225, 5, 120, 0, 0, 225, 226, 5, 112, 0, 0, 226, 227, 5, 108, 0, 0, 227, 228, 5, 97, 0, 0, 228, 229, 5, 105, 0, 0, 229, 230, 5, 110, 0, 0, 230, 231, 1, 0, 0, 0, 231, 232, 6, 4, 2, 0, 232, 13, 1, 0, 0, 0, 233, 234, 5, 102, 0, 0, 234, 235, 5, 114, 0, 0, 235, 236, 5, 111, 0, 0, 236, 237, 5, 109, 0, 0, 237, 238, 1, 0, 0, 0, 238, 239, 6, 5, 1, 0, 239, 15, 1, 0, 0, 0, 240, 241, 5, 103, 0, 0, 241, 242, 5, 114, 0, 0, 242, 243, 5, 111, 0, 0, 243, 244, 5, 107, 0, 0, 244, 245, 1, 0, 0, 0, 245, 246, 6, 6, 0, 0, 246, 17, 1, 0, 0, 0, 247, 248, 5, 105, 0, 0, 248, 249, 5, 110, 0, 0, 249, 250, 5, 108, 0, 0, 250, 251, 5, 105, 0, 0, 251, 252, 5, 110, 0, 0, 252, 253, 5, 101, 0, 0, 253, 254, 5, 115, 0, 0, 254, 255, 5, 116, 0, 0, 255, 256, 5, 97, 0, 0, 256, 257, 5, 116, 0, 0, 257, 258, 5, 115, 0, 0, 258, 259, 1, 0, 0, 0, 259, 260, 6, 7, 0, 0, 260, 19, 1, 0, 0, 0, 261, 262, 5, 107, 0, 0, 262, 263, 5, 101, 0, 0, 263, 264, 5, 101, 0, 0, 264, 265, 5, 112, 0, 0, 265, 266, 1, 0, 0, 0, 266, 267, 6, 8, 1, 0, 267, 21, 1, 0, 0, 0, 268, 269, 5, 108, 0, 0, 269, 270, 5, 105, 0, 0, 270, 271, 5, 109, 0, 0, 271, 272, 5, 105, 0, 0, 272, 273, 5, 116, 0, 0, 273, 274, 1, 0, 0, 0, 274, 275, 6, 9, 0, 0, 275, 23, 1, 0, 0, 0, 276, 277, 5, 109, 0, 0, 277, 278, 5, 118, 0, 0, 278, 279, 5, 95, 0, 0, 279, 280, 5, 101, 0, 0, 280, 281, 5, 120, 0, 0, 281, 282, 5, 112, 0, 0, 282, 283, 5, 97, 0, 0, 283, 284, 5, 110, 0, 0, 284, 285, 5, 100, 0, 0, 285, 286, 1, 0, 0, 0, 286, 287, 6, 10, 1, 0, 287, 25, 1, 0, 0, 0, 288, 289, 5, 112, 0, 0, 289, 290, 5, 114, 0, 0, 290, 291, 5, 111, 0, 0, 291, 292, 5, 106, 0, 0, 292, 293, 5, 101, 0, 0, 293, 294, 5, 99, 0, 0, 294, 295, 5, 116, 0, 0, 295, 296, 1, 0, 0, 0, 296, 297, 6, 11, 1, 0, 297, 27, 1, 0, 0, 0, 298, 299, 5, 114, 0, 0, 299, 300, 5, 101, 0, 0, 300, 301, 5, 110, 0, 0, 301, 302, 5, 97, 0, 0, 302, 303, 5, 109, 0, 0, 303, 304, 5, 101, 0, 0, 304, 305, 1, 0, 0, 0, 305, 306, 6, 12, 1, 0, 306, 29, 1, 0, 0, 0, 307, 308, 5, 114, 0, 0, 308, 309, 5, 111, 0, 0, 309, 310, 5, 119, 0, 0, 310, 311, 1, 0, 0, 0, 311, 312, 6, 13, 0, 0, 312, 31, 1, 0, 0, 0, 313, 314, 5, 115, 0, 0, 314, 315, 5, 104, 0, 0, 315, 316, 5, 111, 0, 0, 316, 317, 5, 119, 0, 0, 317, 318, 1, 0, 0, 0, 318, 319, 6, 14, 0, 0, 319, 33, 1, 0, 0, 0, 320, 321, 5, 115, 0, 0, 321, 322, 5, 111, 0, 0, 322, 323, 5, 114, 0, 0, 323, 324, 5, 116, 0, 0, 324, 325, 1, 0, 0, 0, 325, 326, 6, 15, 0, 0, 326, 35, 1, 0, 0, 0, 327, 328, 5, 115, 0, 0, 328, 329, 5, 116, 0, 0, 329, 330, 5, 97, 0, 0, 330, 331, 5, 116, 0, 0, 331, 332, 5, 115, 0, 0, 332, 333, 1, 0, 0, 0, 333, 334, 6, 16, 0, 0, 334, 37, 1, 0, 0, 0, 335, 336, 5, 119, 0, 0, 336, 337, 5, 104, 0, 0, 337, 338, 5, 101, 0, 0, 338, 339, 5, 114, 0, 0, 339, 340, 5, 101, 0, 0, 340, 341, 1, 0, 0, 0, 341, 342, 6, 17, 0, 0, 342, 39, 1, 0, 0, 0, 343, 345, 8, 0, 0, 0, 344, 343, 1, 0, 0, 0, 345, 346, 1, 0, 0, 0, 346, 344, 1, 0, 0, 0, 346, 347, 1, 0, 0, 0, 347, 348, 1, 0, 0, 0, 348, 349, 6, 18, 0, 0, 349, 41, 1, 0, 0, 0, 350, 351, 5, 47, 0, 0, 351, 352, 5, 47, 0, 0, 352, 356, 1, 0, 0, 0, 353, 355, 8, 1, 0, 0, 354, 353, 1, 0, 0, 0, 355, 358, 1, 0, 0, 0, 356, 354, 1, 0, 0, 0, 356, 357, 1, 0, 0, 0, 357, 360, 1, 0, 0, 0, 358, 356, 1, 0, 0, 0, 359, 361, 5, 13, 0, 0, 360, 359, 1, 0, 0, 0, 360, 361, 1, 0, 0, 0, 361, 363, 1, 0, 0, 0, 362, 364, 5, 10, 0, 0, 363, 362, 1, 0, 0, 0, 363, 364, 1, 0, 0, 0, 364, 365, 1, 0, 0, 0, 365, 366, 6, 19, 3, 0, 366, 43, 1, 0, 0, 0, 367, 368, 5, 47, 0, 0, 368, 369, 5, 42, 0, 0, 369, 374, 1, 0, 0, 0, 370, 373, 3, 44, 20, 0, 371, 373, 9, 0, 0, 0, 372, 370, 1, 0, 0, 0, 372, 371, 1, 0, 0, 0, 373, 376, 1, 0, 0, 0, 374, 375, 1, 0, 0, 0, 374, 372, 1, 0, 0, 0, 375, 377, 1, 0, 0, 0, 376, 374, 1, 0, 0, 0, 377, 378, 5, 42, 0, 0, 378, 379, 5, 47, 0, 0, 379, 380, 1, 0, 0, 0, 380, 381, 6, 20, 3, 0, 381, 45, 1, 0, 0, 0, 382, 384, 7, 2, 0, 0, 383, 382, 1, 0, 0, 0, 384, 385, 1, 0, 0, 0, 385, 383, 1, 0, 0, 0, 385, 386, 1, 0, 0, 0, 386, 387, 1, 0, 0, 0, 387, 388, 6, 21, 3, 0, 388, 47, 1, 0, 0, 0, 389, 390, 5, 91, 0, 0, 390, 391, 1, 0, 0, 0, 391, 392, 6, 22, 4, 0, 392, 393, 6, 22, 5, 0, 393, 49, 1, 0, 0, 0, 394, 395, 5, 124, 0, 0, 395, 396, 1, 0, 0, 0, 396, 397, 6, 23, 6, 0, 397, 398, 6, 23, 7, 0, 398, 51, 1, 0, 0, 0, 399, 400, 3, 46, 21, 0, 400, 401, 1, 0, 0, 0, 401, 402, 6, 24, 3, 0, 402, 53, 1, 0, 0, 0, 403, 404, 3, 42, 19, 0, 404, 405, 1, 0, 0, 0, 405, 406, 6, 25, 3, 0, 406, 55, 1, 0, 0, 0, 407, 408, 3, 44, 20, 0, 408, 409, 1, 0, 0, 0, 409, 410, 6, 26, 3, 0, 410, 57, 1, 0, 0, 0, 411, 412, 5, 124, 0, 0, 412, 413, 1, 0, 0, 0, 413, 414, 6, 27, 7, 0, 414, 59, 1, 0, 0, 0, 415, 416, 7, 3, 0, 0, 416, 61, 1, 0, 0, 0, 417, 418, 7, 4, 0, 0, 418, 63, 1, 0, 0, 0, 419, 420, 5, 92, 0, 0, 420, 421, 7, 5, 0, 0, 421, 65, 1, 0, 0, 0, 422, 423, 8, 6, 0, 0, 423, 67, 1, 0, 0, 0, 424, 426, 7, 7, 0, 0, 425, 427, 7, 8, 0, 0, 426, 425, 1, 0, 0, 0, 426, 427, 1, 0, 0, 0, 427, 429, 1, 0, 0, 0, 428, 430, 3, 60, 28, 0, 429, 428, 1, 0, 0, 0, 430, 431, 1, 0, 0, 0, 431, 429, 1, 0, 0, 0, 431, 432, 1, 0, 0, 0, 432, 69, 1, 0, 0, 0, 433, 438, 5, 34, 0, 0, 434, 437, 3, 64, 30, 0, 435, 437, 3, 66, 31, 0, 436, 434, 1, 0, 0, 0, 436, 435, 1, 0, 0, 0, 437, 440, 1, 0, 0, 0, 438, 436, 1, 0, 0, 0, 438, 439, 1, 0, 0, 0, 439, 441, 1, 0, 0, 0, 440, 438, 1, 0, 0, 0, 441, 463, 5, 34, 0, 0, 442, 443, 5, 34, 0, 0, 443, 444, 5, 34, 0, 0, 444, 445, 5, 34, 0, 0, 445, 449, 1, 0, 0, 0, 446, 448, 8, 1, 0, 0, 447, 446, 1, 0, 0, 0, 448, 451, 1, 0, 0, 0, 449, 450, 1, 0, 0, 0, 449, 447, 1, 0, 0, 0, 450, 452, 1, 0, 0, 0, 451, 449, 1, 0, 0, 0, 452, 453, 5, 34, 0, 0, 453, 454, 5, 34, 0, 0, 454, 455, 5, 34, 0, 0, 455, 457, 1, 0, 0, 0, 456, 458, 5, 34, 0, 0, 457, 456, 1, 0, 0, 0, 457, 458, 1, 0, 0, 0, 458, 460, 1, 0, 0, 0, 459, 461, 5, 34, 0, 0, 460, 459, 1, 0, 0, 0, 460, 461, 1, 0, 0, 0, 461, 463, 1, 0, 0, 0, 462, 433, 1, 0, 0, 0, 462, 442, 1, 0, 0, 0, 463, 71, 1, 0, 0, 0, 464, 466, 3, 60, 28, 0, 465, 464, 1, 0, 0, 0, 466, 467, 1, 0, 0, 0, 467, 465, 1, 0, 0, 0, 467, 468, 1, 0, 0, 0, 468, 73, 1, 0, 0, 0, 469, 471, 3, 60, 28, 0, 470, 469, 1, 0, 0, 0, 471, 472, 1, 0, 0, 0, 472, 470, 1, 0, 0, 0, 472, 473, 1, 0, 0, 0, 473, 474, 1, 0, 0, 0, 474, 478, 3, 88, 42, 0, 475, 477, 3, 60, 28, 0, 476, 475, 1, 0, 0, 0, 477, 480, 1, 0, 0, 0, 478, 476, 1, 0, 0, 0, 478, 479, 1, 0, 0, 0, 479, 512, 1, 0, 0, 0, 480, 478, 1, 0, 0, 0, 481, 483, 3, 88, 42, 0, 482, 484, 3, 60, 28, 0, 483, 482, 1, 0, 0, 0, 484, 485, 1, 0, 0, 0, 485, 483, 1, 0, 0, 0, 485, 486, 1, 0, 0, 0, 486, 512, 1, 0, 0, 0, 487, 489, 3, 60, 28, 0, 488, 487, 1, 0, 0, 0, 489, 490, 1, 0, 0, 0, 490, 488, 1, 0, 0, 0, 490, 491, 1, 0, 0, 0, 491, 499, 1, 0, 0, 0, 492, 496, 3, 88, 42, 0, 493, 495, 3, 60, 28, 0, 494, 493, 1, 0, 0, 0, 495, 498, 1, 0, 0, 0, 496, 494, 1, 0, 0, 0, 496, 497, 1, 0, 0, 0, 497, 500, 1, 0, 0, 0, 498, 496, 1, 0, 0, 0, 499, 492, 1, 0, 0, 0, 499, 500, 1, 0, 0, 0, 500, 501, 1, 0, 0, 0, 501, 502, 3, 68, 32, 0, 502, 512, 1, 0, 0, 0, 503, 505, 3, 88, 42, 0, 504, 506, 3, 60, 28, 0, 505, 504, 1, 0, 0, 0, 506, 507, 1, 0, 0, 0, 507, 505, 1, 0, 0, 0, 507, 508, 1, 0, 0, 0, 508, 509, 1, 0, 0, 0, 509, 510, 3, 68, 32, 0, 510, 512, 1, 0, 0, 0, 511, 470, 1, 0, 0, 0, 511, 481, 1, 0, 0, 0, 511, 488, 1, 0, 0, 0, 511, 503, 1, 0, 0, 0, 512, 75, 1, 0, 0, 0, 513, 514, 5, 98, 0, 0, 514, 515, 5, 121, 0, 0, 515, 77, 1, 0, 0, 0, 516, 517, 5, 97, 0, 0, 517, 518, 5, 110, 0, 0, 518, 519, 5, 100, 0, 0, 519, 79, 1, 0, 0, 0, 520, 521, 5, 97, 0, 0, 521, 522, 5, 115, 0, 0, 522, 523, 5, 99, 0, 0, 523, 81, 1, 0, 0, 0, 524, 525, 5, 61, 0, 0, 525, 83, 1, 0, 0, 0, 526, 527, 5, 44, 0, 0, 527, 85, 1, 0, 0, 0, 528, 529, 5, 100, 0, 0, 529, 530, 5, 101, 0, 0, 530, 531, 5, 115, 0, 0, 531, 532, 5, 99, 0, 0, 532, 87, 1, 0, 0, 0, 533, 534, 5, 46, 0, 0, 534, 89, 1, 0, 0, 0, 535, 536, 5, 102, 0, 0, 536, 537, 5, 97, 0, 0, 537, 538, 5, 108, 0, 0, 538, 539, 5, 115, 0, 0, 539, 540, 5, 101, 0, 0, 540, 91, 1, 0, 0, 0, 541, 542, 5, 102, 0, 0, 542, 543, 5, 105, 0, 0, 543, 544, 5, 114, 0, 0, 544, 545, 5, 115, 0, 0, 545, 546, 5, 116, 0, 0, 546, 93, 1, 0, 0, 0, 547, 548, 5, 108, 0, 0, 548, 549, 5, 97, 0, 0, 549, 550, 5, 115, 0, 0, 550, 551, 5, 116, 0, 0, 551, 95, 1, 0, 0, 0, 552, 553, 5, 40, 0, 0, 553, 97, 1, 0, 0, 0, 554, 555, 5, 105, 0, 0, 555, 556, 5, 110, 0, 0, 556, 99, 1, 0, 0, 0, 557, 558, 5, 105, 0, 0, 558, 559, 5, 115, 0, 0, 559, 101, 1, 0, 0, 0, 560, 561, 5, 108, 0, 0, 561, 562, 5, 105, 0, 0, 562, 563, 5, 107, 0, 0, 563, 564, 5, 101, 0, 0, 564, 103, 1, 0, 0, 0, 565, 566, 5, 110, 0, 0, 566, 567, 5, 111, 0, 0, 567, 568, 5, 116, 0, 0, 568, 105, 1, 0, 0, 0, 569, 570, 5, 110, 0, 0, 570, 571, 5, 117, 0, 0, 571, 572, 5, 108, 0, 0, 572, 573, 5, 108, 0, 0, 573, 107, 1, 0, 0, 0, 574, 575, 5, 110, 0, 0, 575, 576, 5, 117, 0, 0, 576, 577, 5, 108, 0, 0, 577, 578, 5, 108, 0, 0, 578, 579, 5, 115, 0, 0, 579, 109, 1, 0, 0, 0, 580, 581, 5, 111, 0, 0, 581, 582, 5, 114, 0, 0, 582, 111, 1, 0, 0, 0, 583, 584, 5, 63, 0, 0, 584, 113, 1, 0, 0, 0, 585, 586, 5, 114, 0, 0, 586, 587, 5, 108, 0, 0, 587, 588, 5, 105, 0, 0, 588, 589, 5, 107, 0, 0, 589, 590, 5, 101, 0, 0, 590, 115, 1, 0, 0, 0, 591, 592, 5, 41, 0, 0, 592, 117, 1, 0, 0, 0, 593, 594, 5, 116, 0, 0, 594, 595, 5, 114, 0, 0, 595, 596, 5, 117, 0, 0, 596, 597, 5, 101, 0, 0, 597, 119, 1, 0, 0, 0, 598, 599, 5, 105, 0, 0, 599, 600, 5, 110, 0, 0, 600, 601, 5, 102, 0, 0, 601, 602, 5, 111, 0, 0, 602, 121, 1, 0, 0, 0, 603, 604, 5, 102, 0, 0, 604, 605, 5, 117, 0, 0, 605, 606, 5, 110, 0, 0, 606, 607, 5, 99, 0, 0, 607, 608, 5, 116, 0, 0, 608, 609, 5, 105, 0, 0, 609, 610, 5, 111, 0, 0, 610, 611, 5, 110, 0, 0, 611, 612, 5, 115, 0, 0, 612, 123, 1, 0, 0, 0, 613, 614, 5, 61, 0, 0, 614, 615, 5, 61, 0, 0, 615, 125, 1, 0, 0, 0, 616, 617, 5, 33, 0, 0, 617, 618, 5, 61, 0, 0, 618, 127, 1, 0, 0, 0, 619, 620, 5, 60, 0, 0, 620, 129, 1, 0, 0, 0, 621, 622, 5, 60, 0, 0, 622, 623, 5, 61, 0, 0, 623, 131, 1, 0, 0, 0, 624, 625, 5, 62, 0, 0, 625, 133, 1, 0, 0, 0, 626, 627, 5, 62, 0, 0, 627, 628, 5, 61, 0, 0, 628, 135, 1, 0, 0, 0, 629, 630, 5, 43, 0, 0, 630, 137, 1, 0, 0, 0, 631, 632, 5, 45, 0, 0, 632, 139, 1, 0, 0, 0, 633, 634, 5, 42, 0, 0, 634, 141, 1, 0, 0, 0, 635, 636, 5, 47, 0, 0, 636, 143, 1, 0, 0, 0, 637, 638, 5, 37, 0, 0, 638, 145, 1, 0, 0, 0, 639, 640, 5, 91, 0, 0, 640, 641, 1, 0, 0, 0, 641, 642, 6, 71, 0, 0, 642, 643, 6, 71, 0, 0, 643, 147, 1, 0, 0, 0, 644, 645, 5, 93, 0, 0, 645, 646, 1, 0, 0, 0, 646, 647, 6, 72, 7, 0, 647, 648, 6, 72, 7, 0, 648, 149, 1, 0, 0, 0, 649, 655, 3, 62, 29, 0, 650, 654, 3, 62, 29, 0, 651, 654, 3, 60, 28, 0, 652, 654, 5, 95, 0, 0, 653, 650, 1, 0, 0, 0, 653, 651, 1, 0, 0, 0, 653, 652, 1, 0, 0, 0, 654, 657, 1, 0, 0, 0, 655, 653, 1, 0, 0, 0, 655, 656, 1, 0, 0, 0, 656, 667, 1, 0, 0, 0, 657, 655, 1, 0, 0, 0, 658, 662, 7, 9, 0, 0, 659, 663, 3, 62, 29, 0, 660, 663, 3, 60, 28, 0, 661, 663, 5, 95, 0, 0, 662, 659, 1, 0, 0, 0, 662, 660, 1, 0, 0, 0, 662, 661, 1, 0, 0, 0, 663, 664, 1, 0, 0, 0, 664, 662, 1, 0, 0, 0, 664, 665, 1, 0, 0, 0, 665, 667, 1, 0, 0, 0, 666, 649, 1, 0, 0, 0, 666, 658, 1, 0, 0, 0, 667, 151, 1, 0, 0, 0, 668, 674, 5, 96, 0, 0, 669, 673, 8, 10, 0, 0, 670, 671, 5, 96, 0, 0, 671, 673, 5, 96, 0, 0, 672, 669, 1, 0, 0, 0, 672, 670, 1, 0, 0, 0, 673, 676, 1, 0, 0, 0, 674, 672, 1, 0, 0, 0, 674, 675, 1, 0, 0, 0, 675, 677, 1, 0, 0, 0, 676, 674, 1, 0, 0, 0, 677, 678, 5, 96, 0, 0, 678, 153, 1, 0, 0, 0, 679, 680, 3, 42, 19, 0, 680, 681, 1, 0, 0, 0, 681, 682, 6, 75, 3, 0, 682, 155, 1, 0, 0, 0, 683, 684, 3, 44, 20, 0, 684, 685, 1, 0, 0, 0, 685, 686, 6, 76, 3, 0, 686, 157, 1, 0, 0, 0, 687, 688, 3, 46, 21, 0, 688, 689, 1, 0, 0, 0, 689, 690, 6, 77, 3, 0, 690, 159, 1, 0, 0, 0, 691, 692, 5, 124, 0, 0, 692, 693, 1, 0, 0, 0, 693, 694, 6, 78, 6, 0, 694, 695, 6, 78, 7, 0, 695, 161, 1, 0, 0, 0, 696, 697, 5, 91, 0, 0, 697, 698, 1, 0, 0, 0, 698, 699, 6, 79, 4, 0, 699, 700, 6, 79, 1, 0, 700, 701, 6, 79, 1, 0, 701, 163, 1, 0, 0, 0, 702, 703, 5, 93, 0, 0, 703, 704, 1, 0, 0, 0, 704, 705, 6, 80, 7, 0, 705, 706, 6, 80, 7, 0, 706, 707, 6, 80, 8, 0, 707, 165, 1, 0, 0, 0, 708, 709, 5, 44, 0, 0, 709, 710, 1, 0, 0, 0, 710, 711, 6, 81, 9, 0, 711, 167, 1, 0, 0, 0, 712, 713, 5, 61, 0, 0, 713, 714, 1, 0, 0, 0, 714, 715, 6, 82, 10, 0, 715, 169, 1, 0, 0, 0, 716, 717, 5, 97, 0, 0, 717, 718, 5, 115, 0, 0, 718, 171, 1, 0, 0, 0, 719, 720, 5, 109, 0, 0, 720, 721, 5, 101, 0, 0, 721, 722, 5, 116, 0, 0, 722, 723, 5, 97, 0, 0, 723, 724, 5, 100, 0, 0, 724, 725, 5, 97, 0, 0, 725, 726, 5, 116, 0, 0, 726, 727, 5, 97, 0, 0, 727, 173, 1, 0, 0, 0, 728, 729, 5, 111, 0, 0, 729, 730, 5, 110, 0, 0, 730, 175, 1, 0, 0, 0, 731, 732, 5, 119, 0, 0, 732, 733, 5, 105, 0, 0, 733, 734, 5, 116, 0, 0, 734, 735, 5, 104, 0, 0, 735, 177, 1, 0, 0, 0, 736, 738, 3, 180, 88, 0, 737, 736, 1, 0, 0, 0, 738, 739, 1, 0, 0, 0, 739, 737, 1, 0, 0, 0, 739, 740, 1, 0, 0, 0, 740, 179, 1, 0, 0, 0, 741, 743, 8, 11, 0, 0, 742, 741, 1, 0, 0, 0, 743, 744, 1, 0, 0, 0, 744, 742, 1, 0, 0, 0, 744, 745, 1, 0, 0, 0, 745, 749, 1, 0, 0, 0, 746, 747, 5, 47, 0, 0, 747, 749, 8, 12, 0, 0, 748, 742, 1, 0, 0, 0, 748, 746, 1, 0, 0, 0, 749, 181, 1, 0, 0, 0, 750, 751, 3, 152, 74, 0, 751, 183, 1, 0, 0, 0, 752, 753, 3, 42, 19, 0, 753, 754, 1, 0, 0, 0, 754, 755, 6, 90, 3, 0, 755, 185, 1, 0, 0, 0, 756, 757, 3, 44, 20, 0, 757, 758, 1, 0, 0, 0, 758, 759, 6, 91, 3, 0, 759, 187, 1, 0, 0, 0, 760, 761, 3, 46, 21, 0, 761, 762, 1, 0, 0, 0, 762, 763, 6, 92, 3, 0, 763, 189, 1, 0, 0, 0, 38, 0, 1, 2, 3, 346, 356, 360, 363, 372, 374, 385, 426, 431, 436, 438, 449, 457, 460, 462, 467, 472, 478, 485, 490, 496, 499, 507, 511, 653, 655, 662, 664, 666, 672, 674, 739, 744, 748, 11, 5, 2, 0, 5, 3, 0, 5, 1, 0, 0, 1, 0, 7, 65, 0, 5, 0, 0, 7, 26, 0, 4, 0, 0, 7, 66, 0, 7, 34, 0, 7, 33, 0]
\ No newline at end of file
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java
index 0a006b9f8ad14..be46b6c6e1797 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java
@@ -23,13 +23,13 @@ public class EsqlBaseLexer extends Lexer {
WS=22, EXPLAIN_WS=23, EXPLAIN_LINE_COMMENT=24, EXPLAIN_MULTILINE_COMMENT=25,
PIPE=26, STRING=27, INTEGER_LITERAL=28, DECIMAL_LITERAL=29, BY=30, AND=31,
ASC=32, ASSIGN=33, COMMA=34, DESC=35, DOT=36, FALSE=37, FIRST=38, LAST=39,
- LP=40, IN=41, LIKE=42, NOT=43, NULL=44, NULLS=45, OR=46, PARAM=47, RLIKE=48,
- RP=49, TRUE=50, INFO=51, FUNCTIONS=52, EQ=53, NEQ=54, LT=55, LTE=56, GT=57,
- GTE=58, PLUS=59, MINUS=60, ASTERISK=61, SLASH=62, PERCENT=63, OPENING_BRACKET=64,
- CLOSING_BRACKET=65, UNQUOTED_IDENTIFIER=66, QUOTED_IDENTIFIER=67, EXPR_LINE_COMMENT=68,
- EXPR_MULTILINE_COMMENT=69, EXPR_WS=70, AS=71, METADATA=72, ON=73, WITH=74,
- SRC_UNQUOTED_IDENTIFIER=75, SRC_QUOTED_IDENTIFIER=76, SRC_LINE_COMMENT=77,
- SRC_MULTILINE_COMMENT=78, SRC_WS=79, EXPLAIN_PIPE=80;
+ LP=40, IN=41, IS=42, LIKE=43, NOT=44, NULL=45, NULLS=46, OR=47, PARAM=48,
+ RLIKE=49, RP=50, TRUE=51, INFO=52, FUNCTIONS=53, EQ=54, NEQ=55, LT=56,
+ LTE=57, GT=58, GTE=59, PLUS=60, MINUS=61, ASTERISK=62, SLASH=63, PERCENT=64,
+ OPENING_BRACKET=65, CLOSING_BRACKET=66, UNQUOTED_IDENTIFIER=67, QUOTED_IDENTIFIER=68,
+ EXPR_LINE_COMMENT=69, EXPR_MULTILINE_COMMENT=70, EXPR_WS=71, AS=72, METADATA=73,
+ ON=74, WITH=75, SRC_UNQUOTED_IDENTIFIER=76, SRC_QUOTED_IDENTIFIER=77,
+ SRC_LINE_COMMENT=78, SRC_MULTILINE_COMMENT=79, SRC_WS=80, EXPLAIN_PIPE=81;
public static final int
EXPLAIN_MODE=1, EXPRESSION=2, SOURCE_IDENTIFIERS=3;
public static String[] channelNames = {
@@ -49,14 +49,14 @@ private static String[] makeRuleNames() {
"EXPLAIN_MULTILINE_COMMENT", "PIPE", "DIGIT", "LETTER", "ESCAPE_SEQUENCE",
"UNESCAPED_CHARS", "EXPONENT", "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL",
"BY", "AND", "ASC", "ASSIGN", "COMMA", "DESC", "DOT", "FALSE", "FIRST",
- "LAST", "LP", "IN", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE",
- "RP", "TRUE", "INFO", "FUNCTIONS", "EQ", "NEQ", "LT", "LTE", "GT", "GTE",
- "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET",
- "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT",
- "EXPR_WS", "SRC_PIPE", "SRC_OPENING_BRACKET", "SRC_CLOSING_BRACKET",
- "SRC_COMMA", "SRC_ASSIGN", "AS", "METADATA", "ON", "WITH", "SRC_UNQUOTED_IDENTIFIER",
- "SRC_UNQUOTED_IDENTIFIER_PART", "SRC_QUOTED_IDENTIFIER", "SRC_LINE_COMMENT",
- "SRC_MULTILINE_COMMENT", "SRC_WS"
+ "LAST", "LP", "IN", "IS", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM",
+ "RLIKE", "RP", "TRUE", "INFO", "FUNCTIONS", "EQ", "NEQ", "LT", "LTE",
+ "GT", "GTE", "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT", "OPENING_BRACKET",
+ "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT",
+ "EXPR_MULTILINE_COMMENT", "EXPR_WS", "SRC_PIPE", "SRC_OPENING_BRACKET",
+ "SRC_CLOSING_BRACKET", "SRC_COMMA", "SRC_ASSIGN", "AS", "METADATA", "ON",
+ "WITH", "SRC_UNQUOTED_IDENTIFIER", "SRC_UNQUOTED_IDENTIFIER_PART", "SRC_QUOTED_IDENTIFIER",
+ "SRC_LINE_COMMENT", "SRC_MULTILINE_COMMENT", "SRC_WS"
};
}
public static final String[] ruleNames = makeRuleNames();
@@ -68,8 +68,8 @@ private static String[] makeLiteralNames() {
"'rename'", "'row'", "'show'", "'sort'", "'stats'", "'where'", null,
null, null, null, null, null, null, null, null, null, null, "'by'", "'and'",
"'asc'", null, null, "'desc'", "'.'", "'false'", "'first'", "'last'",
- "'('", "'in'", "'like'", "'not'", "'null'", "'nulls'", "'or'", "'?'",
- "'rlike'", "')'", "'true'", "'info'", "'functions'", "'=='", "'!='",
+ "'('", "'in'", "'is'", "'like'", "'not'", "'null'", "'nulls'", "'or'",
+ "'?'", "'rlike'", "')'", "'true'", "'info'", "'functions'", "'=='", "'!='",
"'<'", "'<='", "'>'", "'>='", "'+'", "'-'", "'*'", "'/'", "'%'", null,
"']'", null, null, null, null, null, "'as'", "'metadata'", "'on'", "'with'"
};
@@ -83,9 +83,9 @@ private static String[] makeSymbolicNames() {
"WS", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", "EXPLAIN_MULTILINE_COMMENT",
"PIPE", "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND",
"ASC", "ASSIGN", "COMMA", "DESC", "DOT", "FALSE", "FIRST", "LAST", "LP",
- "IN", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", "TRUE",
- "INFO", "FUNCTIONS", "EQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS",
- "ASTERISK", "SLASH", "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET",
+ "IN", "IS", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP",
+ "TRUE", "INFO", "FUNCTIONS", "EQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS",
+ "MINUS", "ASTERISK", "SLASH", "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET",
"UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT",
"EXPR_WS", "AS", "METADATA", "ON", "WITH", "SRC_UNQUOTED_IDENTIFIER",
"SRC_QUOTED_IDENTIFIER", "SRC_LINE_COMMENT", "SRC_MULTILINE_COMMENT",
@@ -151,7 +151,7 @@ public EsqlBaseLexer(CharStream input) {
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
- "\u0004\u0000P\u02f7\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff"+
+ "\u0004\u0000Q\u02fc\u0006\uffff\uffff\u0006\uffff\uffff\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"+
@@ -174,456 +174,459 @@ public EsqlBaseLexer(CharStream input) {
"K\u0007K\u0002L\u0007L\u0002M\u0007M\u0002N\u0007N\u0002O\u0007O\u0002"+
"P\u0007P\u0002Q\u0007Q\u0002R\u0007R\u0002S\u0007S\u0002T\u0007T\u0002"+
"U\u0007U\u0002V\u0007V\u0002W\u0007W\u0002X\u0007X\u0002Y\u0007Y\u0002"+
- "Z\u0007Z\u0002[\u0007[\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000"+
+ "Z\u0007Z\u0002[\u0007[\u0002\\\u0007\\\u0001\u0000\u0001\u0000\u0001\u0000"+
"\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000"+
- "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+
- "\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002"+
- "\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003"+
- "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0004"+
+ "\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+
+ "\u0001\u0001\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002"+
+ "\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0003"+
+ "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+
"\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+
- "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005"+
- "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006"+
- "\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0007"+
+ "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005"+
+ "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0006"+
+ "\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+
"\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+
"\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+
- "\u0001\u0007\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001"+
- "\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\n\u0001"+
- "\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001"+
- "\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+
- "\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\f\u0001"+
- "\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\r\u0001"+
- "\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\u000e\u0001\u000e\u0001\u000e"+
- "\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000f\u0001\u000f"+
- "\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u0010"+
+ "\u0001\u0007\u0001\u0007\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001"+
+ "\b\u0001\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001"+
+ "\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001"+
+ "\n\u0001\n\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+
+ "\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+
+ "\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001"+
+ "\f\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\u000e\u0001\u000e"+
+ "\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\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\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011"+
- "\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0012\u0004\u0012\u0157\b\u0012"+
- "\u000b\u0012\f\u0012\u0158\u0001\u0012\u0001\u0012\u0001\u0013\u0001\u0013"+
- "\u0001\u0013\u0001\u0013\u0005\u0013\u0161\b\u0013\n\u0013\f\u0013\u0164"+
- "\t\u0013\u0001\u0013\u0003\u0013\u0167\b\u0013\u0001\u0013\u0003\u0013"+
- "\u016a\b\u0013\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014\u0001\u0014"+
- "\u0001\u0014\u0001\u0014\u0005\u0014\u0173\b\u0014\n\u0014\f\u0014\u0176"+
- "\t\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001"+
- "\u0015\u0004\u0015\u017e\b\u0015\u000b\u0015\f\u0015\u017f\u0001\u0015"+
- "\u0001\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016"+
- "\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0018"+
- "\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0019\u0001\u0019\u0001\u0019"+
- "\u0001\u0019\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001b"+
- "\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001c\u0001\u001c\u0001\u001d"+
- "\u0001\u001d\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001f\u0001\u001f"+
- "\u0001 \u0001 \u0003 \u01a9\b \u0001 \u0004 \u01ac\b \u000b \f \u01ad"+
- "\u0001!\u0001!\u0001!\u0005!\u01b3\b!\n!\f!\u01b6\t!\u0001!\u0001!\u0001"+
- "!\u0001!\u0001!\u0001!\u0005!\u01be\b!\n!\f!\u01c1\t!\u0001!\u0001!\u0001"+
- "!\u0001!\u0001!\u0003!\u01c8\b!\u0001!\u0003!\u01cb\b!\u0003!\u01cd\b"+
- "!\u0001\"\u0004\"\u01d0\b\"\u000b\"\f\"\u01d1\u0001#\u0004#\u01d5\b#\u000b"+
- "#\f#\u01d6\u0001#\u0001#\u0005#\u01db\b#\n#\f#\u01de\t#\u0001#\u0001#"+
- "\u0004#\u01e2\b#\u000b#\f#\u01e3\u0001#\u0004#\u01e7\b#\u000b#\f#\u01e8"+
- "\u0001#\u0001#\u0005#\u01ed\b#\n#\f#\u01f0\t#\u0003#\u01f2\b#\u0001#\u0001"+
- "#\u0001#\u0001#\u0004#\u01f8\b#\u000b#\f#\u01f9\u0001#\u0001#\u0003#\u01fe"+
- "\b#\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\u00010\u00010\u0001"+
- "1\u00011\u00011\u00011\u00012\u00012\u00012\u00012\u00012\u00013\u0001"+
- "3\u00013\u00013\u00013\u00013\u00014\u00014\u00014\u00015\u00015\u0001"+
- "6\u00016\u00016\u00016\u00016\u00016\u00017\u00017\u00018\u00018\u0001"+
- "8\u00018\u00018\u00019\u00019\u00019\u00019\u00019\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@\u0001A\u0001A\u0001B\u0001B\u0001C\u0001C\u0001"+
- "D\u0001D\u0001E\u0001E\u0001F\u0001F\u0001F\u0001F\u0001F\u0001G\u0001"+
- "G\u0001G\u0001G\u0001G\u0001H\u0001H\u0001H\u0001H\u0005H\u0289\bH\nH"+
- "\fH\u028c\tH\u0001H\u0001H\u0001H\u0001H\u0004H\u0292\bH\u000bH\fH\u0293"+
- "\u0003H\u0296\bH\u0001I\u0001I\u0001I\u0001I\u0005I\u029c\bI\nI\fI\u029f"+
- "\tI\u0001I\u0001I\u0001J\u0001J\u0001J\u0001J\u0001K\u0001K\u0001K\u0001"+
- "K\u0001L\u0001L\u0001L\u0001L\u0001M\u0001M\u0001M\u0001M\u0001M\u0001"+
- "N\u0001N\u0001N\u0001N\u0001N\u0001N\u0001O\u0001O\u0001O\u0001O\u0001"+
- "O\u0001O\u0001P\u0001P\u0001P\u0001P\u0001Q\u0001Q\u0001Q\u0001Q\u0001"+
- "R\u0001R\u0001R\u0001S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001"+
- "S\u0001S\u0001T\u0001T\u0001T\u0001U\u0001U\u0001U\u0001U\u0001U\u0001"+
- "V\u0004V\u02dd\bV\u000bV\fV\u02de\u0001W\u0004W\u02e2\bW\u000bW\fW\u02e3"+
- "\u0001W\u0001W\u0003W\u02e8\bW\u0001X\u0001X\u0001Y\u0001Y\u0001Y\u0001"+
- "Y\u0001Z\u0001Z\u0001Z\u0001Z\u0001[\u0001[\u0001[\u0001[\u0002\u0174"+
- "\u01bf\u0000\\\u0004\u0001\u0006\u0002\b\u0003\n\u0004\f\u0005\u000e\u0006"+
- "\u0010\u0007\u0012\b\u0014\t\u0016\n\u0018\u000b\u001a\f\u001c\r\u001e"+
- "\u000e \u000f\"\u0010$\u0011&\u0012(\u0013*\u0014,\u0015.\u00160\u0000"+
- "2P4\u00176\u00188\u0019:\u001a<\u0000>\u0000@\u0000B\u0000D\u0000F\u001b"+
- "H\u001cJ\u001dL\u001eN\u001fP R!T\"V#X$Z%\\&^\'`(b)d*f+h,j-l.n/p0r1t2"+
- "v3x4z5|6~7\u00808\u00829\u0084:\u0086;\u0088<\u008a=\u008c>\u008e?\u0090"+
- "@\u0092A\u0094B\u0096C\u0098D\u009aE\u009cF\u009e\u0000\u00a0\u0000\u00a2"+
- "\u0000\u00a4\u0000\u00a6\u0000\u00a8G\u00aaH\u00acI\u00aeJ\u00b0K\u00b2"+
- "\u0000\u00b4L\u00b6M\u00b8N\u00baO\u0004\u0000\u0001\u0002\u0003\r\u0006"+
- "\u0000\t\n\r\r //[[]]\u0002\u0000\n\n\r\r\u0003\u0000\t\n\r\r \u0001"+
- "\u000009\u0002\u0000AZaz\u0005\u0000\"\"\\\\nnrrtt\u0004\u0000\n\n\r\r"+
- "\"\"\\\\\u0002\u0000EEee\u0002\u0000++--\u0002\u0000@@__\u0001\u0000`"+
- "`\n\u0000\t\n\r\r ,,//==[[]]``||\u0002\u0000**//\u0313\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\u00010\u0001\u0000\u0000\u0000\u00012\u0001\u0000\u0000\u0000\u0001"+
- "4\u0001\u0000\u0000\u0000\u00016\u0001\u0000\u0000\u0000\u00018\u0001"+
- "\u0000\u0000\u0000\u0002:\u0001\u0000\u0000\u0000\u0002F\u0001\u0000\u0000"+
- "\u0000\u0002H\u0001\u0000\u0000\u0000\u0002J\u0001\u0000\u0000\u0000\u0002"+
- "L\u0001\u0000\u0000\u0000\u0002N\u0001\u0000\u0000\u0000\u0002P\u0001"+
- "\u0000\u0000\u0000\u0002R\u0001\u0000\u0000\u0000\u0002T\u0001\u0000\u0000"+
- "\u0000\u0002V\u0001\u0000\u0000\u0000\u0002X\u0001\u0000\u0000\u0000\u0002"+
- "Z\u0001\u0000\u0000\u0000\u0002\\\u0001\u0000\u0000\u0000\u0002^\u0001"+
- "\u0000\u0000\u0000\u0002`\u0001\u0000\u0000\u0000\u0002b\u0001\u0000\u0000"+
- "\u0000\u0002d\u0001\u0000\u0000\u0000\u0002f\u0001\u0000\u0000\u0000\u0002"+
- "h\u0001\u0000\u0000\u0000\u0002j\u0001\u0000\u0000\u0000\u0002l\u0001"+
- "\u0000\u0000\u0000\u0002n\u0001\u0000\u0000\u0000\u0002p\u0001\u0000\u0000"+
- "\u0000\u0002r\u0001\u0000\u0000\u0000\u0002t\u0001\u0000\u0000\u0000\u0002"+
- "v\u0001\u0000\u0000\u0000\u0002x\u0001\u0000\u0000\u0000\u0002z\u0001"+
- "\u0000\u0000\u0000\u0002|\u0001\u0000\u0000\u0000\u0002~\u0001\u0000\u0000"+
- "\u0000\u0002\u0080\u0001\u0000\u0000\u0000\u0002\u0082\u0001\u0000\u0000"+
- "\u0000\u0002\u0084\u0001\u0000\u0000\u0000\u0002\u0086\u0001\u0000\u0000"+
- "\u0000\u0002\u0088\u0001\u0000\u0000\u0000\u0002\u008a\u0001\u0000\u0000"+
- "\u0000\u0002\u008c\u0001\u0000\u0000\u0000\u0002\u008e\u0001\u0000\u0000"+
- "\u0000\u0002\u0090\u0001\u0000\u0000\u0000\u0002\u0092\u0001\u0000\u0000"+
- "\u0000\u0002\u0094\u0001\u0000\u0000\u0000\u0002\u0096\u0001\u0000\u0000"+
- "\u0000\u0002\u0098\u0001\u0000\u0000\u0000\u0002\u009a\u0001\u0000\u0000"+
- "\u0000\u0002\u009c\u0001\u0000\u0000\u0000\u0003\u009e\u0001\u0000\u0000"+
- "\u0000\u0003\u00a0\u0001\u0000\u0000\u0000\u0003\u00a2\u0001\u0000\u0000"+
- "\u0000\u0003\u00a4\u0001\u0000\u0000\u0000\u0003\u00a6\u0001\u0000\u0000"+
- "\u0000\u0003\u00a8\u0001\u0000\u0000\u0000\u0003\u00aa\u0001\u0000\u0000"+
- "\u0000\u0003\u00ac\u0001\u0000\u0000\u0000\u0003\u00ae\u0001\u0000\u0000"+
- "\u0000\u0003\u00b0\u0001\u0000\u0000\u0000\u0003\u00b4\u0001\u0000\u0000"+
- "\u0000\u0003\u00b6\u0001\u0000\u0000\u0000\u0003\u00b8\u0001\u0000\u0000"+
- "\u0000\u0003\u00ba\u0001\u0000\u0000\u0000\u0004\u00bc\u0001\u0000\u0000"+
- "\u0000\u0006\u00c6\u0001\u0000\u0000\u0000\b\u00cd\u0001\u0000\u0000\u0000"+
- "\n\u00d6\u0001\u0000\u0000\u0000\f\u00dd\u0001\u0000\u0000\u0000\u000e"+
- "\u00e7\u0001\u0000\u0000\u0000\u0010\u00ee\u0001\u0000\u0000\u0000\u0012"+
- "\u00f5\u0001\u0000\u0000\u0000\u0014\u0103\u0001\u0000\u0000\u0000\u0016"+
- "\u010a\u0001\u0000\u0000\u0000\u0018\u0112\u0001\u0000\u0000\u0000\u001a"+
- "\u011e\u0001\u0000\u0000\u0000\u001c\u0128\u0001\u0000\u0000\u0000\u001e"+
- "\u0131\u0001\u0000\u0000\u0000 \u0137\u0001\u0000\u0000\u0000\"\u013e"+
- "\u0001\u0000\u0000\u0000$\u0145\u0001\u0000\u0000\u0000&\u014d\u0001\u0000"+
- "\u0000\u0000(\u0156\u0001\u0000\u0000\u0000*\u015c\u0001\u0000\u0000\u0000"+
- ",\u016d\u0001\u0000\u0000\u0000.\u017d\u0001\u0000\u0000\u00000\u0183"+
- "\u0001\u0000\u0000\u00002\u0188\u0001\u0000\u0000\u00004\u018d\u0001\u0000"+
- "\u0000\u00006\u0191\u0001\u0000\u0000\u00008\u0195\u0001\u0000\u0000\u0000"+
- ":\u0199\u0001\u0000\u0000\u0000<\u019d\u0001\u0000\u0000\u0000>\u019f"+
- "\u0001\u0000\u0000\u0000@\u01a1\u0001\u0000\u0000\u0000B\u01a4\u0001\u0000"+
- "\u0000\u0000D\u01a6\u0001\u0000\u0000\u0000F\u01cc\u0001\u0000\u0000\u0000"+
- "H\u01cf\u0001\u0000\u0000\u0000J\u01fd\u0001\u0000\u0000\u0000L\u01ff"+
- "\u0001\u0000\u0000\u0000N\u0202\u0001\u0000\u0000\u0000P\u0206\u0001\u0000"+
- "\u0000\u0000R\u020a\u0001\u0000\u0000\u0000T\u020c\u0001\u0000\u0000\u0000"+
- "V\u020e\u0001\u0000\u0000\u0000X\u0213\u0001\u0000\u0000\u0000Z\u0215"+
- "\u0001\u0000\u0000\u0000\\\u021b\u0001\u0000\u0000\u0000^\u0221\u0001"+
- "\u0000\u0000\u0000`\u0226\u0001\u0000\u0000\u0000b\u0228\u0001\u0000\u0000"+
- "\u0000d\u022b\u0001\u0000\u0000\u0000f\u0230\u0001\u0000\u0000\u0000h"+
- "\u0234\u0001\u0000\u0000\u0000j\u0239\u0001\u0000\u0000\u0000l\u023f\u0001"+
- "\u0000\u0000\u0000n\u0242\u0001\u0000\u0000\u0000p\u0244\u0001\u0000\u0000"+
- "\u0000r\u024a\u0001\u0000\u0000\u0000t\u024c\u0001\u0000\u0000\u0000v"+
- "\u0251\u0001\u0000\u0000\u0000x\u0256\u0001\u0000\u0000\u0000z\u0260\u0001"+
- "\u0000\u0000\u0000|\u0263\u0001\u0000\u0000\u0000~\u0266\u0001\u0000\u0000"+
- "\u0000\u0080\u0268\u0001\u0000\u0000\u0000\u0082\u026b\u0001\u0000\u0000"+
- "\u0000\u0084\u026d\u0001\u0000\u0000\u0000\u0086\u0270\u0001\u0000\u0000"+
- "\u0000\u0088\u0272\u0001\u0000\u0000\u0000\u008a\u0274\u0001\u0000\u0000"+
- "\u0000\u008c\u0276\u0001\u0000\u0000\u0000\u008e\u0278\u0001\u0000\u0000"+
- "\u0000\u0090\u027a\u0001\u0000\u0000\u0000\u0092\u027f\u0001\u0000\u0000"+
- "\u0000\u0094\u0295\u0001\u0000\u0000\u0000\u0096\u0297\u0001\u0000\u0000"+
- "\u0000\u0098\u02a2\u0001\u0000\u0000\u0000\u009a\u02a6\u0001\u0000\u0000"+
- "\u0000\u009c\u02aa\u0001\u0000\u0000\u0000\u009e\u02ae\u0001\u0000\u0000"+
- "\u0000\u00a0\u02b3\u0001\u0000\u0000\u0000\u00a2\u02b9\u0001\u0000\u0000"+
- "\u0000\u00a4\u02bf\u0001\u0000\u0000\u0000\u00a6\u02c3\u0001\u0000\u0000"+
- "\u0000\u00a8\u02c7\u0001\u0000\u0000\u0000\u00aa\u02ca\u0001\u0000\u0000"+
- "\u0000\u00ac\u02d3\u0001\u0000\u0000\u0000\u00ae\u02d6\u0001\u0000\u0000"+
- "\u0000\u00b0\u02dc\u0001\u0000\u0000\u0000\u00b2\u02e7\u0001\u0000\u0000"+
- "\u0000\u00b4\u02e9\u0001\u0000\u0000\u0000\u00b6\u02eb\u0001\u0000\u0000"+
- "\u0000\u00b8\u02ef\u0001\u0000\u0000\u0000\u00ba\u02f3\u0001\u0000\u0000"+
- "\u0000\u00bc\u00bd\u0005d\u0000\u0000\u00bd\u00be\u0005i\u0000\u0000\u00be"+
- "\u00bf\u0005s\u0000\u0000\u00bf\u00c0\u0005s\u0000\u0000\u00c0\u00c1\u0005"+
- "e\u0000\u0000\u00c1\u00c2\u0005c\u0000\u0000\u00c2\u00c3\u0005t\u0000"+
- "\u0000\u00c3\u00c4\u0001\u0000\u0000\u0000\u00c4\u00c5\u0006\u0000\u0000"+
- "\u0000\u00c5\u0005\u0001\u0000\u0000\u0000\u00c6\u00c7\u0005d\u0000\u0000"+
- "\u00c7\u00c8\u0005r\u0000\u0000\u00c8\u00c9\u0005o\u0000\u0000\u00c9\u00ca"+
- "\u0005p\u0000\u0000\u00ca\u00cb\u0001\u0000\u0000\u0000\u00cb\u00cc\u0006"+
- "\u0001\u0001\u0000\u00cc\u0007\u0001\u0000\u0000\u0000\u00cd\u00ce\u0005"+
- "e\u0000\u0000\u00ce\u00cf\u0005n\u0000\u0000\u00cf\u00d0\u0005r\u0000"+
- "\u0000\u00d0\u00d1\u0005i\u0000\u0000\u00d1\u00d2\u0005c\u0000\u0000\u00d2"+
- "\u00d3\u0005h\u0000\u0000\u00d3\u00d4\u0001\u0000\u0000\u0000\u00d4\u00d5"+
- "\u0006\u0002\u0001\u0000\u00d5\t\u0001\u0000\u0000\u0000\u00d6\u00d7\u0005"+
- "e\u0000\u0000\u00d7\u00d8\u0005v\u0000\u0000\u00d8\u00d9\u0005a\u0000"+
- "\u0000\u00d9\u00da\u0005l\u0000\u0000\u00da\u00db\u0001\u0000\u0000\u0000"+
- "\u00db\u00dc\u0006\u0003\u0000\u0000\u00dc\u000b\u0001\u0000\u0000\u0000"+
- "\u00dd\u00de\u0005e\u0000\u0000\u00de\u00df\u0005x\u0000\u0000\u00df\u00e0"+
- "\u0005p\u0000\u0000\u00e0\u00e1\u0005l\u0000\u0000\u00e1\u00e2\u0005a"+
- "\u0000\u0000\u00e2\u00e3\u0005i\u0000\u0000\u00e3\u00e4\u0005n\u0000\u0000"+
- "\u00e4\u00e5\u0001\u0000\u0000\u0000\u00e5\u00e6\u0006\u0004\u0002\u0000"+
- "\u00e6\r\u0001\u0000\u0000\u0000\u00e7\u00e8\u0005f\u0000\u0000\u00e8"+
- "\u00e9\u0005r\u0000\u0000\u00e9\u00ea\u0005o\u0000\u0000\u00ea\u00eb\u0005"+
- "m\u0000\u0000\u00eb\u00ec\u0001\u0000\u0000\u0000\u00ec\u00ed\u0006\u0005"+
- "\u0001\u0000\u00ed\u000f\u0001\u0000\u0000\u0000\u00ee\u00ef\u0005g\u0000"+
- "\u0000\u00ef\u00f0\u0005r\u0000\u0000\u00f0\u00f1\u0005o\u0000\u0000\u00f1"+
- "\u00f2\u0005k\u0000\u0000\u00f2\u00f3\u0001\u0000\u0000\u0000\u00f3\u00f4"+
- "\u0006\u0006\u0000\u0000\u00f4\u0011\u0001\u0000\u0000\u0000\u00f5\u00f6"+
- "\u0005i\u0000\u0000\u00f6\u00f7\u0005n\u0000\u0000\u00f7\u00f8\u0005l"+
- "\u0000\u0000\u00f8\u00f9\u0005i\u0000\u0000\u00f9\u00fa\u0005n\u0000\u0000"+
- "\u00fa\u00fb\u0005e\u0000\u0000\u00fb\u00fc\u0005s\u0000\u0000\u00fc\u00fd"+
- "\u0005t\u0000\u0000\u00fd\u00fe\u0005a\u0000\u0000\u00fe\u00ff\u0005t"+
- "\u0000\u0000\u00ff\u0100\u0005s\u0000\u0000\u0100\u0101\u0001\u0000\u0000"+
- "\u0000\u0101\u0102\u0006\u0007\u0000\u0000\u0102\u0013\u0001\u0000\u0000"+
- "\u0000\u0103\u0104\u0005k\u0000\u0000\u0104\u0105\u0005e\u0000\u0000\u0105"+
- "\u0106\u0005e\u0000\u0000\u0106\u0107\u0005p\u0000\u0000\u0107\u0108\u0001"+
- "\u0000\u0000\u0000\u0108\u0109\u0006\b\u0001\u0000\u0109\u0015\u0001\u0000"+
- "\u0000\u0000\u010a\u010b\u0005l\u0000\u0000\u010b\u010c\u0005i\u0000\u0000"+
- "\u010c\u010d\u0005m\u0000\u0000\u010d\u010e\u0005i\u0000\u0000\u010e\u010f"+
- "\u0005t\u0000\u0000\u010f\u0110\u0001\u0000\u0000\u0000\u0110\u0111\u0006"+
- "\t\u0000\u0000\u0111\u0017\u0001\u0000\u0000\u0000\u0112\u0113\u0005m"+
- "\u0000\u0000\u0113\u0114\u0005v\u0000\u0000\u0114\u0115\u0005_\u0000\u0000"+
- "\u0115\u0116\u0005e\u0000\u0000\u0116\u0117\u0005x\u0000\u0000\u0117\u0118"+
- "\u0005p\u0000\u0000\u0118\u0119\u0005a\u0000\u0000\u0119\u011a\u0005n"+
- "\u0000\u0000\u011a\u011b\u0005d\u0000\u0000\u011b\u011c\u0001\u0000\u0000"+
- "\u0000\u011c\u011d\u0006\n\u0001\u0000\u011d\u0019\u0001\u0000\u0000\u0000"+
- "\u011e\u011f\u0005p\u0000\u0000\u011f\u0120\u0005r\u0000\u0000\u0120\u0121"+
- "\u0005o\u0000\u0000\u0121\u0122\u0005j\u0000\u0000\u0122\u0123\u0005e"+
- "\u0000\u0000\u0123\u0124\u0005c\u0000\u0000\u0124\u0125\u0005t\u0000\u0000"+
- "\u0125\u0126\u0001\u0000\u0000\u0000\u0126\u0127\u0006\u000b\u0001\u0000"+
- "\u0127\u001b\u0001\u0000\u0000\u0000\u0128\u0129\u0005r\u0000\u0000\u0129"+
- "\u012a\u0005e\u0000\u0000\u012a\u012b\u0005n\u0000\u0000\u012b\u012c\u0005"+
- "a\u0000\u0000\u012c\u012d\u0005m\u0000\u0000\u012d\u012e\u0005e\u0000"+
- "\u0000\u012e\u012f\u0001\u0000\u0000\u0000\u012f\u0130\u0006\f\u0001\u0000"+
- "\u0130\u001d\u0001\u0000\u0000\u0000\u0131\u0132\u0005r\u0000\u0000\u0132"+
- "\u0133\u0005o\u0000\u0000\u0133\u0134\u0005w\u0000\u0000\u0134\u0135\u0001"+
- "\u0000\u0000\u0000\u0135\u0136\u0006\r\u0000\u0000\u0136\u001f\u0001\u0000"+
- "\u0000\u0000\u0137\u0138\u0005s\u0000\u0000\u0138\u0139\u0005h\u0000\u0000"+
- "\u0139\u013a\u0005o\u0000\u0000\u013a\u013b\u0005w\u0000\u0000\u013b\u013c"+
- "\u0001\u0000\u0000\u0000\u013c\u013d\u0006\u000e\u0000\u0000\u013d!\u0001"+
- "\u0000\u0000\u0000\u013e\u013f\u0005s\u0000\u0000\u013f\u0140\u0005o\u0000"+
- "\u0000\u0140\u0141\u0005r\u0000\u0000\u0141\u0142\u0005t\u0000\u0000\u0142"+
- "\u0143\u0001\u0000\u0000\u0000\u0143\u0144\u0006\u000f\u0000\u0000\u0144"+
- "#\u0001\u0000\u0000\u0000\u0145\u0146\u0005s\u0000\u0000\u0146\u0147\u0005"+
- "t\u0000\u0000\u0147\u0148\u0005a\u0000\u0000\u0148\u0149\u0005t\u0000"+
- "\u0000\u0149\u014a\u0005s\u0000\u0000\u014a\u014b\u0001\u0000\u0000\u0000"+
- "\u014b\u014c\u0006\u0010\u0000\u0000\u014c%\u0001\u0000\u0000\u0000\u014d"+
- "\u014e\u0005w\u0000\u0000\u014e\u014f\u0005h\u0000\u0000\u014f\u0150\u0005"+
- "e\u0000\u0000\u0150\u0151\u0005r\u0000\u0000\u0151\u0152\u0005e\u0000"+
- "\u0000\u0152\u0153\u0001\u0000\u0000\u0000\u0153\u0154\u0006\u0011\u0000"+
- "\u0000\u0154\'\u0001\u0000\u0000\u0000\u0155\u0157\b\u0000\u0000\u0000"+
- "\u0156\u0155\u0001\u0000\u0000\u0000\u0157\u0158\u0001\u0000\u0000\u0000"+
- "\u0158\u0156\u0001\u0000\u0000\u0000\u0158\u0159\u0001\u0000\u0000\u0000"+
- "\u0159\u015a\u0001\u0000\u0000\u0000\u015a\u015b\u0006\u0012\u0000\u0000"+
- "\u015b)\u0001\u0000\u0000\u0000\u015c\u015d\u0005/\u0000\u0000\u015d\u015e"+
- "\u0005/\u0000\u0000\u015e\u0162\u0001\u0000\u0000\u0000\u015f\u0161\b"+
- "\u0001\u0000\u0000\u0160\u015f\u0001\u0000\u0000\u0000\u0161\u0164\u0001"+
- "\u0000\u0000\u0000\u0162\u0160\u0001\u0000\u0000\u0000\u0162\u0163\u0001"+
+ "\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011"+
+ "\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0012\u0004\u0012"+
+ "\u0159\b\u0012\u000b\u0012\f\u0012\u015a\u0001\u0012\u0001\u0012\u0001"+
+ "\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0005\u0013\u0163\b\u0013\n"+
+ "\u0013\f\u0013\u0166\t\u0013\u0001\u0013\u0003\u0013\u0169\b\u0013\u0001"+
+ "\u0013\u0003\u0013\u016c\b\u0013\u0001\u0013\u0001\u0013\u0001\u0014\u0001"+
+ "\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0005\u0014\u0175\b\u0014\n"+
+ "\u0014\f\u0014\u0178\t\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001"+
+ "\u0014\u0001\u0014\u0001\u0015\u0004\u0015\u0180\b\u0015\u000b\u0015\f"+
+ "\u0015\u0181\u0001\u0015\u0001\u0015\u0001\u0016\u0001\u0016\u0001\u0016"+
+ "\u0001\u0016\u0001\u0016\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017"+
+ "\u0001\u0017\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0019"+
+ "\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u001a\u0001\u001a\u0001\u001a"+
+ "\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001c"+
+ "\u0001\u001c\u0001\u001d\u0001\u001d\u0001\u001e\u0001\u001e\u0001\u001e"+
+ "\u0001\u001f\u0001\u001f\u0001 \u0001 \u0003 \u01ab\b \u0001 \u0004 \u01ae"+
+ "\b \u000b \f \u01af\u0001!\u0001!\u0001!\u0005!\u01b5\b!\n!\f!\u01b8\t"+
+ "!\u0001!\u0001!\u0001!\u0001!\u0001!\u0001!\u0005!\u01c0\b!\n!\f!\u01c3"+
+ "\t!\u0001!\u0001!\u0001!\u0001!\u0001!\u0003!\u01ca\b!\u0001!\u0003!\u01cd"+
+ "\b!\u0003!\u01cf\b!\u0001\"\u0004\"\u01d2\b\"\u000b\"\f\"\u01d3\u0001"+
+ "#\u0004#\u01d7\b#\u000b#\f#\u01d8\u0001#\u0001#\u0005#\u01dd\b#\n#\f#"+
+ "\u01e0\t#\u0001#\u0001#\u0004#\u01e4\b#\u000b#\f#\u01e5\u0001#\u0004#"+
+ "\u01e9\b#\u000b#\f#\u01ea\u0001#\u0001#\u0005#\u01ef\b#\n#\f#\u01f2\t"+
+ "#\u0003#\u01f4\b#\u0001#\u0001#\u0001#\u0001#\u0004#\u01fa\b#\u000b#\f"+
+ "#\u01fb\u0001#\u0001#\u0003#\u0200\b#\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/\u0001"+
+ "0\u00010\u00010\u00011\u00011\u00011\u00011\u00011\u00012\u00012\u0001"+
+ "2\u00012\u00013\u00013\u00013\u00013\u00013\u00014\u00014\u00014\u0001"+
+ "4\u00014\u00014\u00015\u00015\u00015\u00016\u00016\u00017\u00017\u0001"+
+ "7\u00017\u00017\u00017\u00018\u00018\u00019\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"+
+ "=\u0001=\u0001>\u0001>\u0001?\u0001?\u0001?\u0001@\u0001@\u0001A\u0001"+
+ "A\u0001A\u0001B\u0001B\u0001C\u0001C\u0001D\u0001D\u0001E\u0001E\u0001"+
+ "F\u0001F\u0001G\u0001G\u0001G\u0001G\u0001G\u0001H\u0001H\u0001H\u0001"+
+ "H\u0001H\u0001I\u0001I\u0001I\u0001I\u0005I\u028e\bI\nI\fI\u0291\tI\u0001"+
+ "I\u0001I\u0001I\u0001I\u0004I\u0297\bI\u000bI\fI\u0298\u0003I\u029b\b"+
+ "I\u0001J\u0001J\u0001J\u0001J\u0005J\u02a1\bJ\nJ\fJ\u02a4\tJ\u0001J\u0001"+
+ "J\u0001K\u0001K\u0001K\u0001K\u0001L\u0001L\u0001L\u0001L\u0001M\u0001"+
+ "M\u0001M\u0001M\u0001N\u0001N\u0001N\u0001N\u0001N\u0001O\u0001O\u0001"+
+ "O\u0001O\u0001O\u0001O\u0001P\u0001P\u0001P\u0001P\u0001P\u0001P\u0001"+
+ "Q\u0001Q\u0001Q\u0001Q\u0001R\u0001R\u0001R\u0001R\u0001S\u0001S\u0001"+
+ "S\u0001T\u0001T\u0001T\u0001T\u0001T\u0001T\u0001T\u0001T\u0001T\u0001"+
+ "U\u0001U\u0001U\u0001V\u0001V\u0001V\u0001V\u0001V\u0001W\u0004W\u02e2"+
+ "\bW\u000bW\fW\u02e3\u0001X\u0004X\u02e7\bX\u000bX\fX\u02e8\u0001X\u0001"+
+ "X\u0003X\u02ed\bX\u0001Y\u0001Y\u0001Z\u0001Z\u0001Z\u0001Z\u0001[\u0001"+
+ "[\u0001[\u0001[\u0001\\\u0001\\\u0001\\\u0001\\\u0002\u0176\u01c1\u0000"+
+ "]\u0004\u0001\u0006\u0002\b\u0003\n\u0004\f\u0005\u000e\u0006\u0010\u0007"+
+ "\u0012\b\u0014\t\u0016\n\u0018\u000b\u001a\f\u001c\r\u001e\u000e \u000f"+
+ "\"\u0010$\u0011&\u0012(\u0013*\u0014,\u0015.\u00160\u00002Q4\u00176\u0018"+
+ "8\u0019:\u001a<\u0000>\u0000@\u0000B\u0000D\u0000F\u001bH\u001cJ\u001d"+
+ "L\u001eN\u001fP R!T\"V#X$Z%\\&^\'`(b)d*f+h,j-l.n/p0r1t2v3x4z5|6~7\u0080"+
+ "8\u00829\u0084:\u0086;\u0088<\u008a=\u008c>\u008e?\u0090@\u0092A\u0094"+
+ "B\u0096C\u0098D\u009aE\u009cF\u009eG\u00a0\u0000\u00a2\u0000\u00a4\u0000"+
+ "\u00a6\u0000\u00a8\u0000\u00aaH\u00acI\u00aeJ\u00b0K\u00b2L\u00b4\u0000"+
+ "\u00b6M\u00b8N\u00baO\u00bcP\u0004\u0000\u0001\u0002\u0003\r\u0006\u0000"+
+ "\t\n\r\r //[[]]\u0002\u0000\n\n\r\r\u0003\u0000\t\n\r\r \u0001\u0000"+
+ "09\u0002\u0000AZaz\u0005\u0000\"\"\\\\nnrrtt\u0004\u0000\n\n\r\r\"\"\\"+
+ "\\\u0002\u0000EEee\u0002\u0000++--\u0002\u0000@@__\u0001\u0000``\n\u0000"+
+ "\t\n\r\r ,,//==[[]]``||\u0002\u0000**//\u0318\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\u0001"+
+ "0\u0001\u0000\u0000\u0000\u00012\u0001\u0000\u0000\u0000\u00014\u0001"+
+ "\u0000\u0000\u0000\u00016\u0001\u0000\u0000\u0000\u00018\u0001\u0000\u0000"+
+ "\u0000\u0002:\u0001\u0000\u0000\u0000\u0002F\u0001\u0000\u0000\u0000\u0002"+
+ "H\u0001\u0000\u0000\u0000\u0002J\u0001\u0000\u0000\u0000\u0002L\u0001"+
+ "\u0000\u0000\u0000\u0002N\u0001\u0000\u0000\u0000\u0002P\u0001\u0000\u0000"+
+ "\u0000\u0002R\u0001\u0000\u0000\u0000\u0002T\u0001\u0000\u0000\u0000\u0002"+
+ "V\u0001\u0000\u0000\u0000\u0002X\u0001\u0000\u0000\u0000\u0002Z\u0001"+
+ "\u0000\u0000\u0000\u0002\\\u0001\u0000\u0000\u0000\u0002^\u0001\u0000"+
+ "\u0000\u0000\u0002`\u0001\u0000\u0000\u0000\u0002b\u0001\u0000\u0000\u0000"+
+ "\u0002d\u0001\u0000\u0000\u0000\u0002f\u0001\u0000\u0000\u0000\u0002h"+
+ "\u0001\u0000\u0000\u0000\u0002j\u0001\u0000\u0000\u0000\u0002l\u0001\u0000"+
+ "\u0000\u0000\u0002n\u0001\u0000\u0000\u0000\u0002p\u0001\u0000\u0000\u0000"+
+ "\u0002r\u0001\u0000\u0000\u0000\u0002t\u0001\u0000\u0000\u0000\u0002v"+
+ "\u0001\u0000\u0000\u0000\u0002x\u0001\u0000\u0000\u0000\u0002z\u0001\u0000"+
+ "\u0000\u0000\u0002|\u0001\u0000\u0000\u0000\u0002~\u0001\u0000\u0000\u0000"+
+ "\u0002\u0080\u0001\u0000\u0000\u0000\u0002\u0082\u0001\u0000\u0000\u0000"+
+ "\u0002\u0084\u0001\u0000\u0000\u0000\u0002\u0086\u0001\u0000\u0000\u0000"+
+ "\u0002\u0088\u0001\u0000\u0000\u0000\u0002\u008a\u0001\u0000\u0000\u0000"+
+ "\u0002\u008c\u0001\u0000\u0000\u0000\u0002\u008e\u0001\u0000\u0000\u0000"+
+ "\u0002\u0090\u0001\u0000\u0000\u0000\u0002\u0092\u0001\u0000\u0000\u0000"+
+ "\u0002\u0094\u0001\u0000\u0000\u0000\u0002\u0096\u0001\u0000\u0000\u0000"+
+ "\u0002\u0098\u0001\u0000\u0000\u0000\u0002\u009a\u0001\u0000\u0000\u0000"+
+ "\u0002\u009c\u0001\u0000\u0000\u0000\u0002\u009e\u0001\u0000\u0000\u0000"+
+ "\u0003\u00a0\u0001\u0000\u0000\u0000\u0003\u00a2\u0001\u0000\u0000\u0000"+
+ "\u0003\u00a4\u0001\u0000\u0000\u0000\u0003\u00a6\u0001\u0000\u0000\u0000"+
+ "\u0003\u00a8\u0001\u0000\u0000\u0000\u0003\u00aa\u0001\u0000\u0000\u0000"+
+ "\u0003\u00ac\u0001\u0000\u0000\u0000\u0003\u00ae\u0001\u0000\u0000\u0000"+
+ "\u0003\u00b0\u0001\u0000\u0000\u0000\u0003\u00b2\u0001\u0000\u0000\u0000"+
+ "\u0003\u00b6\u0001\u0000\u0000\u0000\u0003\u00b8\u0001\u0000\u0000\u0000"+
+ "\u0003\u00ba\u0001\u0000\u0000\u0000\u0003\u00bc\u0001\u0000\u0000\u0000"+
+ "\u0004\u00be\u0001\u0000\u0000\u0000\u0006\u00c8\u0001\u0000\u0000\u0000"+
+ "\b\u00cf\u0001\u0000\u0000\u0000\n\u00d8\u0001\u0000\u0000\u0000\f\u00df"+
+ "\u0001\u0000\u0000\u0000\u000e\u00e9\u0001\u0000\u0000\u0000\u0010\u00f0"+
+ "\u0001\u0000\u0000\u0000\u0012\u00f7\u0001\u0000\u0000\u0000\u0014\u0105"+
+ "\u0001\u0000\u0000\u0000\u0016\u010c\u0001\u0000\u0000\u0000\u0018\u0114"+
+ "\u0001\u0000\u0000\u0000\u001a\u0120\u0001\u0000\u0000\u0000\u001c\u012a"+
+ "\u0001\u0000\u0000\u0000\u001e\u0133\u0001\u0000\u0000\u0000 \u0139\u0001"+
+ "\u0000\u0000\u0000\"\u0140\u0001\u0000\u0000\u0000$\u0147\u0001\u0000"+
+ "\u0000\u0000&\u014f\u0001\u0000\u0000\u0000(\u0158\u0001\u0000\u0000\u0000"+
+ "*\u015e\u0001\u0000\u0000\u0000,\u016f\u0001\u0000\u0000\u0000.\u017f"+
+ "\u0001\u0000\u0000\u00000\u0185\u0001\u0000\u0000\u00002\u018a\u0001\u0000"+
+ "\u0000\u00004\u018f\u0001\u0000\u0000\u00006\u0193\u0001\u0000\u0000\u0000"+
+ "8\u0197\u0001\u0000\u0000\u0000:\u019b\u0001\u0000\u0000\u0000<\u019f"+
+ "\u0001\u0000\u0000\u0000>\u01a1\u0001\u0000\u0000\u0000@\u01a3\u0001\u0000"+
+ "\u0000\u0000B\u01a6\u0001\u0000\u0000\u0000D\u01a8\u0001\u0000\u0000\u0000"+
+ "F\u01ce\u0001\u0000\u0000\u0000H\u01d1\u0001\u0000\u0000\u0000J\u01ff"+
+ "\u0001\u0000\u0000\u0000L\u0201\u0001\u0000\u0000\u0000N\u0204\u0001\u0000"+
+ "\u0000\u0000P\u0208\u0001\u0000\u0000\u0000R\u020c\u0001\u0000\u0000\u0000"+
+ "T\u020e\u0001\u0000\u0000\u0000V\u0210\u0001\u0000\u0000\u0000X\u0215"+
+ "\u0001\u0000\u0000\u0000Z\u0217\u0001\u0000\u0000\u0000\\\u021d\u0001"+
+ "\u0000\u0000\u0000^\u0223\u0001\u0000\u0000\u0000`\u0228\u0001\u0000\u0000"+
+ "\u0000b\u022a\u0001\u0000\u0000\u0000d\u022d\u0001\u0000\u0000\u0000f"+
+ "\u0230\u0001\u0000\u0000\u0000h\u0235\u0001\u0000\u0000\u0000j\u0239\u0001"+
+ "\u0000\u0000\u0000l\u023e\u0001\u0000\u0000\u0000n\u0244\u0001\u0000\u0000"+
+ "\u0000p\u0247\u0001\u0000\u0000\u0000r\u0249\u0001\u0000\u0000\u0000t"+
+ "\u024f\u0001\u0000\u0000\u0000v\u0251\u0001\u0000\u0000\u0000x\u0256\u0001"+
+ "\u0000\u0000\u0000z\u025b\u0001\u0000\u0000\u0000|\u0265\u0001\u0000\u0000"+
+ "\u0000~\u0268\u0001\u0000\u0000\u0000\u0080\u026b\u0001\u0000\u0000\u0000"+
+ "\u0082\u026d\u0001\u0000\u0000\u0000\u0084\u0270\u0001\u0000\u0000\u0000"+
+ "\u0086\u0272\u0001\u0000\u0000\u0000\u0088\u0275\u0001\u0000\u0000\u0000"+
+ "\u008a\u0277\u0001\u0000\u0000\u0000\u008c\u0279\u0001\u0000\u0000\u0000"+
+ "\u008e\u027b\u0001\u0000\u0000\u0000\u0090\u027d\u0001\u0000\u0000\u0000"+
+ "\u0092\u027f\u0001\u0000\u0000\u0000\u0094\u0284\u0001\u0000\u0000\u0000"+
+ "\u0096\u029a\u0001\u0000\u0000\u0000\u0098\u029c\u0001\u0000\u0000\u0000"+
+ "\u009a\u02a7\u0001\u0000\u0000\u0000\u009c\u02ab\u0001\u0000\u0000\u0000"+
+ "\u009e\u02af\u0001\u0000\u0000\u0000\u00a0\u02b3\u0001\u0000\u0000\u0000"+
+ "\u00a2\u02b8\u0001\u0000\u0000\u0000\u00a4\u02be\u0001\u0000\u0000\u0000"+
+ "\u00a6\u02c4\u0001\u0000\u0000\u0000\u00a8\u02c8\u0001\u0000\u0000\u0000"+
+ "\u00aa\u02cc\u0001\u0000\u0000\u0000\u00ac\u02cf\u0001\u0000\u0000\u0000"+
+ "\u00ae\u02d8\u0001\u0000\u0000\u0000\u00b0\u02db\u0001\u0000\u0000\u0000"+
+ "\u00b2\u02e1\u0001\u0000\u0000\u0000\u00b4\u02ec\u0001\u0000\u0000\u0000"+
+ "\u00b6\u02ee\u0001\u0000\u0000\u0000\u00b8\u02f0\u0001\u0000\u0000\u0000"+
+ "\u00ba\u02f4\u0001\u0000\u0000\u0000\u00bc\u02f8\u0001\u0000\u0000\u0000"+
+ "\u00be\u00bf\u0005d\u0000\u0000\u00bf\u00c0\u0005i\u0000\u0000\u00c0\u00c1"+
+ "\u0005s\u0000\u0000\u00c1\u00c2\u0005s\u0000\u0000\u00c2\u00c3\u0005e"+
+ "\u0000\u0000\u00c3\u00c4\u0005c\u0000\u0000\u00c4\u00c5\u0005t\u0000\u0000"+
+ "\u00c5\u00c6\u0001\u0000\u0000\u0000\u00c6\u00c7\u0006\u0000\u0000\u0000"+
+ "\u00c7\u0005\u0001\u0000\u0000\u0000\u00c8\u00c9\u0005d\u0000\u0000\u00c9"+
+ "\u00ca\u0005r\u0000\u0000\u00ca\u00cb\u0005o\u0000\u0000\u00cb\u00cc\u0005"+
+ "p\u0000\u0000\u00cc\u00cd\u0001\u0000\u0000\u0000\u00cd\u00ce\u0006\u0001"+
+ "\u0001\u0000\u00ce\u0007\u0001\u0000\u0000\u0000\u00cf\u00d0\u0005e\u0000"+
+ "\u0000\u00d0\u00d1\u0005n\u0000\u0000\u00d1\u00d2\u0005r\u0000\u0000\u00d2"+
+ "\u00d3\u0005i\u0000\u0000\u00d3\u00d4\u0005c\u0000\u0000\u00d4\u00d5\u0005"+
+ "h\u0000\u0000\u00d5\u00d6\u0001\u0000\u0000\u0000\u00d6\u00d7\u0006\u0002"+
+ "\u0001\u0000\u00d7\t\u0001\u0000\u0000\u0000\u00d8\u00d9\u0005e\u0000"+
+ "\u0000\u00d9\u00da\u0005v\u0000\u0000\u00da\u00db\u0005a\u0000\u0000\u00db"+
+ "\u00dc\u0005l\u0000\u0000\u00dc\u00dd\u0001\u0000\u0000\u0000\u00dd\u00de"+
+ "\u0006\u0003\u0000\u0000\u00de\u000b\u0001\u0000\u0000\u0000\u00df\u00e0"+
+ "\u0005e\u0000\u0000\u00e0\u00e1\u0005x\u0000\u0000\u00e1\u00e2\u0005p"+
+ "\u0000\u0000\u00e2\u00e3\u0005l\u0000\u0000\u00e3\u00e4\u0005a\u0000\u0000"+
+ "\u00e4\u00e5\u0005i\u0000\u0000\u00e5\u00e6\u0005n\u0000\u0000\u00e6\u00e7"+
+ "\u0001\u0000\u0000\u0000\u00e7\u00e8\u0006\u0004\u0002\u0000\u00e8\r\u0001"+
+ "\u0000\u0000\u0000\u00e9\u00ea\u0005f\u0000\u0000\u00ea\u00eb\u0005r\u0000"+
+ "\u0000\u00eb\u00ec\u0005o\u0000\u0000\u00ec\u00ed\u0005m\u0000\u0000\u00ed"+
+ "\u00ee\u0001\u0000\u0000\u0000\u00ee\u00ef\u0006\u0005\u0001\u0000\u00ef"+
+ "\u000f\u0001\u0000\u0000\u0000\u00f0\u00f1\u0005g\u0000\u0000\u00f1\u00f2"+
+ "\u0005r\u0000\u0000\u00f2\u00f3\u0005o\u0000\u0000\u00f3\u00f4\u0005k"+
+ "\u0000\u0000\u00f4\u00f5\u0001\u0000\u0000\u0000\u00f5\u00f6\u0006\u0006"+
+ "\u0000\u0000\u00f6\u0011\u0001\u0000\u0000\u0000\u00f7\u00f8\u0005i\u0000"+
+ "\u0000\u00f8\u00f9\u0005n\u0000\u0000\u00f9\u00fa\u0005l\u0000\u0000\u00fa"+
+ "\u00fb\u0005i\u0000\u0000\u00fb\u00fc\u0005n\u0000\u0000\u00fc\u00fd\u0005"+
+ "e\u0000\u0000\u00fd\u00fe\u0005s\u0000\u0000\u00fe\u00ff\u0005t\u0000"+
+ "\u0000\u00ff\u0100\u0005a\u0000\u0000\u0100\u0101\u0005t\u0000\u0000\u0101"+
+ "\u0102\u0005s\u0000\u0000\u0102\u0103\u0001\u0000\u0000\u0000\u0103\u0104"+
+ "\u0006\u0007\u0000\u0000\u0104\u0013\u0001\u0000\u0000\u0000\u0105\u0106"+
+ "\u0005k\u0000\u0000\u0106\u0107\u0005e\u0000\u0000\u0107\u0108\u0005e"+
+ "\u0000\u0000\u0108\u0109\u0005p\u0000\u0000\u0109\u010a\u0001\u0000\u0000"+
+ "\u0000\u010a\u010b\u0006\b\u0001\u0000\u010b\u0015\u0001\u0000\u0000\u0000"+
+ "\u010c\u010d\u0005l\u0000\u0000\u010d\u010e\u0005i\u0000\u0000\u010e\u010f"+
+ "\u0005m\u0000\u0000\u010f\u0110\u0005i\u0000\u0000\u0110\u0111\u0005t"+
+ "\u0000\u0000\u0111\u0112\u0001\u0000\u0000\u0000\u0112\u0113\u0006\t\u0000"+
+ "\u0000\u0113\u0017\u0001\u0000\u0000\u0000\u0114\u0115\u0005m\u0000\u0000"+
+ "\u0115\u0116\u0005v\u0000\u0000\u0116\u0117\u0005_\u0000\u0000\u0117\u0118"+
+ "\u0005e\u0000\u0000\u0118\u0119\u0005x\u0000\u0000\u0119\u011a\u0005p"+
+ "\u0000\u0000\u011a\u011b\u0005a\u0000\u0000\u011b\u011c\u0005n\u0000\u0000"+
+ "\u011c\u011d\u0005d\u0000\u0000\u011d\u011e\u0001\u0000\u0000\u0000\u011e"+
+ "\u011f\u0006\n\u0001\u0000\u011f\u0019\u0001\u0000\u0000\u0000\u0120\u0121"+
+ "\u0005p\u0000\u0000\u0121\u0122\u0005r\u0000\u0000\u0122\u0123\u0005o"+
+ "\u0000\u0000\u0123\u0124\u0005j\u0000\u0000\u0124\u0125\u0005e\u0000\u0000"+
+ "\u0125\u0126\u0005c\u0000\u0000\u0126\u0127\u0005t\u0000\u0000\u0127\u0128"+
+ "\u0001\u0000\u0000\u0000\u0128\u0129\u0006\u000b\u0001\u0000\u0129\u001b"+
+ "\u0001\u0000\u0000\u0000\u012a\u012b\u0005r\u0000\u0000\u012b\u012c\u0005"+
+ "e\u0000\u0000\u012c\u012d\u0005n\u0000\u0000\u012d\u012e\u0005a\u0000"+
+ "\u0000\u012e\u012f\u0005m\u0000\u0000\u012f\u0130\u0005e\u0000\u0000\u0130"+
+ "\u0131\u0001\u0000\u0000\u0000\u0131\u0132\u0006\f\u0001\u0000\u0132\u001d"+
+ "\u0001\u0000\u0000\u0000\u0133\u0134\u0005r\u0000\u0000\u0134\u0135\u0005"+
+ "o\u0000\u0000\u0135\u0136\u0005w\u0000\u0000\u0136\u0137\u0001\u0000\u0000"+
+ "\u0000\u0137\u0138\u0006\r\u0000\u0000\u0138\u001f\u0001\u0000\u0000\u0000"+
+ "\u0139\u013a\u0005s\u0000\u0000\u013a\u013b\u0005h\u0000\u0000\u013b\u013c"+
+ "\u0005o\u0000\u0000\u013c\u013d\u0005w\u0000\u0000\u013d\u013e\u0001\u0000"+
+ "\u0000\u0000\u013e\u013f\u0006\u000e\u0000\u0000\u013f!\u0001\u0000\u0000"+
+ "\u0000\u0140\u0141\u0005s\u0000\u0000\u0141\u0142\u0005o\u0000\u0000\u0142"+
+ "\u0143\u0005r\u0000\u0000\u0143\u0144\u0005t\u0000\u0000\u0144\u0145\u0001"+
+ "\u0000\u0000\u0000\u0145\u0146\u0006\u000f\u0000\u0000\u0146#\u0001\u0000"+
+ "\u0000\u0000\u0147\u0148\u0005s\u0000\u0000\u0148\u0149\u0005t\u0000\u0000"+
+ "\u0149\u014a\u0005a\u0000\u0000\u014a\u014b\u0005t\u0000\u0000\u014b\u014c"+
+ "\u0005s\u0000\u0000\u014c\u014d\u0001\u0000\u0000\u0000\u014d\u014e\u0006"+
+ "\u0010\u0000\u0000\u014e%\u0001\u0000\u0000\u0000\u014f\u0150\u0005w\u0000"+
+ "\u0000\u0150\u0151\u0005h\u0000\u0000\u0151\u0152\u0005e\u0000\u0000\u0152"+
+ "\u0153\u0005r\u0000\u0000\u0153\u0154\u0005e\u0000\u0000\u0154\u0155\u0001"+
+ "\u0000\u0000\u0000\u0155\u0156\u0006\u0011\u0000\u0000\u0156\'\u0001\u0000"+
+ "\u0000\u0000\u0157\u0159\b\u0000\u0000\u0000\u0158\u0157\u0001\u0000\u0000"+
+ "\u0000\u0159\u015a\u0001\u0000\u0000\u0000\u015a\u0158\u0001\u0000\u0000"+
+ "\u0000\u015a\u015b\u0001\u0000\u0000\u0000\u015b\u015c\u0001\u0000\u0000"+
+ "\u0000\u015c\u015d\u0006\u0012\u0000\u0000\u015d)\u0001\u0000\u0000\u0000"+
+ "\u015e\u015f\u0005/\u0000\u0000\u015f\u0160\u0005/\u0000\u0000\u0160\u0164"+
+ "\u0001\u0000\u0000\u0000\u0161\u0163\b\u0001\u0000\u0000\u0162\u0161\u0001"+
"\u0000\u0000\u0000\u0163\u0166\u0001\u0000\u0000\u0000\u0164\u0162\u0001"+
- "\u0000\u0000\u0000\u0165\u0167\u0005\r\u0000\u0000\u0166\u0165\u0001\u0000"+
- "\u0000\u0000\u0166\u0167\u0001\u0000\u0000\u0000\u0167\u0169\u0001\u0000"+
- "\u0000\u0000\u0168\u016a\u0005\n\u0000\u0000\u0169\u0168\u0001\u0000\u0000"+
- "\u0000\u0169\u016a\u0001\u0000\u0000\u0000\u016a\u016b\u0001\u0000\u0000"+
- "\u0000\u016b\u016c\u0006\u0013\u0003\u0000\u016c+\u0001\u0000\u0000\u0000"+
- "\u016d\u016e\u0005/\u0000\u0000\u016e\u016f\u0005*\u0000\u0000\u016f\u0174"+
- "\u0001\u0000\u0000\u0000\u0170\u0173\u0003,\u0014\u0000\u0171\u0173\t"+
- "\u0000\u0000\u0000\u0172\u0170\u0001\u0000\u0000\u0000\u0172\u0171\u0001"+
- "\u0000\u0000\u0000\u0173\u0176\u0001\u0000\u0000\u0000\u0174\u0175\u0001"+
- "\u0000\u0000\u0000\u0174\u0172\u0001\u0000\u0000\u0000\u0175\u0177\u0001"+
- "\u0000\u0000\u0000\u0176\u0174\u0001\u0000\u0000\u0000\u0177\u0178\u0005"+
- "*\u0000\u0000\u0178\u0179\u0005/\u0000\u0000\u0179\u017a\u0001\u0000\u0000"+
- "\u0000\u017a\u017b\u0006\u0014\u0003\u0000\u017b-\u0001\u0000\u0000\u0000"+
- "\u017c\u017e\u0007\u0002\u0000\u0000\u017d\u017c\u0001\u0000\u0000\u0000"+
- "\u017e\u017f\u0001\u0000\u0000\u0000\u017f\u017d\u0001\u0000\u0000\u0000"+
- "\u017f\u0180\u0001\u0000\u0000\u0000\u0180\u0181\u0001\u0000\u0000\u0000"+
- "\u0181\u0182\u0006\u0015\u0003\u0000\u0182/\u0001\u0000\u0000\u0000\u0183"+
- "\u0184\u0005[\u0000\u0000\u0184\u0185\u0001\u0000\u0000\u0000\u0185\u0186"+
- "\u0006\u0016\u0004\u0000\u0186\u0187\u0006\u0016\u0005\u0000\u01871\u0001"+
- "\u0000\u0000\u0000\u0188\u0189\u0005|\u0000\u0000\u0189\u018a\u0001\u0000"+
- "\u0000\u0000\u018a\u018b\u0006\u0017\u0006\u0000\u018b\u018c\u0006\u0017"+
- "\u0007\u0000\u018c3\u0001\u0000\u0000\u0000\u018d\u018e\u0003.\u0015\u0000"+
- "\u018e\u018f\u0001\u0000\u0000\u0000\u018f\u0190\u0006\u0018\u0003\u0000"+
- "\u01905\u0001\u0000\u0000\u0000\u0191\u0192\u0003*\u0013\u0000\u0192\u0193"+
- "\u0001\u0000\u0000\u0000\u0193\u0194\u0006\u0019\u0003\u0000\u01947\u0001"+
- "\u0000\u0000\u0000\u0195\u0196\u0003,\u0014\u0000\u0196\u0197\u0001\u0000"+
- "\u0000\u0000\u0197\u0198\u0006\u001a\u0003\u0000\u01989\u0001\u0000\u0000"+
- "\u0000\u0199\u019a\u0005|\u0000\u0000\u019a\u019b\u0001\u0000\u0000\u0000"+
- "\u019b\u019c\u0006\u001b\u0007\u0000\u019c;\u0001\u0000\u0000\u0000\u019d"+
- "\u019e\u0007\u0003\u0000\u0000\u019e=\u0001\u0000\u0000\u0000\u019f\u01a0"+
- "\u0007\u0004\u0000\u0000\u01a0?\u0001\u0000\u0000\u0000\u01a1\u01a2\u0005"+
- "\\\u0000\u0000\u01a2\u01a3\u0007\u0005\u0000\u0000\u01a3A\u0001\u0000"+
- "\u0000\u0000\u01a4\u01a5\b\u0006\u0000\u0000\u01a5C\u0001\u0000\u0000"+
- "\u0000\u01a6\u01a8\u0007\u0007\u0000\u0000\u01a7\u01a9\u0007\b\u0000\u0000"+
- "\u01a8\u01a7\u0001\u0000\u0000\u0000\u01a8\u01a9\u0001\u0000\u0000\u0000"+
- "\u01a9\u01ab\u0001\u0000\u0000\u0000\u01aa\u01ac\u0003<\u001c\u0000\u01ab"+
- "\u01aa\u0001\u0000\u0000\u0000\u01ac\u01ad\u0001\u0000\u0000\u0000\u01ad"+
- "\u01ab\u0001\u0000\u0000\u0000\u01ad\u01ae\u0001\u0000\u0000\u0000\u01ae"+
- "E\u0001\u0000\u0000\u0000\u01af\u01b4\u0005\"\u0000\u0000\u01b0\u01b3"+
- "\u0003@\u001e\u0000\u01b1\u01b3\u0003B\u001f\u0000\u01b2\u01b0\u0001\u0000"+
- "\u0000\u0000\u01b2\u01b1\u0001\u0000\u0000\u0000\u01b3\u01b6\u0001\u0000"+
- "\u0000\u0000\u01b4\u01b2\u0001\u0000\u0000\u0000\u01b4\u01b5\u0001\u0000"+
- "\u0000\u0000\u01b5\u01b7\u0001\u0000\u0000\u0000\u01b6\u01b4\u0001\u0000"+
- "\u0000\u0000\u01b7\u01cd\u0005\"\u0000\u0000\u01b8\u01b9\u0005\"\u0000"+
- "\u0000\u01b9\u01ba\u0005\"\u0000\u0000\u01ba\u01bb\u0005\"\u0000\u0000"+
- "\u01bb\u01bf\u0001\u0000\u0000\u0000\u01bc\u01be\b\u0001\u0000\u0000\u01bd"+
- "\u01bc\u0001\u0000\u0000\u0000\u01be\u01c1\u0001\u0000\u0000\u0000\u01bf"+
- "\u01c0\u0001\u0000\u0000\u0000\u01bf\u01bd\u0001\u0000\u0000\u0000\u01c0"+
- "\u01c2\u0001\u0000\u0000\u0000\u01c1\u01bf\u0001\u0000\u0000\u0000\u01c2"+
- "\u01c3\u0005\"\u0000\u0000\u01c3\u01c4\u0005\"\u0000\u0000\u01c4\u01c5"+
- "\u0005\"\u0000\u0000\u01c5\u01c7\u0001\u0000\u0000\u0000\u01c6\u01c8\u0005"+
- "\"\u0000\u0000\u01c7\u01c6\u0001\u0000\u0000\u0000\u01c7\u01c8\u0001\u0000"+
- "\u0000\u0000\u01c8\u01ca\u0001\u0000\u0000\u0000\u01c9\u01cb\u0005\"\u0000"+
- "\u0000\u01ca\u01c9\u0001\u0000\u0000\u0000\u01ca\u01cb\u0001\u0000\u0000"+
- "\u0000\u01cb\u01cd\u0001\u0000\u0000\u0000\u01cc\u01af\u0001\u0000\u0000"+
- "\u0000\u01cc\u01b8\u0001\u0000\u0000\u0000\u01cdG\u0001\u0000\u0000\u0000"+
- "\u01ce\u01d0\u0003<\u001c\u0000\u01cf\u01ce\u0001\u0000\u0000\u0000\u01d0"+
- "\u01d1\u0001\u0000\u0000\u0000\u01d1\u01cf\u0001\u0000\u0000\u0000\u01d1"+
- "\u01d2\u0001\u0000\u0000\u0000\u01d2I\u0001\u0000\u0000\u0000\u01d3\u01d5"+
- "\u0003<\u001c\u0000\u01d4\u01d3\u0001\u0000\u0000\u0000\u01d5\u01d6\u0001"+
- "\u0000\u0000\u0000\u01d6\u01d4\u0001\u0000\u0000\u0000\u01d6\u01d7\u0001"+
- "\u0000\u0000\u0000\u01d7\u01d8\u0001\u0000\u0000\u0000\u01d8\u01dc\u0003"+
- "X*\u0000\u01d9\u01db\u0003<\u001c\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\u01fe\u0001\u0000\u0000"+
- "\u0000\u01de\u01dc\u0001\u0000\u0000\u0000\u01df\u01e1\u0003X*\u0000\u01e0"+
- "\u01e2\u0003<\u001c\u0000\u01e1\u01e0\u0001\u0000\u0000\u0000\u01e2\u01e3"+
- "\u0001\u0000\u0000\u0000\u01e3\u01e1\u0001\u0000\u0000\u0000\u01e3\u01e4"+
- "\u0001\u0000\u0000\u0000\u01e4\u01fe\u0001\u0000\u0000\u0000\u01e5\u01e7"+
- "\u0003<\u001c\u0000\u01e6\u01e5\u0001\u0000\u0000\u0000\u01e7\u01e8\u0001"+
- "\u0000\u0000\u0000\u01e8\u01e6\u0001\u0000\u0000\u0000\u01e8\u01e9\u0001"+
- "\u0000\u0000\u0000\u01e9\u01f1\u0001\u0000\u0000\u0000\u01ea\u01ee\u0003"+
- "X*\u0000\u01eb\u01ed\u0003<\u001c\u0000\u01ec\u01eb\u0001\u0000\u0000"+
- "\u0000\u01ed\u01f0\u0001\u0000\u0000\u0000\u01ee\u01ec\u0001\u0000\u0000"+
- "\u0000\u01ee\u01ef\u0001\u0000\u0000\u0000\u01ef\u01f2\u0001\u0000\u0000"+
- "\u0000\u01f0\u01ee\u0001\u0000\u0000\u0000\u01f1\u01ea\u0001\u0000\u0000"+
- "\u0000\u01f1\u01f2\u0001\u0000\u0000\u0000\u01f2\u01f3\u0001\u0000\u0000"+
- "\u0000\u01f3\u01f4\u0003D \u0000\u01f4\u01fe\u0001\u0000\u0000\u0000\u01f5"+
- "\u01f7\u0003X*\u0000\u01f6\u01f8\u0003<\u001c\u0000\u01f7\u01f6\u0001"+
- "\u0000\u0000\u0000\u01f8\u01f9\u0001\u0000\u0000\u0000\u01f9\u01f7\u0001"+
- "\u0000\u0000\u0000\u01f9\u01fa\u0001\u0000\u0000\u0000\u01fa\u01fb\u0001"+
- "\u0000\u0000\u0000\u01fb\u01fc\u0003D \u0000\u01fc\u01fe\u0001\u0000\u0000"+
- "\u0000\u01fd\u01d4\u0001\u0000\u0000\u0000\u01fd\u01df\u0001\u0000\u0000"+
- "\u0000\u01fd\u01e6\u0001\u0000\u0000\u0000\u01fd\u01f5\u0001\u0000\u0000"+
- "\u0000\u01feK\u0001\u0000\u0000\u0000\u01ff\u0200\u0005b\u0000\u0000\u0200"+
- "\u0201\u0005y\u0000\u0000\u0201M\u0001\u0000\u0000\u0000\u0202\u0203\u0005"+
- "a\u0000\u0000\u0203\u0204\u0005n\u0000\u0000\u0204\u0205\u0005d\u0000"+
- "\u0000\u0205O\u0001\u0000\u0000\u0000\u0206\u0207\u0005a\u0000\u0000\u0207"+
- "\u0208\u0005s\u0000\u0000\u0208\u0209\u0005c\u0000\u0000\u0209Q\u0001"+
- "\u0000\u0000\u0000\u020a\u020b\u0005=\u0000\u0000\u020bS\u0001\u0000\u0000"+
- "\u0000\u020c\u020d\u0005,\u0000\u0000\u020dU\u0001\u0000\u0000\u0000\u020e"+
- "\u020f\u0005d\u0000\u0000\u020f\u0210\u0005e\u0000\u0000\u0210\u0211\u0005"+
- "s\u0000\u0000\u0211\u0212\u0005c\u0000\u0000\u0212W\u0001\u0000\u0000"+
- "\u0000\u0213\u0214\u0005.\u0000\u0000\u0214Y\u0001\u0000\u0000\u0000\u0215"+
- "\u0216\u0005f\u0000\u0000\u0216\u0217\u0005a\u0000\u0000\u0217\u0218\u0005"+
- "l\u0000\u0000\u0218\u0219\u0005s\u0000\u0000\u0219\u021a\u0005e\u0000"+
- "\u0000\u021a[\u0001\u0000\u0000\u0000\u021b\u021c\u0005f\u0000\u0000\u021c"+
- "\u021d\u0005i\u0000\u0000\u021d\u021e\u0005r\u0000\u0000\u021e\u021f\u0005"+
- "s\u0000\u0000\u021f\u0220\u0005t\u0000\u0000\u0220]\u0001\u0000\u0000"+
- "\u0000\u0221\u0222\u0005l\u0000\u0000\u0222\u0223\u0005a\u0000\u0000\u0223"+
- "\u0224\u0005s\u0000\u0000\u0224\u0225\u0005t\u0000\u0000\u0225_\u0001"+
- "\u0000\u0000\u0000\u0226\u0227\u0005(\u0000\u0000\u0227a\u0001\u0000\u0000"+
- "\u0000\u0228\u0229\u0005i\u0000\u0000\u0229\u022a\u0005n\u0000\u0000\u022a"+
- "c\u0001\u0000\u0000\u0000\u022b\u022c\u0005l\u0000\u0000\u022c\u022d\u0005"+
- "i\u0000\u0000\u022d\u022e\u0005k\u0000\u0000\u022e\u022f\u0005e\u0000"+
- "\u0000\u022fe\u0001\u0000\u0000\u0000\u0230\u0231\u0005n\u0000\u0000\u0231"+
- "\u0232\u0005o\u0000\u0000\u0232\u0233\u0005t\u0000\u0000\u0233g\u0001"+
- "\u0000\u0000\u0000\u0234\u0235\u0005n\u0000\u0000\u0235\u0236\u0005u\u0000"+
- "\u0000\u0236\u0237\u0005l\u0000\u0000\u0237\u0238\u0005l\u0000\u0000\u0238"+
- "i\u0001\u0000\u0000\u0000\u0239\u023a\u0005n\u0000\u0000\u023a\u023b\u0005"+
- "u\u0000\u0000\u023b\u023c\u0005l\u0000\u0000\u023c\u023d\u0005l\u0000"+
- "\u0000\u023d\u023e\u0005s\u0000\u0000\u023ek\u0001\u0000\u0000\u0000\u023f"+
- "\u0240\u0005o\u0000\u0000\u0240\u0241\u0005r\u0000\u0000\u0241m\u0001"+
- "\u0000\u0000\u0000\u0242\u0243\u0005?\u0000\u0000\u0243o\u0001\u0000\u0000"+
- "\u0000\u0244\u0245\u0005r\u0000\u0000\u0245\u0246\u0005l\u0000\u0000\u0246"+
- "\u0247\u0005i\u0000\u0000\u0247\u0248\u0005k\u0000\u0000\u0248\u0249\u0005"+
- "e\u0000\u0000\u0249q\u0001\u0000\u0000\u0000\u024a\u024b\u0005)\u0000"+
- "\u0000\u024bs\u0001\u0000\u0000\u0000\u024c\u024d\u0005t\u0000\u0000\u024d"+
- "\u024e\u0005r\u0000\u0000\u024e\u024f\u0005u\u0000\u0000\u024f\u0250\u0005"+
- "e\u0000\u0000\u0250u\u0001\u0000\u0000\u0000\u0251\u0252\u0005i\u0000"+
- "\u0000\u0252\u0253\u0005n\u0000\u0000\u0253\u0254\u0005f\u0000\u0000\u0254"+
- "\u0255\u0005o\u0000\u0000\u0255w\u0001\u0000\u0000\u0000\u0256\u0257\u0005"+
- "f\u0000\u0000\u0257\u0258\u0005u\u0000\u0000\u0258\u0259\u0005n\u0000"+
- "\u0000\u0259\u025a\u0005c\u0000\u0000\u025a\u025b\u0005t\u0000\u0000\u025b"+
- "\u025c\u0005i\u0000\u0000\u025c\u025d\u0005o\u0000\u0000\u025d\u025e\u0005"+
- "n\u0000\u0000\u025e\u025f\u0005s\u0000\u0000\u025fy\u0001\u0000\u0000"+
- "\u0000\u0260\u0261\u0005=\u0000\u0000\u0261\u0262\u0005=\u0000\u0000\u0262"+
- "{\u0001\u0000\u0000\u0000\u0263\u0264\u0005!\u0000\u0000\u0264\u0265\u0005"+
- "=\u0000\u0000\u0265}\u0001\u0000\u0000\u0000\u0266\u0267\u0005<\u0000"+
- "\u0000\u0267\u007f\u0001\u0000\u0000\u0000\u0268\u0269\u0005<\u0000\u0000"+
- "\u0269\u026a\u0005=\u0000\u0000\u026a\u0081\u0001\u0000\u0000\u0000\u026b"+
- "\u026c\u0005>\u0000\u0000\u026c\u0083\u0001\u0000\u0000\u0000\u026d\u026e"+
- "\u0005>\u0000\u0000\u026e\u026f\u0005=\u0000\u0000\u026f\u0085\u0001\u0000"+
- "\u0000\u0000\u0270\u0271\u0005+\u0000\u0000\u0271\u0087\u0001\u0000\u0000"+
- "\u0000\u0272\u0273\u0005-\u0000\u0000\u0273\u0089\u0001\u0000\u0000\u0000"+
- "\u0274\u0275\u0005*\u0000\u0000\u0275\u008b\u0001\u0000\u0000\u0000\u0276"+
- "\u0277\u0005/\u0000\u0000\u0277\u008d\u0001\u0000\u0000\u0000\u0278\u0279"+
- "\u0005%\u0000\u0000\u0279\u008f\u0001\u0000\u0000\u0000\u027a\u027b\u0005"+
- "[\u0000\u0000\u027b\u027c\u0001\u0000\u0000\u0000\u027c\u027d\u0006F\u0000"+
- "\u0000\u027d\u027e\u0006F\u0000\u0000\u027e\u0091\u0001\u0000\u0000\u0000"+
- "\u027f\u0280\u0005]\u0000\u0000\u0280\u0281\u0001\u0000\u0000\u0000\u0281"+
- "\u0282\u0006G\u0007\u0000\u0282\u0283\u0006G\u0007\u0000\u0283\u0093\u0001"+
- "\u0000\u0000\u0000\u0284\u028a\u0003>\u001d\u0000\u0285\u0289\u0003>\u001d"+
- "\u0000\u0286\u0289\u0003<\u001c\u0000\u0287\u0289\u0005_\u0000\u0000\u0288"+
- "\u0285\u0001\u0000\u0000\u0000\u0288\u0286\u0001\u0000\u0000\u0000\u0288"+
- "\u0287\u0001\u0000\u0000\u0000\u0289\u028c\u0001\u0000\u0000\u0000\u028a"+
- "\u0288\u0001\u0000\u0000\u0000\u028a\u028b\u0001\u0000\u0000\u0000\u028b"+
- "\u0296\u0001\u0000\u0000\u0000\u028c\u028a\u0001\u0000\u0000\u0000\u028d"+
- "\u0291\u0007\t\u0000\u0000\u028e\u0292\u0003>\u001d\u0000\u028f\u0292"+
- "\u0003<\u001c\u0000\u0290\u0292\u0005_\u0000\u0000\u0291\u028e\u0001\u0000"+
- "\u0000\u0000\u0291\u028f\u0001\u0000\u0000\u0000\u0291\u0290\u0001\u0000"+
- "\u0000\u0000\u0292\u0293\u0001\u0000\u0000\u0000\u0293\u0291\u0001\u0000"+
- "\u0000\u0000\u0293\u0294\u0001\u0000\u0000\u0000\u0294\u0296\u0001\u0000"+
- "\u0000\u0000\u0295\u0284\u0001\u0000\u0000\u0000\u0295\u028d\u0001\u0000"+
- "\u0000\u0000\u0296\u0095\u0001\u0000\u0000\u0000\u0297\u029d\u0005`\u0000"+
- "\u0000\u0298\u029c\b\n\u0000\u0000\u0299\u029a\u0005`\u0000\u0000\u029a"+
- "\u029c\u0005`\u0000\u0000\u029b\u0298\u0001\u0000\u0000\u0000\u029b\u0299"+
- "\u0001\u0000\u0000\u0000\u029c\u029f\u0001\u0000\u0000\u0000\u029d\u029b"+
- "\u0001\u0000\u0000\u0000\u029d\u029e\u0001\u0000\u0000\u0000\u029e\u02a0"+
- "\u0001\u0000\u0000\u0000\u029f\u029d\u0001\u0000\u0000\u0000\u02a0\u02a1"+
- "\u0005`\u0000\u0000\u02a1\u0097\u0001\u0000\u0000\u0000\u02a2\u02a3\u0003"+
- "*\u0013\u0000\u02a3\u02a4\u0001\u0000\u0000\u0000\u02a4\u02a5\u0006J\u0003"+
- "\u0000\u02a5\u0099\u0001\u0000\u0000\u0000\u02a6\u02a7\u0003,\u0014\u0000"+
- "\u02a7\u02a8\u0001\u0000\u0000\u0000\u02a8\u02a9\u0006K\u0003\u0000\u02a9"+
- "\u009b\u0001\u0000\u0000\u0000\u02aa\u02ab\u0003.\u0015\u0000\u02ab\u02ac"+
- "\u0001\u0000\u0000\u0000\u02ac\u02ad\u0006L\u0003\u0000\u02ad\u009d\u0001"+
- "\u0000\u0000\u0000\u02ae\u02af\u0005|\u0000\u0000\u02af\u02b0\u0001\u0000"+
- "\u0000\u0000\u02b0\u02b1\u0006M\u0006\u0000\u02b1\u02b2\u0006M\u0007\u0000"+
- "\u02b2\u009f\u0001\u0000\u0000\u0000\u02b3\u02b4\u0005[\u0000\u0000\u02b4"+
- "\u02b5\u0001\u0000\u0000\u0000\u02b5\u02b6\u0006N\u0004\u0000\u02b6\u02b7"+
- "\u0006N\u0001\u0000\u02b7\u02b8\u0006N\u0001\u0000\u02b8\u00a1\u0001\u0000"+
- "\u0000\u0000\u02b9\u02ba\u0005]\u0000\u0000\u02ba\u02bb\u0001\u0000\u0000"+
- "\u0000\u02bb\u02bc\u0006O\u0007\u0000\u02bc\u02bd\u0006O\u0007\u0000\u02bd"+
- "\u02be\u0006O\b\u0000\u02be\u00a3\u0001\u0000\u0000\u0000\u02bf\u02c0"+
- "\u0005,\u0000\u0000\u02c0\u02c1\u0001\u0000\u0000\u0000\u02c1\u02c2\u0006"+
- "P\t\u0000\u02c2\u00a5\u0001\u0000\u0000\u0000\u02c3\u02c4\u0005=\u0000"+
- "\u0000\u02c4\u02c5\u0001\u0000\u0000\u0000\u02c5\u02c6\u0006Q\n\u0000"+
- "\u02c6\u00a7\u0001\u0000\u0000\u0000\u02c7\u02c8\u0005a\u0000\u0000\u02c8"+
- "\u02c9\u0005s\u0000\u0000\u02c9\u00a9\u0001\u0000\u0000\u0000\u02ca\u02cb"+
- "\u0005m\u0000\u0000\u02cb\u02cc\u0005e\u0000\u0000\u02cc\u02cd\u0005t"+
- "\u0000\u0000\u02cd\u02ce\u0005a\u0000\u0000\u02ce\u02cf\u0005d\u0000\u0000"+
- "\u02cf\u02d0\u0005a\u0000\u0000\u02d0\u02d1\u0005t\u0000\u0000\u02d1\u02d2"+
- "\u0005a\u0000\u0000\u02d2\u00ab\u0001\u0000\u0000\u0000\u02d3\u02d4\u0005"+
- "o\u0000\u0000\u02d4\u02d5\u0005n\u0000\u0000\u02d5\u00ad\u0001\u0000\u0000"+
- "\u0000\u02d6\u02d7\u0005w\u0000\u0000\u02d7\u02d8\u0005i\u0000\u0000\u02d8"+
- "\u02d9\u0005t\u0000\u0000\u02d9\u02da\u0005h\u0000\u0000\u02da\u00af\u0001"+
- "\u0000\u0000\u0000\u02db\u02dd\u0003\u00b2W\u0000\u02dc\u02db\u0001\u0000"+
- "\u0000\u0000\u02dd\u02de\u0001\u0000\u0000\u0000\u02de\u02dc\u0001\u0000"+
- "\u0000\u0000\u02de\u02df\u0001\u0000\u0000\u0000\u02df\u00b1\u0001\u0000"+
- "\u0000\u0000\u02e0\u02e2\b\u000b\u0000\u0000\u02e1\u02e0\u0001\u0000\u0000"+
- "\u0000\u02e2\u02e3\u0001\u0000\u0000\u0000\u02e3\u02e1\u0001\u0000\u0000"+
- "\u0000\u02e3\u02e4\u0001\u0000\u0000\u0000\u02e4\u02e8\u0001\u0000\u0000"+
- "\u0000\u02e5\u02e6\u0005/\u0000\u0000\u02e6\u02e8\b\f\u0000\u0000\u02e7"+
- "\u02e1\u0001\u0000\u0000\u0000\u02e7\u02e5\u0001\u0000\u0000\u0000\u02e8"+
- "\u00b3\u0001\u0000\u0000\u0000\u02e9\u02ea\u0003\u0096I\u0000\u02ea\u00b5"+
- "\u0001\u0000\u0000\u0000\u02eb\u02ec\u0003*\u0013\u0000\u02ec\u02ed\u0001"+
- "\u0000\u0000\u0000\u02ed\u02ee\u0006Y\u0003\u0000\u02ee\u00b7\u0001\u0000"+
- "\u0000\u0000\u02ef\u02f0\u0003,\u0014\u0000\u02f0\u02f1\u0001\u0000\u0000"+
- "\u0000\u02f1\u02f2\u0006Z\u0003\u0000\u02f2\u00b9\u0001\u0000\u0000\u0000"+
- "\u02f3\u02f4\u0003.\u0015\u0000\u02f4\u02f5\u0001\u0000\u0000\u0000\u02f5"+
- "\u02f6\u0006[\u0003\u0000\u02f6\u00bb\u0001\u0000\u0000\u0000&\u0000\u0001"+
- "\u0002\u0003\u0158\u0162\u0166\u0169\u0172\u0174\u017f\u01a8\u01ad\u01b2"+
- "\u01b4\u01bf\u01c7\u01ca\u01cc\u01d1\u01d6\u01dc\u01e3\u01e8\u01ee\u01f1"+
- "\u01f9\u01fd\u0288\u028a\u0291\u0293\u0295\u029b\u029d\u02de\u02e3\u02e7"+
- "\u000b\u0005\u0002\u0000\u0005\u0003\u0000\u0005\u0001\u0000\u0000\u0001"+
- "\u0000\u0007@\u0000\u0005\u0000\u0000\u0007\u001a\u0000\u0004\u0000\u0000"+
- "\u0007A\u0000\u0007\"\u0000\u0007!\u0000";
+ "\u0000\u0000\u0000\u0164\u0165\u0001\u0000\u0000\u0000\u0165\u0168\u0001"+
+ "\u0000\u0000\u0000\u0166\u0164\u0001\u0000\u0000\u0000\u0167\u0169\u0005"+
+ "\r\u0000\u0000\u0168\u0167\u0001\u0000\u0000\u0000\u0168\u0169\u0001\u0000"+
+ "\u0000\u0000\u0169\u016b\u0001\u0000\u0000\u0000\u016a\u016c\u0005\n\u0000"+
+ "\u0000\u016b\u016a\u0001\u0000\u0000\u0000\u016b\u016c\u0001\u0000\u0000"+
+ "\u0000\u016c\u016d\u0001\u0000\u0000\u0000\u016d\u016e\u0006\u0013\u0003"+
+ "\u0000\u016e+\u0001\u0000\u0000\u0000\u016f\u0170\u0005/\u0000\u0000\u0170"+
+ "\u0171\u0005*\u0000\u0000\u0171\u0176\u0001\u0000\u0000\u0000\u0172\u0175"+
+ "\u0003,\u0014\u0000\u0173\u0175\t\u0000\u0000\u0000\u0174\u0172\u0001"+
+ "\u0000\u0000\u0000\u0174\u0173\u0001\u0000\u0000\u0000\u0175\u0178\u0001"+
+ "\u0000\u0000\u0000\u0176\u0177\u0001\u0000\u0000\u0000\u0176\u0174\u0001"+
+ "\u0000\u0000\u0000\u0177\u0179\u0001\u0000\u0000\u0000\u0178\u0176\u0001"+
+ "\u0000\u0000\u0000\u0179\u017a\u0005*\u0000\u0000\u017a\u017b\u0005/\u0000"+
+ "\u0000\u017b\u017c\u0001\u0000\u0000\u0000\u017c\u017d\u0006\u0014\u0003"+
+ "\u0000\u017d-\u0001\u0000\u0000\u0000\u017e\u0180\u0007\u0002\u0000\u0000"+
+ "\u017f\u017e\u0001\u0000\u0000\u0000\u0180\u0181\u0001\u0000\u0000\u0000"+
+ "\u0181\u017f\u0001\u0000\u0000\u0000\u0181\u0182\u0001\u0000\u0000\u0000"+
+ "\u0182\u0183\u0001\u0000\u0000\u0000\u0183\u0184\u0006\u0015\u0003\u0000"+
+ "\u0184/\u0001\u0000\u0000\u0000\u0185\u0186\u0005[\u0000\u0000\u0186\u0187"+
+ "\u0001\u0000\u0000\u0000\u0187\u0188\u0006\u0016\u0004\u0000\u0188\u0189"+
+ "\u0006\u0016\u0005\u0000\u01891\u0001\u0000\u0000\u0000\u018a\u018b\u0005"+
+ "|\u0000\u0000\u018b\u018c\u0001\u0000\u0000\u0000\u018c\u018d\u0006\u0017"+
+ "\u0006\u0000\u018d\u018e\u0006\u0017\u0007\u0000\u018e3\u0001\u0000\u0000"+
+ "\u0000\u018f\u0190\u0003.\u0015\u0000\u0190\u0191\u0001\u0000\u0000\u0000"+
+ "\u0191\u0192\u0006\u0018\u0003\u0000\u01925\u0001\u0000\u0000\u0000\u0193"+
+ "\u0194\u0003*\u0013\u0000\u0194\u0195\u0001\u0000\u0000\u0000\u0195\u0196"+
+ "\u0006\u0019\u0003\u0000\u01967\u0001\u0000\u0000\u0000\u0197\u0198\u0003"+
+ ",\u0014\u0000\u0198\u0199\u0001\u0000\u0000\u0000\u0199\u019a\u0006\u001a"+
+ "\u0003\u0000\u019a9\u0001\u0000\u0000\u0000\u019b\u019c\u0005|\u0000\u0000"+
+ "\u019c\u019d\u0001\u0000\u0000\u0000\u019d\u019e\u0006\u001b\u0007\u0000"+
+ "\u019e;\u0001\u0000\u0000\u0000\u019f\u01a0\u0007\u0003\u0000\u0000\u01a0"+
+ "=\u0001\u0000\u0000\u0000\u01a1\u01a2\u0007\u0004\u0000\u0000\u01a2?\u0001"+
+ "\u0000\u0000\u0000\u01a3\u01a4\u0005\\\u0000\u0000\u01a4\u01a5\u0007\u0005"+
+ "\u0000\u0000\u01a5A\u0001\u0000\u0000\u0000\u01a6\u01a7\b\u0006\u0000"+
+ "\u0000\u01a7C\u0001\u0000\u0000\u0000\u01a8\u01aa\u0007\u0007\u0000\u0000"+
+ "\u01a9\u01ab\u0007\b\u0000\u0000\u01aa\u01a9\u0001\u0000\u0000\u0000\u01aa"+
+ "\u01ab\u0001\u0000\u0000\u0000\u01ab\u01ad\u0001\u0000\u0000\u0000\u01ac"+
+ "\u01ae\u0003<\u001c\u0000\u01ad\u01ac\u0001\u0000\u0000\u0000\u01ae\u01af"+
+ "\u0001\u0000\u0000\u0000\u01af\u01ad\u0001\u0000\u0000\u0000\u01af\u01b0"+
+ "\u0001\u0000\u0000\u0000\u01b0E\u0001\u0000\u0000\u0000\u01b1\u01b6\u0005"+
+ "\"\u0000\u0000\u01b2\u01b5\u0003@\u001e\u0000\u01b3\u01b5\u0003B\u001f"+
+ "\u0000\u01b4\u01b2\u0001\u0000\u0000\u0000\u01b4\u01b3\u0001\u0000\u0000"+
+ "\u0000\u01b5\u01b8\u0001\u0000\u0000\u0000\u01b6\u01b4\u0001\u0000\u0000"+
+ "\u0000\u01b6\u01b7\u0001\u0000\u0000\u0000\u01b7\u01b9\u0001\u0000\u0000"+
+ "\u0000\u01b8\u01b6\u0001\u0000\u0000\u0000\u01b9\u01cf\u0005\"\u0000\u0000"+
+ "\u01ba\u01bb\u0005\"\u0000\u0000\u01bb\u01bc\u0005\"\u0000\u0000\u01bc"+
+ "\u01bd\u0005\"\u0000\u0000\u01bd\u01c1\u0001\u0000\u0000\u0000\u01be\u01c0"+
+ "\b\u0001\u0000\u0000\u01bf\u01be\u0001\u0000\u0000\u0000\u01c0\u01c3\u0001"+
+ "\u0000\u0000\u0000\u01c1\u01c2\u0001\u0000\u0000\u0000\u01c1\u01bf\u0001"+
+ "\u0000\u0000\u0000\u01c2\u01c4\u0001\u0000\u0000\u0000\u01c3\u01c1\u0001"+
+ "\u0000\u0000\u0000\u01c4\u01c5\u0005\"\u0000\u0000\u01c5\u01c6\u0005\""+
+ "\u0000\u0000\u01c6\u01c7\u0005\"\u0000\u0000\u01c7\u01c9\u0001\u0000\u0000"+
+ "\u0000\u01c8\u01ca\u0005\"\u0000\u0000\u01c9\u01c8\u0001\u0000\u0000\u0000"+
+ "\u01c9\u01ca\u0001\u0000\u0000\u0000\u01ca\u01cc\u0001\u0000\u0000\u0000"+
+ "\u01cb\u01cd\u0005\"\u0000\u0000\u01cc\u01cb\u0001\u0000\u0000\u0000\u01cc"+
+ "\u01cd\u0001\u0000\u0000\u0000\u01cd\u01cf\u0001\u0000\u0000\u0000\u01ce"+
+ "\u01b1\u0001\u0000\u0000\u0000\u01ce\u01ba\u0001\u0000\u0000\u0000\u01cf"+
+ "G\u0001\u0000\u0000\u0000\u01d0\u01d2\u0003<\u001c\u0000\u01d1\u01d0\u0001"+
+ "\u0000\u0000\u0000\u01d2\u01d3\u0001\u0000\u0000\u0000\u01d3\u01d1\u0001"+
+ "\u0000\u0000\u0000\u01d3\u01d4\u0001\u0000\u0000\u0000\u01d4I\u0001\u0000"+
+ "\u0000\u0000\u01d5\u01d7\u0003<\u001c\u0000\u01d6\u01d5\u0001\u0000\u0000"+
+ "\u0000\u01d7\u01d8\u0001\u0000\u0000\u0000\u01d8\u01d6\u0001\u0000\u0000"+
+ "\u0000\u01d8\u01d9\u0001\u0000\u0000\u0000\u01d9\u01da\u0001\u0000\u0000"+
+ "\u0000\u01da\u01de\u0003X*\u0000\u01db\u01dd\u0003<\u001c\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"+
+ "\u0200\u0001\u0000\u0000\u0000\u01e0\u01de\u0001\u0000\u0000\u0000\u01e1"+
+ "\u01e3\u0003X*\u0000\u01e2\u01e4\u0003<\u001c\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\u0200\u0001"+
+ "\u0000\u0000\u0000\u01e7\u01e9\u0003<\u001c\u0000\u01e8\u01e7\u0001\u0000"+
+ "\u0000\u0000\u01e9\u01ea\u0001\u0000\u0000\u0000\u01ea\u01e8\u0001\u0000"+
+ "\u0000\u0000\u01ea\u01eb\u0001\u0000\u0000\u0000\u01eb\u01f3\u0001\u0000"+
+ "\u0000\u0000\u01ec\u01f0\u0003X*\u0000\u01ed\u01ef\u0003<\u001c\u0000"+
+ "\u01ee\u01ed\u0001\u0000\u0000\u0000\u01ef\u01f2\u0001\u0000\u0000\u0000"+
+ "\u01f0\u01ee\u0001\u0000\u0000\u0000\u01f0\u01f1\u0001\u0000\u0000\u0000"+
+ "\u01f1\u01f4\u0001\u0000\u0000\u0000\u01f2\u01f0\u0001\u0000\u0000\u0000"+
+ "\u01f3\u01ec\u0001\u0000\u0000\u0000\u01f3\u01f4\u0001\u0000\u0000\u0000"+
+ "\u01f4\u01f5\u0001\u0000\u0000\u0000\u01f5\u01f6\u0003D \u0000\u01f6\u0200"+
+ "\u0001\u0000\u0000\u0000\u01f7\u01f9\u0003X*\u0000\u01f8\u01fa\u0003<"+
+ "\u001c\u0000\u01f9\u01f8\u0001\u0000\u0000\u0000\u01fa\u01fb\u0001\u0000"+
+ "\u0000\u0000\u01fb\u01f9\u0001\u0000\u0000\u0000\u01fb\u01fc\u0001\u0000"+
+ "\u0000\u0000\u01fc\u01fd\u0001\u0000\u0000\u0000\u01fd\u01fe\u0003D \u0000"+
+ "\u01fe\u0200\u0001\u0000\u0000\u0000\u01ff\u01d6\u0001\u0000\u0000\u0000"+
+ "\u01ff\u01e1\u0001\u0000\u0000\u0000\u01ff\u01e8\u0001\u0000\u0000\u0000"+
+ "\u01ff\u01f7\u0001\u0000\u0000\u0000\u0200K\u0001\u0000\u0000\u0000\u0201"+
+ "\u0202\u0005b\u0000\u0000\u0202\u0203\u0005y\u0000\u0000\u0203M\u0001"+
+ "\u0000\u0000\u0000\u0204\u0205\u0005a\u0000\u0000\u0205\u0206\u0005n\u0000"+
+ "\u0000\u0206\u0207\u0005d\u0000\u0000\u0207O\u0001\u0000\u0000\u0000\u0208"+
+ "\u0209\u0005a\u0000\u0000\u0209\u020a\u0005s\u0000\u0000\u020a\u020b\u0005"+
+ "c\u0000\u0000\u020bQ\u0001\u0000\u0000\u0000\u020c\u020d\u0005=\u0000"+
+ "\u0000\u020dS\u0001\u0000\u0000\u0000\u020e\u020f\u0005,\u0000\u0000\u020f"+
+ "U\u0001\u0000\u0000\u0000\u0210\u0211\u0005d\u0000\u0000\u0211\u0212\u0005"+
+ "e\u0000\u0000\u0212\u0213\u0005s\u0000\u0000\u0213\u0214\u0005c\u0000"+
+ "\u0000\u0214W\u0001\u0000\u0000\u0000\u0215\u0216\u0005.\u0000\u0000\u0216"+
+ "Y\u0001\u0000\u0000\u0000\u0217\u0218\u0005f\u0000\u0000\u0218\u0219\u0005"+
+ "a\u0000\u0000\u0219\u021a\u0005l\u0000\u0000\u021a\u021b\u0005s\u0000"+
+ "\u0000\u021b\u021c\u0005e\u0000\u0000\u021c[\u0001\u0000\u0000\u0000\u021d"+
+ "\u021e\u0005f\u0000\u0000\u021e\u021f\u0005i\u0000\u0000\u021f\u0220\u0005"+
+ "r\u0000\u0000\u0220\u0221\u0005s\u0000\u0000\u0221\u0222\u0005t\u0000"+
+ "\u0000\u0222]\u0001\u0000\u0000\u0000\u0223\u0224\u0005l\u0000\u0000\u0224"+
+ "\u0225\u0005a\u0000\u0000\u0225\u0226\u0005s\u0000\u0000\u0226\u0227\u0005"+
+ "t\u0000\u0000\u0227_\u0001\u0000\u0000\u0000\u0228\u0229\u0005(\u0000"+
+ "\u0000\u0229a\u0001\u0000\u0000\u0000\u022a\u022b\u0005i\u0000\u0000\u022b"+
+ "\u022c\u0005n\u0000\u0000\u022cc\u0001\u0000\u0000\u0000\u022d\u022e\u0005"+
+ "i\u0000\u0000\u022e\u022f\u0005s\u0000\u0000\u022fe\u0001\u0000\u0000"+
+ "\u0000\u0230\u0231\u0005l\u0000\u0000\u0231\u0232\u0005i\u0000\u0000\u0232"+
+ "\u0233\u0005k\u0000\u0000\u0233\u0234\u0005e\u0000\u0000\u0234g\u0001"+
+ "\u0000\u0000\u0000\u0235\u0236\u0005n\u0000\u0000\u0236\u0237\u0005o\u0000"+
+ "\u0000\u0237\u0238\u0005t\u0000\u0000\u0238i\u0001\u0000\u0000\u0000\u0239"+
+ "\u023a\u0005n\u0000\u0000\u023a\u023b\u0005u\u0000\u0000\u023b\u023c\u0005"+
+ "l\u0000\u0000\u023c\u023d\u0005l\u0000\u0000\u023dk\u0001\u0000\u0000"+
+ "\u0000\u023e\u023f\u0005n\u0000\u0000\u023f\u0240\u0005u\u0000\u0000\u0240"+
+ "\u0241\u0005l\u0000\u0000\u0241\u0242\u0005l\u0000\u0000\u0242\u0243\u0005"+
+ "s\u0000\u0000\u0243m\u0001\u0000\u0000\u0000\u0244\u0245\u0005o\u0000"+
+ "\u0000\u0245\u0246\u0005r\u0000\u0000\u0246o\u0001\u0000\u0000\u0000\u0247"+
+ "\u0248\u0005?\u0000\u0000\u0248q\u0001\u0000\u0000\u0000\u0249\u024a\u0005"+
+ "r\u0000\u0000\u024a\u024b\u0005l\u0000\u0000\u024b\u024c\u0005i\u0000"+
+ "\u0000\u024c\u024d\u0005k\u0000\u0000\u024d\u024e\u0005e\u0000\u0000\u024e"+
+ "s\u0001\u0000\u0000\u0000\u024f\u0250\u0005)\u0000\u0000\u0250u\u0001"+
+ "\u0000\u0000\u0000\u0251\u0252\u0005t\u0000\u0000\u0252\u0253\u0005r\u0000"+
+ "\u0000\u0253\u0254\u0005u\u0000\u0000\u0254\u0255\u0005e\u0000\u0000\u0255"+
+ "w\u0001\u0000\u0000\u0000\u0256\u0257\u0005i\u0000\u0000\u0257\u0258\u0005"+
+ "n\u0000\u0000\u0258\u0259\u0005f\u0000\u0000\u0259\u025a\u0005o\u0000"+
+ "\u0000\u025ay\u0001\u0000\u0000\u0000\u025b\u025c\u0005f\u0000\u0000\u025c"+
+ "\u025d\u0005u\u0000\u0000\u025d\u025e\u0005n\u0000\u0000\u025e\u025f\u0005"+
+ "c\u0000\u0000\u025f\u0260\u0005t\u0000\u0000\u0260\u0261\u0005i\u0000"+
+ "\u0000\u0261\u0262\u0005o\u0000\u0000\u0262\u0263\u0005n\u0000\u0000\u0263"+
+ "\u0264\u0005s\u0000\u0000\u0264{\u0001\u0000\u0000\u0000\u0265\u0266\u0005"+
+ "=\u0000\u0000\u0266\u0267\u0005=\u0000\u0000\u0267}\u0001\u0000\u0000"+
+ "\u0000\u0268\u0269\u0005!\u0000\u0000\u0269\u026a\u0005=\u0000\u0000\u026a"+
+ "\u007f\u0001\u0000\u0000\u0000\u026b\u026c\u0005<\u0000\u0000\u026c\u0081"+
+ "\u0001\u0000\u0000\u0000\u026d\u026e\u0005<\u0000\u0000\u026e\u026f\u0005"+
+ "=\u0000\u0000\u026f\u0083\u0001\u0000\u0000\u0000\u0270\u0271\u0005>\u0000"+
+ "\u0000\u0271\u0085\u0001\u0000\u0000\u0000\u0272\u0273\u0005>\u0000\u0000"+
+ "\u0273\u0274\u0005=\u0000\u0000\u0274\u0087\u0001\u0000\u0000\u0000\u0275"+
+ "\u0276\u0005+\u0000\u0000\u0276\u0089\u0001\u0000\u0000\u0000\u0277\u0278"+
+ "\u0005-\u0000\u0000\u0278\u008b\u0001\u0000\u0000\u0000\u0279\u027a\u0005"+
+ "*\u0000\u0000\u027a\u008d\u0001\u0000\u0000\u0000\u027b\u027c\u0005/\u0000"+
+ "\u0000\u027c\u008f\u0001\u0000\u0000\u0000\u027d\u027e\u0005%\u0000\u0000"+
+ "\u027e\u0091\u0001\u0000\u0000\u0000\u027f\u0280\u0005[\u0000\u0000\u0280"+
+ "\u0281\u0001\u0000\u0000\u0000\u0281\u0282\u0006G\u0000\u0000\u0282\u0283"+
+ "\u0006G\u0000\u0000\u0283\u0093\u0001\u0000\u0000\u0000\u0284\u0285\u0005"+
+ "]\u0000\u0000\u0285\u0286\u0001\u0000\u0000\u0000\u0286\u0287\u0006H\u0007"+
+ "\u0000\u0287\u0288\u0006H\u0007\u0000\u0288\u0095\u0001\u0000\u0000\u0000"+
+ "\u0289\u028f\u0003>\u001d\u0000\u028a\u028e\u0003>\u001d\u0000\u028b\u028e"+
+ "\u0003<\u001c\u0000\u028c\u028e\u0005_\u0000\u0000\u028d\u028a\u0001\u0000"+
+ "\u0000\u0000\u028d\u028b\u0001\u0000\u0000\u0000\u028d\u028c\u0001\u0000"+
+ "\u0000\u0000\u028e\u0291\u0001\u0000\u0000\u0000\u028f\u028d\u0001\u0000"+
+ "\u0000\u0000\u028f\u0290\u0001\u0000\u0000\u0000\u0290\u029b\u0001\u0000"+
+ "\u0000\u0000\u0291\u028f\u0001\u0000\u0000\u0000\u0292\u0296\u0007\t\u0000"+
+ "\u0000\u0293\u0297\u0003>\u001d\u0000\u0294\u0297\u0003<\u001c\u0000\u0295"+
+ "\u0297\u0005_\u0000\u0000\u0296\u0293\u0001\u0000\u0000\u0000\u0296\u0294"+
+ "\u0001\u0000\u0000\u0000\u0296\u0295\u0001\u0000\u0000\u0000\u0297\u0298"+
+ "\u0001\u0000\u0000\u0000\u0298\u0296\u0001\u0000\u0000\u0000\u0298\u0299"+
+ "\u0001\u0000\u0000\u0000\u0299\u029b\u0001\u0000\u0000\u0000\u029a\u0289"+
+ "\u0001\u0000\u0000\u0000\u029a\u0292\u0001\u0000\u0000\u0000\u029b\u0097"+
+ "\u0001\u0000\u0000\u0000\u029c\u02a2\u0005`\u0000\u0000\u029d\u02a1\b"+
+ "\n\u0000\u0000\u029e\u029f\u0005`\u0000\u0000\u029f\u02a1\u0005`\u0000"+
+ "\u0000\u02a0\u029d\u0001\u0000\u0000\u0000\u02a0\u029e\u0001\u0000\u0000"+
+ "\u0000\u02a1\u02a4\u0001\u0000\u0000\u0000\u02a2\u02a0\u0001\u0000\u0000"+
+ "\u0000\u02a2\u02a3\u0001\u0000\u0000\u0000\u02a3\u02a5\u0001\u0000\u0000"+
+ "\u0000\u02a4\u02a2\u0001\u0000\u0000\u0000\u02a5\u02a6\u0005`\u0000\u0000"+
+ "\u02a6\u0099\u0001\u0000\u0000\u0000\u02a7\u02a8\u0003*\u0013\u0000\u02a8"+
+ "\u02a9\u0001\u0000\u0000\u0000\u02a9\u02aa\u0006K\u0003\u0000\u02aa\u009b"+
+ "\u0001\u0000\u0000\u0000\u02ab\u02ac\u0003,\u0014\u0000\u02ac\u02ad\u0001"+
+ "\u0000\u0000\u0000\u02ad\u02ae\u0006L\u0003\u0000\u02ae\u009d\u0001\u0000"+
+ "\u0000\u0000\u02af\u02b0\u0003.\u0015\u0000\u02b0\u02b1\u0001\u0000\u0000"+
+ "\u0000\u02b1\u02b2\u0006M\u0003\u0000\u02b2\u009f\u0001\u0000\u0000\u0000"+
+ "\u02b3\u02b4\u0005|\u0000\u0000\u02b4\u02b5\u0001\u0000\u0000\u0000\u02b5"+
+ "\u02b6\u0006N\u0006\u0000\u02b6\u02b7\u0006N\u0007\u0000\u02b7\u00a1\u0001"+
+ "\u0000\u0000\u0000\u02b8\u02b9\u0005[\u0000\u0000\u02b9\u02ba\u0001\u0000"+
+ "\u0000\u0000\u02ba\u02bb\u0006O\u0004\u0000\u02bb\u02bc\u0006O\u0001\u0000"+
+ "\u02bc\u02bd\u0006O\u0001\u0000\u02bd\u00a3\u0001\u0000\u0000\u0000\u02be"+
+ "\u02bf\u0005]\u0000\u0000\u02bf\u02c0\u0001\u0000\u0000\u0000\u02c0\u02c1"+
+ "\u0006P\u0007\u0000\u02c1\u02c2\u0006P\u0007\u0000\u02c2\u02c3\u0006P"+
+ "\b\u0000\u02c3\u00a5\u0001\u0000\u0000\u0000\u02c4\u02c5\u0005,\u0000"+
+ "\u0000\u02c5\u02c6\u0001\u0000\u0000\u0000\u02c6\u02c7\u0006Q\t\u0000"+
+ "\u02c7\u00a7\u0001\u0000\u0000\u0000\u02c8\u02c9\u0005=\u0000\u0000\u02c9"+
+ "\u02ca\u0001\u0000\u0000\u0000\u02ca\u02cb\u0006R\n\u0000\u02cb\u00a9"+
+ "\u0001\u0000\u0000\u0000\u02cc\u02cd\u0005a\u0000\u0000\u02cd\u02ce\u0005"+
+ "s\u0000\u0000\u02ce\u00ab\u0001\u0000\u0000\u0000\u02cf\u02d0\u0005m\u0000"+
+ "\u0000\u02d0\u02d1\u0005e\u0000\u0000\u02d1\u02d2\u0005t\u0000\u0000\u02d2"+
+ "\u02d3\u0005a\u0000\u0000\u02d3\u02d4\u0005d\u0000\u0000\u02d4\u02d5\u0005"+
+ "a\u0000\u0000\u02d5\u02d6\u0005t\u0000\u0000\u02d6\u02d7\u0005a\u0000"+
+ "\u0000\u02d7\u00ad\u0001\u0000\u0000\u0000\u02d8\u02d9\u0005o\u0000\u0000"+
+ "\u02d9\u02da\u0005n\u0000\u0000\u02da\u00af\u0001\u0000\u0000\u0000\u02db"+
+ "\u02dc\u0005w\u0000\u0000\u02dc\u02dd\u0005i\u0000\u0000\u02dd\u02de\u0005"+
+ "t\u0000\u0000\u02de\u02df\u0005h\u0000\u0000\u02df\u00b1\u0001\u0000\u0000"+
+ "\u0000\u02e0\u02e2\u0003\u00b4X\u0000\u02e1\u02e0\u0001\u0000\u0000\u0000"+
+ "\u02e2\u02e3\u0001\u0000\u0000\u0000\u02e3\u02e1\u0001\u0000\u0000\u0000"+
+ "\u02e3\u02e4\u0001\u0000\u0000\u0000\u02e4\u00b3\u0001\u0000\u0000\u0000"+
+ "\u02e5\u02e7\b\u000b\u0000\u0000\u02e6\u02e5\u0001\u0000\u0000\u0000\u02e7"+
+ "\u02e8\u0001\u0000\u0000\u0000\u02e8\u02e6\u0001\u0000\u0000\u0000\u02e8"+
+ "\u02e9\u0001\u0000\u0000\u0000\u02e9\u02ed\u0001\u0000\u0000\u0000\u02ea"+
+ "\u02eb\u0005/\u0000\u0000\u02eb\u02ed\b\f\u0000\u0000\u02ec\u02e6\u0001"+
+ "\u0000\u0000\u0000\u02ec\u02ea\u0001\u0000\u0000\u0000\u02ed\u00b5\u0001"+
+ "\u0000\u0000\u0000\u02ee\u02ef\u0003\u0098J\u0000\u02ef\u00b7\u0001\u0000"+
+ "\u0000\u0000\u02f0\u02f1\u0003*\u0013\u0000\u02f1\u02f2\u0001\u0000\u0000"+
+ "\u0000\u02f2\u02f3\u0006Z\u0003\u0000\u02f3\u00b9\u0001\u0000\u0000\u0000"+
+ "\u02f4\u02f5\u0003,\u0014\u0000\u02f5\u02f6\u0001\u0000\u0000\u0000\u02f6"+
+ "\u02f7\u0006[\u0003\u0000\u02f7\u00bb\u0001\u0000\u0000\u0000\u02f8\u02f9"+
+ "\u0003.\u0015\u0000\u02f9\u02fa\u0001\u0000\u0000\u0000\u02fa\u02fb\u0006"+
+ "\\\u0003\u0000\u02fb\u00bd\u0001\u0000\u0000\u0000&\u0000\u0001\u0002"+
+ "\u0003\u015a\u0164\u0168\u016b\u0174\u0176\u0181\u01aa\u01af\u01b4\u01b6"+
+ "\u01c1\u01c9\u01cc\u01ce\u01d3\u01d8\u01de\u01e5\u01ea\u01f0\u01f3\u01fb"+
+ "\u01ff\u028d\u028f\u0296\u0298\u029a\u02a0\u02a2\u02e3\u02e8\u02ec\u000b"+
+ "\u0005\u0002\u0000\u0005\u0003\u0000\u0005\u0001\u0000\u0000\u0001\u0000"+
+ "\u0007A\u0000\u0005\u0000\u0000\u0007\u001a\u0000\u0004\u0000\u0000\u0007"+
+ "B\u0000\u0007\"\u0000\u0007!\u0000";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp
index 50cadcaf1495c..349f31f7c476d 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp
@@ -41,6 +41,7 @@ null
'last'
'('
'in'
+'is'
'like'
'not'
'null'
@@ -124,6 +125,7 @@ FIRST
LAST
LP
IN
+IS
LIKE
NOT
NULL
@@ -214,4 +216,4 @@ enrichWithClause
atn:
-[4, 1, 80, 494, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 102, 8, 1, 10, 1, 12, 1, 105, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 111, 8, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 126, 8, 3, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 138, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 145, 8, 5, 10, 5, 12, 5, 148, 9, 5, 1, 5, 1, 5, 3, 5, 152, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 160, 8, 5, 10, 5, 12, 5, 163, 9, 5, 1, 6, 1, 6, 3, 6, 167, 8, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 174, 8, 6, 1, 6, 1, 6, 1, 6, 3, 6, 179, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 186, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 192, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 5, 8, 200, 8, 8, 10, 8, 12, 8, 203, 9, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 5, 9, 216, 8, 9, 10, 9, 12, 9, 219, 9, 9, 3, 9, 221, 8, 9, 1, 9, 1, 9, 3, 9, 225, 8, 9, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 5, 11, 233, 8, 11, 10, 11, 12, 11, 236, 9, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 243, 8, 12, 1, 13, 1, 13, 1, 13, 1, 13, 5, 13, 249, 8, 13, 10, 13, 12, 13, 252, 9, 13, 1, 13, 3, 13, 255, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 5, 14, 262, 8, 14, 10, 14, 12, 14, 265, 9, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 3, 16, 274, 8, 16, 1, 16, 1, 16, 3, 16, 278, 8, 16, 1, 17, 1, 17, 1, 17, 1, 17, 3, 17, 284, 8, 17, 1, 18, 1, 18, 1, 18, 5, 18, 289, 8, 18, 10, 18, 12, 18, 292, 9, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 5, 20, 299, 8, 20, 10, 20, 12, 20, 302, 9, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 319, 8, 22, 10, 22, 12, 22, 322, 9, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 330, 8, 22, 10, 22, 12, 22, 333, 9, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 341, 8, 22, 10, 22, 12, 22, 344, 9, 22, 1, 22, 1, 22, 3, 22, 348, 8, 22, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 5, 24, 357, 8, 24, 10, 24, 12, 24, 360, 9, 24, 1, 25, 1, 25, 3, 25, 364, 8, 25, 1, 25, 1, 25, 3, 25, 368, 8, 25, 1, 26, 1, 26, 1, 26, 1, 26, 5, 26, 374, 8, 26, 10, 26, 12, 26, 377, 9, 26, 1, 26, 1, 26, 1, 26, 1, 26, 5, 26, 383, 8, 26, 10, 26, 12, 26, 386, 9, 26, 3, 26, 388, 8, 26, 1, 27, 1, 27, 1, 27, 1, 27, 5, 27, 394, 8, 27, 10, 27, 12, 27, 397, 9, 27, 1, 28, 1, 28, 1, 28, 1, 28, 5, 28, 403, 8, 28, 10, 28, 12, 28, 406, 9, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 3, 30, 416, 8, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 5, 33, 428, 8, 33, 10, 33, 12, 33, 431, 9, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 36, 1, 36, 3, 36, 441, 8, 36, 1, 37, 3, 37, 444, 8, 37, 1, 37, 1, 37, 1, 38, 3, 38, 449, 8, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 468, 8, 43, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 474, 8, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 480, 8, 44, 10, 44, 12, 44, 483, 9, 44, 3, 44, 485, 8, 44, 1, 45, 1, 45, 1, 45, 3, 45, 490, 8, 45, 1, 45, 1, 45, 1, 45, 0, 3, 2, 10, 16, 46, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 0, 8, 1, 0, 59, 60, 1, 0, 61, 63, 1, 0, 75, 76, 1, 0, 66, 67, 2, 0, 32, 32, 35, 35, 1, 0, 38, 39, 2, 0, 37, 37, 50, 50, 1, 0, 53, 58, 522, 0, 92, 1, 0, 0, 0, 2, 95, 1, 0, 0, 0, 4, 110, 1, 0, 0, 0, 6, 125, 1, 0, 0, 0, 8, 127, 1, 0, 0, 0, 10, 151, 1, 0, 0, 0, 12, 178, 1, 0, 0, 0, 14, 185, 1, 0, 0, 0, 16, 191, 1, 0, 0, 0, 18, 224, 1, 0, 0, 0, 20, 226, 1, 0, 0, 0, 22, 229, 1, 0, 0, 0, 24, 242, 1, 0, 0, 0, 26, 244, 1, 0, 0, 0, 28, 256, 1, 0, 0, 0, 30, 268, 1, 0, 0, 0, 32, 271, 1, 0, 0, 0, 34, 279, 1, 0, 0, 0, 36, 285, 1, 0, 0, 0, 38, 293, 1, 0, 0, 0, 40, 295, 1, 0, 0, 0, 42, 303, 1, 0, 0, 0, 44, 347, 1, 0, 0, 0, 46, 349, 1, 0, 0, 0, 48, 352, 1, 0, 0, 0, 50, 361, 1, 0, 0, 0, 52, 387, 1, 0, 0, 0, 54, 389, 1, 0, 0, 0, 56, 398, 1, 0, 0, 0, 58, 407, 1, 0, 0, 0, 60, 411, 1, 0, 0, 0, 62, 417, 1, 0, 0, 0, 64, 421, 1, 0, 0, 0, 66, 424, 1, 0, 0, 0, 68, 432, 1, 0, 0, 0, 70, 436, 1, 0, 0, 0, 72, 440, 1, 0, 0, 0, 74, 443, 1, 0, 0, 0, 76, 448, 1, 0, 0, 0, 78, 452, 1, 0, 0, 0, 80, 454, 1, 0, 0, 0, 82, 456, 1, 0, 0, 0, 84, 459, 1, 0, 0, 0, 86, 467, 1, 0, 0, 0, 88, 469, 1, 0, 0, 0, 90, 489, 1, 0, 0, 0, 92, 93, 3, 2, 1, 0, 93, 94, 5, 0, 0, 1, 94, 1, 1, 0, 0, 0, 95, 96, 6, 1, -1, 0, 96, 97, 3, 4, 2, 0, 97, 103, 1, 0, 0, 0, 98, 99, 10, 1, 0, 0, 99, 100, 5, 26, 0, 0, 100, 102, 3, 6, 3, 0, 101, 98, 1, 0, 0, 0, 102, 105, 1, 0, 0, 0, 103, 101, 1, 0, 0, 0, 103, 104, 1, 0, 0, 0, 104, 3, 1, 0, 0, 0, 105, 103, 1, 0, 0, 0, 106, 111, 3, 82, 41, 0, 107, 111, 3, 26, 13, 0, 108, 111, 3, 20, 10, 0, 109, 111, 3, 86, 43, 0, 110, 106, 1, 0, 0, 0, 110, 107, 1, 0, 0, 0, 110, 108, 1, 0, 0, 0, 110, 109, 1, 0, 0, 0, 111, 5, 1, 0, 0, 0, 112, 126, 3, 30, 15, 0, 113, 126, 3, 34, 17, 0, 114, 126, 3, 46, 23, 0, 115, 126, 3, 52, 26, 0, 116, 126, 3, 48, 24, 0, 117, 126, 3, 32, 16, 0, 118, 126, 3, 8, 4, 0, 119, 126, 3, 54, 27, 0, 120, 126, 3, 56, 28, 0, 121, 126, 3, 60, 30, 0, 122, 126, 3, 62, 31, 0, 123, 126, 3, 88, 44, 0, 124, 126, 3, 64, 32, 0, 125, 112, 1, 0, 0, 0, 125, 113, 1, 0, 0, 0, 125, 114, 1, 0, 0, 0, 125, 115, 1, 0, 0, 0, 125, 116, 1, 0, 0, 0, 125, 117, 1, 0, 0, 0, 125, 118, 1, 0, 0, 0, 125, 119, 1, 0, 0, 0, 125, 120, 1, 0, 0, 0, 125, 121, 1, 0, 0, 0, 125, 122, 1, 0, 0, 0, 125, 123, 1, 0, 0, 0, 125, 124, 1, 0, 0, 0, 126, 7, 1, 0, 0, 0, 127, 128, 5, 18, 0, 0, 128, 129, 3, 10, 5, 0, 129, 9, 1, 0, 0, 0, 130, 131, 6, 5, -1, 0, 131, 132, 5, 43, 0, 0, 132, 152, 3, 10, 5, 6, 133, 152, 3, 14, 7, 0, 134, 152, 3, 12, 6, 0, 135, 137, 3, 14, 7, 0, 136, 138, 5, 43, 0, 0, 137, 136, 1, 0, 0, 0, 137, 138, 1, 0, 0, 0, 138, 139, 1, 0, 0, 0, 139, 140, 5, 41, 0, 0, 140, 141, 5, 40, 0, 0, 141, 146, 3, 14, 7, 0, 142, 143, 5, 34, 0, 0, 143, 145, 3, 14, 7, 0, 144, 142, 1, 0, 0, 0, 145, 148, 1, 0, 0, 0, 146, 144, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, 147, 149, 1, 0, 0, 0, 148, 146, 1, 0, 0, 0, 149, 150, 5, 49, 0, 0, 150, 152, 1, 0, 0, 0, 151, 130, 1, 0, 0, 0, 151, 133, 1, 0, 0, 0, 151, 134, 1, 0, 0, 0, 151, 135, 1, 0, 0, 0, 152, 161, 1, 0, 0, 0, 153, 154, 10, 3, 0, 0, 154, 155, 5, 31, 0, 0, 155, 160, 3, 10, 5, 4, 156, 157, 10, 2, 0, 0, 157, 158, 5, 46, 0, 0, 158, 160, 3, 10, 5, 3, 159, 153, 1, 0, 0, 0, 159, 156, 1, 0, 0, 0, 160, 163, 1, 0, 0, 0, 161, 159, 1, 0, 0, 0, 161, 162, 1, 0, 0, 0, 162, 11, 1, 0, 0, 0, 163, 161, 1, 0, 0, 0, 164, 166, 3, 14, 7, 0, 165, 167, 5, 43, 0, 0, 166, 165, 1, 0, 0, 0, 166, 167, 1, 0, 0, 0, 167, 168, 1, 0, 0, 0, 168, 169, 5, 42, 0, 0, 169, 170, 3, 78, 39, 0, 170, 179, 1, 0, 0, 0, 171, 173, 3, 14, 7, 0, 172, 174, 5, 43, 0, 0, 173, 172, 1, 0, 0, 0, 173, 174, 1, 0, 0, 0, 174, 175, 1, 0, 0, 0, 175, 176, 5, 48, 0, 0, 176, 177, 3, 78, 39, 0, 177, 179, 1, 0, 0, 0, 178, 164, 1, 0, 0, 0, 178, 171, 1, 0, 0, 0, 179, 13, 1, 0, 0, 0, 180, 186, 3, 16, 8, 0, 181, 182, 3, 16, 8, 0, 182, 183, 3, 80, 40, 0, 183, 184, 3, 16, 8, 0, 184, 186, 1, 0, 0, 0, 185, 180, 1, 0, 0, 0, 185, 181, 1, 0, 0, 0, 186, 15, 1, 0, 0, 0, 187, 188, 6, 8, -1, 0, 188, 192, 3, 18, 9, 0, 189, 190, 7, 0, 0, 0, 190, 192, 3, 16, 8, 3, 191, 187, 1, 0, 0, 0, 191, 189, 1, 0, 0, 0, 192, 201, 1, 0, 0, 0, 193, 194, 10, 2, 0, 0, 194, 195, 7, 1, 0, 0, 195, 200, 3, 16, 8, 3, 196, 197, 10, 1, 0, 0, 197, 198, 7, 0, 0, 0, 198, 200, 3, 16, 8, 2, 199, 193, 1, 0, 0, 0, 199, 196, 1, 0, 0, 0, 200, 203, 1, 0, 0, 0, 201, 199, 1, 0, 0, 0, 201, 202, 1, 0, 0, 0, 202, 17, 1, 0, 0, 0, 203, 201, 1, 0, 0, 0, 204, 225, 3, 44, 22, 0, 205, 225, 3, 40, 20, 0, 206, 207, 5, 40, 0, 0, 207, 208, 3, 10, 5, 0, 208, 209, 5, 49, 0, 0, 209, 225, 1, 0, 0, 0, 210, 211, 3, 42, 21, 0, 211, 220, 5, 40, 0, 0, 212, 217, 3, 10, 5, 0, 213, 214, 5, 34, 0, 0, 214, 216, 3, 10, 5, 0, 215, 213, 1, 0, 0, 0, 216, 219, 1, 0, 0, 0, 217, 215, 1, 0, 0, 0, 217, 218, 1, 0, 0, 0, 218, 221, 1, 0, 0, 0, 219, 217, 1, 0, 0, 0, 220, 212, 1, 0, 0, 0, 220, 221, 1, 0, 0, 0, 221, 222, 1, 0, 0, 0, 222, 223, 5, 49, 0, 0, 223, 225, 1, 0, 0, 0, 224, 204, 1, 0, 0, 0, 224, 205, 1, 0, 0, 0, 224, 206, 1, 0, 0, 0, 224, 210, 1, 0, 0, 0, 225, 19, 1, 0, 0, 0, 226, 227, 5, 14, 0, 0, 227, 228, 3, 22, 11, 0, 228, 21, 1, 0, 0, 0, 229, 234, 3, 24, 12, 0, 230, 231, 5, 34, 0, 0, 231, 233, 3, 24, 12, 0, 232, 230, 1, 0, 0, 0, 233, 236, 1, 0, 0, 0, 234, 232, 1, 0, 0, 0, 234, 235, 1, 0, 0, 0, 235, 23, 1, 0, 0, 0, 236, 234, 1, 0, 0, 0, 237, 243, 3, 10, 5, 0, 238, 239, 3, 40, 20, 0, 239, 240, 5, 33, 0, 0, 240, 241, 3, 10, 5, 0, 241, 243, 1, 0, 0, 0, 242, 237, 1, 0, 0, 0, 242, 238, 1, 0, 0, 0, 243, 25, 1, 0, 0, 0, 244, 245, 5, 6, 0, 0, 245, 250, 3, 38, 19, 0, 246, 247, 5, 34, 0, 0, 247, 249, 3, 38, 19, 0, 248, 246, 1, 0, 0, 0, 249, 252, 1, 0, 0, 0, 250, 248, 1, 0, 0, 0, 250, 251, 1, 0, 0, 0, 251, 254, 1, 0, 0, 0, 252, 250, 1, 0, 0, 0, 253, 255, 3, 28, 14, 0, 254, 253, 1, 0, 0, 0, 254, 255, 1, 0, 0, 0, 255, 27, 1, 0, 0, 0, 256, 257, 5, 64, 0, 0, 257, 258, 5, 72, 0, 0, 258, 263, 3, 38, 19, 0, 259, 260, 5, 34, 0, 0, 260, 262, 3, 38, 19, 0, 261, 259, 1, 0, 0, 0, 262, 265, 1, 0, 0, 0, 263, 261, 1, 0, 0, 0, 263, 264, 1, 0, 0, 0, 264, 266, 1, 0, 0, 0, 265, 263, 1, 0, 0, 0, 266, 267, 5, 65, 0, 0, 267, 29, 1, 0, 0, 0, 268, 269, 5, 4, 0, 0, 269, 270, 3, 22, 11, 0, 270, 31, 1, 0, 0, 0, 271, 273, 5, 17, 0, 0, 272, 274, 3, 22, 11, 0, 273, 272, 1, 0, 0, 0, 273, 274, 1, 0, 0, 0, 274, 277, 1, 0, 0, 0, 275, 276, 5, 30, 0, 0, 276, 278, 3, 36, 18, 0, 277, 275, 1, 0, 0, 0, 277, 278, 1, 0, 0, 0, 278, 33, 1, 0, 0, 0, 279, 280, 5, 8, 0, 0, 280, 283, 3, 22, 11, 0, 281, 282, 5, 30, 0, 0, 282, 284, 3, 36, 18, 0, 283, 281, 1, 0, 0, 0, 283, 284, 1, 0, 0, 0, 284, 35, 1, 0, 0, 0, 285, 290, 3, 40, 20, 0, 286, 287, 5, 34, 0, 0, 287, 289, 3, 40, 20, 0, 288, 286, 1, 0, 0, 0, 289, 292, 1, 0, 0, 0, 290, 288, 1, 0, 0, 0, 290, 291, 1, 0, 0, 0, 291, 37, 1, 0, 0, 0, 292, 290, 1, 0, 0, 0, 293, 294, 7, 2, 0, 0, 294, 39, 1, 0, 0, 0, 295, 300, 3, 42, 21, 0, 296, 297, 5, 36, 0, 0, 297, 299, 3, 42, 21, 0, 298, 296, 1, 0, 0, 0, 299, 302, 1, 0, 0, 0, 300, 298, 1, 0, 0, 0, 300, 301, 1, 0, 0, 0, 301, 41, 1, 0, 0, 0, 302, 300, 1, 0, 0, 0, 303, 304, 7, 3, 0, 0, 304, 43, 1, 0, 0, 0, 305, 348, 5, 44, 0, 0, 306, 307, 3, 76, 38, 0, 307, 308, 5, 66, 0, 0, 308, 348, 1, 0, 0, 0, 309, 348, 3, 74, 37, 0, 310, 348, 3, 76, 38, 0, 311, 348, 3, 70, 35, 0, 312, 348, 5, 47, 0, 0, 313, 348, 3, 78, 39, 0, 314, 315, 5, 64, 0, 0, 315, 320, 3, 72, 36, 0, 316, 317, 5, 34, 0, 0, 317, 319, 3, 72, 36, 0, 318, 316, 1, 0, 0, 0, 319, 322, 1, 0, 0, 0, 320, 318, 1, 0, 0, 0, 320, 321, 1, 0, 0, 0, 321, 323, 1, 0, 0, 0, 322, 320, 1, 0, 0, 0, 323, 324, 5, 65, 0, 0, 324, 348, 1, 0, 0, 0, 325, 326, 5, 64, 0, 0, 326, 331, 3, 70, 35, 0, 327, 328, 5, 34, 0, 0, 328, 330, 3, 70, 35, 0, 329, 327, 1, 0, 0, 0, 330, 333, 1, 0, 0, 0, 331, 329, 1, 0, 0, 0, 331, 332, 1, 0, 0, 0, 332, 334, 1, 0, 0, 0, 333, 331, 1, 0, 0, 0, 334, 335, 5, 65, 0, 0, 335, 348, 1, 0, 0, 0, 336, 337, 5, 64, 0, 0, 337, 342, 3, 78, 39, 0, 338, 339, 5, 34, 0, 0, 339, 341, 3, 78, 39, 0, 340, 338, 1, 0, 0, 0, 341, 344, 1, 0, 0, 0, 342, 340, 1, 0, 0, 0, 342, 343, 1, 0, 0, 0, 343, 345, 1, 0, 0, 0, 344, 342, 1, 0, 0, 0, 345, 346, 5, 65, 0, 0, 346, 348, 1, 0, 0, 0, 347, 305, 1, 0, 0, 0, 347, 306, 1, 0, 0, 0, 347, 309, 1, 0, 0, 0, 347, 310, 1, 0, 0, 0, 347, 311, 1, 0, 0, 0, 347, 312, 1, 0, 0, 0, 347, 313, 1, 0, 0, 0, 347, 314, 1, 0, 0, 0, 347, 325, 1, 0, 0, 0, 347, 336, 1, 0, 0, 0, 348, 45, 1, 0, 0, 0, 349, 350, 5, 10, 0, 0, 350, 351, 5, 28, 0, 0, 351, 47, 1, 0, 0, 0, 352, 353, 5, 16, 0, 0, 353, 358, 3, 50, 25, 0, 354, 355, 5, 34, 0, 0, 355, 357, 3, 50, 25, 0, 356, 354, 1, 0, 0, 0, 357, 360, 1, 0, 0, 0, 358, 356, 1, 0, 0, 0, 358, 359, 1, 0, 0, 0, 359, 49, 1, 0, 0, 0, 360, 358, 1, 0, 0, 0, 361, 363, 3, 10, 5, 0, 362, 364, 7, 4, 0, 0, 363, 362, 1, 0, 0, 0, 363, 364, 1, 0, 0, 0, 364, 367, 1, 0, 0, 0, 365, 366, 5, 45, 0, 0, 366, 368, 7, 5, 0, 0, 367, 365, 1, 0, 0, 0, 367, 368, 1, 0, 0, 0, 368, 51, 1, 0, 0, 0, 369, 370, 5, 9, 0, 0, 370, 375, 3, 38, 19, 0, 371, 372, 5, 34, 0, 0, 372, 374, 3, 38, 19, 0, 373, 371, 1, 0, 0, 0, 374, 377, 1, 0, 0, 0, 375, 373, 1, 0, 0, 0, 375, 376, 1, 0, 0, 0, 376, 388, 1, 0, 0, 0, 377, 375, 1, 0, 0, 0, 378, 379, 5, 12, 0, 0, 379, 384, 3, 38, 19, 0, 380, 381, 5, 34, 0, 0, 381, 383, 3, 38, 19, 0, 382, 380, 1, 0, 0, 0, 383, 386, 1, 0, 0, 0, 384, 382, 1, 0, 0, 0, 384, 385, 1, 0, 0, 0, 385, 388, 1, 0, 0, 0, 386, 384, 1, 0, 0, 0, 387, 369, 1, 0, 0, 0, 387, 378, 1, 0, 0, 0, 388, 53, 1, 0, 0, 0, 389, 390, 5, 2, 0, 0, 390, 395, 3, 38, 19, 0, 391, 392, 5, 34, 0, 0, 392, 394, 3, 38, 19, 0, 393, 391, 1, 0, 0, 0, 394, 397, 1, 0, 0, 0, 395, 393, 1, 0, 0, 0, 395, 396, 1, 0, 0, 0, 396, 55, 1, 0, 0, 0, 397, 395, 1, 0, 0, 0, 398, 399, 5, 13, 0, 0, 399, 404, 3, 58, 29, 0, 400, 401, 5, 34, 0, 0, 401, 403, 3, 58, 29, 0, 402, 400, 1, 0, 0, 0, 403, 406, 1, 0, 0, 0, 404, 402, 1, 0, 0, 0, 404, 405, 1, 0, 0, 0, 405, 57, 1, 0, 0, 0, 406, 404, 1, 0, 0, 0, 407, 408, 3, 38, 19, 0, 408, 409, 5, 71, 0, 0, 409, 410, 3, 38, 19, 0, 410, 59, 1, 0, 0, 0, 411, 412, 5, 1, 0, 0, 412, 413, 3, 18, 9, 0, 413, 415, 3, 78, 39, 0, 414, 416, 3, 66, 33, 0, 415, 414, 1, 0, 0, 0, 415, 416, 1, 0, 0, 0, 416, 61, 1, 0, 0, 0, 417, 418, 5, 7, 0, 0, 418, 419, 3, 18, 9, 0, 419, 420, 3, 78, 39, 0, 420, 63, 1, 0, 0, 0, 421, 422, 5, 11, 0, 0, 422, 423, 3, 38, 19, 0, 423, 65, 1, 0, 0, 0, 424, 429, 3, 68, 34, 0, 425, 426, 5, 34, 0, 0, 426, 428, 3, 68, 34, 0, 427, 425, 1, 0, 0, 0, 428, 431, 1, 0, 0, 0, 429, 427, 1, 0, 0, 0, 429, 430, 1, 0, 0, 0, 430, 67, 1, 0, 0, 0, 431, 429, 1, 0, 0, 0, 432, 433, 3, 42, 21, 0, 433, 434, 5, 33, 0, 0, 434, 435, 3, 44, 22, 0, 435, 69, 1, 0, 0, 0, 436, 437, 7, 6, 0, 0, 437, 71, 1, 0, 0, 0, 438, 441, 3, 74, 37, 0, 439, 441, 3, 76, 38, 0, 440, 438, 1, 0, 0, 0, 440, 439, 1, 0, 0, 0, 441, 73, 1, 0, 0, 0, 442, 444, 7, 0, 0, 0, 443, 442, 1, 0, 0, 0, 443, 444, 1, 0, 0, 0, 444, 445, 1, 0, 0, 0, 445, 446, 5, 29, 0, 0, 446, 75, 1, 0, 0, 0, 447, 449, 7, 0, 0, 0, 448, 447, 1, 0, 0, 0, 448, 449, 1, 0, 0, 0, 449, 450, 1, 0, 0, 0, 450, 451, 5, 28, 0, 0, 451, 77, 1, 0, 0, 0, 452, 453, 5, 27, 0, 0, 453, 79, 1, 0, 0, 0, 454, 455, 7, 7, 0, 0, 455, 81, 1, 0, 0, 0, 456, 457, 5, 5, 0, 0, 457, 458, 3, 84, 42, 0, 458, 83, 1, 0, 0, 0, 459, 460, 5, 64, 0, 0, 460, 461, 3, 2, 1, 0, 461, 462, 5, 65, 0, 0, 462, 85, 1, 0, 0, 0, 463, 464, 5, 15, 0, 0, 464, 468, 5, 51, 0, 0, 465, 466, 5, 15, 0, 0, 466, 468, 5, 52, 0, 0, 467, 463, 1, 0, 0, 0, 467, 465, 1, 0, 0, 0, 468, 87, 1, 0, 0, 0, 469, 470, 5, 3, 0, 0, 470, 473, 3, 38, 19, 0, 471, 472, 5, 73, 0, 0, 472, 474, 3, 38, 19, 0, 473, 471, 1, 0, 0, 0, 473, 474, 1, 0, 0, 0, 474, 484, 1, 0, 0, 0, 475, 476, 5, 74, 0, 0, 476, 481, 3, 90, 45, 0, 477, 478, 5, 34, 0, 0, 478, 480, 3, 90, 45, 0, 479, 477, 1, 0, 0, 0, 480, 483, 1, 0, 0, 0, 481, 479, 1, 0, 0, 0, 481, 482, 1, 0, 0, 0, 482, 485, 1, 0, 0, 0, 483, 481, 1, 0, 0, 0, 484, 475, 1, 0, 0, 0, 484, 485, 1, 0, 0, 0, 485, 89, 1, 0, 0, 0, 486, 487, 3, 38, 19, 0, 487, 488, 5, 33, 0, 0, 488, 490, 1, 0, 0, 0, 489, 486, 1, 0, 0, 0, 489, 490, 1, 0, 0, 0, 490, 491, 1, 0, 0, 0, 491, 492, 3, 38, 19, 0, 492, 91, 1, 0, 0, 0, 50, 103, 110, 125, 137, 146, 151, 159, 161, 166, 173, 178, 185, 191, 199, 201, 217, 220, 224, 234, 242, 250, 254, 263, 273, 277, 283, 290, 300, 320, 331, 342, 347, 358, 363, 367, 375, 384, 387, 395, 404, 415, 429, 440, 443, 448, 467, 473, 481, 484, 489]
\ No newline at end of file
+[4, 1, 81, 501, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 102, 8, 1, 10, 1, 12, 1, 105, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 111, 8, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 126, 8, 3, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 138, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 145, 8, 5, 10, 5, 12, 5, 148, 9, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 155, 8, 5, 1, 5, 1, 5, 3, 5, 159, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 167, 8, 5, 10, 5, 12, 5, 170, 9, 5, 1, 6, 1, 6, 3, 6, 174, 8, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 181, 8, 6, 1, 6, 1, 6, 1, 6, 3, 6, 186, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 193, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 199, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 5, 8, 207, 8, 8, 10, 8, 12, 8, 210, 9, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 5, 9, 223, 8, 9, 10, 9, 12, 9, 226, 9, 9, 3, 9, 228, 8, 9, 1, 9, 1, 9, 3, 9, 232, 8, 9, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 5, 11, 240, 8, 11, 10, 11, 12, 11, 243, 9, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 250, 8, 12, 1, 13, 1, 13, 1, 13, 1, 13, 5, 13, 256, 8, 13, 10, 13, 12, 13, 259, 9, 13, 1, 13, 3, 13, 262, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 5, 14, 269, 8, 14, 10, 14, 12, 14, 272, 9, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 3, 16, 281, 8, 16, 1, 16, 1, 16, 3, 16, 285, 8, 16, 1, 17, 1, 17, 1, 17, 1, 17, 3, 17, 291, 8, 17, 1, 18, 1, 18, 1, 18, 5, 18, 296, 8, 18, 10, 18, 12, 18, 299, 9, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 5, 20, 306, 8, 20, 10, 20, 12, 20, 309, 9, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 326, 8, 22, 10, 22, 12, 22, 329, 9, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 337, 8, 22, 10, 22, 12, 22, 340, 9, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 348, 8, 22, 10, 22, 12, 22, 351, 9, 22, 1, 22, 1, 22, 3, 22, 355, 8, 22, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 5, 24, 364, 8, 24, 10, 24, 12, 24, 367, 9, 24, 1, 25, 1, 25, 3, 25, 371, 8, 25, 1, 25, 1, 25, 3, 25, 375, 8, 25, 1, 26, 1, 26, 1, 26, 1, 26, 5, 26, 381, 8, 26, 10, 26, 12, 26, 384, 9, 26, 1, 26, 1, 26, 1, 26, 1, 26, 5, 26, 390, 8, 26, 10, 26, 12, 26, 393, 9, 26, 3, 26, 395, 8, 26, 1, 27, 1, 27, 1, 27, 1, 27, 5, 27, 401, 8, 27, 10, 27, 12, 27, 404, 9, 27, 1, 28, 1, 28, 1, 28, 1, 28, 5, 28, 410, 8, 28, 10, 28, 12, 28, 413, 9, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 3, 30, 423, 8, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 5, 33, 435, 8, 33, 10, 33, 12, 33, 438, 9, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 36, 1, 36, 3, 36, 448, 8, 36, 1, 37, 3, 37, 451, 8, 37, 1, 37, 1, 37, 1, 38, 3, 38, 456, 8, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 475, 8, 43, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 481, 8, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 487, 8, 44, 10, 44, 12, 44, 490, 9, 44, 3, 44, 492, 8, 44, 1, 45, 1, 45, 1, 45, 3, 45, 497, 8, 45, 1, 45, 1, 45, 1, 45, 0, 3, 2, 10, 16, 46, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 0, 8, 1, 0, 60, 61, 1, 0, 62, 64, 1, 0, 76, 77, 1, 0, 67, 68, 2, 0, 32, 32, 35, 35, 1, 0, 38, 39, 2, 0, 37, 37, 51, 51, 1, 0, 54, 59, 531, 0, 92, 1, 0, 0, 0, 2, 95, 1, 0, 0, 0, 4, 110, 1, 0, 0, 0, 6, 125, 1, 0, 0, 0, 8, 127, 1, 0, 0, 0, 10, 158, 1, 0, 0, 0, 12, 185, 1, 0, 0, 0, 14, 192, 1, 0, 0, 0, 16, 198, 1, 0, 0, 0, 18, 231, 1, 0, 0, 0, 20, 233, 1, 0, 0, 0, 22, 236, 1, 0, 0, 0, 24, 249, 1, 0, 0, 0, 26, 251, 1, 0, 0, 0, 28, 263, 1, 0, 0, 0, 30, 275, 1, 0, 0, 0, 32, 278, 1, 0, 0, 0, 34, 286, 1, 0, 0, 0, 36, 292, 1, 0, 0, 0, 38, 300, 1, 0, 0, 0, 40, 302, 1, 0, 0, 0, 42, 310, 1, 0, 0, 0, 44, 354, 1, 0, 0, 0, 46, 356, 1, 0, 0, 0, 48, 359, 1, 0, 0, 0, 50, 368, 1, 0, 0, 0, 52, 394, 1, 0, 0, 0, 54, 396, 1, 0, 0, 0, 56, 405, 1, 0, 0, 0, 58, 414, 1, 0, 0, 0, 60, 418, 1, 0, 0, 0, 62, 424, 1, 0, 0, 0, 64, 428, 1, 0, 0, 0, 66, 431, 1, 0, 0, 0, 68, 439, 1, 0, 0, 0, 70, 443, 1, 0, 0, 0, 72, 447, 1, 0, 0, 0, 74, 450, 1, 0, 0, 0, 76, 455, 1, 0, 0, 0, 78, 459, 1, 0, 0, 0, 80, 461, 1, 0, 0, 0, 82, 463, 1, 0, 0, 0, 84, 466, 1, 0, 0, 0, 86, 474, 1, 0, 0, 0, 88, 476, 1, 0, 0, 0, 90, 496, 1, 0, 0, 0, 92, 93, 3, 2, 1, 0, 93, 94, 5, 0, 0, 1, 94, 1, 1, 0, 0, 0, 95, 96, 6, 1, -1, 0, 96, 97, 3, 4, 2, 0, 97, 103, 1, 0, 0, 0, 98, 99, 10, 1, 0, 0, 99, 100, 5, 26, 0, 0, 100, 102, 3, 6, 3, 0, 101, 98, 1, 0, 0, 0, 102, 105, 1, 0, 0, 0, 103, 101, 1, 0, 0, 0, 103, 104, 1, 0, 0, 0, 104, 3, 1, 0, 0, 0, 105, 103, 1, 0, 0, 0, 106, 111, 3, 82, 41, 0, 107, 111, 3, 26, 13, 0, 108, 111, 3, 20, 10, 0, 109, 111, 3, 86, 43, 0, 110, 106, 1, 0, 0, 0, 110, 107, 1, 0, 0, 0, 110, 108, 1, 0, 0, 0, 110, 109, 1, 0, 0, 0, 111, 5, 1, 0, 0, 0, 112, 126, 3, 30, 15, 0, 113, 126, 3, 34, 17, 0, 114, 126, 3, 46, 23, 0, 115, 126, 3, 52, 26, 0, 116, 126, 3, 48, 24, 0, 117, 126, 3, 32, 16, 0, 118, 126, 3, 8, 4, 0, 119, 126, 3, 54, 27, 0, 120, 126, 3, 56, 28, 0, 121, 126, 3, 60, 30, 0, 122, 126, 3, 62, 31, 0, 123, 126, 3, 88, 44, 0, 124, 126, 3, 64, 32, 0, 125, 112, 1, 0, 0, 0, 125, 113, 1, 0, 0, 0, 125, 114, 1, 0, 0, 0, 125, 115, 1, 0, 0, 0, 125, 116, 1, 0, 0, 0, 125, 117, 1, 0, 0, 0, 125, 118, 1, 0, 0, 0, 125, 119, 1, 0, 0, 0, 125, 120, 1, 0, 0, 0, 125, 121, 1, 0, 0, 0, 125, 122, 1, 0, 0, 0, 125, 123, 1, 0, 0, 0, 125, 124, 1, 0, 0, 0, 126, 7, 1, 0, 0, 0, 127, 128, 5, 18, 0, 0, 128, 129, 3, 10, 5, 0, 129, 9, 1, 0, 0, 0, 130, 131, 6, 5, -1, 0, 131, 132, 5, 44, 0, 0, 132, 159, 3, 10, 5, 7, 133, 159, 3, 14, 7, 0, 134, 159, 3, 12, 6, 0, 135, 137, 3, 14, 7, 0, 136, 138, 5, 44, 0, 0, 137, 136, 1, 0, 0, 0, 137, 138, 1, 0, 0, 0, 138, 139, 1, 0, 0, 0, 139, 140, 5, 41, 0, 0, 140, 141, 5, 40, 0, 0, 141, 146, 3, 14, 7, 0, 142, 143, 5, 34, 0, 0, 143, 145, 3, 14, 7, 0, 144, 142, 1, 0, 0, 0, 145, 148, 1, 0, 0, 0, 146, 144, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, 147, 149, 1, 0, 0, 0, 148, 146, 1, 0, 0, 0, 149, 150, 5, 50, 0, 0, 150, 159, 1, 0, 0, 0, 151, 152, 3, 14, 7, 0, 152, 154, 5, 42, 0, 0, 153, 155, 5, 44, 0, 0, 154, 153, 1, 0, 0, 0, 154, 155, 1, 0, 0, 0, 155, 156, 1, 0, 0, 0, 156, 157, 5, 45, 0, 0, 157, 159, 1, 0, 0, 0, 158, 130, 1, 0, 0, 0, 158, 133, 1, 0, 0, 0, 158, 134, 1, 0, 0, 0, 158, 135, 1, 0, 0, 0, 158, 151, 1, 0, 0, 0, 159, 168, 1, 0, 0, 0, 160, 161, 10, 4, 0, 0, 161, 162, 5, 31, 0, 0, 162, 167, 3, 10, 5, 5, 163, 164, 10, 3, 0, 0, 164, 165, 5, 47, 0, 0, 165, 167, 3, 10, 5, 4, 166, 160, 1, 0, 0, 0, 166, 163, 1, 0, 0, 0, 167, 170, 1, 0, 0, 0, 168, 166, 1, 0, 0, 0, 168, 169, 1, 0, 0, 0, 169, 11, 1, 0, 0, 0, 170, 168, 1, 0, 0, 0, 171, 173, 3, 14, 7, 0, 172, 174, 5, 44, 0, 0, 173, 172, 1, 0, 0, 0, 173, 174, 1, 0, 0, 0, 174, 175, 1, 0, 0, 0, 175, 176, 5, 43, 0, 0, 176, 177, 3, 78, 39, 0, 177, 186, 1, 0, 0, 0, 178, 180, 3, 14, 7, 0, 179, 181, 5, 44, 0, 0, 180, 179, 1, 0, 0, 0, 180, 181, 1, 0, 0, 0, 181, 182, 1, 0, 0, 0, 182, 183, 5, 49, 0, 0, 183, 184, 3, 78, 39, 0, 184, 186, 1, 0, 0, 0, 185, 171, 1, 0, 0, 0, 185, 178, 1, 0, 0, 0, 186, 13, 1, 0, 0, 0, 187, 193, 3, 16, 8, 0, 188, 189, 3, 16, 8, 0, 189, 190, 3, 80, 40, 0, 190, 191, 3, 16, 8, 0, 191, 193, 1, 0, 0, 0, 192, 187, 1, 0, 0, 0, 192, 188, 1, 0, 0, 0, 193, 15, 1, 0, 0, 0, 194, 195, 6, 8, -1, 0, 195, 199, 3, 18, 9, 0, 196, 197, 7, 0, 0, 0, 197, 199, 3, 16, 8, 3, 198, 194, 1, 0, 0, 0, 198, 196, 1, 0, 0, 0, 199, 208, 1, 0, 0, 0, 200, 201, 10, 2, 0, 0, 201, 202, 7, 1, 0, 0, 202, 207, 3, 16, 8, 3, 203, 204, 10, 1, 0, 0, 204, 205, 7, 0, 0, 0, 205, 207, 3, 16, 8, 2, 206, 200, 1, 0, 0, 0, 206, 203, 1, 0, 0, 0, 207, 210, 1, 0, 0, 0, 208, 206, 1, 0, 0, 0, 208, 209, 1, 0, 0, 0, 209, 17, 1, 0, 0, 0, 210, 208, 1, 0, 0, 0, 211, 232, 3, 44, 22, 0, 212, 232, 3, 40, 20, 0, 213, 214, 5, 40, 0, 0, 214, 215, 3, 10, 5, 0, 215, 216, 5, 50, 0, 0, 216, 232, 1, 0, 0, 0, 217, 218, 3, 42, 21, 0, 218, 227, 5, 40, 0, 0, 219, 224, 3, 10, 5, 0, 220, 221, 5, 34, 0, 0, 221, 223, 3, 10, 5, 0, 222, 220, 1, 0, 0, 0, 223, 226, 1, 0, 0, 0, 224, 222, 1, 0, 0, 0, 224, 225, 1, 0, 0, 0, 225, 228, 1, 0, 0, 0, 226, 224, 1, 0, 0, 0, 227, 219, 1, 0, 0, 0, 227, 228, 1, 0, 0, 0, 228, 229, 1, 0, 0, 0, 229, 230, 5, 50, 0, 0, 230, 232, 1, 0, 0, 0, 231, 211, 1, 0, 0, 0, 231, 212, 1, 0, 0, 0, 231, 213, 1, 0, 0, 0, 231, 217, 1, 0, 0, 0, 232, 19, 1, 0, 0, 0, 233, 234, 5, 14, 0, 0, 234, 235, 3, 22, 11, 0, 235, 21, 1, 0, 0, 0, 236, 241, 3, 24, 12, 0, 237, 238, 5, 34, 0, 0, 238, 240, 3, 24, 12, 0, 239, 237, 1, 0, 0, 0, 240, 243, 1, 0, 0, 0, 241, 239, 1, 0, 0, 0, 241, 242, 1, 0, 0, 0, 242, 23, 1, 0, 0, 0, 243, 241, 1, 0, 0, 0, 244, 250, 3, 10, 5, 0, 245, 246, 3, 40, 20, 0, 246, 247, 5, 33, 0, 0, 247, 248, 3, 10, 5, 0, 248, 250, 1, 0, 0, 0, 249, 244, 1, 0, 0, 0, 249, 245, 1, 0, 0, 0, 250, 25, 1, 0, 0, 0, 251, 252, 5, 6, 0, 0, 252, 257, 3, 38, 19, 0, 253, 254, 5, 34, 0, 0, 254, 256, 3, 38, 19, 0, 255, 253, 1, 0, 0, 0, 256, 259, 1, 0, 0, 0, 257, 255, 1, 0, 0, 0, 257, 258, 1, 0, 0, 0, 258, 261, 1, 0, 0, 0, 259, 257, 1, 0, 0, 0, 260, 262, 3, 28, 14, 0, 261, 260, 1, 0, 0, 0, 261, 262, 1, 0, 0, 0, 262, 27, 1, 0, 0, 0, 263, 264, 5, 65, 0, 0, 264, 265, 5, 73, 0, 0, 265, 270, 3, 38, 19, 0, 266, 267, 5, 34, 0, 0, 267, 269, 3, 38, 19, 0, 268, 266, 1, 0, 0, 0, 269, 272, 1, 0, 0, 0, 270, 268, 1, 0, 0, 0, 270, 271, 1, 0, 0, 0, 271, 273, 1, 0, 0, 0, 272, 270, 1, 0, 0, 0, 273, 274, 5, 66, 0, 0, 274, 29, 1, 0, 0, 0, 275, 276, 5, 4, 0, 0, 276, 277, 3, 22, 11, 0, 277, 31, 1, 0, 0, 0, 278, 280, 5, 17, 0, 0, 279, 281, 3, 22, 11, 0, 280, 279, 1, 0, 0, 0, 280, 281, 1, 0, 0, 0, 281, 284, 1, 0, 0, 0, 282, 283, 5, 30, 0, 0, 283, 285, 3, 36, 18, 0, 284, 282, 1, 0, 0, 0, 284, 285, 1, 0, 0, 0, 285, 33, 1, 0, 0, 0, 286, 287, 5, 8, 0, 0, 287, 290, 3, 22, 11, 0, 288, 289, 5, 30, 0, 0, 289, 291, 3, 36, 18, 0, 290, 288, 1, 0, 0, 0, 290, 291, 1, 0, 0, 0, 291, 35, 1, 0, 0, 0, 292, 297, 3, 40, 20, 0, 293, 294, 5, 34, 0, 0, 294, 296, 3, 40, 20, 0, 295, 293, 1, 0, 0, 0, 296, 299, 1, 0, 0, 0, 297, 295, 1, 0, 0, 0, 297, 298, 1, 0, 0, 0, 298, 37, 1, 0, 0, 0, 299, 297, 1, 0, 0, 0, 300, 301, 7, 2, 0, 0, 301, 39, 1, 0, 0, 0, 302, 307, 3, 42, 21, 0, 303, 304, 5, 36, 0, 0, 304, 306, 3, 42, 21, 0, 305, 303, 1, 0, 0, 0, 306, 309, 1, 0, 0, 0, 307, 305, 1, 0, 0, 0, 307, 308, 1, 0, 0, 0, 308, 41, 1, 0, 0, 0, 309, 307, 1, 0, 0, 0, 310, 311, 7, 3, 0, 0, 311, 43, 1, 0, 0, 0, 312, 355, 5, 45, 0, 0, 313, 314, 3, 76, 38, 0, 314, 315, 5, 67, 0, 0, 315, 355, 1, 0, 0, 0, 316, 355, 3, 74, 37, 0, 317, 355, 3, 76, 38, 0, 318, 355, 3, 70, 35, 0, 319, 355, 5, 48, 0, 0, 320, 355, 3, 78, 39, 0, 321, 322, 5, 65, 0, 0, 322, 327, 3, 72, 36, 0, 323, 324, 5, 34, 0, 0, 324, 326, 3, 72, 36, 0, 325, 323, 1, 0, 0, 0, 326, 329, 1, 0, 0, 0, 327, 325, 1, 0, 0, 0, 327, 328, 1, 0, 0, 0, 328, 330, 1, 0, 0, 0, 329, 327, 1, 0, 0, 0, 330, 331, 5, 66, 0, 0, 331, 355, 1, 0, 0, 0, 332, 333, 5, 65, 0, 0, 333, 338, 3, 70, 35, 0, 334, 335, 5, 34, 0, 0, 335, 337, 3, 70, 35, 0, 336, 334, 1, 0, 0, 0, 337, 340, 1, 0, 0, 0, 338, 336, 1, 0, 0, 0, 338, 339, 1, 0, 0, 0, 339, 341, 1, 0, 0, 0, 340, 338, 1, 0, 0, 0, 341, 342, 5, 66, 0, 0, 342, 355, 1, 0, 0, 0, 343, 344, 5, 65, 0, 0, 344, 349, 3, 78, 39, 0, 345, 346, 5, 34, 0, 0, 346, 348, 3, 78, 39, 0, 347, 345, 1, 0, 0, 0, 348, 351, 1, 0, 0, 0, 349, 347, 1, 0, 0, 0, 349, 350, 1, 0, 0, 0, 350, 352, 1, 0, 0, 0, 351, 349, 1, 0, 0, 0, 352, 353, 5, 66, 0, 0, 353, 355, 1, 0, 0, 0, 354, 312, 1, 0, 0, 0, 354, 313, 1, 0, 0, 0, 354, 316, 1, 0, 0, 0, 354, 317, 1, 0, 0, 0, 354, 318, 1, 0, 0, 0, 354, 319, 1, 0, 0, 0, 354, 320, 1, 0, 0, 0, 354, 321, 1, 0, 0, 0, 354, 332, 1, 0, 0, 0, 354, 343, 1, 0, 0, 0, 355, 45, 1, 0, 0, 0, 356, 357, 5, 10, 0, 0, 357, 358, 5, 28, 0, 0, 358, 47, 1, 0, 0, 0, 359, 360, 5, 16, 0, 0, 360, 365, 3, 50, 25, 0, 361, 362, 5, 34, 0, 0, 362, 364, 3, 50, 25, 0, 363, 361, 1, 0, 0, 0, 364, 367, 1, 0, 0, 0, 365, 363, 1, 0, 0, 0, 365, 366, 1, 0, 0, 0, 366, 49, 1, 0, 0, 0, 367, 365, 1, 0, 0, 0, 368, 370, 3, 10, 5, 0, 369, 371, 7, 4, 0, 0, 370, 369, 1, 0, 0, 0, 370, 371, 1, 0, 0, 0, 371, 374, 1, 0, 0, 0, 372, 373, 5, 46, 0, 0, 373, 375, 7, 5, 0, 0, 374, 372, 1, 0, 0, 0, 374, 375, 1, 0, 0, 0, 375, 51, 1, 0, 0, 0, 376, 377, 5, 9, 0, 0, 377, 382, 3, 38, 19, 0, 378, 379, 5, 34, 0, 0, 379, 381, 3, 38, 19, 0, 380, 378, 1, 0, 0, 0, 381, 384, 1, 0, 0, 0, 382, 380, 1, 0, 0, 0, 382, 383, 1, 0, 0, 0, 383, 395, 1, 0, 0, 0, 384, 382, 1, 0, 0, 0, 385, 386, 5, 12, 0, 0, 386, 391, 3, 38, 19, 0, 387, 388, 5, 34, 0, 0, 388, 390, 3, 38, 19, 0, 389, 387, 1, 0, 0, 0, 390, 393, 1, 0, 0, 0, 391, 389, 1, 0, 0, 0, 391, 392, 1, 0, 0, 0, 392, 395, 1, 0, 0, 0, 393, 391, 1, 0, 0, 0, 394, 376, 1, 0, 0, 0, 394, 385, 1, 0, 0, 0, 395, 53, 1, 0, 0, 0, 396, 397, 5, 2, 0, 0, 397, 402, 3, 38, 19, 0, 398, 399, 5, 34, 0, 0, 399, 401, 3, 38, 19, 0, 400, 398, 1, 0, 0, 0, 401, 404, 1, 0, 0, 0, 402, 400, 1, 0, 0, 0, 402, 403, 1, 0, 0, 0, 403, 55, 1, 0, 0, 0, 404, 402, 1, 0, 0, 0, 405, 406, 5, 13, 0, 0, 406, 411, 3, 58, 29, 0, 407, 408, 5, 34, 0, 0, 408, 410, 3, 58, 29, 0, 409, 407, 1, 0, 0, 0, 410, 413, 1, 0, 0, 0, 411, 409, 1, 0, 0, 0, 411, 412, 1, 0, 0, 0, 412, 57, 1, 0, 0, 0, 413, 411, 1, 0, 0, 0, 414, 415, 3, 38, 19, 0, 415, 416, 5, 72, 0, 0, 416, 417, 3, 38, 19, 0, 417, 59, 1, 0, 0, 0, 418, 419, 5, 1, 0, 0, 419, 420, 3, 18, 9, 0, 420, 422, 3, 78, 39, 0, 421, 423, 3, 66, 33, 0, 422, 421, 1, 0, 0, 0, 422, 423, 1, 0, 0, 0, 423, 61, 1, 0, 0, 0, 424, 425, 5, 7, 0, 0, 425, 426, 3, 18, 9, 0, 426, 427, 3, 78, 39, 0, 427, 63, 1, 0, 0, 0, 428, 429, 5, 11, 0, 0, 429, 430, 3, 38, 19, 0, 430, 65, 1, 0, 0, 0, 431, 436, 3, 68, 34, 0, 432, 433, 5, 34, 0, 0, 433, 435, 3, 68, 34, 0, 434, 432, 1, 0, 0, 0, 435, 438, 1, 0, 0, 0, 436, 434, 1, 0, 0, 0, 436, 437, 1, 0, 0, 0, 437, 67, 1, 0, 0, 0, 438, 436, 1, 0, 0, 0, 439, 440, 3, 42, 21, 0, 440, 441, 5, 33, 0, 0, 441, 442, 3, 44, 22, 0, 442, 69, 1, 0, 0, 0, 443, 444, 7, 6, 0, 0, 444, 71, 1, 0, 0, 0, 445, 448, 3, 74, 37, 0, 446, 448, 3, 76, 38, 0, 447, 445, 1, 0, 0, 0, 447, 446, 1, 0, 0, 0, 448, 73, 1, 0, 0, 0, 449, 451, 7, 0, 0, 0, 450, 449, 1, 0, 0, 0, 450, 451, 1, 0, 0, 0, 451, 452, 1, 0, 0, 0, 452, 453, 5, 29, 0, 0, 453, 75, 1, 0, 0, 0, 454, 456, 7, 0, 0, 0, 455, 454, 1, 0, 0, 0, 455, 456, 1, 0, 0, 0, 456, 457, 1, 0, 0, 0, 457, 458, 5, 28, 0, 0, 458, 77, 1, 0, 0, 0, 459, 460, 5, 27, 0, 0, 460, 79, 1, 0, 0, 0, 461, 462, 7, 7, 0, 0, 462, 81, 1, 0, 0, 0, 463, 464, 5, 5, 0, 0, 464, 465, 3, 84, 42, 0, 465, 83, 1, 0, 0, 0, 466, 467, 5, 65, 0, 0, 467, 468, 3, 2, 1, 0, 468, 469, 5, 66, 0, 0, 469, 85, 1, 0, 0, 0, 470, 471, 5, 15, 0, 0, 471, 475, 5, 52, 0, 0, 472, 473, 5, 15, 0, 0, 473, 475, 5, 53, 0, 0, 474, 470, 1, 0, 0, 0, 474, 472, 1, 0, 0, 0, 475, 87, 1, 0, 0, 0, 476, 477, 5, 3, 0, 0, 477, 480, 3, 38, 19, 0, 478, 479, 5, 74, 0, 0, 479, 481, 3, 38, 19, 0, 480, 478, 1, 0, 0, 0, 480, 481, 1, 0, 0, 0, 481, 491, 1, 0, 0, 0, 482, 483, 5, 75, 0, 0, 483, 488, 3, 90, 45, 0, 484, 485, 5, 34, 0, 0, 485, 487, 3, 90, 45, 0, 486, 484, 1, 0, 0, 0, 487, 490, 1, 0, 0, 0, 488, 486, 1, 0, 0, 0, 488, 489, 1, 0, 0, 0, 489, 492, 1, 0, 0, 0, 490, 488, 1, 0, 0, 0, 491, 482, 1, 0, 0, 0, 491, 492, 1, 0, 0, 0, 492, 89, 1, 0, 0, 0, 493, 494, 3, 38, 19, 0, 494, 495, 5, 33, 0, 0, 495, 497, 1, 0, 0, 0, 496, 493, 1, 0, 0, 0, 496, 497, 1, 0, 0, 0, 497, 498, 1, 0, 0, 0, 498, 499, 3, 38, 19, 0, 499, 91, 1, 0, 0, 0, 51, 103, 110, 125, 137, 146, 154, 158, 166, 168, 173, 180, 185, 192, 198, 206, 208, 224, 227, 231, 241, 249, 257, 261, 270, 280, 284, 290, 297, 307, 327, 338, 349, 354, 365, 370, 374, 382, 391, 394, 402, 411, 422, 436, 447, 450, 455, 474, 480, 488, 491, 496]
\ No newline at end of file
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java
index fffa822231681..b5eac5f58f9f6 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java
@@ -23,13 +23,13 @@ public class EsqlBaseParser extends Parser {
WS=22, EXPLAIN_WS=23, EXPLAIN_LINE_COMMENT=24, EXPLAIN_MULTILINE_COMMENT=25,
PIPE=26, STRING=27, INTEGER_LITERAL=28, DECIMAL_LITERAL=29, BY=30, AND=31,
ASC=32, ASSIGN=33, COMMA=34, DESC=35, DOT=36, FALSE=37, FIRST=38, LAST=39,
- LP=40, IN=41, LIKE=42, NOT=43, NULL=44, NULLS=45, OR=46, PARAM=47, RLIKE=48,
- RP=49, TRUE=50, INFO=51, FUNCTIONS=52, EQ=53, NEQ=54, LT=55, LTE=56, GT=57,
- GTE=58, PLUS=59, MINUS=60, ASTERISK=61, SLASH=62, PERCENT=63, OPENING_BRACKET=64,
- CLOSING_BRACKET=65, UNQUOTED_IDENTIFIER=66, QUOTED_IDENTIFIER=67, EXPR_LINE_COMMENT=68,
- EXPR_MULTILINE_COMMENT=69, EXPR_WS=70, AS=71, METADATA=72, ON=73, WITH=74,
- SRC_UNQUOTED_IDENTIFIER=75, SRC_QUOTED_IDENTIFIER=76, SRC_LINE_COMMENT=77,
- SRC_MULTILINE_COMMENT=78, SRC_WS=79, EXPLAIN_PIPE=80;
+ LP=40, IN=41, IS=42, LIKE=43, NOT=44, NULL=45, NULLS=46, OR=47, PARAM=48,
+ RLIKE=49, RP=50, TRUE=51, INFO=52, FUNCTIONS=53, EQ=54, NEQ=55, LT=56,
+ LTE=57, GT=58, GTE=59, PLUS=60, MINUS=61, ASTERISK=62, SLASH=63, PERCENT=64,
+ OPENING_BRACKET=65, CLOSING_BRACKET=66, UNQUOTED_IDENTIFIER=67, QUOTED_IDENTIFIER=68,
+ EXPR_LINE_COMMENT=69, EXPR_MULTILINE_COMMENT=70, EXPR_WS=71, AS=72, METADATA=73,
+ ON=74, WITH=75, SRC_UNQUOTED_IDENTIFIER=76, SRC_QUOTED_IDENTIFIER=77,
+ SRC_LINE_COMMENT=78, SRC_MULTILINE_COMMENT=79, SRC_WS=80, EXPLAIN_PIPE=81;
public static final int
RULE_singleStatement = 0, RULE_query = 1, RULE_sourceCommand = 2, RULE_processingCommand = 3,
RULE_whereCommand = 4, RULE_booleanExpression = 5, RULE_regexBooleanExpression = 6,
@@ -68,8 +68,8 @@ private static String[] makeLiteralNames() {
"'rename'", "'row'", "'show'", "'sort'", "'stats'", "'where'", null,
null, null, null, null, null, null, null, null, null, null, "'by'", "'and'",
"'asc'", null, null, "'desc'", "'.'", "'false'", "'first'", "'last'",
- "'('", "'in'", "'like'", "'not'", "'null'", "'nulls'", "'or'", "'?'",
- "'rlike'", "')'", "'true'", "'info'", "'functions'", "'=='", "'!='",
+ "'('", "'in'", "'is'", "'like'", "'not'", "'null'", "'nulls'", "'or'",
+ "'?'", "'rlike'", "')'", "'true'", "'info'", "'functions'", "'=='", "'!='",
"'<'", "'<='", "'>'", "'>='", "'+'", "'-'", "'*'", "'/'", "'%'", null,
"']'", null, null, null, null, null, "'as'", "'metadata'", "'on'", "'with'"
};
@@ -83,9 +83,9 @@ private static String[] makeSymbolicNames() {
"WS", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", "EXPLAIN_MULTILINE_COMMENT",
"PIPE", "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND",
"ASC", "ASSIGN", "COMMA", "DESC", "DOT", "FALSE", "FIRST", "LAST", "LP",
- "IN", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", "TRUE",
- "INFO", "FUNCTIONS", "EQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS",
- "ASTERISK", "SLASH", "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET",
+ "IN", "IS", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP",
+ "TRUE", "INFO", "FUNCTIONS", "EQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS",
+ "MINUS", "ASTERISK", "SLASH", "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET",
"UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT",
"EXPR_WS", "AS", "METADATA", "ON", "WITH", "SRC_UNQUOTED_IDENTIFIER",
"SRC_QUOTED_IDENTIFIER", "SRC_LINE_COMMENT", "SRC_MULTILINE_COMMENT",
@@ -668,6 +668,29 @@ public T accept(ParseTreeVisitor extends T> visitor) {
}
}
@SuppressWarnings("CheckReturnValue")
+ public static class IsNullContext extends BooleanExpressionContext {
+ public ValueExpressionContext valueExpression() {
+ return getRuleContext(ValueExpressionContext.class,0);
+ }
+ public TerminalNode IS() { return getToken(EsqlBaseParser.IS, 0); }
+ public TerminalNode NULL() { return getToken(EsqlBaseParser.NULL, 0); }
+ public TerminalNode NOT() { return getToken(EsqlBaseParser.NOT, 0); }
+ public IsNullContext(BooleanExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).enterIsNull(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).exitIsNull(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof EsqlBaseParserVisitor ) return ((EsqlBaseParserVisitor extends T>)visitor).visitIsNull(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ @SuppressWarnings("CheckReturnValue")
public static class RegexExpressionContext extends BooleanExpressionContext {
public RegexBooleanExpressionContext regexBooleanExpression() {
return getRuleContext(RegexBooleanExpressionContext.class,0);
@@ -763,9 +786,9 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(151);
+ setState(158);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) {
case 1:
{
_localctx = new LogicalNotContext(_localctx);
@@ -775,7 +798,7 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc
setState(131);
match(NOT);
setState(132);
- booleanExpression(6);
+ booleanExpression(7);
}
break;
case 2:
@@ -839,30 +862,53 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc
match(RP);
}
break;
+ case 5:
+ {
+ _localctx = new IsNullContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(151);
+ valueExpression();
+ setState(152);
+ match(IS);
+ setState(154);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ if (_la==NOT) {
+ {
+ setState(153);
+ match(NOT);
+ }
+ }
+
+ setState(156);
+ match(NULL);
+ }
+ break;
}
_ctx.stop = _input.LT(-1);
- setState(161);
+ setState(168);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,7,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,8,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
if ( _parseListeners!=null ) triggerExitRuleEvent();
_prevctx = _localctx;
{
- setState(159);
+ setState(166);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) {
case 1:
{
_localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState));
((LogicalBinaryContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_booleanExpression);
- setState(153);
- if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)");
- setState(154);
+ setState(160);
+ if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)");
+ setState(161);
((LogicalBinaryContext)_localctx).operator = match(AND);
- setState(155);
- ((LogicalBinaryContext)_localctx).right = booleanExpression(4);
+ setState(162);
+ ((LogicalBinaryContext)_localctx).right = booleanExpression(5);
}
break;
case 2:
@@ -870,20 +916,20 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc
_localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState));
((LogicalBinaryContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_booleanExpression);
- setState(156);
- if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
- setState(157);
+ setState(163);
+ if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)");
+ setState(164);
((LogicalBinaryContext)_localctx).operator = match(OR);
- setState(158);
- ((LogicalBinaryContext)_localctx).right = booleanExpression(3);
+ setState(165);
+ ((LogicalBinaryContext)_localctx).right = booleanExpression(4);
}
break;
}
}
}
- setState(163);
+ setState(170);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,7,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,8,_ctx);
}
}
}
@@ -935,48 +981,48 @@ public final RegexBooleanExpressionContext regexBooleanExpression() throws Recog
enterRule(_localctx, 12, RULE_regexBooleanExpression);
int _la;
try {
- setState(178);
+ setState(185);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,10,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
- setState(164);
+ setState(171);
valueExpression();
- setState(166);
+ setState(173);
_errHandler.sync(this);
_la = _input.LA(1);
if (_la==NOT) {
{
- setState(165);
+ setState(172);
match(NOT);
}
}
- setState(168);
+ setState(175);
((RegexBooleanExpressionContext)_localctx).kind = match(LIKE);
- setState(169);
+ setState(176);
((RegexBooleanExpressionContext)_localctx).pattern = string();
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
- setState(171);
+ setState(178);
valueExpression();
- setState(173);
+ setState(180);
_errHandler.sync(this);
_la = _input.LA(1);
if (_la==NOT) {
{
- setState(172);
+ setState(179);
match(NOT);
}
}
- setState(175);
+ setState(182);
((RegexBooleanExpressionContext)_localctx).kind = match(RLIKE);
- setState(176);
+ setState(183);
((RegexBooleanExpressionContext)_localctx).pattern = string();
}
break;
@@ -1058,14 +1104,14 @@ public final ValueExpressionContext valueExpression() throws RecognitionExceptio
ValueExpressionContext _localctx = new ValueExpressionContext(_ctx, getState());
enterRule(_localctx, 14, RULE_valueExpression);
try {
- setState(185);
+ setState(192);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) {
case 1:
_localctx = new ValueExpressionDefaultContext(_localctx);
enterOuterAlt(_localctx, 1);
{
- setState(180);
+ setState(187);
operatorExpression(0);
}
break;
@@ -1073,11 +1119,11 @@ public final ValueExpressionContext valueExpression() throws RecognitionExceptio
_localctx = new ComparisonContext(_localctx);
enterOuterAlt(_localctx, 2);
{
- setState(181);
+ setState(188);
((ComparisonContext)_localctx).left = operatorExpression(0);
- setState(182);
+ setState(189);
comparisonOperator();
- setState(183);
+ setState(190);
((ComparisonContext)_localctx).right = operatorExpression(0);
}
break;
@@ -1197,16 +1243,16 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(191);
+ setState(198);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) {
case 1:
{
_localctx = new OperatorExpressionDefaultContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(188);
+ setState(195);
primaryExpression();
}
break;
@@ -1215,7 +1261,7 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE
_localctx = new ArithmeticUnaryContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(189);
+ setState(196);
((ArithmeticUnaryContext)_localctx).operator = _input.LT(1);
_la = _input.LA(1);
if ( !(_la==PLUS || _la==MINUS) ) {
@@ -1226,34 +1272,34 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE
_errHandler.reportMatch(this);
consume();
}
- setState(190);
+ setState(197);
operatorExpression(3);
}
break;
}
_ctx.stop = _input.LT(-1);
- setState(201);
+ setState(208);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,14,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,15,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
if ( _parseListeners!=null ) triggerExitRuleEvent();
_prevctx = _localctx;
{
- setState(199);
+ setState(206);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) {
case 1:
{
_localctx = new ArithmeticBinaryContext(new OperatorExpressionContext(_parentctx, _parentState));
((ArithmeticBinaryContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_operatorExpression);
- setState(193);
+ setState(200);
if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
- setState(194);
+ setState(201);
((ArithmeticBinaryContext)_localctx).operator = _input.LT(1);
_la = _input.LA(1);
- if ( !(((_la) & ~0x3f) == 0 && ((1L << _la) & -2305843009213693952L) != 0) ) {
+ if ( !((((_la - 62)) & ~0x3f) == 0 && ((1L << (_la - 62)) & 7L) != 0) ) {
((ArithmeticBinaryContext)_localctx).operator = (Token)_errHandler.recoverInline(this);
}
else {
@@ -1261,7 +1307,7 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE
_errHandler.reportMatch(this);
consume();
}
- setState(195);
+ setState(202);
((ArithmeticBinaryContext)_localctx).right = operatorExpression(3);
}
break;
@@ -1270,9 +1316,9 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE
_localctx = new ArithmeticBinaryContext(new OperatorExpressionContext(_parentctx, _parentState));
((ArithmeticBinaryContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_operatorExpression);
- setState(196);
+ setState(203);
if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
- setState(197);
+ setState(204);
((ArithmeticBinaryContext)_localctx).operator = _input.LT(1);
_la = _input.LA(1);
if ( !(_la==PLUS || _la==MINUS) ) {
@@ -1283,16 +1329,16 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE
_errHandler.reportMatch(this);
consume();
}
- setState(198);
+ setState(205);
((ArithmeticBinaryContext)_localctx).right = operatorExpression(2);
}
break;
}
}
}
- setState(203);
+ setState(210);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,14,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,15,_ctx);
}
}
}
@@ -1419,14 +1465,14 @@ public final PrimaryExpressionContext primaryExpression() throws RecognitionExce
enterRule(_localctx, 18, RULE_primaryExpression);
int _la;
try {
- setState(224);
+ setState(231);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,17,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,18,_ctx) ) {
case 1:
_localctx = new ConstantDefaultContext(_localctx);
enterOuterAlt(_localctx, 1);
{
- setState(204);
+ setState(211);
constant();
}
break;
@@ -1434,7 +1480,7 @@ public final PrimaryExpressionContext primaryExpression() throws RecognitionExce
_localctx = new DereferenceContext(_localctx);
enterOuterAlt(_localctx, 2);
{
- setState(205);
+ setState(212);
qualifiedName();
}
break;
@@ -1442,11 +1488,11 @@ public final PrimaryExpressionContext primaryExpression() throws RecognitionExce
_localctx = new ParenthesizedExpressionContext(_localctx);
enterOuterAlt(_localctx, 3);
{
- setState(206);
+ setState(213);
match(LP);
- setState(207);
+ setState(214);
booleanExpression(0);
- setState(208);
+ setState(215);
match(RP);
}
break;
@@ -1454,37 +1500,37 @@ public final PrimaryExpressionContext primaryExpression() throws RecognitionExce
_localctx = new FunctionExpressionContext(_localctx);
enterOuterAlt(_localctx, 4);
{
- setState(210);
+ setState(217);
identifier();
- setState(211);
+ setState(218);
match(LP);
- setState(220);
+ setState(227);
_errHandler.sync(this);
_la = _input.LA(1);
- if ((((_la - 27)) & ~0x3f) == 0 && ((1L << (_la - 27)) & 1799600940039L) != 0) {
+ if ((((_la - 27)) & ~0x3f) == 0 && ((1L << (_la - 27)) & 3599201870855L) != 0) {
{
- setState(212);
+ setState(219);
booleanExpression(0);
- setState(217);
+ setState(224);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==COMMA) {
{
{
- setState(213);
+ setState(220);
match(COMMA);
- setState(214);
+ setState(221);
booleanExpression(0);
}
}
- setState(219);
+ setState(226);
_errHandler.sync(this);
_la = _input.LA(1);
}
}
}
- setState(222);
+ setState(229);
match(RP);
}
break;
@@ -1532,9 +1578,9 @@ public final RowCommandContext rowCommand() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(226);
+ setState(233);
match(ROW);
- setState(227);
+ setState(234);
fields();
}
}
@@ -1587,25 +1633,25 @@ public final FieldsContext fields() throws RecognitionException {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(229);
+ setState(236);
field();
- setState(234);
+ setState(241);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,18,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,19,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(230);
+ setState(237);
match(COMMA);
- setState(231);
+ setState(238);
field();
}
}
}
- setState(236);
+ setState(243);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,18,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,19,_ctx);
}
}
}
@@ -1652,24 +1698,24 @@ public final FieldContext field() throws RecognitionException {
FieldContext _localctx = new FieldContext(_ctx, getState());
enterRule(_localctx, 24, RULE_field);
try {
- setState(242);
+ setState(249);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,19,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,20,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
- setState(237);
+ setState(244);
booleanExpression(0);
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
- setState(238);
+ setState(245);
qualifiedName();
- setState(239);
+ setState(246);
match(ASSIGN);
- setState(240);
+ setState(247);
booleanExpression(0);
}
break;
@@ -1728,34 +1774,34 @@ public final FromCommandContext fromCommand() throws RecognitionException {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(244);
+ setState(251);
match(FROM);
- setState(245);
+ setState(252);
sourceIdentifier();
- setState(250);
+ setState(257);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,20,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,21,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(246);
+ setState(253);
match(COMMA);
- setState(247);
+ setState(254);
sourceIdentifier();
}
}
}
- setState(252);
+ setState(259);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,20,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,21,_ctx);
}
- setState(254);
+ setState(261);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,21,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,22,_ctx) ) {
case 1:
{
- setState(253);
+ setState(260);
metadata();
}
break;
@@ -1814,29 +1860,29 @@ public final MetadataContext metadata() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(256);
+ setState(263);
match(OPENING_BRACKET);
- setState(257);
+ setState(264);
match(METADATA);
- setState(258);
+ setState(265);
sourceIdentifier();
- setState(263);
+ setState(270);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==COMMA) {
{
{
- setState(259);
+ setState(266);
match(COMMA);
- setState(260);
+ setState(267);
sourceIdentifier();
}
}
- setState(265);
+ setState(272);
_errHandler.sync(this);
_la = _input.LA(1);
}
- setState(266);
+ setState(273);
match(CLOSING_BRACKET);
}
}
@@ -1882,9 +1928,9 @@ public final EvalCommandContext evalCommand() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(268);
+ setState(275);
match(EVAL);
- setState(269);
+ setState(276);
fields();
}
}
@@ -1934,26 +1980,26 @@ public final StatsCommandContext statsCommand() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(271);
+ setState(278);
match(STATS);
- setState(273);
+ setState(280);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,23,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,24,_ctx) ) {
case 1:
{
- setState(272);
+ setState(279);
fields();
}
break;
}
- setState(277);
+ setState(284);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,24,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,25,_ctx) ) {
case 1:
{
- setState(275);
+ setState(282);
match(BY);
- setState(276);
+ setState(283);
grouping();
}
break;
@@ -2006,18 +2052,18 @@ public final InlinestatsCommandContext inlinestatsCommand() throws RecognitionEx
try {
enterOuterAlt(_localctx, 1);
{
- setState(279);
+ setState(286);
match(INLINESTATS);
- setState(280);
+ setState(287);
fields();
- setState(283);
+ setState(290);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,25,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,26,_ctx) ) {
case 1:
{
- setState(281);
+ setState(288);
match(BY);
- setState(282);
+ setState(289);
grouping();
}
break;
@@ -2073,25 +2119,25 @@ public final GroupingContext grouping() throws RecognitionException {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(285);
+ setState(292);
qualifiedName();
- setState(290);
+ setState(297);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,26,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,27,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(286);
+ setState(293);
match(COMMA);
- setState(287);
+ setState(294);
qualifiedName();
}
}
}
- setState(292);
+ setState(299);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,26,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,27,_ctx);
}
}
}
@@ -2136,7 +2182,7 @@ public final SourceIdentifierContext sourceIdentifier() throws RecognitionExcept
try {
enterOuterAlt(_localctx, 1);
{
- setState(293);
+ setState(300);
_la = _input.LA(1);
if ( !(_la==SRC_UNQUOTED_IDENTIFIER || _la==SRC_QUOTED_IDENTIFIER) ) {
_errHandler.recoverInline(this);
@@ -2197,25 +2243,25 @@ public final QualifiedNameContext qualifiedName() throws RecognitionException {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(295);
+ setState(302);
identifier();
- setState(300);
+ setState(307);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,27,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,28,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(296);
+ setState(303);
match(DOT);
- setState(297);
+ setState(304);
identifier();
}
}
}
- setState(302);
+ setState(309);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,27,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,28,_ctx);
}
}
}
@@ -2260,7 +2306,7 @@ public final IdentifierContext identifier() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(303);
+ setState(310);
_la = _input.LA(1);
if ( !(_la==UNQUOTED_IDENTIFIER || _la==QUOTED_IDENTIFIER) ) {
_errHandler.recoverInline(this);
@@ -2525,14 +2571,14 @@ public final ConstantContext constant() throws RecognitionException {
enterRule(_localctx, 44, RULE_constant);
int _la;
try {
- setState(347);
+ setState(354);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,31,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,32,_ctx) ) {
case 1:
_localctx = new NullLiteralContext(_localctx);
enterOuterAlt(_localctx, 1);
{
- setState(305);
+ setState(312);
match(NULL);
}
break;
@@ -2540,9 +2586,9 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new QualifiedIntegerLiteralContext(_localctx);
enterOuterAlt(_localctx, 2);
{
- setState(306);
+ setState(313);
integerValue();
- setState(307);
+ setState(314);
match(UNQUOTED_IDENTIFIER);
}
break;
@@ -2550,7 +2596,7 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new DecimalLiteralContext(_localctx);
enterOuterAlt(_localctx, 3);
{
- setState(309);
+ setState(316);
decimalValue();
}
break;
@@ -2558,7 +2604,7 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new IntegerLiteralContext(_localctx);
enterOuterAlt(_localctx, 4);
{
- setState(310);
+ setState(317);
integerValue();
}
break;
@@ -2566,7 +2612,7 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new BooleanLiteralContext(_localctx);
enterOuterAlt(_localctx, 5);
{
- setState(311);
+ setState(318);
booleanValue();
}
break;
@@ -2574,7 +2620,7 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new InputParamContext(_localctx);
enterOuterAlt(_localctx, 6);
{
- setState(312);
+ setState(319);
match(PARAM);
}
break;
@@ -2582,7 +2628,7 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new StringLiteralContext(_localctx);
enterOuterAlt(_localctx, 7);
{
- setState(313);
+ setState(320);
string();
}
break;
@@ -2590,27 +2636,27 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new NumericArrayLiteralContext(_localctx);
enterOuterAlt(_localctx, 8);
{
- setState(314);
+ setState(321);
match(OPENING_BRACKET);
- setState(315);
+ setState(322);
numericValue();
- setState(320);
+ setState(327);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==COMMA) {
{
{
- setState(316);
+ setState(323);
match(COMMA);
- setState(317);
+ setState(324);
numericValue();
}
}
- setState(322);
+ setState(329);
_errHandler.sync(this);
_la = _input.LA(1);
}
- setState(323);
+ setState(330);
match(CLOSING_BRACKET);
}
break;
@@ -2618,27 +2664,27 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new BooleanArrayLiteralContext(_localctx);
enterOuterAlt(_localctx, 9);
{
- setState(325);
+ setState(332);
match(OPENING_BRACKET);
- setState(326);
+ setState(333);
booleanValue();
- setState(331);
+ setState(338);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==COMMA) {
{
{
- setState(327);
+ setState(334);
match(COMMA);
- setState(328);
+ setState(335);
booleanValue();
}
}
- setState(333);
+ setState(340);
_errHandler.sync(this);
_la = _input.LA(1);
}
- setState(334);
+ setState(341);
match(CLOSING_BRACKET);
}
break;
@@ -2646,27 +2692,27 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new StringArrayLiteralContext(_localctx);
enterOuterAlt(_localctx, 10);
{
- setState(336);
+ setState(343);
match(OPENING_BRACKET);
- setState(337);
+ setState(344);
string();
- setState(342);
+ setState(349);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==COMMA) {
{
{
- setState(338);
+ setState(345);
match(COMMA);
- setState(339);
+ setState(346);
string();
}
}
- setState(344);
+ setState(351);
_errHandler.sync(this);
_la = _input.LA(1);
}
- setState(345);
+ setState(352);
match(CLOSING_BRACKET);
}
break;
@@ -2712,9 +2758,9 @@ public final LimitCommandContext limitCommand() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(349);
+ setState(356);
match(LIMIT);
- setState(350);
+ setState(357);
match(INTEGER_LITERAL);
}
}
@@ -2768,27 +2814,27 @@ public final SortCommandContext sortCommand() throws RecognitionException {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(352);
+ setState(359);
match(SORT);
- setState(353);
+ setState(360);
orderExpression();
- setState(358);
+ setState(365);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,32,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,33,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(354);
+ setState(361);
match(COMMA);
- setState(355);
+ setState(362);
orderExpression();
}
}
}
- setState(360);
+ setState(367);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,32,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,33,_ctx);
}
}
}
@@ -2841,14 +2887,14 @@ public final OrderExpressionContext orderExpression() throws RecognitionExceptio
try {
enterOuterAlt(_localctx, 1);
{
- setState(361);
+ setState(368);
booleanExpression(0);
- setState(363);
+ setState(370);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,33,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,34,_ctx) ) {
case 1:
{
- setState(362);
+ setState(369);
((OrderExpressionContext)_localctx).ordering = _input.LT(1);
_la = _input.LA(1);
if ( !(_la==ASC || _la==DESC) ) {
@@ -2862,14 +2908,14 @@ public final OrderExpressionContext orderExpression() throws RecognitionExceptio
}
break;
}
- setState(367);
+ setState(374);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,34,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,35,_ctx) ) {
case 1:
{
- setState(365);
+ setState(372);
match(NULLS);
- setState(366);
+ setState(373);
((OrderExpressionContext)_localctx).nullOrdering = _input.LT(1);
_la = _input.LA(1);
if ( !(_la==FIRST || _la==LAST) ) {
@@ -2934,60 +2980,60 @@ public final KeepCommandContext keepCommand() throws RecognitionException {
enterRule(_localctx, 52, RULE_keepCommand);
try {
int _alt;
- setState(387);
+ setState(394);
_errHandler.sync(this);
switch (_input.LA(1)) {
case KEEP:
enterOuterAlt(_localctx, 1);
{
- setState(369);
+ setState(376);
match(KEEP);
- setState(370);
+ setState(377);
sourceIdentifier();
- setState(375);
+ setState(382);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,35,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,36,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(371);
+ setState(378);
match(COMMA);
- setState(372);
+ setState(379);
sourceIdentifier();
}
}
}
- setState(377);
+ setState(384);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,35,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,36,_ctx);
}
}
break;
case PROJECT:
enterOuterAlt(_localctx, 2);
{
- setState(378);
+ setState(385);
match(PROJECT);
- setState(379);
+ setState(386);
sourceIdentifier();
- setState(384);
+ setState(391);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,36,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,37,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(380);
+ setState(387);
match(COMMA);
- setState(381);
+ setState(388);
sourceIdentifier();
}
}
}
- setState(386);
+ setState(393);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,36,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,37,_ctx);
}
}
break;
@@ -3045,27 +3091,27 @@ public final DropCommandContext dropCommand() throws RecognitionException {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(389);
+ setState(396);
match(DROP);
- setState(390);
+ setState(397);
sourceIdentifier();
- setState(395);
+ setState(402);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,38,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,39,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(391);
+ setState(398);
match(COMMA);
- setState(392);
+ setState(399);
sourceIdentifier();
}
}
}
- setState(397);
+ setState(404);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,38,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,39,_ctx);
}
}
}
@@ -3119,27 +3165,27 @@ public final RenameCommandContext renameCommand() throws RecognitionException {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(398);
+ setState(405);
match(RENAME);
- setState(399);
+ setState(406);
renameClause();
- setState(404);
+ setState(411);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,39,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,40,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(400);
+ setState(407);
match(COMMA);
- setState(401);
+ setState(408);
renameClause();
}
}
}
- setState(406);
+ setState(413);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,39,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,40,_ctx);
}
}
}
@@ -3190,11 +3236,11 @@ public final RenameClauseContext renameClause() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(407);
+ setState(414);
((RenameClauseContext)_localctx).oldName = sourceIdentifier();
- setState(408);
+ setState(415);
match(AS);
- setState(409);
+ setState(416);
((RenameClauseContext)_localctx).newName = sourceIdentifier();
}
}
@@ -3246,18 +3292,18 @@ public final DissectCommandContext dissectCommand() throws RecognitionException
try {
enterOuterAlt(_localctx, 1);
{
- setState(411);
+ setState(418);
match(DISSECT);
- setState(412);
+ setState(419);
primaryExpression();
- setState(413);
+ setState(420);
string();
- setState(415);
+ setState(422);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,40,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,41,_ctx) ) {
case 1:
{
- setState(414);
+ setState(421);
commandOptions();
}
break;
@@ -3309,11 +3355,11 @@ public final GrokCommandContext grokCommand() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(417);
+ setState(424);
match(GROK);
- setState(418);
+ setState(425);
primaryExpression();
- setState(419);
+ setState(426);
string();
}
}
@@ -3359,9 +3405,9 @@ public final MvExpandCommandContext mvExpandCommand() throws RecognitionExceptio
try {
enterOuterAlt(_localctx, 1);
{
- setState(421);
+ setState(428);
match(MV_EXPAND);
- setState(422);
+ setState(429);
sourceIdentifier();
}
}
@@ -3414,25 +3460,25 @@ public final CommandOptionsContext commandOptions() throws RecognitionException
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(424);
+ setState(431);
commandOption();
- setState(429);
+ setState(436);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,41,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,42,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(425);
+ setState(432);
match(COMMA);
- setState(426);
+ setState(433);
commandOption();
}
}
}
- setState(431);
+ setState(438);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,41,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,42,_ctx);
}
}
}
@@ -3481,11 +3527,11 @@ public final CommandOptionContext commandOption() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(432);
+ setState(439);
identifier();
- setState(433);
+ setState(440);
match(ASSIGN);
- setState(434);
+ setState(441);
constant();
}
}
@@ -3530,7 +3576,7 @@ public final BooleanValueContext booleanValue() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(436);
+ setState(443);
_la = _input.LA(1);
if ( !(_la==FALSE || _la==TRUE) ) {
_errHandler.recoverInline(this);
@@ -3584,20 +3630,20 @@ public final NumericValueContext numericValue() throws RecognitionException {
NumericValueContext _localctx = new NumericValueContext(_ctx, getState());
enterRule(_localctx, 72, RULE_numericValue);
try {
- setState(440);
+ setState(447);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,42,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,43,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
- setState(438);
+ setState(445);
decimalValue();
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
- setState(439);
+ setState(446);
integerValue();
}
break;
@@ -3645,12 +3691,12 @@ public final DecimalValueContext decimalValue() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(443);
+ setState(450);
_errHandler.sync(this);
_la = _input.LA(1);
if (_la==PLUS || _la==MINUS) {
{
- setState(442);
+ setState(449);
_la = _input.LA(1);
if ( !(_la==PLUS || _la==MINUS) ) {
_errHandler.recoverInline(this);
@@ -3663,7 +3709,7 @@ public final DecimalValueContext decimalValue() throws RecognitionException {
}
}
- setState(445);
+ setState(452);
match(DECIMAL_LITERAL);
}
}
@@ -3709,12 +3755,12 @@ public final IntegerValueContext integerValue() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(448);
+ setState(455);
_errHandler.sync(this);
_la = _input.LA(1);
if (_la==PLUS || _la==MINUS) {
{
- setState(447);
+ setState(454);
_la = _input.LA(1);
if ( !(_la==PLUS || _la==MINUS) ) {
_errHandler.recoverInline(this);
@@ -3727,7 +3773,7 @@ public final IntegerValueContext integerValue() throws RecognitionException {
}
}
- setState(450);
+ setState(457);
match(INTEGER_LITERAL);
}
}
@@ -3770,7 +3816,7 @@ public final StringContext string() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(452);
+ setState(459);
match(STRING);
}
}
@@ -3819,9 +3865,9 @@ public final ComparisonOperatorContext comparisonOperator() throws RecognitionEx
try {
enterOuterAlt(_localctx, 1);
{
- setState(454);
+ setState(461);
_la = _input.LA(1);
- if ( !(((_la) & ~0x3f) == 0 && ((1L << _la) & 567453553048682496L) != 0) ) {
+ if ( !(((_la) & ~0x3f) == 0 && ((1L << _la) & 1134907106097364992L) != 0) ) {
_errHandler.recoverInline(this);
}
else {
@@ -3873,9 +3919,9 @@ public final ExplainCommandContext explainCommand() throws RecognitionException
try {
enterOuterAlt(_localctx, 1);
{
- setState(456);
+ setState(463);
match(EXPLAIN);
- setState(457);
+ setState(464);
subqueryExpression();
}
}
@@ -3922,11 +3968,11 @@ public final SubqueryExpressionContext subqueryExpression() throws RecognitionEx
try {
enterOuterAlt(_localctx, 1);
{
- setState(459);
+ setState(466);
match(OPENING_BRACKET);
- setState(460);
+ setState(467);
query(0);
- setState(461);
+ setState(468);
match(CLOSING_BRACKET);
}
}
@@ -3996,16 +4042,16 @@ public final ShowCommandContext showCommand() throws RecognitionException {
ShowCommandContext _localctx = new ShowCommandContext(_ctx, getState());
enterRule(_localctx, 86, RULE_showCommand);
try {
- setState(467);
+ setState(474);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,45,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,46,_ctx) ) {
case 1:
_localctx = new ShowInfoContext(_localctx);
enterOuterAlt(_localctx, 1);
{
- setState(463);
+ setState(470);
match(SHOW);
- setState(464);
+ setState(471);
match(INFO);
}
break;
@@ -4013,9 +4059,9 @@ public final ShowCommandContext showCommand() throws RecognitionException {
_localctx = new ShowFunctionsContext(_localctx);
enterOuterAlt(_localctx, 2);
{
- setState(465);
+ setState(472);
match(SHOW);
- setState(466);
+ setState(473);
match(FUNCTIONS);
}
break;
@@ -4081,48 +4127,48 @@ public final EnrichCommandContext enrichCommand() throws RecognitionException {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(469);
+ setState(476);
match(ENRICH);
- setState(470);
+ setState(477);
((EnrichCommandContext)_localctx).policyName = sourceIdentifier();
- setState(473);
+ setState(480);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,46,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,47,_ctx) ) {
case 1:
{
- setState(471);
+ setState(478);
match(ON);
- setState(472);
+ setState(479);
((EnrichCommandContext)_localctx).matchField = sourceIdentifier();
}
break;
}
- setState(484);
+ setState(491);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,48,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,49,_ctx) ) {
case 1:
{
- setState(475);
+ setState(482);
match(WITH);
- setState(476);
+ setState(483);
enrichWithClause();
- setState(481);
+ setState(488);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,47,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,48,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(477);
+ setState(484);
match(COMMA);
- setState(478);
+ setState(485);
enrichWithClause();
}
}
}
- setState(483);
+ setState(490);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,47,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,48,_ctx);
}
}
break;
@@ -4176,19 +4222,19 @@ public final EnrichWithClauseContext enrichWithClause() throws RecognitionExcept
try {
enterOuterAlt(_localctx, 1);
{
- setState(489);
+ setState(496);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,49,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,50,_ctx) ) {
case 1:
{
- setState(486);
+ setState(493);
((EnrichWithClauseContext)_localctx).newName = sourceIdentifier();
- setState(487);
+ setState(494);
match(ASSIGN);
}
break;
}
- setState(491);
+ setState(498);
((EnrichWithClauseContext)_localctx).enrichField = sourceIdentifier();
}
}
@@ -4224,9 +4270,9 @@ private boolean query_sempred(QueryContext _localctx, int predIndex) {
private boolean booleanExpression_sempred(BooleanExpressionContext _localctx, int predIndex) {
switch (predIndex) {
case 1:
- return precpred(_ctx, 3);
+ return precpred(_ctx, 4);
case 2:
- return precpred(_ctx, 2);
+ return precpred(_ctx, 3);
}
return true;
}
@@ -4241,7 +4287,7 @@ private boolean operatorExpression_sempred(OperatorExpressionContext _localctx,
}
public static final String _serializedATN =
- "\u0004\u0001P\u01ee\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+
+ "\u0004\u0001Q\u01f5\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"+
@@ -4263,301 +4309,307 @@ private boolean operatorExpression_sempred(OperatorExpressionContext _localctx,
"\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+
"\u0005\u0001\u0005\u0001\u0005\u0003\u0005\u008a\b\u0005\u0001\u0005\u0001"+
"\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0005\u0005\u0091\b\u0005\n"+
- "\u0005\f\u0005\u0094\t\u0005\u0001\u0005\u0001\u0005\u0003\u0005\u0098"+
- "\b\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+
- "\u0005\u0005\u0005\u00a0\b\u0005\n\u0005\f\u0005\u00a3\t\u0005\u0001\u0006"+
- "\u0001\u0006\u0003\u0006\u00a7\b\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+
+ "\u0005\f\u0005\u0094\t\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+
+ "\u0005\u0001\u0005\u0003\u0005\u009b\b\u0005\u0001\u0005\u0001\u0005\u0003"+
+ "\u0005\u009f\b\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+
+ "\u0005\u0001\u0005\u0005\u0005\u00a7\b\u0005\n\u0005\f\u0005\u00aa\t\u0005"+
"\u0001\u0006\u0001\u0006\u0003\u0006\u00ae\b\u0006\u0001\u0006\u0001\u0006"+
- "\u0001\u0006\u0003\u0006\u00b3\b\u0006\u0001\u0007\u0001\u0007\u0001\u0007"+
- "\u0001\u0007\u0001\u0007\u0003\u0007\u00ba\b\u0007\u0001\b\u0001\b\u0001"+
- "\b\u0001\b\u0003\b\u00c0\b\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001"+
- "\b\u0005\b\u00c8\b\b\n\b\f\b\u00cb\t\b\u0001\t\u0001\t\u0001\t\u0001\t"+
- "\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0005\t\u00d8"+
- "\b\t\n\t\f\t\u00db\t\t\u0003\t\u00dd\b\t\u0001\t\u0001\t\u0003\t\u00e1"+
- "\b\t\u0001\n\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b\u0005"+
- "\u000b\u00e9\b\u000b\n\u000b\f\u000b\u00ec\t\u000b\u0001\f\u0001\f\u0001"+
- "\f\u0001\f\u0001\f\u0003\f\u00f3\b\f\u0001\r\u0001\r\u0001\r\u0001\r\u0005"+
- "\r\u00f9\b\r\n\r\f\r\u00fc\t\r\u0001\r\u0003\r\u00ff\b\r\u0001\u000e\u0001"+
- "\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0005\u000e\u0106\b\u000e\n"+
- "\u000e\f\u000e\u0109\t\u000e\u0001\u000e\u0001\u000e\u0001\u000f\u0001"+
- "\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0003\u0010\u0112\b\u0010\u0001"+
- "\u0010\u0001\u0010\u0003\u0010\u0116\b\u0010\u0001\u0011\u0001\u0011\u0001"+
- "\u0011\u0001\u0011\u0003\u0011\u011c\b\u0011\u0001\u0012\u0001\u0012\u0001"+
- "\u0012\u0005\u0012\u0121\b\u0012\n\u0012\f\u0012\u0124\t\u0012\u0001\u0013"+
- "\u0001\u0013\u0001\u0014\u0001\u0014\u0001\u0014\u0005\u0014\u012b\b\u0014"+
- "\n\u0014\f\u0014\u012e\t\u0014\u0001\u0015\u0001\u0015\u0001\u0016\u0001"+
- "\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001"+
+ "\u0001\u0006\u0001\u0006\u0001\u0006\u0003\u0006\u00b5\b\u0006\u0001\u0006"+
+ "\u0001\u0006\u0001\u0006\u0003\u0006\u00ba\b\u0006\u0001\u0007\u0001\u0007"+
+ "\u0001\u0007\u0001\u0007\u0001\u0007\u0003\u0007\u00c1\b\u0007\u0001\b"+
+ "\u0001\b\u0001\b\u0001\b\u0003\b\u00c7\b\b\u0001\b\u0001\b\u0001\b\u0001"+
+ "\b\u0001\b\u0001\b\u0005\b\u00cf\b\b\n\b\f\b\u00d2\t\b\u0001\t\u0001\t"+
+ "\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001"+
+ "\t\u0005\t\u00df\b\t\n\t\f\t\u00e2\t\t\u0003\t\u00e4\b\t\u0001\t\u0001"+
+ "\t\u0003\t\u00e8\b\t\u0001\n\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001"+
+ "\u000b\u0005\u000b\u00f0\b\u000b\n\u000b\f\u000b\u00f3\t\u000b\u0001\f"+
+ "\u0001\f\u0001\f\u0001\f\u0001\f\u0003\f\u00fa\b\f\u0001\r\u0001\r\u0001"+
+ "\r\u0001\r\u0005\r\u0100\b\r\n\r\f\r\u0103\t\r\u0001\r\u0003\r\u0106\b"+
+ "\r\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0005\u000e"+
+ "\u010d\b\u000e\n\u000e\f\u000e\u0110\t\u000e\u0001\u000e\u0001\u000e\u0001"+
+ "\u000f\u0001\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0003\u0010\u0119"+
+ "\b\u0010\u0001\u0010\u0001\u0010\u0003\u0010\u011d\b\u0010\u0001\u0011"+
+ "\u0001\u0011\u0001\u0011\u0001\u0011\u0003\u0011\u0123\b\u0011\u0001\u0012"+
+ "\u0001\u0012\u0001\u0012\u0005\u0012\u0128\b\u0012\n\u0012\f\u0012\u012b"+
+ "\t\u0012\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014\u0001\u0014\u0005"+
+ "\u0014\u0132\b\u0014\n\u0014\f\u0014\u0135\t\u0014\u0001\u0015\u0001\u0015"+
+ "\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016"+
+ "\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016"+
+ "\u0001\u0016\u0005\u0016\u0146\b\u0016\n\u0016\f\u0016\u0149\t\u0016\u0001"+
"\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0005"+
- "\u0016\u013f\b\u0016\n\u0016\f\u0016\u0142\t\u0016\u0001\u0016\u0001\u0016"+
- "\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0005\u0016\u014a\b\u0016"+
- "\n\u0016\f\u0016\u014d\t\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001"+
- "\u0016\u0001\u0016\u0001\u0016\u0005\u0016\u0155\b\u0016\n\u0016\f\u0016"+
- "\u0158\t\u0016\u0001\u0016\u0001\u0016\u0003\u0016\u015c\b\u0016\u0001"+
- "\u0017\u0001\u0017\u0001\u0017\u0001\u0018\u0001\u0018\u0001\u0018\u0001"+
- "\u0018\u0005\u0018\u0165\b\u0018\n\u0018\f\u0018\u0168\t\u0018\u0001\u0019"+
- "\u0001\u0019\u0003\u0019\u016c\b\u0019\u0001\u0019\u0001\u0019\u0003\u0019"+
- "\u0170\b\u0019\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0005\u001a"+
- "\u0176\b\u001a\n\u001a\f\u001a\u0179\t\u001a\u0001\u001a\u0001\u001a\u0001"+
- "\u001a\u0001\u001a\u0005\u001a\u017f\b\u001a\n\u001a\f\u001a\u0182\t\u001a"+
- "\u0003\u001a\u0184\b\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b"+
- "\u0005\u001b\u018a\b\u001b\n\u001b\f\u001b\u018d\t\u001b\u0001\u001c\u0001"+
- "\u001c\u0001\u001c\u0001\u001c\u0005\u001c\u0193\b\u001c\n\u001c\f\u001c"+
- "\u0196\t\u001c\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001e"+
- "\u0001\u001e\u0001\u001e\u0001\u001e\u0003\u001e\u01a0\b\u001e\u0001\u001f"+
- "\u0001\u001f\u0001\u001f\u0001\u001f\u0001 \u0001 \u0001 \u0001!\u0001"+
- "!\u0001!\u0005!\u01ac\b!\n!\f!\u01af\t!\u0001\"\u0001\"\u0001\"\u0001"+
- "\"\u0001#\u0001#\u0001$\u0001$\u0003$\u01b9\b$\u0001%\u0003%\u01bc\b%"+
- "\u0001%\u0001%\u0001&\u0003&\u01c1\b&\u0001&\u0001&\u0001\'\u0001\'\u0001"+
- "(\u0001(\u0001)\u0001)\u0001)\u0001*\u0001*\u0001*\u0001*\u0001+\u0001"+
- "+\u0001+\u0001+\u0003+\u01d4\b+\u0001,\u0001,\u0001,\u0001,\u0003,\u01da"+
- "\b,\u0001,\u0001,\u0001,\u0001,\u0005,\u01e0\b,\n,\f,\u01e3\t,\u0003,"+
- "\u01e5\b,\u0001-\u0001-\u0001-\u0003-\u01ea\b-\u0001-\u0001-\u0001-\u0000"+
- "\u0003\u0002\n\u0010.\u0000\u0002\u0004\u0006\b\n\f\u000e\u0010\u0012"+
- "\u0014\u0016\u0018\u001a\u001c\u001e \"$&(*,.02468:<>@BDFHJLNPRTVXZ\u0000"+
- "\b\u0001\u0000;<\u0001\u0000=?\u0001\u0000KL\u0001\u0000BC\u0002\u0000"+
- " ##\u0001\u0000&\'\u0002\u0000%%22\u0001\u00005:\u020a\u0000\\\u0001"+
- "\u0000\u0000\u0000\u0002_\u0001\u0000\u0000\u0000\u0004n\u0001\u0000\u0000"+
- "\u0000\u0006}\u0001\u0000\u0000\u0000\b\u007f\u0001\u0000\u0000\u0000"+
- "\n\u0097\u0001\u0000\u0000\u0000\f\u00b2\u0001\u0000\u0000\u0000\u000e"+
- "\u00b9\u0001\u0000\u0000\u0000\u0010\u00bf\u0001\u0000\u0000\u0000\u0012"+
- "\u00e0\u0001\u0000\u0000\u0000\u0014\u00e2\u0001\u0000\u0000\u0000\u0016"+
- "\u00e5\u0001\u0000\u0000\u0000\u0018\u00f2\u0001\u0000\u0000\u0000\u001a"+
- "\u00f4\u0001\u0000\u0000\u0000\u001c\u0100\u0001\u0000\u0000\u0000\u001e"+
- "\u010c\u0001\u0000\u0000\u0000 \u010f\u0001\u0000\u0000\u0000\"\u0117"+
- "\u0001\u0000\u0000\u0000$\u011d\u0001\u0000\u0000\u0000&\u0125\u0001\u0000"+
- "\u0000\u0000(\u0127\u0001\u0000\u0000\u0000*\u012f\u0001\u0000\u0000\u0000"+
- ",\u015b\u0001\u0000\u0000\u0000.\u015d\u0001\u0000\u0000\u00000\u0160"+
- "\u0001\u0000\u0000\u00002\u0169\u0001\u0000\u0000\u00004\u0183\u0001\u0000"+
- "\u0000\u00006\u0185\u0001\u0000\u0000\u00008\u018e\u0001\u0000\u0000\u0000"+
- ":\u0197\u0001\u0000\u0000\u0000<\u019b\u0001\u0000\u0000\u0000>\u01a1"+
- "\u0001\u0000\u0000\u0000@\u01a5\u0001\u0000\u0000\u0000B\u01a8\u0001\u0000"+
- "\u0000\u0000D\u01b0\u0001\u0000\u0000\u0000F\u01b4\u0001\u0000\u0000\u0000"+
- "H\u01b8\u0001\u0000\u0000\u0000J\u01bb\u0001\u0000\u0000\u0000L\u01c0"+
- "\u0001\u0000\u0000\u0000N\u01c4\u0001\u0000\u0000\u0000P\u01c6\u0001\u0000"+
- "\u0000\u0000R\u01c8\u0001\u0000\u0000\u0000T\u01cb\u0001\u0000\u0000\u0000"+
- "V\u01d3\u0001\u0000\u0000\u0000X\u01d5\u0001\u0000\u0000\u0000Z\u01e9"+
- "\u0001\u0000\u0000\u0000\\]\u0003\u0002\u0001\u0000]^\u0005\u0000\u0000"+
- "\u0001^\u0001\u0001\u0000\u0000\u0000_`\u0006\u0001\uffff\uffff\u0000"+
- "`a\u0003\u0004\u0002\u0000ag\u0001\u0000\u0000\u0000bc\n\u0001\u0000\u0000"+
- "cd\u0005\u001a\u0000\u0000df\u0003\u0006\u0003\u0000eb\u0001\u0000\u0000"+
- "\u0000fi\u0001\u0000\u0000\u0000ge\u0001\u0000\u0000\u0000gh\u0001\u0000"+
- "\u0000\u0000h\u0003\u0001\u0000\u0000\u0000ig\u0001\u0000\u0000\u0000"+
- "jo\u0003R)\u0000ko\u0003\u001a\r\u0000lo\u0003\u0014\n\u0000mo\u0003V"+
- "+\u0000nj\u0001\u0000\u0000\u0000nk\u0001\u0000\u0000\u0000nl\u0001\u0000"+
- "\u0000\u0000nm\u0001\u0000\u0000\u0000o\u0005\u0001\u0000\u0000\u0000"+
- "p~\u0003\u001e\u000f\u0000q~\u0003\"\u0011\u0000r~\u0003.\u0017\u0000"+
- "s~\u00034\u001a\u0000t~\u00030\u0018\u0000u~\u0003 \u0010\u0000v~\u0003"+
- "\b\u0004\u0000w~\u00036\u001b\u0000x~\u00038\u001c\u0000y~\u0003<\u001e"+
- "\u0000z~\u0003>\u001f\u0000{~\u0003X,\u0000|~\u0003@ \u0000}p\u0001\u0000"+
- "\u0000\u0000}q\u0001\u0000\u0000\u0000}r\u0001\u0000\u0000\u0000}s\u0001"+
- "\u0000\u0000\u0000}t\u0001\u0000\u0000\u0000}u\u0001\u0000\u0000\u0000"+
- "}v\u0001\u0000\u0000\u0000}w\u0001\u0000\u0000\u0000}x\u0001\u0000\u0000"+
- "\u0000}y\u0001\u0000\u0000\u0000}z\u0001\u0000\u0000\u0000}{\u0001\u0000"+
- "\u0000\u0000}|\u0001\u0000\u0000\u0000~\u0007\u0001\u0000\u0000\u0000"+
- "\u007f\u0080\u0005\u0012\u0000\u0000\u0080\u0081\u0003\n\u0005\u0000\u0081"+
- "\t\u0001\u0000\u0000\u0000\u0082\u0083\u0006\u0005\uffff\uffff\u0000\u0083"+
- "\u0084\u0005+\u0000\u0000\u0084\u0098\u0003\n\u0005\u0006\u0085\u0098"+
- "\u0003\u000e\u0007\u0000\u0086\u0098\u0003\f\u0006\u0000\u0087\u0089\u0003"+
- "\u000e\u0007\u0000\u0088\u008a\u0005+\u0000\u0000\u0089\u0088\u0001\u0000"+
- "\u0000\u0000\u0089\u008a\u0001\u0000\u0000\u0000\u008a\u008b\u0001\u0000"+
- "\u0000\u0000\u008b\u008c\u0005)\u0000\u0000\u008c\u008d\u0005(\u0000\u0000"+
- "\u008d\u0092\u0003\u000e\u0007\u0000\u008e\u008f\u0005\"\u0000\u0000\u008f"+
- "\u0091\u0003\u000e\u0007\u0000\u0090\u008e\u0001\u0000\u0000\u0000\u0091"+
- "\u0094\u0001\u0000\u0000\u0000\u0092\u0090\u0001\u0000\u0000\u0000\u0092"+
- "\u0093\u0001\u0000\u0000\u0000\u0093\u0095\u0001\u0000\u0000\u0000\u0094"+
- "\u0092\u0001\u0000\u0000\u0000\u0095\u0096\u00051\u0000\u0000\u0096\u0098"+
- "\u0001\u0000\u0000\u0000\u0097\u0082\u0001\u0000\u0000\u0000\u0097\u0085"+
- "\u0001\u0000\u0000\u0000\u0097\u0086\u0001\u0000\u0000\u0000\u0097\u0087"+
- "\u0001\u0000\u0000\u0000\u0098\u00a1\u0001\u0000\u0000\u0000\u0099\u009a"+
- "\n\u0003\u0000\u0000\u009a\u009b\u0005\u001f\u0000\u0000\u009b\u00a0\u0003"+
- "\n\u0005\u0004\u009c\u009d\n\u0002\u0000\u0000\u009d\u009e\u0005.\u0000"+
- "\u0000\u009e\u00a0\u0003\n\u0005\u0003\u009f\u0099\u0001\u0000\u0000\u0000"+
- "\u009f\u009c\u0001\u0000\u0000\u0000\u00a0\u00a3\u0001\u0000\u0000\u0000"+
- "\u00a1\u009f\u0001\u0000\u0000\u0000\u00a1\u00a2\u0001\u0000\u0000\u0000"+
- "\u00a2\u000b\u0001\u0000\u0000\u0000\u00a3\u00a1\u0001\u0000\u0000\u0000"+
- "\u00a4\u00a6\u0003\u000e\u0007\u0000\u00a5\u00a7\u0005+\u0000\u0000\u00a6"+
- "\u00a5\u0001\u0000\u0000\u0000\u00a6\u00a7\u0001\u0000\u0000\u0000\u00a7"+
- "\u00a8\u0001\u0000\u0000\u0000\u00a8\u00a9\u0005*\u0000\u0000\u00a9\u00aa"+
- "\u0003N\'\u0000\u00aa\u00b3\u0001\u0000\u0000\u0000\u00ab\u00ad\u0003"+
- "\u000e\u0007\u0000\u00ac\u00ae\u0005+\u0000\u0000\u00ad\u00ac\u0001\u0000"+
- "\u0000\u0000\u00ad\u00ae\u0001\u0000\u0000\u0000\u00ae\u00af\u0001\u0000"+
- "\u0000\u0000\u00af\u00b0\u00050\u0000\u0000\u00b0\u00b1\u0003N\'\u0000"+
- "\u00b1\u00b3\u0001\u0000\u0000\u0000\u00b2\u00a4\u0001\u0000\u0000\u0000"+
- "\u00b2\u00ab\u0001\u0000\u0000\u0000\u00b3\r\u0001\u0000\u0000\u0000\u00b4"+
- "\u00ba\u0003\u0010\b\u0000\u00b5\u00b6\u0003\u0010\b\u0000\u00b6\u00b7"+
- "\u0003P(\u0000\u00b7\u00b8\u0003\u0010\b\u0000\u00b8\u00ba\u0001\u0000"+
- "\u0000\u0000\u00b9\u00b4\u0001\u0000\u0000\u0000\u00b9\u00b5\u0001\u0000"+
- "\u0000\u0000\u00ba\u000f\u0001\u0000\u0000\u0000\u00bb\u00bc\u0006\b\uffff"+
- "\uffff\u0000\u00bc\u00c0\u0003\u0012\t\u0000\u00bd\u00be\u0007\u0000\u0000"+
- "\u0000\u00be\u00c0\u0003\u0010\b\u0003\u00bf\u00bb\u0001\u0000\u0000\u0000"+
- "\u00bf\u00bd\u0001\u0000\u0000\u0000\u00c0\u00c9\u0001\u0000\u0000\u0000"+
- "\u00c1\u00c2\n\u0002\u0000\u0000\u00c2\u00c3\u0007\u0001\u0000\u0000\u00c3"+
- "\u00c8\u0003\u0010\b\u0003\u00c4\u00c5\n\u0001\u0000\u0000\u00c5\u00c6"+
- "\u0007\u0000\u0000\u0000\u00c6\u00c8\u0003\u0010\b\u0002\u00c7\u00c1\u0001"+
- "\u0000\u0000\u0000\u00c7\u00c4\u0001\u0000\u0000\u0000\u00c8\u00cb\u0001"+
- "\u0000\u0000\u0000\u00c9\u00c7\u0001\u0000\u0000\u0000\u00c9\u00ca\u0001"+
- "\u0000\u0000\u0000\u00ca\u0011\u0001\u0000\u0000\u0000\u00cb\u00c9\u0001"+
- "\u0000\u0000\u0000\u00cc\u00e1\u0003,\u0016\u0000\u00cd\u00e1\u0003(\u0014"+
- "\u0000\u00ce\u00cf\u0005(\u0000\u0000\u00cf\u00d0\u0003\n\u0005\u0000"+
- "\u00d0\u00d1\u00051\u0000\u0000\u00d1\u00e1\u0001\u0000\u0000\u0000\u00d2"+
- "\u00d3\u0003*\u0015\u0000\u00d3\u00dc\u0005(\u0000\u0000\u00d4\u00d9\u0003"+
- "\n\u0005\u0000\u00d5\u00d6\u0005\"\u0000\u0000\u00d6\u00d8\u0003\n\u0005"+
- "\u0000\u00d7\u00d5\u0001\u0000\u0000\u0000\u00d8\u00db\u0001\u0000\u0000"+
- "\u0000\u00d9\u00d7\u0001\u0000\u0000\u0000\u00d9\u00da\u0001\u0000\u0000"+
- "\u0000\u00da\u00dd\u0001\u0000\u0000\u0000\u00db\u00d9\u0001\u0000\u0000"+
- "\u0000\u00dc\u00d4\u0001\u0000\u0000\u0000\u00dc\u00dd\u0001\u0000\u0000"+
- "\u0000\u00dd\u00de\u0001\u0000\u0000\u0000\u00de\u00df\u00051\u0000\u0000"+
- "\u00df\u00e1\u0001\u0000\u0000\u0000\u00e0\u00cc\u0001\u0000\u0000\u0000"+
- "\u00e0\u00cd\u0001\u0000\u0000\u0000\u00e0\u00ce\u0001\u0000\u0000\u0000"+
- "\u00e0\u00d2\u0001\u0000\u0000\u0000\u00e1\u0013\u0001\u0000\u0000\u0000"+
- "\u00e2\u00e3\u0005\u000e\u0000\u0000\u00e3\u00e4\u0003\u0016\u000b\u0000"+
- "\u00e4\u0015\u0001\u0000\u0000\u0000\u00e5\u00ea\u0003\u0018\f\u0000\u00e6"+
- "\u00e7\u0005\"\u0000\u0000\u00e7\u00e9\u0003\u0018\f\u0000\u00e8\u00e6"+
- "\u0001\u0000\u0000\u0000\u00e9\u00ec\u0001\u0000\u0000\u0000\u00ea\u00e8"+
- "\u0001\u0000\u0000\u0000\u00ea\u00eb\u0001\u0000\u0000\u0000\u00eb\u0017"+
- "\u0001\u0000\u0000\u0000\u00ec\u00ea\u0001\u0000\u0000\u0000\u00ed\u00f3"+
- "\u0003\n\u0005\u0000\u00ee\u00ef\u0003(\u0014\u0000\u00ef\u00f0\u0005"+
- "!\u0000\u0000\u00f0\u00f1\u0003\n\u0005\u0000\u00f1\u00f3\u0001\u0000"+
- "\u0000\u0000\u00f2\u00ed\u0001\u0000\u0000\u0000\u00f2\u00ee\u0001\u0000"+
- "\u0000\u0000\u00f3\u0019\u0001\u0000\u0000\u0000\u00f4\u00f5\u0005\u0006"+
- "\u0000\u0000\u00f5\u00fa\u0003&\u0013\u0000\u00f6\u00f7\u0005\"\u0000"+
- "\u0000\u00f7\u00f9\u0003&\u0013\u0000\u00f8\u00f6\u0001\u0000\u0000\u0000"+
- "\u00f9\u00fc\u0001\u0000\u0000\u0000\u00fa\u00f8\u0001\u0000\u0000\u0000"+
- "\u00fa\u00fb\u0001\u0000\u0000\u0000\u00fb\u00fe\u0001\u0000\u0000\u0000"+
- "\u00fc\u00fa\u0001\u0000\u0000\u0000\u00fd\u00ff\u0003\u001c\u000e\u0000"+
- "\u00fe\u00fd\u0001\u0000\u0000\u0000\u00fe\u00ff\u0001\u0000\u0000\u0000"+
- "\u00ff\u001b\u0001\u0000\u0000\u0000\u0100\u0101\u0005@\u0000\u0000\u0101"+
- "\u0102\u0005H\u0000\u0000\u0102\u0107\u0003&\u0013\u0000\u0103\u0104\u0005"+
- "\"\u0000\u0000\u0104\u0106\u0003&\u0013\u0000\u0105\u0103\u0001\u0000"+
- "\u0000\u0000\u0106\u0109\u0001\u0000\u0000\u0000\u0107\u0105\u0001\u0000"+
- "\u0000\u0000\u0107\u0108\u0001\u0000\u0000\u0000\u0108\u010a\u0001\u0000"+
- "\u0000\u0000\u0109\u0107\u0001\u0000\u0000\u0000\u010a\u010b\u0005A\u0000"+
- "\u0000\u010b\u001d\u0001\u0000\u0000\u0000\u010c\u010d\u0005\u0004\u0000"+
- "\u0000\u010d\u010e\u0003\u0016\u000b\u0000\u010e\u001f\u0001\u0000\u0000"+
- "\u0000\u010f\u0111\u0005\u0011\u0000\u0000\u0110\u0112\u0003\u0016\u000b"+
- "\u0000\u0111\u0110\u0001\u0000\u0000\u0000\u0111\u0112\u0001\u0000\u0000"+
- "\u0000\u0112\u0115\u0001\u0000\u0000\u0000\u0113\u0114\u0005\u001e\u0000"+
- "\u0000\u0114\u0116\u0003$\u0012\u0000\u0115\u0113\u0001\u0000\u0000\u0000"+
- "\u0115\u0116\u0001\u0000\u0000\u0000\u0116!\u0001\u0000\u0000\u0000\u0117"+
- "\u0118\u0005\b\u0000\u0000\u0118\u011b\u0003\u0016\u000b\u0000\u0119\u011a"+
- "\u0005\u001e\u0000\u0000\u011a\u011c\u0003$\u0012\u0000\u011b\u0119\u0001"+
- "\u0000\u0000\u0000\u011b\u011c\u0001\u0000\u0000\u0000\u011c#\u0001\u0000"+
- "\u0000\u0000\u011d\u0122\u0003(\u0014\u0000\u011e\u011f\u0005\"\u0000"+
- "\u0000\u011f\u0121\u0003(\u0014\u0000\u0120\u011e\u0001\u0000\u0000\u0000"+
- "\u0121\u0124\u0001\u0000\u0000\u0000\u0122\u0120\u0001\u0000\u0000\u0000"+
- "\u0122\u0123\u0001\u0000\u0000\u0000\u0123%\u0001\u0000\u0000\u0000\u0124"+
- "\u0122\u0001\u0000\u0000\u0000\u0125\u0126\u0007\u0002\u0000\u0000\u0126"+
- "\'\u0001\u0000\u0000\u0000\u0127\u012c\u0003*\u0015\u0000\u0128\u0129"+
- "\u0005$\u0000\u0000\u0129\u012b\u0003*\u0015\u0000\u012a\u0128\u0001\u0000"+
- "\u0000\u0000\u012b\u012e\u0001\u0000\u0000\u0000\u012c\u012a\u0001\u0000"+
- "\u0000\u0000\u012c\u012d\u0001\u0000\u0000\u0000\u012d)\u0001\u0000\u0000"+
- "\u0000\u012e\u012c\u0001\u0000\u0000\u0000\u012f\u0130\u0007\u0003\u0000"+
- "\u0000\u0130+\u0001\u0000\u0000\u0000\u0131\u015c\u0005,\u0000\u0000\u0132"+
- "\u0133\u0003L&\u0000\u0133\u0134\u0005B\u0000\u0000\u0134\u015c\u0001"+
- "\u0000\u0000\u0000\u0135\u015c\u0003J%\u0000\u0136\u015c\u0003L&\u0000"+
- "\u0137\u015c\u0003F#\u0000\u0138\u015c\u0005/\u0000\u0000\u0139\u015c"+
- "\u0003N\'\u0000\u013a\u013b\u0005@\u0000\u0000\u013b\u0140\u0003H$\u0000"+
- "\u013c\u013d\u0005\"\u0000\u0000\u013d\u013f\u0003H$\u0000\u013e\u013c"+
- "\u0001\u0000\u0000\u0000\u013f\u0142\u0001\u0000\u0000\u0000\u0140\u013e"+
- "\u0001\u0000\u0000\u0000\u0140\u0141\u0001\u0000\u0000\u0000\u0141\u0143"+
- "\u0001\u0000\u0000\u0000\u0142\u0140\u0001\u0000\u0000\u0000\u0143\u0144"+
- "\u0005A\u0000\u0000\u0144\u015c\u0001\u0000\u0000\u0000\u0145\u0146\u0005"+
- "@\u0000\u0000\u0146\u014b\u0003F#\u0000\u0147\u0148\u0005\"\u0000\u0000"+
- "\u0148\u014a\u0003F#\u0000\u0149\u0147\u0001\u0000\u0000\u0000\u014a\u014d"+
- "\u0001\u0000\u0000\u0000\u014b\u0149\u0001\u0000\u0000\u0000\u014b\u014c"+
- "\u0001\u0000\u0000\u0000\u014c\u014e\u0001\u0000\u0000\u0000\u014d\u014b"+
- "\u0001\u0000\u0000\u0000\u014e\u014f\u0005A\u0000\u0000\u014f\u015c\u0001"+
- "\u0000\u0000\u0000\u0150\u0151\u0005@\u0000\u0000\u0151\u0156\u0003N\'"+
- "\u0000\u0152\u0153\u0005\"\u0000\u0000\u0153\u0155\u0003N\'\u0000\u0154"+
- "\u0152\u0001\u0000\u0000\u0000\u0155\u0158\u0001\u0000\u0000\u0000\u0156"+
- "\u0154\u0001\u0000\u0000\u0000\u0156\u0157\u0001\u0000\u0000\u0000\u0157"+
- "\u0159\u0001\u0000\u0000\u0000\u0158\u0156\u0001\u0000\u0000\u0000\u0159"+
- "\u015a\u0005A\u0000\u0000\u015a\u015c\u0001\u0000\u0000\u0000\u015b\u0131"+
- "\u0001\u0000\u0000\u0000\u015b\u0132\u0001\u0000\u0000\u0000\u015b\u0135"+
- "\u0001\u0000\u0000\u0000\u015b\u0136\u0001\u0000\u0000\u0000\u015b\u0137"+
- "\u0001\u0000\u0000\u0000\u015b\u0138\u0001\u0000\u0000\u0000\u015b\u0139"+
- "\u0001\u0000\u0000\u0000\u015b\u013a\u0001\u0000\u0000\u0000\u015b\u0145"+
- "\u0001\u0000\u0000\u0000\u015b\u0150\u0001\u0000\u0000\u0000\u015c-\u0001"+
- "\u0000\u0000\u0000\u015d\u015e\u0005\n\u0000\u0000\u015e\u015f\u0005\u001c"+
- "\u0000\u0000\u015f/\u0001\u0000\u0000\u0000\u0160\u0161\u0005\u0010\u0000"+
- "\u0000\u0161\u0166\u00032\u0019\u0000\u0162\u0163\u0005\"\u0000\u0000"+
- "\u0163\u0165\u00032\u0019\u0000\u0164\u0162\u0001\u0000\u0000\u0000\u0165"+
- "\u0168\u0001\u0000\u0000\u0000\u0166\u0164\u0001\u0000\u0000\u0000\u0166"+
- "\u0167\u0001\u0000\u0000\u0000\u01671\u0001\u0000\u0000\u0000\u0168\u0166"+
- "\u0001\u0000\u0000\u0000\u0169\u016b\u0003\n\u0005\u0000\u016a\u016c\u0007"+
- "\u0004\u0000\u0000\u016b\u016a\u0001\u0000\u0000\u0000\u016b\u016c\u0001"+
- "\u0000\u0000\u0000\u016c\u016f\u0001\u0000\u0000\u0000\u016d\u016e\u0005"+
- "-\u0000\u0000\u016e\u0170\u0007\u0005\u0000\u0000\u016f\u016d\u0001\u0000"+
- "\u0000\u0000\u016f\u0170\u0001\u0000\u0000\u0000\u01703\u0001\u0000\u0000"+
- "\u0000\u0171\u0172\u0005\t\u0000\u0000\u0172\u0177\u0003&\u0013\u0000"+
- "\u0173\u0174\u0005\"\u0000\u0000\u0174\u0176\u0003&\u0013\u0000\u0175"+
- "\u0173\u0001\u0000\u0000\u0000\u0176\u0179\u0001\u0000\u0000\u0000\u0177"+
- "\u0175\u0001\u0000\u0000\u0000\u0177\u0178\u0001\u0000\u0000\u0000\u0178"+
- "\u0184\u0001\u0000\u0000\u0000\u0179\u0177\u0001\u0000\u0000\u0000\u017a"+
- "\u017b\u0005\f\u0000\u0000\u017b\u0180\u0003&\u0013\u0000\u017c\u017d"+
- "\u0005\"\u0000\u0000\u017d\u017f\u0003&\u0013\u0000\u017e\u017c\u0001"+
- "\u0000\u0000\u0000\u017f\u0182\u0001\u0000\u0000\u0000\u0180\u017e\u0001"+
- "\u0000\u0000\u0000\u0180\u0181\u0001\u0000\u0000\u0000\u0181\u0184\u0001"+
- "\u0000\u0000\u0000\u0182\u0180\u0001\u0000\u0000\u0000\u0183\u0171\u0001"+
- "\u0000\u0000\u0000\u0183\u017a\u0001\u0000\u0000\u0000\u01845\u0001\u0000"+
- "\u0000\u0000\u0185\u0186\u0005\u0002\u0000\u0000\u0186\u018b\u0003&\u0013"+
- "\u0000\u0187\u0188\u0005\"\u0000\u0000\u0188\u018a\u0003&\u0013\u0000"+
- "\u0189\u0187\u0001\u0000\u0000\u0000\u018a\u018d\u0001\u0000\u0000\u0000"+
- "\u018b\u0189\u0001\u0000\u0000\u0000\u018b\u018c\u0001\u0000\u0000\u0000"+
- "\u018c7\u0001\u0000\u0000\u0000\u018d\u018b\u0001\u0000\u0000\u0000\u018e"+
- "\u018f\u0005\r\u0000\u0000\u018f\u0194\u0003:\u001d\u0000\u0190\u0191"+
- "\u0005\"\u0000\u0000\u0191\u0193\u0003:\u001d\u0000\u0192\u0190\u0001"+
- "\u0000\u0000\u0000\u0193\u0196\u0001\u0000\u0000\u0000\u0194\u0192\u0001"+
- "\u0000\u0000\u0000\u0194\u0195\u0001\u0000\u0000\u0000\u01959\u0001\u0000"+
- "\u0000\u0000\u0196\u0194\u0001\u0000\u0000\u0000\u0197\u0198\u0003&\u0013"+
- "\u0000\u0198\u0199\u0005G\u0000\u0000\u0199\u019a\u0003&\u0013\u0000\u019a"+
- ";\u0001\u0000\u0000\u0000\u019b\u019c\u0005\u0001\u0000\u0000\u019c\u019d"+
- "\u0003\u0012\t\u0000\u019d\u019f\u0003N\'\u0000\u019e\u01a0\u0003B!\u0000"+
- "\u019f\u019e\u0001\u0000\u0000\u0000\u019f\u01a0\u0001\u0000\u0000\u0000"+
- "\u01a0=\u0001\u0000\u0000\u0000\u01a1\u01a2\u0005\u0007\u0000\u0000\u01a2"+
- "\u01a3\u0003\u0012\t\u0000\u01a3\u01a4\u0003N\'\u0000\u01a4?\u0001\u0000"+
- "\u0000\u0000\u01a5\u01a6\u0005\u000b\u0000\u0000\u01a6\u01a7\u0003&\u0013"+
- "\u0000\u01a7A\u0001\u0000\u0000\u0000\u01a8\u01ad\u0003D\"\u0000\u01a9"+
- "\u01aa\u0005\"\u0000\u0000\u01aa\u01ac\u0003D\"\u0000\u01ab\u01a9\u0001"+
- "\u0000\u0000\u0000\u01ac\u01af\u0001\u0000\u0000\u0000\u01ad\u01ab\u0001"+
- "\u0000\u0000\u0000\u01ad\u01ae\u0001\u0000\u0000\u0000\u01aeC\u0001\u0000"+
- "\u0000\u0000\u01af\u01ad\u0001\u0000\u0000\u0000\u01b0\u01b1\u0003*\u0015"+
- "\u0000\u01b1\u01b2\u0005!\u0000\u0000\u01b2\u01b3\u0003,\u0016\u0000\u01b3"+
- "E\u0001\u0000\u0000\u0000\u01b4\u01b5\u0007\u0006\u0000\u0000\u01b5G\u0001"+
- "\u0000\u0000\u0000\u01b6\u01b9\u0003J%\u0000\u01b7\u01b9\u0003L&\u0000"+
- "\u01b8\u01b6\u0001\u0000\u0000\u0000\u01b8\u01b7\u0001\u0000\u0000\u0000"+
- "\u01b9I\u0001\u0000\u0000\u0000\u01ba\u01bc\u0007\u0000\u0000\u0000\u01bb"+
- "\u01ba\u0001\u0000\u0000\u0000\u01bb\u01bc\u0001\u0000\u0000\u0000\u01bc"+
- "\u01bd\u0001\u0000\u0000\u0000\u01bd\u01be\u0005\u001d\u0000\u0000\u01be"+
- "K\u0001\u0000\u0000\u0000\u01bf\u01c1\u0007\u0000\u0000\u0000\u01c0\u01bf"+
- "\u0001\u0000\u0000\u0000\u01c0\u01c1\u0001\u0000\u0000\u0000\u01c1\u01c2"+
- "\u0001\u0000\u0000\u0000\u01c2\u01c3\u0005\u001c\u0000\u0000\u01c3M\u0001"+
- "\u0000\u0000\u0000\u01c4\u01c5\u0005\u001b\u0000\u0000\u01c5O\u0001\u0000"+
- "\u0000\u0000\u01c6\u01c7\u0007\u0007\u0000\u0000\u01c7Q\u0001\u0000\u0000"+
- "\u0000\u01c8\u01c9\u0005\u0005\u0000\u0000\u01c9\u01ca\u0003T*\u0000\u01ca"+
- "S\u0001\u0000\u0000\u0000\u01cb\u01cc\u0005@\u0000\u0000\u01cc\u01cd\u0003"+
- "\u0002\u0001\u0000\u01cd\u01ce\u0005A\u0000\u0000\u01ceU\u0001\u0000\u0000"+
- "\u0000\u01cf\u01d0\u0005\u000f\u0000\u0000\u01d0\u01d4\u00053\u0000\u0000"+
- "\u01d1\u01d2\u0005\u000f\u0000\u0000\u01d2\u01d4\u00054\u0000\u0000\u01d3"+
- "\u01cf\u0001\u0000\u0000\u0000\u01d3\u01d1\u0001\u0000\u0000\u0000\u01d4"+
- "W\u0001\u0000\u0000\u0000\u01d5\u01d6\u0005\u0003\u0000\u0000\u01d6\u01d9"+
- "\u0003&\u0013\u0000\u01d7\u01d8\u0005I\u0000\u0000\u01d8\u01da\u0003&"+
- "\u0013\u0000\u01d9\u01d7\u0001\u0000\u0000\u0000\u01d9\u01da\u0001\u0000"+
- "\u0000\u0000\u01da\u01e4\u0001\u0000\u0000\u0000\u01db\u01dc\u0005J\u0000"+
- "\u0000\u01dc\u01e1\u0003Z-\u0000\u01dd\u01de\u0005\"\u0000\u0000\u01de"+
- "\u01e0\u0003Z-\u0000\u01df\u01dd\u0001\u0000\u0000\u0000\u01e0\u01e3\u0001"+
- "\u0000\u0000\u0000\u01e1\u01df\u0001\u0000\u0000\u0000\u01e1\u01e2\u0001"+
- "\u0000\u0000\u0000\u01e2\u01e5\u0001\u0000\u0000\u0000\u01e3\u01e1\u0001"+
- "\u0000\u0000\u0000\u01e4\u01db\u0001\u0000\u0000\u0000\u01e4\u01e5\u0001"+
- "\u0000\u0000\u0000\u01e5Y\u0001\u0000\u0000\u0000\u01e6\u01e7\u0003&\u0013"+
- "\u0000\u01e7\u01e8\u0005!\u0000\u0000\u01e8\u01ea\u0001\u0000\u0000\u0000"+
- "\u01e9\u01e6\u0001\u0000\u0000\u0000\u01e9\u01ea\u0001\u0000\u0000\u0000"+
- "\u01ea\u01eb\u0001\u0000\u0000\u0000\u01eb\u01ec\u0003&\u0013\u0000\u01ec"+
- "[\u0001\u0000\u0000\u00002gn}\u0089\u0092\u0097\u009f\u00a1\u00a6\u00ad"+
- "\u00b2\u00b9\u00bf\u00c7\u00c9\u00d9\u00dc\u00e0\u00ea\u00f2\u00fa\u00fe"+
- "\u0107\u0111\u0115\u011b\u0122\u012c\u0140\u014b\u0156\u015b\u0166\u016b"+
- "\u016f\u0177\u0180\u0183\u018b\u0194\u019f\u01ad\u01b8\u01bb\u01c0\u01d3"+
- "\u01d9\u01e1\u01e4\u01e9";
+ "\u0016\u0151\b\u0016\n\u0016\f\u0016\u0154\t\u0016\u0001\u0016\u0001\u0016"+
+ "\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0005\u0016\u015c\b\u0016"+
+ "\n\u0016\f\u0016\u015f\t\u0016\u0001\u0016\u0001\u0016\u0003\u0016\u0163"+
+ "\b\u0016\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0018\u0001\u0018\u0001"+
+ "\u0018\u0001\u0018\u0005\u0018\u016c\b\u0018\n\u0018\f\u0018\u016f\t\u0018"+
+ "\u0001\u0019\u0001\u0019\u0003\u0019\u0173\b\u0019\u0001\u0019\u0001\u0019"+
+ "\u0003\u0019\u0177\b\u0019\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a"+
+ "\u0005\u001a\u017d\b\u001a\n\u001a\f\u001a\u0180\t\u001a\u0001\u001a\u0001"+
+ "\u001a\u0001\u001a\u0001\u001a\u0005\u001a\u0186\b\u001a\n\u001a\f\u001a"+
+ "\u0189\t\u001a\u0003\u001a\u018b\b\u001a\u0001\u001b\u0001\u001b\u0001"+
+ "\u001b\u0001\u001b\u0005\u001b\u0191\b\u001b\n\u001b\f\u001b\u0194\t\u001b"+
+ "\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0005\u001c\u019a\b\u001c"+
+ "\n\u001c\f\u001c\u019d\t\u001c\u0001\u001d\u0001\u001d\u0001\u001d\u0001"+
+ "\u001d\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0003\u001e\u01a7"+
+ "\b\u001e\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001 \u0001"+
+ " \u0001 \u0001!\u0001!\u0001!\u0005!\u01b3\b!\n!\f!\u01b6\t!\u0001\"\u0001"+
+ "\"\u0001\"\u0001\"\u0001#\u0001#\u0001$\u0001$\u0003$\u01c0\b$\u0001%"+
+ "\u0003%\u01c3\b%\u0001%\u0001%\u0001&\u0003&\u01c8\b&\u0001&\u0001&\u0001"+
+ "\'\u0001\'\u0001(\u0001(\u0001)\u0001)\u0001)\u0001*\u0001*\u0001*\u0001"+
+ "*\u0001+\u0001+\u0001+\u0001+\u0003+\u01db\b+\u0001,\u0001,\u0001,\u0001"+
+ ",\u0003,\u01e1\b,\u0001,\u0001,\u0001,\u0001,\u0005,\u01e7\b,\n,\f,\u01ea"+
+ "\t,\u0003,\u01ec\b,\u0001-\u0001-\u0001-\u0003-\u01f1\b-\u0001-\u0001"+
+ "-\u0001-\u0000\u0003\u0002\n\u0010.\u0000\u0002\u0004\u0006\b\n\f\u000e"+
+ "\u0010\u0012\u0014\u0016\u0018\u001a\u001c\u001e \"$&(*,.02468:<>@BDF"+
+ "HJLNPRTVXZ\u0000\b\u0001\u0000<=\u0001\u0000>@\u0001\u0000LM\u0001\u0000"+
+ "CD\u0002\u0000 ##\u0001\u0000&\'\u0002\u0000%%33\u0001\u00006;\u0213"+
+ "\u0000\\\u0001\u0000\u0000\u0000\u0002_\u0001\u0000\u0000\u0000\u0004"+
+ "n\u0001\u0000\u0000\u0000\u0006}\u0001\u0000\u0000\u0000\b\u007f\u0001"+
+ "\u0000\u0000\u0000\n\u009e\u0001\u0000\u0000\u0000\f\u00b9\u0001\u0000"+
+ "\u0000\u0000\u000e\u00c0\u0001\u0000\u0000\u0000\u0010\u00c6\u0001\u0000"+
+ "\u0000\u0000\u0012\u00e7\u0001\u0000\u0000\u0000\u0014\u00e9\u0001\u0000"+
+ "\u0000\u0000\u0016\u00ec\u0001\u0000\u0000\u0000\u0018\u00f9\u0001\u0000"+
+ "\u0000\u0000\u001a\u00fb\u0001\u0000\u0000\u0000\u001c\u0107\u0001\u0000"+
+ "\u0000\u0000\u001e\u0113\u0001\u0000\u0000\u0000 \u0116\u0001\u0000\u0000"+
+ "\u0000\"\u011e\u0001\u0000\u0000\u0000$\u0124\u0001\u0000\u0000\u0000"+
+ "&\u012c\u0001\u0000\u0000\u0000(\u012e\u0001\u0000\u0000\u0000*\u0136"+
+ "\u0001\u0000\u0000\u0000,\u0162\u0001\u0000\u0000\u0000.\u0164\u0001\u0000"+
+ "\u0000\u00000\u0167\u0001\u0000\u0000\u00002\u0170\u0001\u0000\u0000\u0000"+
+ "4\u018a\u0001\u0000\u0000\u00006\u018c\u0001\u0000\u0000\u00008\u0195"+
+ "\u0001\u0000\u0000\u0000:\u019e\u0001\u0000\u0000\u0000<\u01a2\u0001\u0000"+
+ "\u0000\u0000>\u01a8\u0001\u0000\u0000\u0000@\u01ac\u0001\u0000\u0000\u0000"+
+ "B\u01af\u0001\u0000\u0000\u0000D\u01b7\u0001\u0000\u0000\u0000F\u01bb"+
+ "\u0001\u0000\u0000\u0000H\u01bf\u0001\u0000\u0000\u0000J\u01c2\u0001\u0000"+
+ "\u0000\u0000L\u01c7\u0001\u0000\u0000\u0000N\u01cb\u0001\u0000\u0000\u0000"+
+ "P\u01cd\u0001\u0000\u0000\u0000R\u01cf\u0001\u0000\u0000\u0000T\u01d2"+
+ "\u0001\u0000\u0000\u0000V\u01da\u0001\u0000\u0000\u0000X\u01dc\u0001\u0000"+
+ "\u0000\u0000Z\u01f0\u0001\u0000\u0000\u0000\\]\u0003\u0002\u0001\u0000"+
+ "]^\u0005\u0000\u0000\u0001^\u0001\u0001\u0000\u0000\u0000_`\u0006\u0001"+
+ "\uffff\uffff\u0000`a\u0003\u0004\u0002\u0000ag\u0001\u0000\u0000\u0000"+
+ "bc\n\u0001\u0000\u0000cd\u0005\u001a\u0000\u0000df\u0003\u0006\u0003\u0000"+
+ "eb\u0001\u0000\u0000\u0000fi\u0001\u0000\u0000\u0000ge\u0001\u0000\u0000"+
+ "\u0000gh\u0001\u0000\u0000\u0000h\u0003\u0001\u0000\u0000\u0000ig\u0001"+
+ "\u0000\u0000\u0000jo\u0003R)\u0000ko\u0003\u001a\r\u0000lo\u0003\u0014"+
+ "\n\u0000mo\u0003V+\u0000nj\u0001\u0000\u0000\u0000nk\u0001\u0000\u0000"+
+ "\u0000nl\u0001\u0000\u0000\u0000nm\u0001\u0000\u0000\u0000o\u0005\u0001"+
+ "\u0000\u0000\u0000p~\u0003\u001e\u000f\u0000q~\u0003\"\u0011\u0000r~\u0003"+
+ ".\u0017\u0000s~\u00034\u001a\u0000t~\u00030\u0018\u0000u~\u0003 \u0010"+
+ "\u0000v~\u0003\b\u0004\u0000w~\u00036\u001b\u0000x~\u00038\u001c\u0000"+
+ "y~\u0003<\u001e\u0000z~\u0003>\u001f\u0000{~\u0003X,\u0000|~\u0003@ \u0000"+
+ "}p\u0001\u0000\u0000\u0000}q\u0001\u0000\u0000\u0000}r\u0001\u0000\u0000"+
+ "\u0000}s\u0001\u0000\u0000\u0000}t\u0001\u0000\u0000\u0000}u\u0001\u0000"+
+ "\u0000\u0000}v\u0001\u0000\u0000\u0000}w\u0001\u0000\u0000\u0000}x\u0001"+
+ "\u0000\u0000\u0000}y\u0001\u0000\u0000\u0000}z\u0001\u0000\u0000\u0000"+
+ "}{\u0001\u0000\u0000\u0000}|\u0001\u0000\u0000\u0000~\u0007\u0001\u0000"+
+ "\u0000\u0000\u007f\u0080\u0005\u0012\u0000\u0000\u0080\u0081\u0003\n\u0005"+
+ "\u0000\u0081\t\u0001\u0000\u0000\u0000\u0082\u0083\u0006\u0005\uffff\uffff"+
+ "\u0000\u0083\u0084\u0005,\u0000\u0000\u0084\u009f\u0003\n\u0005\u0007"+
+ "\u0085\u009f\u0003\u000e\u0007\u0000\u0086\u009f\u0003\f\u0006\u0000\u0087"+
+ "\u0089\u0003\u000e\u0007\u0000\u0088\u008a\u0005,\u0000\u0000\u0089\u0088"+
+ "\u0001\u0000\u0000\u0000\u0089\u008a\u0001\u0000\u0000\u0000\u008a\u008b"+
+ "\u0001\u0000\u0000\u0000\u008b\u008c\u0005)\u0000\u0000\u008c\u008d\u0005"+
+ "(\u0000\u0000\u008d\u0092\u0003\u000e\u0007\u0000\u008e\u008f\u0005\""+
+ "\u0000\u0000\u008f\u0091\u0003\u000e\u0007\u0000\u0090\u008e\u0001\u0000"+
+ "\u0000\u0000\u0091\u0094\u0001\u0000\u0000\u0000\u0092\u0090\u0001\u0000"+
+ "\u0000\u0000\u0092\u0093\u0001\u0000\u0000\u0000\u0093\u0095\u0001\u0000"+
+ "\u0000\u0000\u0094\u0092\u0001\u0000\u0000\u0000\u0095\u0096\u00052\u0000"+
+ "\u0000\u0096\u009f\u0001\u0000\u0000\u0000\u0097\u0098\u0003\u000e\u0007"+
+ "\u0000\u0098\u009a\u0005*\u0000\u0000\u0099\u009b\u0005,\u0000\u0000\u009a"+
+ "\u0099\u0001\u0000\u0000\u0000\u009a\u009b\u0001\u0000\u0000\u0000\u009b"+
+ "\u009c\u0001\u0000\u0000\u0000\u009c\u009d\u0005-\u0000\u0000\u009d\u009f"+
+ "\u0001\u0000\u0000\u0000\u009e\u0082\u0001\u0000\u0000\u0000\u009e\u0085"+
+ "\u0001\u0000\u0000\u0000\u009e\u0086\u0001\u0000\u0000\u0000\u009e\u0087"+
+ "\u0001\u0000\u0000\u0000\u009e\u0097\u0001\u0000\u0000\u0000\u009f\u00a8"+
+ "\u0001\u0000\u0000\u0000\u00a0\u00a1\n\u0004\u0000\u0000\u00a1\u00a2\u0005"+
+ "\u001f\u0000\u0000\u00a2\u00a7\u0003\n\u0005\u0005\u00a3\u00a4\n\u0003"+
+ "\u0000\u0000\u00a4\u00a5\u0005/\u0000\u0000\u00a5\u00a7\u0003\n\u0005"+
+ "\u0004\u00a6\u00a0\u0001\u0000\u0000\u0000\u00a6\u00a3\u0001\u0000\u0000"+
+ "\u0000\u00a7\u00aa\u0001\u0000\u0000\u0000\u00a8\u00a6\u0001\u0000\u0000"+
+ "\u0000\u00a8\u00a9\u0001\u0000\u0000\u0000\u00a9\u000b\u0001\u0000\u0000"+
+ "\u0000\u00aa\u00a8\u0001\u0000\u0000\u0000\u00ab\u00ad\u0003\u000e\u0007"+
+ "\u0000\u00ac\u00ae\u0005,\u0000\u0000\u00ad\u00ac\u0001\u0000\u0000\u0000"+
+ "\u00ad\u00ae\u0001\u0000\u0000\u0000\u00ae\u00af\u0001\u0000\u0000\u0000"+
+ "\u00af\u00b0\u0005+\u0000\u0000\u00b0\u00b1\u0003N\'\u0000\u00b1\u00ba"+
+ "\u0001\u0000\u0000\u0000\u00b2\u00b4\u0003\u000e\u0007\u0000\u00b3\u00b5"+
+ "\u0005,\u0000\u0000\u00b4\u00b3\u0001\u0000\u0000\u0000\u00b4\u00b5\u0001"+
+ "\u0000\u0000\u0000\u00b5\u00b6\u0001\u0000\u0000\u0000\u00b6\u00b7\u0005"+
+ "1\u0000\u0000\u00b7\u00b8\u0003N\'\u0000\u00b8\u00ba\u0001\u0000\u0000"+
+ "\u0000\u00b9\u00ab\u0001\u0000\u0000\u0000\u00b9\u00b2\u0001\u0000\u0000"+
+ "\u0000\u00ba\r\u0001\u0000\u0000\u0000\u00bb\u00c1\u0003\u0010\b\u0000"+
+ "\u00bc\u00bd\u0003\u0010\b\u0000\u00bd\u00be\u0003P(\u0000\u00be\u00bf"+
+ "\u0003\u0010\b\u0000\u00bf\u00c1\u0001\u0000\u0000\u0000\u00c0\u00bb\u0001"+
+ "\u0000\u0000\u0000\u00c0\u00bc\u0001\u0000\u0000\u0000\u00c1\u000f\u0001"+
+ "\u0000\u0000\u0000\u00c2\u00c3\u0006\b\uffff\uffff\u0000\u00c3\u00c7\u0003"+
+ "\u0012\t\u0000\u00c4\u00c5\u0007\u0000\u0000\u0000\u00c5\u00c7\u0003\u0010"+
+ "\b\u0003\u00c6\u00c2\u0001\u0000\u0000\u0000\u00c6\u00c4\u0001\u0000\u0000"+
+ "\u0000\u00c7\u00d0\u0001\u0000\u0000\u0000\u00c8\u00c9\n\u0002\u0000\u0000"+
+ "\u00c9\u00ca\u0007\u0001\u0000\u0000\u00ca\u00cf\u0003\u0010\b\u0003\u00cb"+
+ "\u00cc\n\u0001\u0000\u0000\u00cc\u00cd\u0007\u0000\u0000\u0000\u00cd\u00cf"+
+ "\u0003\u0010\b\u0002\u00ce\u00c8\u0001\u0000\u0000\u0000\u00ce\u00cb\u0001"+
+ "\u0000\u0000\u0000\u00cf\u00d2\u0001\u0000\u0000\u0000\u00d0\u00ce\u0001"+
+ "\u0000\u0000\u0000\u00d0\u00d1\u0001\u0000\u0000\u0000\u00d1\u0011\u0001"+
+ "\u0000\u0000\u0000\u00d2\u00d0\u0001\u0000\u0000\u0000\u00d3\u00e8\u0003"+
+ ",\u0016\u0000\u00d4\u00e8\u0003(\u0014\u0000\u00d5\u00d6\u0005(\u0000"+
+ "\u0000\u00d6\u00d7\u0003\n\u0005\u0000\u00d7\u00d8\u00052\u0000\u0000"+
+ "\u00d8\u00e8\u0001\u0000\u0000\u0000\u00d9\u00da\u0003*\u0015\u0000\u00da"+
+ "\u00e3\u0005(\u0000\u0000\u00db\u00e0\u0003\n\u0005\u0000\u00dc\u00dd"+
+ "\u0005\"\u0000\u0000\u00dd\u00df\u0003\n\u0005\u0000\u00de\u00dc\u0001"+
+ "\u0000\u0000\u0000\u00df\u00e2\u0001\u0000\u0000\u0000\u00e0\u00de\u0001"+
+ "\u0000\u0000\u0000\u00e0\u00e1\u0001\u0000\u0000\u0000\u00e1\u00e4\u0001"+
+ "\u0000\u0000\u0000\u00e2\u00e0\u0001\u0000\u0000\u0000\u00e3\u00db\u0001"+
+ "\u0000\u0000\u0000\u00e3\u00e4\u0001\u0000\u0000\u0000\u00e4\u00e5\u0001"+
+ "\u0000\u0000\u0000\u00e5\u00e6\u00052\u0000\u0000\u00e6\u00e8\u0001\u0000"+
+ "\u0000\u0000\u00e7\u00d3\u0001\u0000\u0000\u0000\u00e7\u00d4\u0001\u0000"+
+ "\u0000\u0000\u00e7\u00d5\u0001\u0000\u0000\u0000\u00e7\u00d9\u0001\u0000"+
+ "\u0000\u0000\u00e8\u0013\u0001\u0000\u0000\u0000\u00e9\u00ea\u0005\u000e"+
+ "\u0000\u0000\u00ea\u00eb\u0003\u0016\u000b\u0000\u00eb\u0015\u0001\u0000"+
+ "\u0000\u0000\u00ec\u00f1\u0003\u0018\f\u0000\u00ed\u00ee\u0005\"\u0000"+
+ "\u0000\u00ee\u00f0\u0003\u0018\f\u0000\u00ef\u00ed\u0001\u0000\u0000\u0000"+
+ "\u00f0\u00f3\u0001\u0000\u0000\u0000\u00f1\u00ef\u0001\u0000\u0000\u0000"+
+ "\u00f1\u00f2\u0001\u0000\u0000\u0000\u00f2\u0017\u0001\u0000\u0000\u0000"+
+ "\u00f3\u00f1\u0001\u0000\u0000\u0000\u00f4\u00fa\u0003\n\u0005\u0000\u00f5"+
+ "\u00f6\u0003(\u0014\u0000\u00f6\u00f7\u0005!\u0000\u0000\u00f7\u00f8\u0003"+
+ "\n\u0005\u0000\u00f8\u00fa\u0001\u0000\u0000\u0000\u00f9\u00f4\u0001\u0000"+
+ "\u0000\u0000\u00f9\u00f5\u0001\u0000\u0000\u0000\u00fa\u0019\u0001\u0000"+
+ "\u0000\u0000\u00fb\u00fc\u0005\u0006\u0000\u0000\u00fc\u0101\u0003&\u0013"+
+ "\u0000\u00fd\u00fe\u0005\"\u0000\u0000\u00fe\u0100\u0003&\u0013\u0000"+
+ "\u00ff\u00fd\u0001\u0000\u0000\u0000\u0100\u0103\u0001\u0000\u0000\u0000"+
+ "\u0101\u00ff\u0001\u0000\u0000\u0000\u0101\u0102\u0001\u0000\u0000\u0000"+
+ "\u0102\u0105\u0001\u0000\u0000\u0000\u0103\u0101\u0001\u0000\u0000\u0000"+
+ "\u0104\u0106\u0003\u001c\u000e\u0000\u0105\u0104\u0001\u0000\u0000\u0000"+
+ "\u0105\u0106\u0001\u0000\u0000\u0000\u0106\u001b\u0001\u0000\u0000\u0000"+
+ "\u0107\u0108\u0005A\u0000\u0000\u0108\u0109\u0005I\u0000\u0000\u0109\u010e"+
+ "\u0003&\u0013\u0000\u010a\u010b\u0005\"\u0000\u0000\u010b\u010d\u0003"+
+ "&\u0013\u0000\u010c\u010a\u0001\u0000\u0000\u0000\u010d\u0110\u0001\u0000"+
+ "\u0000\u0000\u010e\u010c\u0001\u0000\u0000\u0000\u010e\u010f\u0001\u0000"+
+ "\u0000\u0000\u010f\u0111\u0001\u0000\u0000\u0000\u0110\u010e\u0001\u0000"+
+ "\u0000\u0000\u0111\u0112\u0005B\u0000\u0000\u0112\u001d\u0001\u0000\u0000"+
+ "\u0000\u0113\u0114\u0005\u0004\u0000\u0000\u0114\u0115\u0003\u0016\u000b"+
+ "\u0000\u0115\u001f\u0001\u0000\u0000\u0000\u0116\u0118\u0005\u0011\u0000"+
+ "\u0000\u0117\u0119\u0003\u0016\u000b\u0000\u0118\u0117\u0001\u0000\u0000"+
+ "\u0000\u0118\u0119\u0001\u0000\u0000\u0000\u0119\u011c\u0001\u0000\u0000"+
+ "\u0000\u011a\u011b\u0005\u001e\u0000\u0000\u011b\u011d\u0003$\u0012\u0000"+
+ "\u011c\u011a\u0001\u0000\u0000\u0000\u011c\u011d\u0001\u0000\u0000\u0000"+
+ "\u011d!\u0001\u0000\u0000\u0000\u011e\u011f\u0005\b\u0000\u0000\u011f"+
+ "\u0122\u0003\u0016\u000b\u0000\u0120\u0121\u0005\u001e\u0000\u0000\u0121"+
+ "\u0123\u0003$\u0012\u0000\u0122\u0120\u0001\u0000\u0000\u0000\u0122\u0123"+
+ "\u0001\u0000\u0000\u0000\u0123#\u0001\u0000\u0000\u0000\u0124\u0129\u0003"+
+ "(\u0014\u0000\u0125\u0126\u0005\"\u0000\u0000\u0126\u0128\u0003(\u0014"+
+ "\u0000\u0127\u0125\u0001\u0000\u0000\u0000\u0128\u012b\u0001\u0000\u0000"+
+ "\u0000\u0129\u0127\u0001\u0000\u0000\u0000\u0129\u012a\u0001\u0000\u0000"+
+ "\u0000\u012a%\u0001\u0000\u0000\u0000\u012b\u0129\u0001\u0000\u0000\u0000"+
+ "\u012c\u012d\u0007\u0002\u0000\u0000\u012d\'\u0001\u0000\u0000\u0000\u012e"+
+ "\u0133\u0003*\u0015\u0000\u012f\u0130\u0005$\u0000\u0000\u0130\u0132\u0003"+
+ "*\u0015\u0000\u0131\u012f\u0001\u0000\u0000\u0000\u0132\u0135\u0001\u0000"+
+ "\u0000\u0000\u0133\u0131\u0001\u0000\u0000\u0000\u0133\u0134\u0001\u0000"+
+ "\u0000\u0000\u0134)\u0001\u0000\u0000\u0000\u0135\u0133\u0001\u0000\u0000"+
+ "\u0000\u0136\u0137\u0007\u0003\u0000\u0000\u0137+\u0001\u0000\u0000\u0000"+
+ "\u0138\u0163\u0005-\u0000\u0000\u0139\u013a\u0003L&\u0000\u013a\u013b"+
+ "\u0005C\u0000\u0000\u013b\u0163\u0001\u0000\u0000\u0000\u013c\u0163\u0003"+
+ "J%\u0000\u013d\u0163\u0003L&\u0000\u013e\u0163\u0003F#\u0000\u013f\u0163"+
+ "\u00050\u0000\u0000\u0140\u0163\u0003N\'\u0000\u0141\u0142\u0005A\u0000"+
+ "\u0000\u0142\u0147\u0003H$\u0000\u0143\u0144\u0005\"\u0000\u0000\u0144"+
+ "\u0146\u0003H$\u0000\u0145\u0143\u0001\u0000\u0000\u0000\u0146\u0149\u0001"+
+ "\u0000\u0000\u0000\u0147\u0145\u0001\u0000\u0000\u0000\u0147\u0148\u0001"+
+ "\u0000\u0000\u0000\u0148\u014a\u0001\u0000\u0000\u0000\u0149\u0147\u0001"+
+ "\u0000\u0000\u0000\u014a\u014b\u0005B\u0000\u0000\u014b\u0163\u0001\u0000"+
+ "\u0000\u0000\u014c\u014d\u0005A\u0000\u0000\u014d\u0152\u0003F#\u0000"+
+ "\u014e\u014f\u0005\"\u0000\u0000\u014f\u0151\u0003F#\u0000\u0150\u014e"+
+ "\u0001\u0000\u0000\u0000\u0151\u0154\u0001\u0000\u0000\u0000\u0152\u0150"+
+ "\u0001\u0000\u0000\u0000\u0152\u0153\u0001\u0000\u0000\u0000\u0153\u0155"+
+ "\u0001\u0000\u0000\u0000\u0154\u0152\u0001\u0000\u0000\u0000\u0155\u0156"+
+ "\u0005B\u0000\u0000\u0156\u0163\u0001\u0000\u0000\u0000\u0157\u0158\u0005"+
+ "A\u0000\u0000\u0158\u015d\u0003N\'\u0000\u0159\u015a\u0005\"\u0000\u0000"+
+ "\u015a\u015c\u0003N\'\u0000\u015b\u0159\u0001\u0000\u0000\u0000\u015c"+
+ "\u015f\u0001\u0000\u0000\u0000\u015d\u015b\u0001\u0000\u0000\u0000\u015d"+
+ "\u015e\u0001\u0000\u0000\u0000\u015e\u0160\u0001\u0000\u0000\u0000\u015f"+
+ "\u015d\u0001\u0000\u0000\u0000\u0160\u0161\u0005B\u0000\u0000\u0161\u0163"+
+ "\u0001\u0000\u0000\u0000\u0162\u0138\u0001\u0000\u0000\u0000\u0162\u0139"+
+ "\u0001\u0000\u0000\u0000\u0162\u013c\u0001\u0000\u0000\u0000\u0162\u013d"+
+ "\u0001\u0000\u0000\u0000\u0162\u013e\u0001\u0000\u0000\u0000\u0162\u013f"+
+ "\u0001\u0000\u0000\u0000\u0162\u0140\u0001\u0000\u0000\u0000\u0162\u0141"+
+ "\u0001\u0000\u0000\u0000\u0162\u014c\u0001\u0000\u0000\u0000\u0162\u0157"+
+ "\u0001\u0000\u0000\u0000\u0163-\u0001\u0000\u0000\u0000\u0164\u0165\u0005"+
+ "\n\u0000\u0000\u0165\u0166\u0005\u001c\u0000\u0000\u0166/\u0001\u0000"+
+ "\u0000\u0000\u0167\u0168\u0005\u0010\u0000\u0000\u0168\u016d\u00032\u0019"+
+ "\u0000\u0169\u016a\u0005\"\u0000\u0000\u016a\u016c\u00032\u0019\u0000"+
+ "\u016b\u0169\u0001\u0000\u0000\u0000\u016c\u016f\u0001\u0000\u0000\u0000"+
+ "\u016d\u016b\u0001\u0000\u0000\u0000\u016d\u016e\u0001\u0000\u0000\u0000"+
+ "\u016e1\u0001\u0000\u0000\u0000\u016f\u016d\u0001\u0000\u0000\u0000\u0170"+
+ "\u0172\u0003\n\u0005\u0000\u0171\u0173\u0007\u0004\u0000\u0000\u0172\u0171"+
+ "\u0001\u0000\u0000\u0000\u0172\u0173\u0001\u0000\u0000\u0000\u0173\u0176"+
+ "\u0001\u0000\u0000\u0000\u0174\u0175\u0005.\u0000\u0000\u0175\u0177\u0007"+
+ "\u0005\u0000\u0000\u0176\u0174\u0001\u0000\u0000\u0000\u0176\u0177\u0001"+
+ "\u0000\u0000\u0000\u01773\u0001\u0000\u0000\u0000\u0178\u0179\u0005\t"+
+ "\u0000\u0000\u0179\u017e\u0003&\u0013\u0000\u017a\u017b\u0005\"\u0000"+
+ "\u0000\u017b\u017d\u0003&\u0013\u0000\u017c\u017a\u0001\u0000\u0000\u0000"+
+ "\u017d\u0180\u0001\u0000\u0000\u0000\u017e\u017c\u0001\u0000\u0000\u0000"+
+ "\u017e\u017f\u0001\u0000\u0000\u0000\u017f\u018b\u0001\u0000\u0000\u0000"+
+ "\u0180\u017e\u0001\u0000\u0000\u0000\u0181\u0182\u0005\f\u0000\u0000\u0182"+
+ "\u0187\u0003&\u0013\u0000\u0183\u0184\u0005\"\u0000\u0000\u0184\u0186"+
+ "\u0003&\u0013\u0000\u0185\u0183\u0001\u0000\u0000\u0000\u0186\u0189\u0001"+
+ "\u0000\u0000\u0000\u0187\u0185\u0001\u0000\u0000\u0000\u0187\u0188\u0001"+
+ "\u0000\u0000\u0000\u0188\u018b\u0001\u0000\u0000\u0000\u0189\u0187\u0001"+
+ "\u0000\u0000\u0000\u018a\u0178\u0001\u0000\u0000\u0000\u018a\u0181\u0001"+
+ "\u0000\u0000\u0000\u018b5\u0001\u0000\u0000\u0000\u018c\u018d\u0005\u0002"+
+ "\u0000\u0000\u018d\u0192\u0003&\u0013\u0000\u018e\u018f\u0005\"\u0000"+
+ "\u0000\u018f\u0191\u0003&\u0013\u0000\u0190\u018e\u0001\u0000\u0000\u0000"+
+ "\u0191\u0194\u0001\u0000\u0000\u0000\u0192\u0190\u0001\u0000\u0000\u0000"+
+ "\u0192\u0193\u0001\u0000\u0000\u0000\u01937\u0001\u0000\u0000\u0000\u0194"+
+ "\u0192\u0001\u0000\u0000\u0000\u0195\u0196\u0005\r\u0000\u0000\u0196\u019b"+
+ "\u0003:\u001d\u0000\u0197\u0198\u0005\"\u0000\u0000\u0198\u019a\u0003"+
+ ":\u001d\u0000\u0199\u0197\u0001\u0000\u0000\u0000\u019a\u019d\u0001\u0000"+
+ "\u0000\u0000\u019b\u0199\u0001\u0000\u0000\u0000\u019b\u019c\u0001\u0000"+
+ "\u0000\u0000\u019c9\u0001\u0000\u0000\u0000\u019d\u019b\u0001\u0000\u0000"+
+ "\u0000\u019e\u019f\u0003&\u0013\u0000\u019f\u01a0\u0005H\u0000\u0000\u01a0"+
+ "\u01a1\u0003&\u0013\u0000\u01a1;\u0001\u0000\u0000\u0000\u01a2\u01a3\u0005"+
+ "\u0001\u0000\u0000\u01a3\u01a4\u0003\u0012\t\u0000\u01a4\u01a6\u0003N"+
+ "\'\u0000\u01a5\u01a7\u0003B!\u0000\u01a6\u01a5\u0001\u0000\u0000\u0000"+
+ "\u01a6\u01a7\u0001\u0000\u0000\u0000\u01a7=\u0001\u0000\u0000\u0000\u01a8"+
+ "\u01a9\u0005\u0007\u0000\u0000\u01a9\u01aa\u0003\u0012\t\u0000\u01aa\u01ab"+
+ "\u0003N\'\u0000\u01ab?\u0001\u0000\u0000\u0000\u01ac\u01ad\u0005\u000b"+
+ "\u0000\u0000\u01ad\u01ae\u0003&\u0013\u0000\u01aeA\u0001\u0000\u0000\u0000"+
+ "\u01af\u01b4\u0003D\"\u0000\u01b0\u01b1\u0005\"\u0000\u0000\u01b1\u01b3"+
+ "\u0003D\"\u0000\u01b2\u01b0\u0001\u0000\u0000\u0000\u01b3\u01b6\u0001"+
+ "\u0000\u0000\u0000\u01b4\u01b2\u0001\u0000\u0000\u0000\u01b4\u01b5\u0001"+
+ "\u0000\u0000\u0000\u01b5C\u0001\u0000\u0000\u0000\u01b6\u01b4\u0001\u0000"+
+ "\u0000\u0000\u01b7\u01b8\u0003*\u0015\u0000\u01b8\u01b9\u0005!\u0000\u0000"+
+ "\u01b9\u01ba\u0003,\u0016\u0000\u01baE\u0001\u0000\u0000\u0000\u01bb\u01bc"+
+ "\u0007\u0006\u0000\u0000\u01bcG\u0001\u0000\u0000\u0000\u01bd\u01c0\u0003"+
+ "J%\u0000\u01be\u01c0\u0003L&\u0000\u01bf\u01bd\u0001\u0000\u0000\u0000"+
+ "\u01bf\u01be\u0001\u0000\u0000\u0000\u01c0I\u0001\u0000\u0000\u0000\u01c1"+
+ "\u01c3\u0007\u0000\u0000\u0000\u01c2\u01c1\u0001\u0000\u0000\u0000\u01c2"+
+ "\u01c3\u0001\u0000\u0000\u0000\u01c3\u01c4\u0001\u0000\u0000\u0000\u01c4"+
+ "\u01c5\u0005\u001d\u0000\u0000\u01c5K\u0001\u0000\u0000\u0000\u01c6\u01c8"+
+ "\u0007\u0000\u0000\u0000\u01c7\u01c6\u0001\u0000\u0000\u0000\u01c7\u01c8"+
+ "\u0001\u0000\u0000\u0000\u01c8\u01c9\u0001\u0000\u0000\u0000\u01c9\u01ca"+
+ "\u0005\u001c\u0000\u0000\u01caM\u0001\u0000\u0000\u0000\u01cb\u01cc\u0005"+
+ "\u001b\u0000\u0000\u01ccO\u0001\u0000\u0000\u0000\u01cd\u01ce\u0007\u0007"+
+ "\u0000\u0000\u01ceQ\u0001\u0000\u0000\u0000\u01cf\u01d0\u0005\u0005\u0000"+
+ "\u0000\u01d0\u01d1\u0003T*\u0000\u01d1S\u0001\u0000\u0000\u0000\u01d2"+
+ "\u01d3\u0005A\u0000\u0000\u01d3\u01d4\u0003\u0002\u0001\u0000\u01d4\u01d5"+
+ "\u0005B\u0000\u0000\u01d5U\u0001\u0000\u0000\u0000\u01d6\u01d7\u0005\u000f"+
+ "\u0000\u0000\u01d7\u01db\u00054\u0000\u0000\u01d8\u01d9\u0005\u000f\u0000"+
+ "\u0000\u01d9\u01db\u00055\u0000\u0000\u01da\u01d6\u0001\u0000\u0000\u0000"+
+ "\u01da\u01d8\u0001\u0000\u0000\u0000\u01dbW\u0001\u0000\u0000\u0000\u01dc"+
+ "\u01dd\u0005\u0003\u0000\u0000\u01dd\u01e0\u0003&\u0013\u0000\u01de\u01df"+
+ "\u0005J\u0000\u0000\u01df\u01e1\u0003&\u0013\u0000\u01e0\u01de\u0001\u0000"+
+ "\u0000\u0000\u01e0\u01e1\u0001\u0000\u0000\u0000\u01e1\u01eb\u0001\u0000"+
+ "\u0000\u0000\u01e2\u01e3\u0005K\u0000\u0000\u01e3\u01e8\u0003Z-\u0000"+
+ "\u01e4\u01e5\u0005\"\u0000\u0000\u01e5\u01e7\u0003Z-\u0000\u01e6\u01e4"+
+ "\u0001\u0000\u0000\u0000\u01e7\u01ea\u0001\u0000\u0000\u0000\u01e8\u01e6"+
+ "\u0001\u0000\u0000\u0000\u01e8\u01e9\u0001\u0000\u0000\u0000\u01e9\u01ec"+
+ "\u0001\u0000\u0000\u0000\u01ea\u01e8\u0001\u0000\u0000\u0000\u01eb\u01e2"+
+ "\u0001\u0000\u0000\u0000\u01eb\u01ec\u0001\u0000\u0000\u0000\u01ecY\u0001"+
+ "\u0000\u0000\u0000\u01ed\u01ee\u0003&\u0013\u0000\u01ee\u01ef\u0005!\u0000"+
+ "\u0000\u01ef\u01f1\u0001\u0000\u0000\u0000\u01f0\u01ed\u0001\u0000\u0000"+
+ "\u0000\u01f0\u01f1\u0001\u0000\u0000\u0000\u01f1\u01f2\u0001\u0000\u0000"+
+ "\u0000\u01f2\u01f3\u0003&\u0013\u0000\u01f3[\u0001\u0000\u0000\u00003"+
+ "gn}\u0089\u0092\u009a\u009e\u00a6\u00a8\u00ad\u00b4\u00b9\u00c0\u00c6"+
+ "\u00ce\u00d0\u00e0\u00e3\u00e7\u00f1\u00f9\u0101\u0105\u010e\u0118\u011c"+
+ "\u0122\u0129\u0133\u0147\u0152\u015d\u0162\u016d\u0172\u0176\u017e\u0187"+
+ "\u018a\u0192\u019b\u01a6\u01b4\u01bf\u01c2\u01c7\u01da\u01e0\u01e8\u01eb"+
+ "\u01f0";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java
index 29aa0298c1009..ceef1b4e681a7 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java
@@ -108,6 +108,18 @@ public class EsqlBaseParserBaseListener implements EsqlBaseParserListener {
* The default implementation does nothing.
*/
@Override public void exitBooleanDefault(EsqlBaseParser.BooleanDefaultContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterIsNull(EsqlBaseParser.IsNullContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitIsNull(EsqlBaseParser.IsNullContext ctx) { }
/**
* {@inheritDoc}
*
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java
index caab129e77e72..48f5b33fcfec1 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java
@@ -68,6 +68,13 @@ public class EsqlBaseParserBaseVisitor extends AbstractParseTreeVisitor im
* {@link #visitChildren} on {@code ctx}.
*/
@Override public T visitBooleanDefault(EsqlBaseParser.BooleanDefaultContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitIsNull(EsqlBaseParser.IsNullContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java
index 6e5244069e805..04f0d6da3dbe4 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java
@@ -95,6 +95,18 @@ public interface EsqlBaseParserListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitBooleanDefault(EsqlBaseParser.BooleanDefaultContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code isNull}
+ * labeled alternative in {@link EsqlBaseParser#booleanExpression}.
+ * @param ctx the parse tree
+ */
+ void enterIsNull(EsqlBaseParser.IsNullContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code isNull}
+ * labeled alternative in {@link EsqlBaseParser#booleanExpression}.
+ * @param ctx the parse tree
+ */
+ void exitIsNull(EsqlBaseParser.IsNullContext ctx);
/**
* Enter a parse tree produced by the {@code regexExpression}
* labeled alternative in {@link EsqlBaseParser#booleanExpression}.
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java
index af0b0eb2b732c..681de2590d575 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java
@@ -62,6 +62,13 @@ public interface EsqlBaseParserVisitor extends ParseTreeVisitor {
* @return the visitor result
*/
T visitBooleanDefault(EsqlBaseParser.BooleanDefaultContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code isNull}
+ * labeled alternative in {@link EsqlBaseParser#booleanExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitIsNull(EsqlBaseParser.IsNullContext ctx);
/**
* Visit a parse tree produced by the {@code regexExpression}
* labeled alternative in {@link EsqlBaseParser#booleanExpression}.
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java
index 493710c5b4cee..0f002ab8ef70f 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java
@@ -28,6 +28,8 @@
import java.util.function.BiFunction;
import java.util.function.Function;
+import static org.elasticsearch.xpack.ql.parser.ParserUtils.source;
+
public class EsqlParser {
private static final Logger log = LogManager.getLogger(EsqlParser.class);
@@ -61,6 +63,8 @@ private T invokeParser(
CommonTokenStream tokenStream = new CommonTokenStream(tokenSource);
EsqlBaseParser parser = new EsqlBaseParser(tokenStream);
+ parser.addParseListener(new PostProcessor());
+
parser.removeErrorListeners();
parser.addErrorListener(ERROR_LISTENER);
@@ -78,6 +82,20 @@ private T invokeParser(
}
}
+ private class PostProcessor extends EsqlBaseParserBaseListener {
+ @Override
+ public void exitFunctionExpression(EsqlBaseParser.FunctionExpressionContext ctx) {
+ // TODO remove this at some point
+ EsqlBaseParser.IdentifierContext identifier = ctx.identifier();
+ if (identifier.getText().equalsIgnoreCase("is_null")) {
+ throw new ParsingException(
+ source(ctx),
+ "is_null function is not supported anymore, please use 'is null'/'is not null' predicates instead"
+ );
+ }
+ }
+ }
+
private static final BaseErrorListener ERROR_LISTENER = new BaseErrorListener() {
@Override
public void syntaxError(
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java
index f8e0ee5dac439..efb27707a7c7a 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java
@@ -27,6 +27,8 @@
import org.elasticsearch.xpack.ql.expression.predicate.logical.And;
import org.elasticsearch.xpack.ql.expression.predicate.logical.Not;
import org.elasticsearch.xpack.ql.expression.predicate.logical.Or;
+import org.elasticsearch.xpack.ql.expression.predicate.nulls.IsNotNull;
+import org.elasticsearch.xpack.ql.expression.predicate.nulls.IsNull;
import org.elasticsearch.xpack.ql.expression.predicate.operator.arithmetic.Add;
import org.elasticsearch.xpack.ql.expression.predicate.operator.arithmetic.Div;
import org.elasticsearch.xpack.ql.expression.predicate.operator.arithmetic.Mod;
@@ -338,6 +340,13 @@ public Expression visitLogicalIn(EsqlBaseParser.LogicalInContext ctx) {
return ctx.NOT() == null ? e : new Not(source, e);
}
+ @Override
+ public Object visitIsNull(EsqlBaseParser.IsNullContext ctx) {
+ Expression exp = expression(ctx.valueExpression());
+ Source source = source(ctx.valueExpression(), ctx);
+ return ctx.NOT() != null ? new IsNotNull(source, exp) : new IsNull(source, exp);
+ }
+
@Override
public Expression visitRegexBooleanExpression(EsqlBaseParser.RegexBooleanExpressionContext ctx) {
int type = ctx.kind.getType();
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java
index e69a46e5cc5d9..66a8e3b98a2cd 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java
@@ -1129,7 +1129,7 @@ public void testEnrichNotNullFilter() {
from test
| eval x = to_string(languages)
| enrich languages_idx on x
- | where not is_null(language_name)
+ | where language_name is not null
| limit 10
""");
var limit = as(plan, Limit.class);
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java
index 25658905297d5..9536a8160f150 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java
@@ -548,6 +548,17 @@ public void testSuggestAvailableProcessingCommandsOnParsingError() {
}
}
+ public void testDeprecatedIsNullFunction() {
+ expectError(
+ "from test | eval x = is_null(f)",
+ "line 1:23: is_null function is not supported anymore, please use 'is null'/'is not null' predicates instead"
+ );
+ expectError(
+ "row x = is_null(f)",
+ "line 1:10: is_null function is not supported anymore, please use 'is null'/'is not null' predicates instead"
+ );
+ }
+
public void testMetadataFieldOnOtherSources() {
expectError(
"row a = 1 [metadata _index]",
From 5de0a9013fca9b260d497f93d6be2c080d7de441 Mon Sep 17 00:00:00 2001
From: Nick Chow
Date: Wed, 16 Aug 2023 15:14:32 -0700
Subject: [PATCH 03/21] Documentation update that fixes a query rules code
example (#98540)
* Change example field in rule query guide
* Change fuzzy to contains to get tests to work
---------
Co-authored-by: Kathleen DeRusso
---
.../search-your-data/search-using-query-rules.asciidoc | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/reference/search/search-your-data/search-using-query-rules.asciidoc b/docs/reference/search/search-your-data/search-using-query-rules.asciidoc
index 2eecd891f859a..8d6cea338b246 100644
--- a/docs/reference/search/search-your-data/search-using-query-rules.asciidoc
+++ b/docs/reference/search/search-your-data/search-using-query-rules.asciidoc
@@ -127,7 +127,7 @@ PUT /_query_rules/my-ruleset
"criteria": [
{
"type": "fuzzy",
- "metadata": "user.query",
+ "metadata": "query_string",
"values": [ "puggles", "pugs" ]
},
{
@@ -148,8 +148,8 @@ PUT /_query_rules/my-ruleset
"type": "pinned",
"criteria": [
{
- "type": "fuzzy",
- "metadata": "user.query",
+ "type": "contains",
+ "metadata": "query_string",
"values": [ "beagles" ]
}
],
From 1cba73f7c653f6f2c9ce54726eec45aac26af870 Mon Sep 17 00:00:00 2001
From: Costin Leau
Date: Wed, 16 Aug 2023 15:53:46 -0700
Subject: [PATCH 04/21] Prune unused columns from the query (#98462)
Remove unused aggregations or eval fields that are not needed in the
final result.
For example the query:
from employees
| stats c = count(salary), min = min(salary)
| eval x = emp_no
| keep c
is now optimized as:
from employees
| stats c = count(salary)
| keep c
since neither the min or nor the x fields are actually needed.
---
.../esql/optimizer/LogicalPlanOptimizer.java | 99 +++++++++
.../optimizer/LogicalPlanOptimizerTests.java | 210 ++++++++++++++++--
.../optimizer/PhysicalPlanOptimizerTests.java | 37 ++-
3 files changed, 309 insertions(+), 37 deletions(-)
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizer.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizer.java
index c33a6c3f34432..eb20b167dbc7f 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizer.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizer.java
@@ -50,8 +50,10 @@
import org.elasticsearch.xpack.ql.plan.logical.OrderBy;
import org.elasticsearch.xpack.ql.plan.logical.Project;
import org.elasticsearch.xpack.ql.plan.logical.UnaryPlan;
+import org.elasticsearch.xpack.ql.rule.Rule;
import org.elasticsearch.xpack.ql.rule.RuleExecutor;
import org.elasticsearch.xpack.ql.util.CollectionUtils;
+import org.elasticsearch.xpack.ql.util.Holder;
import java.time.ZoneId;
import java.util.ArrayList;
@@ -105,6 +107,7 @@ protected static List> rules() {
new SimplifyComparisonsArithmetics(EsqlDataTypes::areCompatible),
// prune/elimination
new PruneFilters(),
+ new PruneColumns(),
new PruneLiteralsInOrderBy(),
new PushDownAndCombineLimits(),
new PushDownAndCombineFilters(),
@@ -603,6 +606,102 @@ protected LogicalPlan rule(OrderBy orderBy) {
}
}
+ /**
+ * Remove unused columns created in the plan, in fields inside eval or aggregations inside stats.
+ */
+ static class PruneColumns extends Rule {
+
+ @Override
+ public LogicalPlan apply(LogicalPlan plan) {
+ var used = new Holder<>(new AttributeSet());
+ // don't remove Evals without any Project/Aggregate (which might not occur as the last node in the plan)
+ var seenProjection = new Holder<>(Boolean.FALSE);
+
+ // start top-to-bottom
+ // and track used references
+ var pl = plan.transformDown(p -> {
+ // skip nodes that simply pass the input through
+ if (p instanceof Limit) {
+ return p;
+ }
+
+ // remember used
+ var usedSet = used.get();
+ boolean recheck;
+ // analyze the unused items against dedicated 'producer' nodes such as Eval and Aggregate
+ // perform a loop to retry checking if the current node is completely eliminated
+ do {
+ recheck = false;
+ if (p instanceof Aggregate aggregate) {
+ var remaining = seenProjection.get() ? removeUnused(aggregate.aggregates(), usedSet) : null;
+ // no aggregates, no need
+ if (remaining != null) {
+ if (remaining.isEmpty()) {
+ recheck = true;
+ p = aggregate.child();
+ } else {
+ p = new Aggregate(aggregate.source(), aggregate.child(), aggregate.groupings(), remaining);
+ }
+ }
+
+ seenProjection.set(Boolean.TRUE);
+ } else if (p instanceof Eval eval) {
+ var remaining = seenProjection.get() ? removeUnused(eval.fields(), usedSet) : null;
+ // no fields, no eval
+ if (remaining != null) {
+ if (remaining.isEmpty()) {
+ p = eval.child();
+ recheck = true;
+ } else {
+ p = new Eval(eval.source(), eval.child(), remaining);
+ }
+ }
+ } else if (p instanceof Project) {
+ seenProjection.set(Boolean.TRUE);
+ }
+ } while (recheck);
+
+ var inUse = usedSet.combine(references(p));
+ used.set(inUse);
+
+ // preserve the state before going to the next node
+ return p;
+ });
+
+ return pl;
+ }
+
+ /**
+ * Prunes attributes from the list not found in the given set.
+ * Returns null if no changed occurred.
+ */
+ private static List removeUnused(List named, AttributeSet used) {
+ var clone = new ArrayList<>(named);
+ var it = clone.listIterator(clone.size());
+
+ // due to Eval, go in reverse
+ while (it.hasPrevious()) {
+ N prev = it.previous();
+ if (used.contains(prev.toAttribute()) == false) {
+ it.remove();
+ } else {
+ used = used.combine(prev.references());
+ }
+ }
+ return clone.size() != named.size() ? clone : null;
+ }
+
+ private static List expressions(LogicalPlan plan) {
+ List exp = new ArrayList<>();
+ plan.forEachExpression(exp::add);
+ return exp;
+ }
+
+ private static AttributeSet references(LogicalPlan plan) {
+ return Expressions.references(expressions(plan));
+ }
+ }
+
static class PruneOrderByBeforeStats extends OptimizerRules.OptimizerRule {
@Override
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java
index 66a8e3b98a2cd..926967231f186 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java
@@ -739,7 +739,7 @@ public void testCombineOrderBy() {
| sort salary""");
var topN = as(plan, TopN.class);
- assertThat(topN.order().stream().map(o -> as(o.child(), NamedExpression.class).name()).toList(), contains("salary", "emp_no"));
+ assertThat(orderNames(topN), contains("salary", "emp_no"));
as(topN.child(), EsRelation.class);
}
@@ -751,7 +751,7 @@ public void testCombineOrderByThroughEval() {
| sort x""");
var topN = as(plan, TopN.class);
- assertThat(topN.order().stream().map(o -> as(o.child(), NamedExpression.class).name()).toList(), contains("x", "emp_no"));
+ assertThat(orderNames(topN), contains("x", "emp_no"));
var eval = as(topN.child(), Eval.class);
as(eval.child(), EsRelation.class);
}
@@ -761,12 +761,15 @@ public void testCombineOrderByThroughEvalWithTwoDefs() {
from test
| sort emp_no
| eval x = salary + 1, y = salary + 2
- | sort x""");
+ | eval z = x * y
+ | sort z""");
var topN = as(plan, TopN.class);
- assertThat(topN.order().stream().map(o -> as(o.child(), NamedExpression.class).name()).toList(), contains("x", "emp_no"));
+ assertThat(orderNames(topN), contains("z", "emp_no"));
var eval = as(topN.child(), Eval.class);
- assertThat(eval.fields().stream().map(NamedExpression::name).toList(), contains("x", "y"));
+ assertThat(Expressions.names(eval.fields()), contains("z"));
+ eval = as(eval.child(), Eval.class);
+ assertThat(Expressions.names(eval.fields()), contains("x", "y"));
as(eval.child(), EsRelation.class);
}
@@ -778,7 +781,7 @@ public void testCombineOrderByThroughDissect() {
| sort x""");
var topN = as(plan, TopN.class);
- assertThat(topN.order().stream().map(o -> as(o.child(), NamedExpression.class).name()).toList(), contains("x", "emp_no"));
+ assertThat(orderNames(topN), contains("x", "emp_no"));
var dissect = as(topN.child(), Dissect.class);
as(dissect.child(), EsRelation.class);
}
@@ -791,7 +794,7 @@ public void testCombineOrderByThroughGrok() {
| sort x""");
var topN = as(plan, TopN.class);
- assertThat(topN.order().stream().map(o -> as(o.child(), NamedExpression.class).name()).toList(), contains("x", "emp_no"));
+ assertThat(orderNames(topN), contains("x", "emp_no"));
var grok = as(topN.child(), Grok.class);
as(grok.child(), EsRelation.class);
}
@@ -805,7 +808,7 @@ public void testCombineOrderByThroughProject() {
var keep = as(plan, Project.class);
var topN = as(keep.child(), TopN.class);
- assertThat(topN.order().stream().map(o -> as(o.child(), NamedExpression.class).name()).toList(), contains("salary", "emp_no"));
+ assertThat(orderNames(topN), contains("salary", "emp_no"));
as(topN.child(), EsRelation.class);
}
@@ -820,8 +823,10 @@ public void testCombineOrderByThroughProjectAndEval() {
var keep = as(plan, Project.class);
var topN = as(keep.child(), TopN.class);
- assertThat(topN.order().stream().map(o -> as(o.child(), NamedExpression.class).name()).toList(), contains("salary", "emp_no"));
- as(topN.child(), Eval.class);
+ assertThat(orderNames(topN), contains("salary", "emp_no"));
+ var eval = as(topN.child(), Eval.class);
+ assertThat(Expressions.names(eval.fields()), contains("e"));
+ as(eval.child(), EsRelation.class);
}
public void testCombineOrderByThroughProjectWithAlias() {
@@ -834,7 +839,7 @@ public void testCombineOrderByThroughProjectWithAlias() {
var keep = as(plan, Project.class);
var topN = as(keep.child(), TopN.class);
- assertThat(topN.order().stream().map(o -> as(o.child(), NamedExpression.class).name()).toList(), contains("salary", "emp_no"));
+ assertThat(orderNames(topN), contains("salary", "emp_no"));
as(topN.child(), EsRelation.class);
}
@@ -846,11 +851,15 @@ public void testCombineOrderByThroughFilter() {
| sort salary""");
var topN = as(plan, TopN.class);
- assertThat(topN.order().stream().map(o -> as(o.child(), NamedExpression.class).name()).toList(), contains("salary", "emp_no"));
+ assertThat(orderNames(topN), contains("salary", "emp_no"));
var filter = as(topN.child(), Filter.class);
as(filter.child(), EsRelation.class);
}
+ private static List orderNames(TopN topN) {
+ return topN.order().stream().map(o -> as(o.child(), NamedExpression.class).name()).toList();
+ }
+
public void testCombineLimitWithOrderByThroughFilterAndEval() {
LogicalPlan plan = optimizedPlan("""
from test
@@ -887,10 +896,10 @@ public void testCombineMultipleOrderByAndLimits() {
var keep = as(plan, Project.class);
var topN = as(keep.child(), TopN.class);
- assertThat(topN.order().stream().map(o -> as(o.child(), NamedExpression.class).name()).toList(), contains("emp_no", "first_name"));
+ assertThat(orderNames(topN), contains("emp_no", "first_name"));
var filter = as(topN.child(), Filter.class);
var topN2 = as(filter.child(), TopN.class);
- assertThat(topN2.order().stream().map(o -> as(o.child(), NamedExpression.class).name()).toList(), contains("salary", "emp_no"));
+ assertThat(orderNames(topN2), contains("salary", "emp_no"));
as(topN2.child(), EsRelation.class);
}
@@ -1269,6 +1278,179 @@ public void testSplittingInWithFoldableValue() {
assertThat(new LogicalPlanOptimizer.SplitInWithFoldableValue().rule(in), equalTo(expected));
}
+ public void testPruneUnusedEval() {
+ var plan = plan("""
+ from test
+ | eval garbage = salary + 3
+ | keep salary
+ """);
+
+ var keep = as(plan, Project.class);
+ var limit = as(keep.child(), Limit.class);
+ var source = as(limit.child(), EsRelation.class);
+ }
+
+ public void testPruneChainedEval() {
+ var plan = plan("""
+ from test
+ | eval garbage_a = salary + 3
+ | eval garbage_b = emp_no / garbage_a, garbage_c = garbage_a
+ | eval garbage_x = 1 - garbage_b/garbage_c
+ | keep salary
+ """);
+ var keep = as(plan, Project.class);
+ var limit = as(keep.child(), Limit.class);
+ var source = as(limit.child(), EsRelation.class);
+ }
+
+ public void testPruneEvalDueToStats() {
+ var plan = plan("""
+ from test
+ | eval garbage_a = salary + 3, x = salary
+ | eval garbage_b = x + 3
+ | stats c = count(x)
+ """);
+
+ var limit = as(plan, Limit.class);
+ var aggregate = as(limit.child(), Aggregate.class);
+ assertThat(aggregate.aggregates(), hasSize(1));
+ var alias = as(aggregate.aggregates().get(0), Alias.class);
+ var count = as(alias.child(), Count.class);
+ var eval = as(aggregate.child(), Eval.class);
+ assertThat(eval.fields(), hasSize(1));
+ var field = as(eval.fields().get(0), Alias.class);
+ assertThat(field.name(), is("x"));
+ var source = as(eval.child(), EsRelation.class);
+ }
+
+ public void testPruneUnusedAggSimple() {
+ var plan = plan("""
+ from test
+ | stats c = count(salary), max = max(salary), min = min(salary)
+ | keep c
+ """);
+
+ var limit = as(plan, Limit.class);
+ var agg = as(limit.child(), Aggregate.class);
+ assertThat(agg.groupings(), hasSize(0));
+ assertThat(agg.aggregates(), hasSize(1));
+ var aggOne = as(agg.aggregates().get(0), Alias.class);
+ assertThat(aggOne.name(), is("c"));
+ var count = as(aggOne.child(), Count.class);
+ var source = as(agg.child(), EsRelation.class);
+ }
+
+ public void testPruneUnusedAggMixedWithEval() {
+ var plan = plan("""
+ from test
+ | stats c = count(salary), max = max(salary), min = min(salary)
+ | eval x = c
+ | keep x
+ """);
+
+ var project = as(plan, Project.class);
+ var eval = as(project.child(), Eval.class);
+ var limit = as(eval.child(), Limit.class);
+ var agg = as(limit.child(), Aggregate.class);
+ assertThat(agg.groupings(), hasSize(0));
+ assertThat(agg.aggregates(), hasSize(1));
+ var aggOne = as(agg.aggregates().get(0), Alias.class);
+ assertThat(aggOne.name(), is("c"));
+ var count = as(aggOne.child(), Count.class);
+ var source = as(agg.child(), EsRelation.class);
+ }
+
+ public void testPruneUnusedAggsChainedAgg() {
+ var plan = plan("""
+ from test
+ | stats c = count(salary), max = max(salary), min = min(salary)
+ | eval x = max + min + c
+ | eval y = min
+ | eval z = c
+ | keep c
+ """);
+
+ var project = as(plan, Project.class);
+ var limit = as(project.child(), Limit.class);
+ var agg = as(limit.child(), Aggregate.class);
+ assertThat(agg.groupings(), hasSize(0));
+ var aggs = agg.aggregates();
+ assertThat(aggs, hasSize(1));
+ assertThat(Expressions.names(aggs), contains("c"));
+ var source = as(agg.child(), EsRelation.class);
+ }
+
+ public void testPruneMixedAggInsideUnusedEval() {
+ var plan = plan("""
+ from test
+ | stats c = count(salary), max = max(salary), min = min(salary)
+ | eval x = max + min + c
+ | eval y = min
+ | where y > 10
+ | eval z = c
+ | keep c
+ """);
+
+ var project = as(plan, Project.class);
+ var limit = as(project.child(), Limit.class);
+ var filter = as(limit.child(), Filter.class);
+ var eval = as(filter.child(), Eval.class);
+ var agg = as(eval.child(), Aggregate.class);
+ assertThat(agg.groupings(), hasSize(0));
+ var aggs = agg.aggregates();
+ assertThat(aggs, hasSize(2));
+ assertThat(Expressions.names(aggs), contains("c", "min"));
+ var source = as(agg.child(), EsRelation.class);
+ }
+
+ public void testNoPruningWhenDealingJustWithEvals() {
+ var plan = plan("""
+ from test
+ | stats c = count(salary), max = max(salary), min = min(salary)
+ | eval x = max + min + c
+ | eval y = min
+ | eval z = c
+ """);
+
+ var eval = as(plan, Eval.class);
+ eval = as(eval.child(), Eval.class);
+ eval = as(eval.child(), Eval.class);
+ var limit = as(eval.child(), Limit.class);
+ var agg = as(limit.child(), Aggregate.class);
+ }
+
+ public void testNoPruningWhenChainedEvals() {
+ var plan = plan("""
+ from test
+ | eval x = emp_no, y = x + 1, z = y
+ | keep z
+ """);
+
+ var project = as(plan, Project.class);
+ var eval = as(project.child(), Eval.class);
+ assertThat(Expressions.names(eval.fields()), contains("x", "y", "z"));
+ var limit = as(eval.child(), Limit.class);
+ var source = as(limit.child(), EsRelation.class);
+ }
+
+ public void testPruningDuplicateEvals() {
+ var plan = plan("""
+ from test
+ | eval x = emp_no, x = salary
+ | eval y = salary
+ | eval y = emp_no
+ | keep x, y
+ """);
+
+ var project = as(plan, Project.class);
+ var eval = as(project.child(), Eval.class);
+ assertThat(Expressions.names(eval.fields()), contains("y"));
+ eval = as(eval.child(), Eval.class);
+ assertThat(Expressions.names(eval.fields()), contains("x"));
+ var limit = as(eval.child(), Limit.class);
+ var source = as(limit.child(), EsRelation.class);
+ }
+
private LogicalPlan optimizedPlan(String query) {
return plan(query);
}
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java
index 709c62c0b0fb4..2eab81f02911d 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java
@@ -283,18 +283,13 @@ public void testTripleExtractorPerField() {
var extract = as(aggregate.child(), FieldExtractExec.class);
assertThat(names(extract.attributesToExtract()), contains("salary"));
- var eval = as(extract.child(), EvalExec.class);
-
- extract = as(eval.child(), FieldExtractExec.class);
- assertThat(names(extract.attributesToExtract()), contains("first_name"));
-
var filter = as(extract.child(), FilterExec.class);
extract = as(filter.child(), FieldExtractExec.class);
assertThat(names(extract.attributesToExtract()), contains("emp_no"));
var query = source(extract.child());
- // for doc ids, emp_no, salary, c, and first_name
- int estimatedSize = Integer.BYTES * 3 + KEYWORD_EST * 2;
+ // for doc ids, emp_no, salary
+ int estimatedSize = Integer.BYTES * 3;
assertThat(query.estimatedRowSize(), equalTo(estimatedSize));
}
@@ -303,13 +298,12 @@ public void testTripleExtractorPerField() {
* LimitExec[10000[INTEGER]]
* \_AggregateExec[[],[AVG(salary{f}#14) AS x],FINAL]
* \_AggregateExec[[],[AVG(salary{f}#14) AS x],PARTIAL]
- * \_EvalExec[[first_name{f}#10 AS c]]
- * \_FilterExec[ROUND(emp_no{f}#9) > 10[INTEGER]]
- * \_TopNExec[[Order[last_name{f}#13,ASC,LAST]],10[INTEGER]]
- * \_ExchangeExec[]
- * \_ProjectExec[[salary{f}#14, first_name{f}#10, emp_no{f}#9, last_name{f}#13]] -- project away _doc
- * \_FieldExtractExec[salary{f}#14, first_name{f}#10, emp_no{f}#9, last_n..] -- local field extraction
- * \_EsQueryExec[test], query[][_doc{f}#16], limit[10], sort[[last_name]]
+ * \_FilterExec[ROUND(emp_no{f}#9) > 10[INTEGER]]
+ * \_TopNExec[[Order[last_name{f}#13,ASC,LAST]],10[INTEGER]]
+ * \_ExchangeExec[]
+ * \_ProjectExec[[salary{f}#14, first_name{f}#10, emp_no{f}#9, last_name{f}#13]] -- project away _doc
+ * \_FieldExtractExec[salary{f}#14, first_name{f}#10, emp_no{f}#9, last_n..] -- local field extraction
+ * \_EsQueryExec[test], query[][_doc{f}#16], limit[10], sort[[last_name]]
*/
public void testExtractorForField() {
var plan = physicalPlan("""
@@ -327,14 +321,13 @@ public void testExtractorForField() {
assertThat(aggregateFinal.estimatedRowSize(), equalTo(Long.BYTES));
var aggregatePartial = as(aggregateFinal.child(), AggregateExec.class);
- var eval = as(aggregatePartial.child(), EvalExec.class);
- var filter = as(eval.child(), FilterExec.class);
+ var filter = as(aggregatePartial.child(), FilterExec.class);
var topN = as(filter.child(), TopNExec.class);
var exchange = asRemoteExchange(topN.child());
var project = as(exchange.child(), ProjectExec.class);
var extract = as(project.child(), FieldExtractExec.class);
- assertThat(names(extract.attributesToExtract()), contains("salary", "first_name", "emp_no", "last_name"));
+ assertThat(names(extract.attributesToExtract()), contains("salary", "emp_no", "last_name"));
var source = source(extract.child());
assertThat(source.limit(), is(topN.limit()));
assertThat(source.sorts(), is(sorts(topN.order())));
@@ -344,8 +337,8 @@ public void testExtractorForField() {
FieldSort order = source.sorts().get(0);
assertThat(order.direction(), is(ASC));
assertThat(name(order.field()), is("last_name"));
- // first and last name are keywords, salary, emp_no, doc id, segment, forwards and backwards doc id maps are all ints
- int estimatedSize = KEYWORD_EST * 2 + Integer.BYTES * 6;
+ // last name is keyword, salary, emp_no, doc id, segment, forwards and backwards doc id maps are all ints
+ int estimatedSize = KEYWORD_EST + Integer.BYTES * 6;
assertThat(source.estimatedRowSize(), equalTo(estimatedSize));
}
@@ -494,13 +487,11 @@ public void testExtractGroupingFieldsIfAggdWithEval() {
assertThat(aggregate.groupings(), hasSize(1));
assertThat(aggregate.estimatedRowSize(), equalTo(Long.BYTES + KEYWORD_EST));
- var eval = as(aggregate.child(), EvalExec.class);
- assertThat(names(eval.fields()), equalTo(List.of("g")));
- var extract = as(eval.child(), FieldExtractExec.class);
+ var extract = as(aggregate.child(), FieldExtractExec.class);
assertThat(names(extract.attributesToExtract()), equalTo(List.of("first_name")));
var source = source(extract.child());
- assertThat(source.estimatedRowSize(), equalTo(Integer.BYTES + KEYWORD_EST * 2));
+ assertThat(source.estimatedRowSize(), equalTo(Integer.BYTES + KEYWORD_EST));
}
public void testQueryWithAggregation() {
From 03344d359c9469556eb197c94e86e63173f92afb Mon Sep 17 00:00:00 2001
From: Tim Vernum
Date: Thu, 17 Aug 2023 11:56:54 +1000
Subject: [PATCH 05/21] Add YAML tests for Authorization using API Keys
(#98527)
Adds 2 new YAML tests that test authorization behaviour exclusively
using API Keys
1. Indexing
2. Field Level Security
---
.../authz_api_keys/10_index_authz.yml | 343 ++++++++++++++++++
.../20_field_level_security.yml | 113 ++++++
2 files changed, 456 insertions(+)
create mode 100644 x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/security/authz_api_keys/10_index_authz.yml
create mode 100644 x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/security/authz_api_keys/20_field_level_security.yml
diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/security/authz_api_keys/10_index_authz.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/security/authz_api_keys/10_index_authz.yml
new file mode 100644
index 0000000000000..c97317b1ac971
--- /dev/null
+++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/security/authz_api_keys/10_index_authz.yml
@@ -0,0 +1,343 @@
+---
+setup:
+ - skip:
+ features: headers
+
+ - do:
+ cluster.health:
+ wait_for_status: yellow
+
+ - do:
+ indices.create:
+ index: only_read
+ body:
+ mappings:
+ properties:
+ name:
+ type: "keyword"
+
+ - do:
+ indices.create:
+ index: only_create_doc
+ body:
+ mappings:
+ properties:
+ name:
+ type: "keyword"
+
+ - do:
+ indices.create:
+ index: only_index
+ body:
+ mappings:
+ properties:
+ name:
+ type: "keyword"
+
+ - do:
+ indices.create:
+ index: only_delete
+ body:
+ mappings:
+ properties:
+ name:
+ type: "keyword"
+
+ - do:
+ indices.create:
+ index: everything
+ body:
+ mappings:
+ properties:
+ name:
+ type: "keyword"
+
+---
+"Test indexing documents with API Key":
+ - do:
+ security.create_api_key:
+ body:
+ name: "test-index-access"
+ expiration: "1d"
+ role_descriptors:
+ index_access:
+ indices:
+ - names: [ "only_read" ]
+ privileges: [ "read" ]
+ - names: [ "only_create_doc" ]
+ privileges: [ "create_doc" ]
+ - names: [ "only_index" ]
+ privileges: [ "index" ]
+ - names: [ "only_delete" ]
+ privileges: [ "delete" ]
+ - names: [ "everything" ]
+ privileges: [ "all" ]
+ - match: { name: "test-index-access" }
+ - is_true: id
+ - set:
+ id: api_key_id
+ encoded: credentials
+
+ ###
+ # Successful indexing
+ ###
+
+ # document create
+ - do:
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ create:
+ id: "c1"
+ index: only_create_doc
+ body: >
+ {
+ "name" : "create-doc-1"
+ }
+
+ - do:
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ create:
+ id: "i1"
+ index: only_index
+ body: >
+ {
+ "name" : "index-doc-1"
+ }
+
+ - do:
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ create:
+ id: "e1"
+ index: everything
+ body: >
+ {
+ "name" : "everything-doc-1"
+ }
+
+ # document index
+ - do:
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ index:
+ # no "id" due to create_doc privilege
+ index: only_create_doc
+ body: >
+ {
+ "name" : "create-doc-2"
+ }
+
+ - do:
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ index:
+ id: "i2"
+ index: only_index
+ body: >
+ {
+ "name" : "index-doc-2"
+ }
+
+ - do:
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ create:
+ id: "e2"
+ index: everything
+ body: >
+ {
+ "name" : "everything-doc-2"
+ }
+
+ # bulk
+ - do:
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ bulk:
+ body:
+ - '{"create": {"_index": "only_create_doc", "_id": "c3"}}'
+ - '{"name": "create-doc-3"}'
+ - '{"index": {"_index": "only_index", "_id": "i3"}}'
+ - '{"name": "index-doc-3"}'
+ - '{"index": {"_index": "everything" }}'
+ - '{"name": "everything-doc-3"}'
+ - match: { errors: false }
+
+ - do:
+ indices.refresh:
+ index: only_create_doc,only_index,everything
+
+ - do:
+ search:
+ index: only_create_doc
+ - match: { hits.total.relation: "eq" }
+ - match: { hits.total.value: 3 }
+
+ - do:
+ search:
+ index: only_index
+ - match: { hits.total.value: 3 }
+ - match: { hits.total.relation: "eq" }
+
+ - do:
+ search:
+ index: everything
+ - match: { hits.total.value: 3 }
+ - match: { hits.total.relation: "eq" }
+
+ ###
+ # Authz failures
+ ###
+
+ # Error: Cannot create docs in an index with read only privileges
+ - do:
+ catch: forbidden
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ create:
+ id: "r1"
+ index: only_read
+ body: >
+ {
+ "name" : "read-doc-1"
+ }
+
+ # Error: Cannot index docs in an index with read only privileges
+ - do:
+ catch: forbidden
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ index:
+ id: "r2"
+ index: only_read
+ body: >
+ {
+ "name" : "read-doc-2"
+ }
+
+ # Error: Cannot create docs in an index with only delete privileges
+ - do:
+ catch: forbidden
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ create:
+ id: "d1"
+ index: only_delete
+ body: >
+ {
+ "name" : "delete-doc-1"
+ }
+
+ # Error: Cannot index docs in an index with only delete privileges
+ - do:
+ catch: forbidden
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ index:
+ index: only_delete
+ body: >
+ {
+ "name" : "delete-doc-2"
+ }
+
+ # Error: Cannot index docs (with an id) in an index with only create_doc privileges
+ - do:
+ catch: forbidden
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ index:
+ id: "c4"
+ index: only_create_doc
+ body: >
+ {
+ "name" : "create-doc-4"
+ }
+
+ # Error: Cannot update docs in an index with only create_doc privileges
+ - do:
+ catch: forbidden
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ update:
+ id: "c1"
+ index: only_create_doc
+ body: >
+ {
+ "doc": { "name" : "updated-create-doc-1" }
+ }
+
+ # Subset of the above, via bulk
+ - do:
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ bulk:
+ body:
+ - '{"index": {"_index": "only_read", "_id": "r3"}}'
+ - '{"name": "read-doc-3"}'
+ - '{"create": {"_index": "only_delete"}}'
+ - '{"name": "delete-doc-3"}'
+ - '{"update": {"_index": "only_create_doc", "_id": "c2"}}'
+ - '{"doc": {"name": "updated-create-doc-2"}}'
+ - match: { errors: true }
+ - match: { items.0.index.status: 403 }
+ - match: { items.0.index.error.type: "security_exception" }
+ - match: { items.1.create.status: 403 }
+ - match: { items.1.create.error.type: "security_exception" }
+ - match: { items.2.update.status: 403 }
+ - match: { items.2.update.error.type: "security_exception" }
+
+ - do:
+ indices.refresh:
+ index: only_create_doc,only_read,only_delete
+
+ - do:
+ search:
+ index: only_create_doc,only_read,only_delete
+ - match: { hits.total.relation: "eq" }
+ - match: { hits.total.value: 3 } # Existing docs
+
+ ###
+ # Mixed success / failure
+ ###
+
+ - do:
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ bulk:
+ body:
+ - '{"index": {"_index": "only_read", "_id": "r4"}}'
+ - '{"name": "read-doc-4"}'
+ - '{"index": {"_index": "only_index", "_id": "i4"}}'
+ - '{"name": "index-doc-4"}'
+ - '{"create": {"_index": "only_create_doc" }}'
+ - '{"name": "create-doc-5"}'
+ - match: { errors: true }
+ - match: { items.0.index.status: 403 }
+ - match: { items.0.index.error.type: "security_exception" }
+ - match: { items.1.index.status: 201 }
+ - match: { items.1.index._id: "i4" }
+ - match: { items.2.create.status: 201 }
+ - is_true: items.2.create._id
+
+ - do:
+ indices.refresh:
+ index: only_create_doc,only_read,only_index
+
+ - do:
+ search:
+ index: only_create_doc
+ - match: { hits.total.relation: "eq" }
+ - match: { hits.total.value: 4 } # 3 existing + 1 new
+
+ - do:
+ search:
+ index: only_read
+ - match: { hits.total.relation: "eq" }
+ - match: { hits.total.value: 0 }
+
+ - do:
+ search:
+ index: only_index
+ - match: { hits.total.relation: "eq" }
+ - match: { hits.total.value: 4 } # 3 existing + 1 new
diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/security/authz_api_keys/20_field_level_security.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/security/authz_api_keys/20_field_level_security.yml
new file mode 100644
index 0000000000000..f9872423c3bf1
--- /dev/null
+++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/security/authz_api_keys/20_field_level_security.yml
@@ -0,0 +1,113 @@
+---
+setup:
+ - skip:
+ features: headers
+
+ - do:
+ cluster.health:
+ wait_for_status: yellow
+
+ - do:
+ indices.create:
+ index: index_fls1
+ body:
+ mappings:
+ properties:
+ name:
+ type: "keyword"
+ secret:
+ type: "keyword"
+
+ - do:
+ indices.create:
+ index: index_fls2
+ body:
+ mappings:
+ properties:
+ name:
+ type: "keyword"
+ object:
+ type: "object"
+ properties:
+ secret:
+ type: keyword
+ public:
+ type: keyword
+---
+"Retrieve documents with FLS":
+
+ - do:
+ bulk:
+ refresh: true
+ body:
+ - '{"index": {"_index": "index_fls1", "_id": "1a" }}'
+ - '{"name": "i1_doc", "secret":"squirrel"}'
+ - '{"index": {"_index": "index_fls2", "_id": "2a"}}'
+ - '{"name": "i2_doc", "object":{ "secret":"mission", "public":"interest" }}'
+ - match: { errors: false }
+
+ - do:
+ security.create_api_key:
+ body:
+ name: "test-fls"
+ expiration: "1d"
+ role_descriptors:
+ index_access:
+ indices:
+ - names: [ "index_fls1" ]
+ privileges: [ "read" ]
+ field_security:
+ grant: [ "name" ]
+ - names: [ "index_fls2" ]
+ privileges: [ "read", "monitor" ]
+ field_security:
+ grant: [ "*" ]
+ except: [ "object.secret" ]
+ - match: { name: "test-fls" }
+ - is_true: id
+ - set:
+ id: api_key_id
+ encoded: credentials
+
+ # With superuser...
+ - do:
+ search:
+ index: index_fls1
+ - match: { hits.total.value: 1 }
+ - match: { hits.total.relation: "eq" }
+ - match: { hits.hits.0._source.name: "i1_doc" }
+ - is_true: "hits.hits.0._source.secret"
+ - match: { hits.hits.0._source.secret: "squirrel" }
+
+ # With FLS API Key
+ - do:
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ search:
+ index: index_fls1
+ - match: { hits.total.value: 1 }
+ - match: { hits.total.relation: "eq" }
+ - match: { hits.hits.0._source.name: "i1_doc" }
+ - is_false: "hits.hits.0._source.secret"
+
+
+ # With superuser...
+ - do:
+ get:
+ index: index_fls2
+ id: 2a
+ - match: { _source.name: "i2_doc" }
+ - match: { _source.object.secret: "mission" }
+ - match: { _source.object.public: "interest" }
+ - is_true: "_source.object.secret"
+
+ # With FLS API Key
+ - do:
+ headers:
+ Authorization: "ApiKey ${credentials}"
+ get:
+ index: index_fls2
+ id: 2a
+ - match: { _source.name: "i2_doc" }
+ - match: { _source.object.public: "interest" }
+ - is_false: "_source.object.secret"
From 00fe655ddc326f2fbb87d42890e4a15bbcbd42d0 Mon Sep 17 00:00:00 2001
From: Tim Vernum
Date: Thu, 17 Aug 2023 13:09:02 +1000
Subject: [PATCH 06/21] Mute JobNodeSelectorTests (#98554)
Relates: #98552
---
.../org/elasticsearch/xpack/ml/job/JobNodeSelectorTests.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/JobNodeSelectorTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/JobNodeSelectorTests.java
index be419e2d2497f..32a684097d601 100644
--- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/JobNodeSelectorTests.java
+++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/JobNodeSelectorTests.java
@@ -6,6 +6,7 @@
*/
package org.elasticsearch.xpack.ml.job;
+import org.apache.lucene.tests.util.LuceneTestCase;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterState;
@@ -58,6 +59,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+@LuceneTestCase.AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/98552")
public class JobNodeSelectorTests extends ESTestCase {
// To simplify the logic in this class all jobs have the same memory requirement
From 874fbbc2f05b201873edc21b5baa36753935296f Mon Sep 17 00:00:00 2001
From: William Brafford
Date: Thu, 17 Aug 2023 00:03:12 -0400
Subject: [PATCH 07/21] Add mappings version number to SystemIndexDescriptor
(#97934)
This PR adds a mappings version number to system index descriptor, which is intended to replace the use of Version to signal changes in the mappings for the descriptor. This value is required for managed system indices.
Previously, most of the system index descriptors automatically incremented their mapping version with each release, which meant that the mappings would stay up-to-date with any additive changes. Now, developers will need to increment the mapping version whenever there's a change.
* Add MappingsVersion inner class to SystemIndexDescriptor
* Add mappings version to metadata in all system index mappings
* Rename version meta key ('system' -> 'managed')
* Update mappings for ML indices if required
* Trigger ML index mappings updates based on new index mappings version.
---------
Co-authored-by: Ed Savage
---
.../ingest/geoip/IngestGeoIpPlugin.java | 2 +
.../AbstractFeatureMigrationIntegTest.java | 1 +
.../elasticsearch/http/SystemIndexRestIT.java | 1 +
.../system/indices/SystemIndicesQA.java | 1 +
.../indices/create/CreateSystemIndicesIT.java | 11 +--
.../aliases/NetNewSystemIndexAliasIT.java | 1 +
.../SystemIndexMappingUpdateServiceIT.java | 11 +--
.../indices/TestSystemIndexDescriptor.java | 2 +
.../indices/SystemIndexDescriptor.java | 92 ++++++++++++++++---
.../SystemIndexMappingUpdateService.java | 7 +-
.../SynonymsManagementAPIService.java | 2 +
.../tasks/TaskResultsService.java | 2 +
.../get/TransportGetAliasesActionTests.java | 2 +-
.../TransportCreateIndexActionTests.java | 10 +-
.../indices/resolve/ResolveIndexTests.java | 12 ++-
...ystemIndexMetadataUpgradeServiceTests.java | 12 ++-
.../indices/SystemIndexDescriptorTests.java | 91 +++++++++++++++++-
.../SystemIndexMappingUpdateServiceTests.java | 5 +-
.../core/async/AsyncTaskIndexService.java | 2 +
.../xpack/core/ml/MlConfigIndex.java | 10 +-
.../xpack/core/ml/MlMetaIndex.java | 10 +-
.../xpack/core/ml/MlStatsIndex.java | 9 +-
.../core/ml/annotations/AnnotationIndex.java | 12 ++-
.../persistence/InferenceIndexConstants.java | 10 +-
.../persistence/AnomalyDetectorsIndex.java | 5 +-
.../persistence/ElasticsearchMappings.java | 27 +++---
.../ml/notifications/NotificationsIndex.java | 6 +-
.../ElasticsearchMappingsTests.java | 91 ++++++++++++++----
.../security/test/TestRestrictedIndices.java | 1 +
.../main/resources/fleet-actions-results.json | 3 +-
.../src/main/resources/fleet-actions.json | 3 +-
.../src/main/resources/fleet-agents.json | 3 +-
.../src/main/resources/fleet-artifacts.json | 3 +-
.../resources/fleet-enrollment-api-keys.json | 3 +-
.../main/resources/fleet-policies-leader.json | 3 +-
.../src/main/resources/fleet-policies.json | 3 +-
.../src/main/resources/fleet-secrets.json | 3 +-
.../src/main/resources/fleet-servers.json | 3 +-
.../ml/annotations_index_mappings.json | 3 +-
.../results_index_mappings.json | 3 +-
.../resources/ml/config_index_mappings.json | 3 +-
.../ml/inference_index_mappings.json | 3 +-
.../resources/ml/meta_index_mappings.json | 3 +-
.../ml/notifications_index_mappings.json | 3 +-
.../resources/ml/stats_index_mappings.json | 3 +-
.../rules/QueryRulesIndexService.java | 2 +
.../search/SearchApplicationIndexService.java | 2 +
.../org/elasticsearch/xpack/fleet/Fleet.java | 39 +++++---
.../xpack/logstash/Logstash.java | 2 +
.../ml/action/TransportOpenJobAction.java | 3 +-
.../TransportPutDataFrameAnalyticsAction.java | 3 +-
.../TransportRevertModelSnapshotAction.java | 3 +-
...ansportUpdateDataFrameAnalyticsAction.java | 3 +-
...ransportUpgradeJobModelSnapshotAction.java | 3 +-
.../xpack/ml/datafeed/DatafeedManager.java | 6 +-
.../dataframe/DataFrameAnalyticsManager.java | 3 +-
.../inference/TrainedModelStatsService.java | 3 +-
.../xpack/ml/job/JobManager.java | 6 +-
.../autodetect/AutodetectProcessManager.java | 6 +-
.../upgrader/SnapshotUpgradeTaskExecutor.java | 6 +-
.../task/OpenJobPersistentTasksExecutor.java | 3 +-
.../SearchableSnapshots.java | 2 +
.../support/SecurityIndexManager.java | 2 +-
.../support/SecuritySystemIndices.java | 6 ++
.../persistence/TransformInternalIndex.java | 6 +-
.../elasticsearch/xpack/watcher/Watcher.java | 4 +
.../upgrades/MlMappingsUpgradeIT.java | 15 +++
67 files changed, 497 insertions(+), 127 deletions(-)
diff --git a/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/IngestGeoIpPlugin.java b/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/IngestGeoIpPlugin.java
index 988f1f1a4032c..03607b908d375 100644
--- a/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/IngestGeoIpPlugin.java
+++ b/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/IngestGeoIpPlugin.java
@@ -72,6 +72,7 @@
public class IngestGeoIpPlugin extends Plugin implements IngestPlugin, SystemIndexPlugin, Closeable, PersistentTaskPlugin, ActionPlugin {
public static final Setting CACHE_SIZE = Setting.longSetting("ingest.geoip.cache_size", 1000, 0, Setting.Property.NodeScope);
+ private static final int GEOIP_INDEX_MAPPINGS_VERSION = 1;
private final SetOnce ingestService = new SetOnce<>();
private final SetOnce databaseRegistry = new SetOnce<>();
@@ -222,6 +223,7 @@ private static XContentBuilder mappings() {
.startObject(SINGLE_MAPPING_NAME)
.startObject("_meta")
.field("version", Version.CURRENT)
+ .field(SystemIndexDescriptor.VERSION_META_KEY, GEOIP_INDEX_MAPPINGS_VERSION)
.endObject()
.field("dynamic", "strict")
.startObject("properties")
diff --git a/modules/reindex/src/internalClusterTest/java/org/elasticsearch/migration/AbstractFeatureMigrationIntegTest.java b/modules/reindex/src/internalClusterTest/java/org/elasticsearch/migration/AbstractFeatureMigrationIntegTest.java
index 212a96ff54ff3..a8e8e7bc935ee 100644
--- a/modules/reindex/src/internalClusterTest/java/org/elasticsearch/migration/AbstractFeatureMigrationIntegTest.java
+++ b/modules/reindex/src/internalClusterTest/java/org/elasticsearch/migration/AbstractFeatureMigrationIntegTest.java
@@ -209,6 +209,7 @@ static String createMapping(boolean descriptorManaged, boolean descriptorInterna
{
builder.startObject("_meta");
builder.field(VERSION_META_KEY, META_VERSION);
+ builder.field(SystemIndexDescriptor.VERSION_META_KEY, 1);
builder.field(DESCRIPTOR_MANAGED_META_KEY, descriptorManaged);
builder.field(DESCRIPTOR_INTERNAL_META_KEY, descriptorInternal);
builder.endObject();
diff --git a/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/SystemIndexRestIT.java b/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/SystemIndexRestIT.java
index 9847534c1c042..7d0095dd81f63 100644
--- a/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/SystemIndexRestIT.java
+++ b/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/SystemIndexRestIT.java
@@ -169,6 +169,7 @@ public Collection getSystemIndexDescriptors(Settings sett
{
builder.startObject("_meta");
builder.field("version", Version.CURRENT.toString());
+ builder.field(SystemIndexDescriptor.VERSION_META_KEY, 1);
builder.endObject();
builder.field("dynamic", "strict");
diff --git a/qa/system-indices/src/main/java/org/elasticsearch/system/indices/SystemIndicesQA.java b/qa/system-indices/src/main/java/org/elasticsearch/system/indices/SystemIndicesQA.java
index f55b350520106..d4b242e613c95 100644
--- a/qa/system-indices/src/main/java/org/elasticsearch/system/indices/SystemIndicesQA.java
+++ b/qa/system-indices/src/main/java/org/elasticsearch/system/indices/SystemIndicesQA.java
@@ -111,6 +111,7 @@ private static XContentBuilder mappings() {
.startObject(SINGLE_MAPPING_NAME)
.startObject("_meta")
.field("version", Version.CURRENT)
+ .field(SystemIndexDescriptor.VERSION_META_KEY, 1)
.endObject()
.field("dynamic", "strict")
.startObject("properties")
diff --git a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/CreateSystemIndicesIT.java b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/CreateSystemIndicesIT.java
index f36c2aae7f8ad..f5a2121b2dde9 100644
--- a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/CreateSystemIndicesIT.java
+++ b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/CreateSystemIndicesIT.java
@@ -29,6 +29,7 @@
import org.elasticsearch.cluster.metadata.Template;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.CollectionUtils;
+import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.indices.TestSystemIndexDescriptor;
import org.elasticsearch.indices.TestSystemIndexDescriptorAllowsTemplates;
import org.elasticsearch.indices.TestSystemIndexPlugin;
@@ -38,8 +39,6 @@
import org.junit.After;
import org.junit.Before;
-import java.io.IOException;
-import java.io.UncheckedIOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -51,7 +50,6 @@
import static org.elasticsearch.indices.TestSystemIndexDescriptor.INDEX_NAME;
import static org.elasticsearch.indices.TestSystemIndexDescriptor.PRIMARY_INDEX_NAME;
-import static org.elasticsearch.test.XContentTestUtils.convertToXContent;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
@@ -352,7 +350,6 @@ private void assertHasAliases(Set aliasNames, String name, String primar
/**
* Fetch the mappings and settings for {@link TestSystemIndexDescriptor#INDEX_NAME} and verify that they match the expected values.
- * Note that in the case of the mappings, this is just a dumb string comparison, so order of keys matters.
*/
private void assertMappingsAndSettings(String expectedMappings, String concreteIndex) {
final GetMappingsResponse getMappingsResponse = indicesAdmin().getMappings(new GetMappingsRequest().indices(INDEX_NAME))
@@ -366,11 +363,7 @@ private void assertMappingsAndSettings(String expectedMappings, String concreteI
);
final Map sourceAsMap = mappings.get(concreteIndex).getSourceAsMap();
- try {
- assertThat(convertToXContent(sourceAsMap, XContentType.JSON).utf8ToString(), equalTo(expectedMappings));
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
+ assertThat(sourceAsMap, equalTo(XContentHelper.convertToMap(XContentType.JSON.xContent(), expectedMappings, false)));
final GetSettingsResponse getSettingsResponse = indicesAdmin().getSettings(new GetSettingsRequest().indices(INDEX_NAME))
.actionGet();
diff --git a/server/src/internalClusterTest/java/org/elasticsearch/aliases/NetNewSystemIndexAliasIT.java b/server/src/internalClusterTest/java/org/elasticsearch/aliases/NetNewSystemIndexAliasIT.java
index 9f2a9d3a48162..105e9f5ec91f0 100644
--- a/server/src/internalClusterTest/java/org/elasticsearch/aliases/NetNewSystemIndexAliasIT.java
+++ b/server/src/internalClusterTest/java/org/elasticsearch/aliases/NetNewSystemIndexAliasIT.java
@@ -68,6 +68,7 @@ public Collection getSystemIndexDescriptors(Settings sett
{
builder.startObject("_meta");
builder.field("version", Version.CURRENT.toString());
+ builder.field(SystemIndexDescriptor.VERSION_META_KEY, 1);
builder.endObject();
builder.field("dynamic", "strict");
diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indices/SystemIndexMappingUpdateServiceIT.java b/server/src/internalClusterTest/java/org/elasticsearch/indices/SystemIndexMappingUpdateServiceIT.java
index 279f56f33c1a7..486aa8d1f5084 100644
--- a/server/src/internalClusterTest/java/org/elasticsearch/indices/SystemIndexMappingUpdateServiceIT.java
+++ b/server/src/internalClusterTest/java/org/elasticsearch/indices/SystemIndexMappingUpdateServiceIT.java
@@ -17,13 +17,12 @@
import org.elasticsearch.cluster.metadata.MappingMetadata;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.CollectionUtils;
+import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.xcontent.XContentType;
import org.junit.Before;
-import java.io.IOException;
-import java.io.UncheckedIOException;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
@@ -31,7 +30,6 @@
import static org.elasticsearch.indices.TestSystemIndexDescriptor.INDEX_NAME;
import static org.elasticsearch.indices.TestSystemIndexDescriptor.PRIMARY_INDEX_NAME;
-import static org.elasticsearch.test.XContentTestUtils.convertToXContent;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.hamcrest.Matchers.equalTo;
@@ -122,7 +120,6 @@ private void triggerClusterStateUpdates() {
/**
* Fetch the mappings and settings for {@link TestSystemIndexDescriptor#INDEX_NAME} and verify that they match the expected values.
- * Note that in the case of the mappings, this is just a dumb string comparison, so order of keys matters.
*/
private void assertMappingsAndSettings(String expectedMappings) {
final GetMappingsResponse getMappingsResponse = indicesAdmin().getMappings(new GetMappingsRequest().indices(INDEX_NAME))
@@ -136,11 +133,7 @@ private void assertMappingsAndSettings(String expectedMappings) {
);
final Map sourceAsMap = mappings.get(PRIMARY_INDEX_NAME).getSourceAsMap();
- try {
- assertThat(convertToXContent(sourceAsMap, XContentType.JSON).utf8ToString(), equalTo(expectedMappings));
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
+ assertThat(sourceAsMap, equalTo(XContentHelper.convertToMap(XContentType.JSON.xContent(), expectedMappings, false)));
final GetSettingsResponse getSettingsResponse = indicesAdmin().getSettings(new GetSettingsRequest().indices(INDEX_NAME))
.actionGet();
diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indices/TestSystemIndexDescriptor.java b/server/src/internalClusterTest/java/org/elasticsearch/indices/TestSystemIndexDescriptor.java
index 58830f978ee30..0a090fa889a29 100644
--- a/server/src/internalClusterTest/java/org/elasticsearch/indices/TestSystemIndexDescriptor.java
+++ b/server/src/internalClusterTest/java/org/elasticsearch/indices/TestSystemIndexDescriptor.java
@@ -97,6 +97,7 @@ public static String getOldMappings() {
builder.startObject();
{
builder.startObject("_meta");
+ builder.field(SystemIndexDescriptor.VERSION_META_KEY, 0);
builder.field("version", Version.CURRENT.previousMajor().toString());
builder.endObject();
@@ -123,6 +124,7 @@ public static String getNewMappings() {
builder.startObject();
{
builder.startObject("_meta");
+ builder.field(SystemIndexDescriptor.VERSION_META_KEY, 1);
builder.field("version", Version.CURRENT.toString());
builder.endObject();
diff --git a/server/src/main/java/org/elasticsearch/indices/SystemIndexDescriptor.java b/server/src/main/java/org/elasticsearch/indices/SystemIndexDescriptor.java
index fdccfa72d785f..4d37cea8bcf98 100644
--- a/server/src/main/java/org/elasticsearch/indices/SystemIndexDescriptor.java
+++ b/server/src/main/java/org/elasticsearch/indices/SystemIndexDescriptor.java
@@ -12,6 +12,8 @@
import org.apache.lucene.util.automaton.CharacterRunAutomaton;
import org.apache.lucene.util.automaton.Operations;
import org.elasticsearch.Version;
+import org.elasticsearch.action.admin.indices.create.AutoCreateAction;
+import org.elasticsearch.action.admin.indices.create.TransportCreateIndexAction;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.Metadata;
import org.elasticsearch.cluster.metadata.SystemIndexMetadataUpgradeService;
@@ -130,9 +132,13 @@ public class SystemIndexDescriptor implements IndexPatternMatcher, Comparable_meta in the index mappings
- * that contains the index's mappings' version.
+ * that contains the index's mappings' {@link Version}. We need to read and write this field for
+ * backwards compatibility.
*/
- private final String versionMetaKey;
+ private final String mappingsNodeVersionMetaKey;
+
+ /** The version meta key for the integer system index mapping version */
+ public static final String VERSION_META_KEY = "managed_index_mappings_version";
/** For internally-managed indices, specifies the origin to use when creating or updating the index */
private final String origin;
@@ -140,8 +146,11 @@ public class SystemIndexDescriptor implements IndexPatternMatcher, Comparable_meta where a version can be found, which indicates the
+ * @param mappingsNodeVersionMetaKey a mapping key under _meta
where a version can be found, which indicates the
* Elasticsearch version when the index was created.
* @param origin the client origin to use when creating this index. Internal system indices must not provide an origin, while external
* system indices must do so.
@@ -209,7 +218,7 @@ protected SystemIndexDescriptor(
Settings settings,
String aliasName,
int indexFormat,
- String versionMetaKey,
+ String mappingsNodeVersionMetaKey,
String origin,
Version minimumNodeVersion,
Type type,
@@ -262,18 +271,22 @@ protected SystemIndexDescriptor(
Objects.requireNonNull(settings, "Must supply settings for a managed system index");
Strings.requireNonEmpty(mappings, "Must supply mappings for a managed system index");
Strings.requireNonEmpty(primaryIndex, "Must supply primaryIndex for a managed system index");
- Strings.requireNonEmpty(versionMetaKey, "Must supply versionMetaKey for a managed system index");
+ Strings.requireNonEmpty(mappingsNodeVersionMetaKey, "Must supply nodeVersionMetaKey for a managed system index");
Strings.requireNonEmpty(origin, "Must supply origin for a managed system index");
if (settings.getAsInt(IndexMetadata.INDEX_FORMAT_SETTING.getKey(), 0) != indexFormat) {
throw new IllegalArgumentException("Descriptor index format does not match index format in managed settings");
}
- this.mappingVersion = extractVersionFromMappings(mappings, versionMetaKey);
+ this.mappingsNodeVersion = extractNodeVersionFromMappings(mappings, mappingsNodeVersionMetaKey);
+ this.mappingsVersion = extractVersionFromMappings(mappings);
+ assert mappingsVersion.version >= 0 : "The mappings version must not be negative";
+
} else {
assert Objects.isNull(settings) : "Unmanaged index descriptors should not have settings";
assert Objects.isNull(mappings) : "Unmanaged index descriptors should not have mappings";
assert Objects.isNull(primaryIndex) : "Unmanaged index descriptors should not have a primary index";
- assert Objects.isNull(versionMetaKey) : "Unmanaged index descriptors should not have a version meta key";
- this.mappingVersion = null;
+ assert Objects.isNull(mappingsNodeVersionMetaKey) : "Unmanaged index descriptors should not have a version meta key";
+ this.mappingsNodeVersion = null;
+ this.mappingsVersion = null;
}
Objects.requireNonNull(allowedElasticProductOrigins, "allowedProductOrigins must not be null");
@@ -355,7 +368,7 @@ protected SystemIndexDescriptor(
throw new IllegalArgumentException("System indices must have " + IndexMetadata.SETTING_INDEX_HIDDEN + " set to true.");
}
this.indexFormat = indexFormat;
- this.versionMetaKey = versionMetaKey;
+ this.mappingsNodeVersionMetaKey = mappingsNodeVersionMetaKey;
this.origin = origin;
this.minimumNodeVersion = minimumNodeVersion;
this.type = type;
@@ -450,9 +463,9 @@ public int getIndexFormat() {
return this.indexFormat;
}
- public String getVersionMetaKey() {
+ public String getMappingsNodeVersionMetaKey() {
assert isAutomaticallyManaged() : "Do not request version meta keys for unmanaged system indices";
- return this.versionMetaKey;
+ return this.mappingsNodeVersionMetaKey;
}
public Version getMinimumNodeVersion() {
@@ -506,11 +519,23 @@ public boolean allowsTemplates() {
return allowsTemplates;
}
- public Version getMappingVersion() {
+ /**
+ * Use of the mappings {@link Version} should be replaced with the value returned from {@link #getMappingsVersion()}
+ * @return Elasticsearch version associated with this descriptor's mappings.
+ */
+ @Deprecated
+ public Version getMappingsNodeVersion() {
+ if (isAutomaticallyManaged() == false) {
+ throw new IllegalStateException(this + " is not managed so there are no mappings or version");
+ }
+ return mappingsNodeVersion;
+ }
+
+ public MappingsVersion getMappingsVersion() {
if (isAutomaticallyManaged() == false) {
throw new IllegalStateException(this + " is not managed so there are no mappings or version");
}
- return mappingVersion;
+ return mappingsVersion;
}
/**
@@ -612,6 +637,20 @@ public boolean isInternal() {
}
}
+ /**
+ * The version of the mapping, which should be stored as an int in a mapping metadata
+ * field. This will be used with prior index descriptors to determine which mappings
+ * should be used when creating a system index, and it will be used to determine when
+ * mappings should be updated with the latest mappings from the system index descriptor.
+ * See {@link SystemIndexMappingUpdateService}, {@link TransportCreateIndexAction},
+ * and {@link AutoCreateAction}.
+ *
+ * Version should be a non-negative integer for a managed index, or -1 for unmanaged indices.
+ * The hash is a hash of the system index descriptor's mappings so that we can warn
+ * in case of inconsistencies across nodes.
+ */
+ public record MappingsVersion(int version, int hash) {};
+
/**
* Provides a fluent API for building a {@link SystemIndexDescriptor}. Validation still happens in that class.
*/
@@ -818,8 +857,31 @@ static boolean findDynamicMapping(Map map) {
return false;
}
+ @SuppressWarnings("unchecked") // we do a lot of casting of maps
+ private static MappingsVersion extractVersionFromMappings(String mappings) {
+ final Map mappingsMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), mappings, true);
+ final Map doc = (Map) mappingsMap.get("_doc");
+ final Map meta;
+ final Map properties;
+ if (doc == null) {
+ meta = (Map) mappingsMap.get("_meta");
+ properties = (Map) mappingsMap.get("properties");
+ } else {
+ meta = (Map) doc.get("_meta");
+ properties = (Map) doc.get("properties");
+ }
+ if (meta == null) {
+ throw new IllegalStateException("mappings do not have _meta field");
+ }
+ final Integer value = (Integer) meta.get(VERSION_META_KEY);
+ if (value == null) {
+ throw new IllegalArgumentException("mappings do not have a version in _meta." + VERSION_META_KEY);
+ }
+ return new MappingsVersion(value, Objects.hash(properties));
+ }
+
@SuppressWarnings("unchecked")
- private static Version extractVersionFromMappings(String mappings, String versionMetaKey) {
+ private static Version extractNodeVersionFromMappings(String mappings, String versionMetaKey) {
final Map mappingsMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), mappings, false);
final Map doc = (Map) mappingsMap.get("_doc");
final Map meta;
diff --git a/server/src/main/java/org/elasticsearch/indices/SystemIndexMappingUpdateService.java b/server/src/main/java/org/elasticsearch/indices/SystemIndexMappingUpdateService.java
index d5f4d32914179..d1f8acfccc0ac 100644
--- a/server/src/main/java/org/elasticsearch/indices/SystemIndexMappingUpdateService.java
+++ b/server/src/main/java/org/elasticsearch/indices/SystemIndexMappingUpdateService.java
@@ -289,7 +289,7 @@ private static Version readMappingVersion(SystemIndexDescriptor descriptor, Mapp
return Version.V_EMPTY;
}
- final Object rawVersion = meta.get(descriptor.getVersionMetaKey());
+ final Object rawVersion = meta.get(descriptor.getMappingsNodeVersionMetaKey());
if (rawVersion instanceof Integer) {
// This can happen with old system indices, such as .tasks, which were created before we used an Elasticsearch
// version here. We should just replace the template to be sure.
@@ -297,7 +297,10 @@ private static Version readMappingVersion(SystemIndexDescriptor descriptor, Mapp
}
final String versionString = rawVersion != null ? rawVersion.toString() : null;
if (versionString == null) {
- logger.warn("No value found in mappings for [_meta.{}], assuming mappings update required", descriptor.getVersionMetaKey());
+ logger.warn(
+ "No value found in mappings for [_meta.{}], assuming mappings update required",
+ descriptor.getMappingsNodeVersionMetaKey()
+ );
// If we called `Version.fromString(null)`, it would return `Version.CURRENT` and we wouldn't update the mappings
return Version.V_EMPTY;
}
diff --git a/server/src/main/java/org/elasticsearch/synonyms/SynonymsManagementAPIService.java b/server/src/main/java/org/elasticsearch/synonyms/SynonymsManagementAPIService.java
index b4f84f2fdd1db..848f103aaaf56 100644
--- a/server/src/main/java/org/elasticsearch/synonyms/SynonymsManagementAPIService.java
+++ b/server/src/main/java/org/elasticsearch/synonyms/SynonymsManagementAPIService.java
@@ -81,6 +81,7 @@ public class SynonymsManagementAPIService {
public static final int MAX_SYNONYMS_SETS = 10_000;
private static final String SYNONYM_RULE_ID_FIELD = SynonymRule.ID_FIELD.getPreferredName();
private static final String SYNONYM_SETS_AGG_NAME = "synonym_sets_aggr";
+ private static final int SYNONYMS_INDEX_MAPPINGS_VERSION = 1;
private final Client client;
@@ -123,6 +124,7 @@ private static XContentBuilder mappings() {
builder.startObject("_meta");
{
builder.field("version", Version.CURRENT.toString());
+ builder.field(SystemIndexDescriptor.VERSION_META_KEY, SYNONYMS_INDEX_MAPPINGS_VERSION);
}
builder.endObject();
builder.field("dynamic", "strict");
diff --git a/server/src/main/java/org/elasticsearch/tasks/TaskResultsService.java b/server/src/main/java/org/elasticsearch/tasks/TaskResultsService.java
index d4f4058e358cb..1e42417aa2471 100644
--- a/server/src/main/java/org/elasticsearch/tasks/TaskResultsService.java
+++ b/server/src/main/java/org/elasticsearch/tasks/TaskResultsService.java
@@ -66,6 +66,7 @@ public class TaskResultsService {
* time is 600000 milliseconds, ten minutes.
*/
static final BackoffPolicy STORE_BACKOFF_POLICY = BackoffPolicy.exponentialBackoff(timeValueMillis(250), 14);
+ private static final int TASK_RESULTS_INDEX_MAPPINGS_VERSION = 0;
private final Client client;
@@ -124,6 +125,7 @@ private static XContentBuilder getTaskResultIndexMappings() {
{
builder.startObject("_meta");
builder.field(TASK_RESULT_MAPPING_VERSION_META_FIELD, Version.CURRENT.toString());
+ builder.field(SystemIndexDescriptor.VERSION_META_KEY, TASK_RESULTS_INDEX_MAPPINGS_VERSION);
builder.endObject();
builder.field("dynamic", "strict");
diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesActionTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesActionTests.java
index 2919fd83a446f..6ebdb2729765e 100644
--- a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesActionTests.java
+++ b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesActionTests.java
@@ -274,7 +274,7 @@ public void testNetNewSystemIndicesDontErrorWhenNotRequested() {
.setAliasName(".y")
.setPrimaryIndex(".b")
.setDescription(this.getTestName())
- .setMappings("{\"_meta\": {\"version\": \"1.0.0\"}}")
+ .setMappings("{\"_meta\": {\"version\": \"1.0.0\", \"" + SystemIndexDescriptor.VERSION_META_KEY + "\": 0}}")
.setSettings(Settings.EMPTY)
.setVersionMetaKey("version")
.setOrigin(this.getTestName())
diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/create/TransportCreateIndexActionTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/create/TransportCreateIndexActionTests.java
index 5ccb7900d7ff2..671bf13fb0e77 100644
--- a/server/src/test/java/org/elasticsearch/action/admin/indices/create/TransportCreateIndexActionTests.java
+++ b/server/src/test/java/org/elasticsearch/action/admin/indices/create/TransportCreateIndexActionTests.java
@@ -30,6 +30,7 @@
import org.mockito.ArgumentCaptor;
import java.util.List;
+import java.util.Locale;
import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_INDEX_HIDDEN;
import static org.hamcrest.Matchers.equalTo;
@@ -63,7 +64,14 @@ public class TransportCreateIndexActionTests extends ESTestCase {
.setPrimaryIndex(MANAGED_SYSTEM_INDEX_NAME + "-primary")
.setType(SystemIndexDescriptor.Type.INTERNAL_MANAGED)
.setSettings(SystemIndexDescriptor.DEFAULT_SETTINGS)
- .setMappings("{\"_meta\": {\"version\": \"1.0.0\"}}")
+ .setMappings(String.format(Locale.ROOT, """
+ {
+ "_meta": {
+ "version": "1.0.0",
+ "%s": 0
+ }
+ }"
+ """, SystemIndexDescriptor.VERSION_META_KEY))
.setVersionMetaKey("version")
.setOrigin("origin")
.build()
diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/resolve/ResolveIndexTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/resolve/ResolveIndexTests.java
index 2f82ceb679179..45a21c13f5861 100644
--- a/server/src/test/java/org/elasticsearch/action/admin/indices/resolve/ResolveIndexTests.java
+++ b/server/src/test/java/org/elasticsearch/action/admin/indices/resolve/ResolveIndexTests.java
@@ -43,6 +43,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@@ -512,7 +513,16 @@ private SystemIndices addSystemIndex(Metadata.Builder mdBuilder) {
.setAllowedElasticProductOrigins(List.of("test-net-new-system"))
.setNetNew()
.setSettings(Settings.EMPTY)
- .setMappings("{ \"_doc\": { \"_meta\": { \"version\": \"8.0.0\" } } }")
+ .setMappings(String.format(Locale.ROOT, """
+ {
+ "_doc": {
+ "_meta": {
+ "version": "8.0.0",
+ "%s": 1
+ }
+ }
+ }
+ """, SystemIndexDescriptor.VERSION_META_KEY))
.setPrimaryIndex(".test-net-new-system-1")
.setVersionMetaKey("version")
.setOrigin("system")
diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/SystemIndexMetadataUpgradeServiceTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/SystemIndexMetadataUpgradeServiceTests.java
index 9b4307aae9c3e..bfdef69a5275a 100644
--- a/server/src/test/java/org/elasticsearch/cluster/metadata/SystemIndexMetadataUpgradeServiceTests.java
+++ b/server/src/test/java/org/elasticsearch/cluster/metadata/SystemIndexMetadataUpgradeServiceTests.java
@@ -19,6 +19,7 @@
import org.junit.Before;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;
@@ -26,7 +27,16 @@
public class SystemIndexMetadataUpgradeServiceTests extends ESTestCase {
- private static final String MAPPINGS = "{ \"_doc\": { \"_meta\": { \"version\": \"7.4.0\" } } }";
+ private static final String MAPPINGS = String.format(Locale.ROOT, """
+ {
+ "_doc": {
+ "_meta": {
+ "version": "7.4.0",
+ "%s": 0
+ }
+ }
+ }
+ """, SystemIndexDescriptor.VERSION_META_KEY);
private static final String SYSTEM_INDEX_NAME = ".myindex-1";
private static final String SYSTEM_ALIAS_NAME = ".myindex-alias";
private static final SystemIndexDescriptor DESCRIPTOR = SystemIndexDescriptor.builder()
diff --git a/server/src/test/java/org/elasticsearch/indices/SystemIndexDescriptorTests.java b/server/src/test/java/org/elasticsearch/indices/SystemIndexDescriptorTests.java
index 71239af291ada..7a651dea0c878 100644
--- a/server/src/test/java/org/elasticsearch/indices/SystemIndexDescriptorTests.java
+++ b/server/src/test/java/org/elasticsearch/indices/SystemIndexDescriptorTests.java
@@ -19,15 +19,26 @@
import org.elasticsearch.xcontent.json.JsonXContent;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import static org.elasticsearch.indices.SystemIndexDescriptor.findDynamicMapping;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.not;
public class SystemIndexDescriptorTests extends ESTestCase {
- private static final String MAPPINGS = "{ \"_doc\": { \"_meta\": { \"version\": \"7.4.0\" } } }";
+ private static final String MAPPINGS = String.format(Locale.ROOT, """
+ {
+ "_doc": {
+ "_meta": {
+ "version": "7.4.0",
+ "%s": 1
+ }
+ }
+ }
+ """, SystemIndexDescriptor.VERSION_META_KEY);
/**
* Tests the various validation rules that are applied when creating a new system index descriptor.
@@ -243,7 +254,6 @@ public void testPriorSystemIndexDescriptorValidation() {
}
public void testGetDescriptorCompatibleWith() {
- final String mappings = "{ \"_doc\": { \"_meta\": { \"version\": \"7.4.0\" } } }";
final SystemIndexDescriptor prior = SystemIndexDescriptor.builder()
.setIndexPattern(".system*")
.setDescription("system stuff")
@@ -251,7 +261,7 @@ public void testGetDescriptorCompatibleWith() {
.setAliasName(".system")
.setType(Type.INTERNAL_MANAGED)
.setSettings(Settings.EMPTY)
- .setMappings(mappings)
+ .setMappings(MAPPINGS)
.setVersionMetaKey("version")
.setOrigin("system")
.setMinimumNodeVersion(Version.V_7_0_0)
@@ -263,7 +273,7 @@ public void testGetDescriptorCompatibleWith() {
.setAliasName(".system")
.setType(Type.INTERNAL_MANAGED)
.setSettings(Settings.EMPTY)
- .setMappings(mappings)
+ .setMappings(MAPPINGS)
.setVersionMetaKey("version")
.setOrigin("system")
.setPriorSystemIndexDescriptors(List.of(prior))
@@ -343,6 +353,79 @@ public void testManagedSystemIndexMustHaveMatchingIndexFormat() {
assertThat(e.getMessage(), equalTo("Descriptor index format does not match index format in managed settings"));
}
+ public void testUnmanagedIndexMappingsVersion() {
+ SystemIndexDescriptor indexDescriptor = SystemIndexDescriptor.builder()
+ .setIndexPattern(".unmanaged-*")
+ .setDescription("an unmanaged system index")
+ .setType(Type.INTERNAL_UNMANAGED)
+ .build();
+
+ IllegalStateException e = expectThrows(IllegalStateException.class, indexDescriptor::getMappingsVersion);
+
+ assertThat(e.getMessage(), containsString("is not managed so there are no mappings or version"));
+ }
+
+ // test mapping versions can't be negative
+ public void testNegativeMappingsVersion() {
+ int negativeVersion = randomIntBetween(Integer.MIN_VALUE, -1);
+ String mappings = String.format(Locale.ROOT, """
+ {
+ "_doc": {
+ "_meta": {
+ "version": "7.4.0",
+ "%s": %d
+ }
+ }
+ }
+ """, SystemIndexDescriptor.VERSION_META_KEY, negativeVersion);
+
+ SystemIndexDescriptor.Builder builder = priorSystemIndexDescriptorBuilder().setMappings(mappings);
+
+ AssertionError e = expectThrows(AssertionError.class, builder::build);
+
+ assertThat(e.getMessage(), equalTo("The mappings version must not be negative"));
+ }
+
+ public void testHashesIgnoreMappingMetadata() {
+ String mappingFormatString = """
+ {
+ "_doc": {
+ "_meta": {
+ "version": "%s",
+ "%s": %d
+ }
+ },
+ "properties": {
+ "age": { "type": "integer" },
+ "email": { "type": "keyword" },
+ "name": { "type": "text" }
+ }
+ }
+ """;
+
+ String mappings1 = String.format(
+ Locale.ROOT,
+ mappingFormatString,
+ "8.9.0",
+ SystemIndexDescriptor.VERSION_META_KEY,
+ randomIntBetween(1, 10)
+ );
+ String mappings2 = String.format(
+ Locale.ROOT,
+ mappingFormatString,
+ "8.10.0",
+ SystemIndexDescriptor.VERSION_META_KEY,
+ randomIntBetween(11, 20)
+ );
+
+ SystemIndexDescriptor descriptor1 = priorSystemIndexDescriptorBuilder().setMappings(mappings1).build();
+ SystemIndexDescriptor descriptor2 = priorSystemIndexDescriptorBuilder().setMappings(mappings2).build();
+
+ assertThat(descriptor1.getMappingsVersion().hash(), equalTo(descriptor2.getMappingsVersion().hash()));
+ assertThat(descriptor1.getMappingsVersion().version(), not(equalTo(descriptor2.getMappingsVersion().version())));
+ assertThat(descriptor1.getMappingsNodeVersion(), not(equalTo(descriptor2.getMappingsNodeVersion())));
+ }
+
private SystemIndexDescriptor.Builder priorSystemIndexDescriptorBuilder() {
return SystemIndexDescriptor.builder()
.setIndexPattern(".system*")
diff --git a/server/src/test/java/org/elasticsearch/indices/SystemIndexMappingUpdateServiceTests.java b/server/src/test/java/org/elasticsearch/indices/SystemIndexMappingUpdateServiceTests.java
index 330615aae93f5..b3492b203d354 100644
--- a/server/src/test/java/org/elasticsearch/indices/SystemIndexMappingUpdateServiceTests.java
+++ b/server/src/test/java/org/elasticsearch/indices/SystemIndexMappingUpdateServiceTests.java
@@ -409,7 +409,10 @@ private static XContentBuilder getMappings() {
}
private static XContentBuilder getMappings(String version) {
- return getMappings(builder -> builder.object("_meta", meta -> meta.field("version", version)));
+ return getMappings(builder -> builder.object("_meta", meta -> {
+ meta.field("version", version);
+ meta.field(SystemIndexDescriptor.VERSION_META_KEY, 5);
+ }));
}
// Prior to 7.12.0, .tasks had _meta.version: 3 so we need to be sure we can handle that
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/async/AsyncTaskIndexService.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/async/AsyncTaskIndexService.java
index 4e7a2416c4860..be6c1a29bcc6f 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/async/AsyncTaskIndexService.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/async/AsyncTaskIndexService.java
@@ -88,6 +88,7 @@ public final class AsyncTaskIndexService> {
public static final String RESPONSE_HEADERS_FIELD = "response_headers";
public static final String EXPIRATION_TIME_FIELD = "expiration_time";
public static final String RESULT_FIELD = "result";
+ private static final int ASYNC_TASK_INDEX_MAPPINGS_VERSION = 0;
// Usually the settings, mappings and system index descriptor below
// would be co-located with the SystemIndexPlugin implementation,
@@ -110,6 +111,7 @@ private static XContentBuilder mappings() {
.startObject(SINGLE_MAPPING_NAME)
.startObject("_meta")
.field("version", Version.CURRENT)
+ .field(SystemIndexDescriptor.VERSION_META_KEY, ASYNC_TASK_INDEX_MAPPINGS_VERSION)
.endObject()
.field("dynamic", "strict")
.startObject("properties")
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/MlConfigIndex.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/MlConfigIndex.java
index 2499734672053..da905ef5efdee 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/MlConfigIndex.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/MlConfigIndex.java
@@ -12,12 +12,15 @@
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.xpack.core.template.TemplateUtils;
+import java.util.Map;
+
public final class MlConfigIndex {
private static final String INDEX_NAME = ".ml-config";
private static final String MAPPINGS_VERSION_VARIABLE = "xpack.ml.version";
public static final int CONFIG_INDEX_MAX_RESULTS_WINDOW = 10_000;
+ public static final int CONFIG_INDEX_MAPPINGS_VERSION = 1;
/**
* The name of the index where job, datafeed and analytics configuration is stored
@@ -29,7 +32,12 @@ public static String indexName() {
}
public static String mapping() {
- return TemplateUtils.loadTemplate("/ml/config_index_mappings.json", Version.CURRENT.toString(), MAPPINGS_VERSION_VARIABLE);
+ return TemplateUtils.loadTemplate(
+ "/ml/config_index_mappings.json",
+ Version.CURRENT.toString(),
+ MAPPINGS_VERSION_VARIABLE,
+ Map.of("xpack.ml.managed.index.version", Integer.toString(CONFIG_INDEX_MAPPINGS_VERSION))
+ );
}
public static Settings settings() {
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/MlMetaIndex.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/MlMetaIndex.java
index a72a051414677..9190be89ee1e0 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/MlMetaIndex.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/MlMetaIndex.java
@@ -11,10 +11,13 @@
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.xpack.core.template.TemplateUtils;
+import java.util.Map;
+
public final class MlMetaIndex {
private static final String INDEX_NAME = ".ml-meta";
private static final String MAPPINGS_VERSION_VARIABLE = "xpack.ml.version";
+ private static final int META_INDEX_MAPPINGS_VERSION = 1;
/**
* Where to store the ml info in Elasticsearch - must match what's
@@ -27,7 +30,12 @@ public static String indexName() {
}
public static String mapping() {
- return TemplateUtils.loadTemplate("/ml/meta_index_mappings.json", Version.CURRENT.toString(), MAPPINGS_VERSION_VARIABLE);
+ return TemplateUtils.loadTemplate(
+ "/ml/meta_index_mappings.json",
+ Version.CURRENT.toString(),
+ MAPPINGS_VERSION_VARIABLE,
+ Map.of("xpack.ml.managed.index.version", Integer.toString(META_INDEX_MAPPINGS_VERSION))
+ );
}
public static Settings settings() {
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/MlStatsIndex.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/MlStatsIndex.java
index 76234954b4107..83c7a3fe45a09 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/MlStatsIndex.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/MlStatsIndex.java
@@ -16,6 +16,7 @@
import org.elasticsearch.xpack.core.template.TemplateUtils;
import java.util.Locale;
+import java.util.Map;
/**
* Describes the indices where ML is storing various stats about the users jobs.
@@ -25,6 +26,7 @@ public class MlStatsIndex {
public static final String TEMPLATE_NAME = ".ml-stats";
private static final String MAPPINGS_VERSION_VARIABLE = "xpack.ml.version";
+ public static final int STATS_INDEX_MAPPINGS_VERSION = 1;
private MlStatsIndex() {}
@@ -36,7 +38,12 @@ public static String wrappedMapping() {
}
public static String mapping() {
- return TemplateUtils.loadTemplate("/ml/stats_index_mappings.json", Version.CURRENT.toString(), MAPPINGS_VERSION_VARIABLE);
+ return TemplateUtils.loadTemplate(
+ "/ml/stats_index_mappings.json",
+ Version.CURRENT.toString(),
+ MAPPINGS_VERSION_VARIABLE,
+ Map.of("xpack.ml.managed.index.version", Integer.toString(STATS_INDEX_MAPPINGS_VERSION))
+ );
}
public static String indexPattern() {
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/annotations/AnnotationIndex.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/annotations/AnnotationIndex.java
index c509e52675e38..745e50c920288 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/annotations/AnnotationIndex.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/annotations/AnnotationIndex.java
@@ -31,6 +31,7 @@
import org.elasticsearch.xpack.core.template.TemplateUtils;
import java.util.List;
+import java.util.Map;
import java.util.SortedMap;
import static java.lang.Thread.currentThread;
@@ -56,6 +57,7 @@ public class AnnotationIndex {
public static final List OLD_INDEX_NAMES = List.of(".ml-annotations-6");
private static final String MAPPINGS_VERSION_VARIABLE = "xpack.ml.version";
+ public static final int ANNOTATION_INDEX_MAPPINGS_VERSION = 1;
/**
* Create the .ml-annotations-6 index with correct mappings if it does not already exist. This index is read and written by the UI
@@ -102,7 +104,8 @@ public static void createAnnotationsIndexIfNecessary(
client,
state,
masterNodeTimeout,
- finalListener
+ finalListener,
+ ANNOTATION_INDEX_MAPPINGS_VERSION
),
finalListener::onFailure
);
@@ -208,6 +211,11 @@ public static void createAnnotationsIndexIfNecessary(
}
public static String annotationsMapping() {
- return TemplateUtils.loadTemplate("/ml/annotations_index_mappings.json", Version.CURRENT.toString(), MAPPINGS_VERSION_VARIABLE);
+ return TemplateUtils.loadTemplate(
+ "/ml/annotations_index_mappings.json",
+ Version.CURRENT.toString(),
+ MAPPINGS_VERSION_VARIABLE,
+ Map.of("xpack.ml.managed.index.version", Integer.toString(ANNOTATION_INDEX_MAPPINGS_VERSION))
+ );
}
}
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/inference/persistence/InferenceIndexConstants.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/inference/persistence/InferenceIndexConstants.java
index aa8fa7c88e719..1e60da895c0e7 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/inference/persistence/InferenceIndexConstants.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/inference/persistence/InferenceIndexConstants.java
@@ -12,6 +12,8 @@
import org.elasticsearch.xcontent.ParseField;
import org.elasticsearch.xpack.core.template.TemplateUtils;
+import java.util.Map;
+
/**
* Class containing the index constants so that the index version, name, and prefix are available to a wider audience.
*/
@@ -44,9 +46,15 @@ public final class InferenceIndexConstants {
private static final String NATIVE_LATEST_INDEX = NATIVE_INDEX_PREFIX + NATIVE_INDEX_VERSION;
private static final String MAPPINGS_VERSION_VARIABLE = "xpack.ml.version";
+ public static final int INFERENCE_INDEX_MAPPINGS_VERSION = 1;
public static String mapping() {
- return TemplateUtils.loadTemplate("/ml/inference_index_mappings.json", Version.CURRENT.toString(), MAPPINGS_VERSION_VARIABLE);
+ return TemplateUtils.loadTemplate(
+ "/ml/inference_index_mappings.json",
+ Version.CURRENT.toString(),
+ MAPPINGS_VERSION_VARIABLE,
+ Map.of("xpack.ml.managed.index.version", Integer.toString(INFERENCE_INDEX_MAPPINGS_VERSION))
+ );
}
public static String nativeDefinitionStore() {
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/job/persistence/AnomalyDetectorsIndex.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/job/persistence/AnomalyDetectorsIndex.java
index 0dbed16d3b821..29ac3359c870b 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/job/persistence/AnomalyDetectorsIndex.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/job/persistence/AnomalyDetectorsIndex.java
@@ -18,6 +18,7 @@
import org.elasticsearch.xpack.core.template.TemplateUtils;
import java.util.Locale;
+import java.util.Map;
import static org.elasticsearch.xpack.core.ClientHelper.ML_ORIGIN;
import static org.elasticsearch.xpack.core.ClientHelper.executeAsyncWithOrigin;
@@ -29,6 +30,7 @@ public final class AnomalyDetectorsIndex {
private static final String RESULTS_MAPPINGS_VERSION_VARIABLE = "xpack.ml.version";
private static final String RESOURCE_PATH = "/ml/anomalydetection/";
+ public static final int RESULTS_INDEX_MAPPINGS_VERSION = 1;
private AnomalyDetectorsIndex() {}
@@ -136,7 +138,8 @@ public static String resultsMapping() {
return TemplateUtils.loadTemplate(
RESOURCE_PATH + "results_index_mappings.json",
Version.CURRENT.toString(),
- RESULTS_MAPPINGS_VERSION_VARIABLE
+ RESULTS_MAPPINGS_VERSION_VARIABLE,
+ Map.of("xpack.ml.managed.index.version", Integer.toString(RESULTS_INDEX_MAPPINGS_VERSION))
);
}
}
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/job/persistence/ElasticsearchMappings.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/job/persistence/ElasticsearchMappings.java
index 1bb88f4bc4773..1dde9dc6075d0 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/job/persistence/ElasticsearchMappings.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/job/persistence/ElasticsearchMappings.java
@@ -9,7 +9,6 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.ElasticsearchException;
-import org.elasticsearch.Version;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.ActionRunnable;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingAction;
@@ -22,6 +21,7 @@
import org.elasticsearch.common.CheckedSupplier;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.Index;
+import org.elasticsearch.indices.SystemIndexDescriptor;
import org.elasticsearch.plugins.MapperPlugin;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.Transports;
@@ -100,7 +100,7 @@ public class ElasticsearchMappings {
private ElasticsearchMappings() {}
- static String[] mappingRequiresUpdate(ClusterState state, String[] concreteIndices, Version minVersion) {
+ static String[] mappingRequiresUpdate(ClusterState state, String[] concreteIndices, int minVersion) {
List indicesToUpdate = new ArrayList<>();
Map currentMapping = state.metadata()
@@ -113,22 +113,26 @@ static String[] mappingRequiresUpdate(ClusterState state, String[] concreteIndic
@SuppressWarnings("unchecked")
Map meta = (Map) metadata.sourceAsMap().get("_meta");
if (meta != null) {
- String versionString = (String) meta.get("version");
- if (versionString == null) {
- logger.info("Version of mappings for [{}] not found, recreating", index);
+ Integer systemIndexMappingsVersion = (Integer) meta.get(SystemIndexDescriptor.VERSION_META_KEY);
+ if (systemIndexMappingsVersion == null) {
+ logger.info("System index mappings version for [{}] not found, recreating", index);
indicesToUpdate.add(index);
continue;
}
- Version mappingVersion = Version.fromString(versionString);
-
- if (mappingVersion.onOrAfter(minVersion)) {
+ if (systemIndexMappingsVersion >= minVersion) {
continue;
} else {
- logger.info("Mappings for [{}] are outdated [{}], updating it[{}].", index, mappingVersion, Version.CURRENT);
+ logger.info(
+ "Mappings for [{}] are outdated [{}], updating it[{}].",
+ index,
+ systemIndexMappingsVersion,
+ minVersion
+ );
indicesToUpdate.add(index);
continue;
}
+
} else {
logger.info("Version of mappings for [{}] not found, recreating", index);
indicesToUpdate.add(index);
@@ -153,7 +157,8 @@ public static void addDocMappingIfMissing(
Client client,
ClusterState state,
TimeValue masterNodeTimeout,
- ActionListener listener
+ ActionListener listener,
+ int minVersion
) {
IndexAbstraction indexAbstraction = state.metadata().getIndicesLookup().get(alias);
if (indexAbstraction == null) {
@@ -167,7 +172,7 @@ public static void addDocMappingIfMissing(
protected void doRun() throws Exception {
String[] concreteIndices = indexAbstraction.getIndices().stream().map(Index::getName).toArray(String[]::new);
- final String[] indicesThatRequireAnUpdate = mappingRequiresUpdate(state, concreteIndices, Version.CURRENT);
+ final String[] indicesThatRequireAnUpdate = mappingRequiresUpdate(state, concreteIndices, minVersion);
if (indicesThatRequireAnUpdate.length > 0) {
String mapping = mappingSupplier.get();
PutMappingRequest putMappingRequest = new PutMappingRequest(indicesThatRequireAnUpdate);
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/notifications/NotificationsIndex.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/notifications/NotificationsIndex.java
index 11c4ec2aa0b77..06a923cd9d275 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/notifications/NotificationsIndex.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/notifications/NotificationsIndex.java
@@ -9,12 +9,15 @@
import org.elasticsearch.Version;
import org.elasticsearch.xpack.core.template.TemplateUtils;
+import java.util.Map;
+
public final class NotificationsIndex {
public static final String NOTIFICATIONS_INDEX = ".ml-notifications-000002";
private static final String RESOURCE_PATH = "/ml/";
private static final String MAPPINGS_VERSION_VARIABLE = "xpack.ml.version";
+ private static final int NOTIFICATIONS_INDEX_MAPPINGS_VERSION = 1;
private NotificationsIndex() {}
@@ -22,7 +25,8 @@ public static String mapping() {
return TemplateUtils.loadTemplate(
RESOURCE_PATH + "notifications_index_mappings.json",
Version.CURRENT.toString(),
- MAPPINGS_VERSION_VARIABLE
+ MAPPINGS_VERSION_VARIABLE,
+ Map.of("xpack.ml.managed.index.version", Integer.toString(NOTIFICATIONS_INDEX_MAPPINGS_VERSION))
);
}
}
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/job/persistence/ElasticsearchMappingsTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/job/persistence/ElasticsearchMappingsTests.java
index cf9708505d075..d95c94801e52a 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/job/persistence/ElasticsearchMappingsTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/job/persistence/ElasticsearchMappingsTests.java
@@ -23,9 +23,9 @@
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.index.IndexVersion;
import org.elasticsearch.index.get.GetResult;
+import org.elasticsearch.indices.SystemIndexDescriptor;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.test.ESTestCase;
-import org.elasticsearch.test.VersionUtils;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.xcontent.XContentParseException;
import org.elasticsearch.xcontent.XContentParser;
@@ -130,25 +130,45 @@ public void testMappingRequiresUpdateNoMapping() {
ClusterState cs = csBuilder.build();
String[] indices = new String[] { "no_index" };
- assertArrayEquals(new String[] { "no_index" }, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, Version.CURRENT));
+ assertArrayEquals(new String[] { "no_index" }, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, 1));
}
public void testMappingRequiresUpdateNullMapping() {
ClusterState cs = getClusterStateWithMappingsWithMetadata(Collections.singletonMap("null_mapping", null));
String[] indices = new String[] { "null_index" };
- assertArrayEquals(indices, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, Version.CURRENT));
+ assertArrayEquals(indices, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, 1));
}
public void testMappingRequiresUpdateNoVersion() {
ClusterState cs = getClusterStateWithMappingsWithMetadata(Collections.singletonMap("no_version_field", "NO_VERSION_FIELD"));
String[] indices = new String[] { "no_version_field" };
- assertArrayEquals(indices, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, Version.CURRENT));
+ assertArrayEquals(indices, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, 1));
}
public void testMappingRequiresUpdateRecentMappingVersion() {
- ClusterState cs = getClusterStateWithMappingsWithMetadata(Collections.singletonMap("version_current", Version.CURRENT.toString()));
- String[] indices = new String[] { "version_current" };
- assertArrayEquals(new String[] {}, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, Version.CURRENT));
+ {
+ ClusterState cs = getClusterStateWithMappingsWithMetadata(
+ Collections.singletonMap("version_current", Version.CURRENT.toString())
+ );
+ String[] indices = new String[] { "version_current" };
+ assertArrayEquals(indices, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, 1));
+ }
+ {
+ ClusterState cs = getClusterStateWithMappingsWithMetadata(
+ Collections.singletonMap("version_current", Version.CURRENT.toString()),
+ Collections.singletonMap(SystemIndexDescriptor.VERSION_META_KEY, 1)
+ );
+ String[] indices = new String[] { "version_current" };
+ assertArrayEquals(new String[] {}, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, 1));
+ }
+ {
+ ClusterState cs = getClusterStateWithMappingsWithMetadata(
+ Collections.singletonMap("version_current", Version.CURRENT.toString()),
+ Collections.singletonMap(SystemIndexDescriptor.VERSION_META_KEY, 1)
+ );
+ String[] indices = new String[] { "version_current" };
+ assertArrayEquals(indices, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, 2));
+ }
}
public void testMappingRequiresUpdateMaliciousMappingVersion() {
@@ -156,28 +176,53 @@ public void testMappingRequiresUpdateMaliciousMappingVersion() {
Collections.singletonMap("version_current", Collections.singletonMap("nested", "1.0"))
);
String[] indices = new String[] { "version_nested" };
- assertArrayEquals(indices, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, Version.CURRENT));
+ assertArrayEquals(indices, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, 1));
}
public void testMappingRequiresUpdateBogusMappingVersion() {
ClusterState cs = getClusterStateWithMappingsWithMetadata(Collections.singletonMap("version_bogus", "0.0"));
String[] indices = new String[] { "version_bogus" };
- assertArrayEquals(indices, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, Version.CURRENT));
+ assertArrayEquals(indices, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, 1));
}
public void testMappingRequiresUpdateNewerMappingVersion() {
- ClusterState cs = getClusterStateWithMappingsWithMetadata(Collections.singletonMap("version_newer", Version.CURRENT));
- String[] indices = new String[] { "version_newer" };
- assertArrayEquals(new String[] {}, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, VersionUtils.getPreviousVersion()));
+ {
+ ClusterState cs = getClusterStateWithMappingsWithMetadata(Collections.singletonMap("version_newer", 2));
+ String[] indices = new String[] { "version_newer" };
+ assertArrayEquals(indices, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, 1));
+ }
+ {
+ ClusterState cs = getClusterStateWithMappingsWithMetadata(
+ Collections.singletonMap("version_newer", Version.CURRENT),
+ Collections.singletonMap(SystemIndexDescriptor.VERSION_META_KEY, 2)
+ );
+ String[] indices = new String[] { "version_newer" };
+ assertArrayEquals(new String[] {}, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, 1));
+ }
+ {
+ ClusterState cs = getClusterStateWithMappingsWithMetadata(
+ Collections.singletonMap("version_newer", Version.CURRENT),
+ Collections.singletonMap(SystemIndexDescriptor.VERSION_META_KEY, 1)
+ );
+ String[] indices = new String[] { "version_newer" };
+ assertArrayEquals(indices, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, 2));
+ }
}
public void testMappingRequiresUpdateNewerMappingVersionMinor() {
- ClusterState cs = getClusterStateWithMappingsWithMetadata(Collections.singletonMap("version_newer_minor", Version.CURRENT));
- String[] indices = new String[] { "version_newer_minor" };
- assertArrayEquals(
- new String[] {},
- ElasticsearchMappings.mappingRequiresUpdate(cs, indices, VersionUtils.getPreviousMinorVersion())
- );
+ {
+ ClusterState cs = getClusterStateWithMappingsWithMetadata(Collections.singletonMap("version_newer_minor", 1));
+ String[] indices = new String[] { "version_newer_minor" };
+ assertArrayEquals(indices, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, 1));
+ }
+ {
+ ClusterState cs = getClusterStateWithMappingsWithMetadata(
+ Collections.singletonMap("version_newer_minor", Version.CURRENT),
+ Collections.singletonMap(SystemIndexDescriptor.VERSION_META_KEY, 1)
+ );
+ String[] indices = new String[] { "version_newer_minor" };
+ assertArrayEquals(new String[] {}, ElasticsearchMappings.mappingRequiresUpdate(cs, indices, 1));
+ }
}
@SuppressWarnings({ "unchecked" })
@@ -200,7 +245,8 @@ public void testAddDocMappingIfMissing() {
client,
clusterState,
MasterNodeRequest.DEFAULT_MASTER_NODE_TIMEOUT,
- ActionTestUtils.assertNoFailureListener(Assert::assertTrue)
+ ActionTestUtils.assertNoFailureListener(Assert::assertTrue),
+ 1
);
ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(PutMappingRequest.class);
@@ -215,6 +261,10 @@ public void testAddDocMappingIfMissing() {
}
private ClusterState getClusterStateWithMappingsWithMetadata(Map namesAndVersions) {
+ return getClusterStateWithMappingsWithMetadata(namesAndVersions, null);
+ }
+
+ private ClusterState getClusterStateWithMappingsWithMetadata(Map namesAndVersions, Map metaData) {
Metadata.Builder metadataBuilder = Metadata.builder();
for (Map.Entry entry : namesAndVersions.entrySet()) {
@@ -236,6 +286,9 @@ private ClusterState getClusterStateWithMappingsWithMetadata(Map
if (version != null && version.equals("NO_VERSION_FIELD") == false) {
meta.put("version", version);
}
+ if (metaData != null) {
+ metaData.forEach((k, v) -> meta.putIfAbsent(k, v));
+ }
mapping.put("_meta", meta);
indexMetadata.putMapping(new MappingMetadata("_doc", mapping));
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/test/TestRestrictedIndices.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/test/TestRestrictedIndices.java
index 38bdb8ef18350..92c3a65ffeaa3 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/test/TestRestrictedIndices.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/test/TestRestrictedIndices.java
@@ -266,6 +266,7 @@ private static XContentBuilder mockMappings() {
.startObject(SINGLE_MAPPING_NAME)
.startObject("_meta")
.field("version", Version.CURRENT)
+ .field(SystemIndexDescriptor.VERSION_META_KEY, 0)
.endObject()
.field("dynamic", "strict")
.startObject("properties")
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/fleet-actions-results.json b/x-pack/plugin/core/template-resources/src/main/resources/fleet-actions-results.json
index 04e67d6ebe528..88c51a9aef284 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/fleet-actions-results.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/fleet-actions-results.json
@@ -10,7 +10,8 @@
},
"mappings": {
"_meta": {
- "version": "${fleet.version}"
+ "version": "${fleet.version}",
+ "managed_index_mappings_version": ${fleet.managed.index.version}
},
"dynamic": false,
"properties": {
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/fleet-actions.json b/x-pack/plugin/core/template-resources/src/main/resources/fleet-actions.json
index 55a6575e15c2a..2b3ecbac92352 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/fleet-actions.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/fleet-actions.json
@@ -6,7 +6,8 @@
"_doc" : {
"dynamic": false,
"_meta": {
- "version": "${fleet.version}"
+ "version": "${fleet.version}",
+ "managed_index_mappings_version": ${fleet.managed.index.version}
},
"properties": {
"action_id": {
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/fleet-agents.json b/x-pack/plugin/core/template-resources/src/main/resources/fleet-agents.json
index 7afbd8b3db201..344fe2f5e3a2c 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/fleet-agents.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/fleet-agents.json
@@ -6,7 +6,8 @@
"_doc" : {
"dynamic": false,
"_meta": {
- "version": "${fleet.version}"
+ "version": "${fleet.version}",
+ "managed_index_mappings_version": ${fleet.managed.index.version}
},
"properties": {
"access_api_key_id": {
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/fleet-artifacts.json b/x-pack/plugin/core/template-resources/src/main/resources/fleet-artifacts.json
index bb7fbda297db2..4a5f76470d24f 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/fleet-artifacts.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/fleet-artifacts.json
@@ -6,7 +6,8 @@
"_doc" : {
"dynamic": false,
"_meta": {
- "version": "${fleet.version}"
+ "version": "${fleet.version}",
+ "managed_index_mappings_version": ${fleet.managed.index.version}
},
"properties": {
"identifier": {
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/fleet-enrollment-api-keys.json b/x-pack/plugin/core/template-resources/src/main/resources/fleet-enrollment-api-keys.json
index 2032bee4aaabb..6be455e02825a 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/fleet-enrollment-api-keys.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/fleet-enrollment-api-keys.json
@@ -6,7 +6,8 @@
"_doc" : {
"dynamic": false,
"_meta": {
- "version": "${fleet.version}"
+ "version": "${fleet.version}",
+ "managed_index_mappings_version": ${fleet.managed.index.version}
},
"properties": {
"active": {
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/fleet-policies-leader.json b/x-pack/plugin/core/template-resources/src/main/resources/fleet-policies-leader.json
index 73179d529aae8..7cce4e0d4f53a 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/fleet-policies-leader.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/fleet-policies-leader.json
@@ -6,7 +6,8 @@
"_doc" : {
"dynamic": false,
"_meta": {
- "version": "${fleet.version}"
+ "version": "${fleet.version}",
+ "managed_index_mappings_version": ${fleet.managed.index.version}
},
"properties": {
"server": {
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/fleet-policies.json b/x-pack/plugin/core/template-resources/src/main/resources/fleet-policies.json
index 3e7031c1eab89..44e2e67dd06c3 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/fleet-policies.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/fleet-policies.json
@@ -6,7 +6,8 @@
"_doc" : {
"dynamic": false,
"_meta": {
- "version": "${fleet.version}"
+ "version": "${fleet.version}",
+ "managed_index_mappings_version": ${fleet.managed.index.version}
},
"properties": {
"coordinator_idx": {
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/fleet-secrets.json b/x-pack/plugin/core/template-resources/src/main/resources/fleet-secrets.json
index 684dfc1c7928a..6d16098e38049 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/fleet-secrets.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/fleet-secrets.json
@@ -6,7 +6,8 @@
"_doc" : {
"dynamic": false,
"_meta": {
- "version": "${fleet.version}"
+ "version": "${fleet.version}",
+ "managed_index_mappings_version": ${fleet.managed.index.version}
},
"properties": {
"value": {
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/fleet-servers.json b/x-pack/plugin/core/template-resources/src/main/resources/fleet-servers.json
index b9b9a8f5b5249..8ddd5e7e0693e 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/fleet-servers.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/fleet-servers.json
@@ -6,7 +6,8 @@
"_doc" : {
"dynamic": false,
"_meta": {
- "version": "${fleet.version}"
+ "version": "${fleet.version}",
+ "managed_index_mappings_version": ${fleet.managed.index.version}
},
"properties": {
"agent": {
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/ml/annotations_index_mappings.json b/x-pack/plugin/core/template-resources/src/main/resources/ml/annotations_index_mappings.json
index 1292ce06e3044..42efa741dd99d 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/ml/annotations_index_mappings.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/ml/annotations_index_mappings.json
@@ -1,7 +1,8 @@
{
"_doc": {
"_meta" : {
- "version" : "${xpack.ml.version}"
+ "version": "${xpack.ml.version}",
+ "managed_index_mappings_version": ${xpack.ml.managed.index.version}
},
"dynamic" : false,
"properties" : {
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/ml/anomalydetection/results_index_mappings.json b/x-pack/plugin/core/template-resources/src/main/resources/ml/anomalydetection/results_index_mappings.json
index 89389012664b2..4415afe50a998 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/ml/anomalydetection/results_index_mappings.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/ml/anomalydetection/results_index_mappings.json
@@ -1,6 +1,7 @@
{
"_meta" : {
- "version" : "${xpack.ml.version}"
+ "version" : "${xpack.ml.version}",
+ "managed_index_mappings_version": ${xpack.ml.managed.index.version}
},
"dynamic_templates" : [
{
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/ml/config_index_mappings.json b/x-pack/plugin/core/template-resources/src/main/resources/ml/config_index_mappings.json
index 7de21b4901f1a..811810f5d0f2f 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/ml/config_index_mappings.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/ml/config_index_mappings.json
@@ -1,7 +1,8 @@
{
"_doc" : {
"_meta" : {
- "version" : "${xpack.ml.version}"
+ "version": "${xpack.ml.version}",
+ "managed_index_mappings_version": ${xpack.ml.managed.index.version}
},
"dynamic_templates" : [
{
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/ml/inference_index_mappings.json b/x-pack/plugin/core/template-resources/src/main/resources/ml/inference_index_mappings.json
index d2e73d494bcc3..7ff961a0aac9c 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/ml/inference_index_mappings.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/ml/inference_index_mappings.json
@@ -1,7 +1,8 @@
{
"_doc": {
"_meta": {
- "version": "${xpack.ml.version}"
+ "version": "${xpack.ml.version}",
+ "managed_index_mappings_version": ${xpack.ml.managed.index.version}
},
"dynamic": false,
"properties": {
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/ml/meta_index_mappings.json b/x-pack/plugin/core/template-resources/src/main/resources/ml/meta_index_mappings.json
index f78414f53ea4f..4606cb0d75d8f 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/ml/meta_index_mappings.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/ml/meta_index_mappings.json
@@ -1,7 +1,8 @@
{
"_doc": {
"_meta": {
- "version": "${xpack.ml.version}"
+ "version": "${xpack.ml.version}",
+ "managed_index_mappings_version": ${xpack.ml.managed.index.version}
},
"dynamic_templates": [
{
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/ml/notifications_index_mappings.json b/x-pack/plugin/core/template-resources/src/main/resources/ml/notifications_index_mappings.json
index e0e44d8b230f4..b2135d2c6e76e 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/ml/notifications_index_mappings.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/ml/notifications_index_mappings.json
@@ -1,6 +1,7 @@
{
"_meta" : {
- "version" : "${xpack.ml.version}"
+ "version": "${xpack.ml.version}",
+ "managed_index_mappings_version": ${xpack.ml.managed.index.version}
},
"dynamic" : "false",
"properties" : {
diff --git a/x-pack/plugin/core/template-resources/src/main/resources/ml/stats_index_mappings.json b/x-pack/plugin/core/template-resources/src/main/resources/ml/stats_index_mappings.json
index 711bfe1f9c1dc..8c151cb38c1b3 100644
--- a/x-pack/plugin/core/template-resources/src/main/resources/ml/stats_index_mappings.json
+++ b/x-pack/plugin/core/template-resources/src/main/resources/ml/stats_index_mappings.json
@@ -1,6 +1,7 @@
{
"_meta": {
- "version" : "${xpack.ml.version}"
+ "version": "${xpack.ml.version}",
+ "managed_index_mappings_version": ${xpack.ml.managed.index.version}
},
"dynamic": false,
"properties" : {
diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRulesIndexService.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRulesIndexService.java
index d629700b7c61a..de823ab2a6ce2 100644
--- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRulesIndexService.java
+++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRulesIndexService.java
@@ -63,6 +63,7 @@ public class QueryRulesIndexService {
public static final String QUERY_RULES_ALIAS_NAME = ".query-rules";
public static final String QUERY_RULES_CONCRETE_INDEX_NAME = ".query-rules-1";
public static final String QUERY_RULES_INDEX_NAME_PATTERN = ".query-rules-*";
+ private static final int QUERY_RULES_INDEX_MAPPINGS_VERSION = 1;
private final Client clientWithOrigin;
private final ClusterSettings clusterSettings;
@@ -107,6 +108,7 @@ private static XContentBuilder getIndexMappings() {
{
builder.startObject("_meta");
builder.field("version", Version.CURRENT.toString());
+ builder.field(SystemIndexDescriptor.VERSION_META_KEY, QUERY_RULES_INDEX_MAPPINGS_VERSION);
builder.endObject();
builder.field("dynamic", "strict");
diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/search/SearchApplicationIndexService.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/search/SearchApplicationIndexService.java
index b4917607feb88..681a2ff5028a3 100644
--- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/search/SearchApplicationIndexService.java
+++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/search/SearchApplicationIndexService.java
@@ -94,6 +94,7 @@ public class SearchApplicationIndexService {
public static final String SEARCH_APPLICATION_ALIAS_NAME = ".search-app";
public static final String SEARCH_APPLICATION_CONCRETE_INDEX_NAME = ".search-app-1";
public static final String SEARCH_APPLICATION_INDEX_NAME_PATTERN = ".search-app-*";
+ private static final int SEARCH_APPLICATION_INDEX_MAPPINGS_VERSION = 1;
// The client to perform any operations on user indices (alias, ...).
private final Client client;
@@ -152,6 +153,7 @@ private static XContentBuilder getIndexMappings() {
{
builder.startObject("_meta");
builder.field("version", Version.CURRENT.toString());
+ builder.field(SystemIndexDescriptor.VERSION_META_KEY, SEARCH_APPLICATION_INDEX_MAPPINGS_VERSION);
builder.endObject();
builder.field("dynamic", "strict");
diff --git a/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/Fleet.java b/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/Fleet.java
index 4afc2bb44793a..009e17bd79e6b 100644
--- a/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/Fleet.java
+++ b/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/Fleet.java
@@ -89,6 +89,15 @@ public class Fleet extends Plugin implements SystemIndexPlugin {
private static final String VERSION_KEY = "version";
private static final String MAPPING_VERSION_VARIABLE = "fleet.version";
private static final List ALLOWED_PRODUCTS = List.of("kibana", "fleet");
+ private static final int FLEET_ACTIONS_MAPPINGS_VERSION = 1;
+ private static final int FLEET_AGENTS_MAPPINGS_VERSION = 1;
+ private static final int FLEET_ENROLLMENT_API_KEYS_MAPPINGS_VERSION = 1;
+ private static final int FLEET_SECRETS_MAPPINGS_VERSION = 1;
+ private static final int FLEET_POLICIES_MAPPINGS_VERSION = 1;
+ private static final int FLEET_POLICIES_LEADER_MAPPINGS_VERSION = 1;
+ private static final int FLEET_SERVERS_MAPPINGS_VERSION = 1;
+ private static final int FLEET_ARTIFACTS_MAPPINGS_VERSION = 1;
+ private static final int FLEET_ACTIONS_RESULTS_MAPPINGS_VERSION = 1;
@Override
public Collection