From c530883e5e0876263ab861199c63808265b43c21 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 15 Aug 2019 22:05:46 +1200 Subject: [PATCH] #1793 - ENH: Add filterMany() that takes expressions ... as a simpler option --- src/main/java/io/ebean/ExpressionFactory.java | 8 + src/main/java/io/ebean/ExpressionList.java | 39 ++- .../expression/DefaultExpressionFactory.java | 6 + .../expression/DefaultExpressionList.java | 16 +- .../server/expression/JunctionExpression.java | 10 + .../server/grammer/EqlAdapter.java | 5 + .../server/grammer/EqlParser.java | 2 +- .../server/grammer/EqlValueType.java | 1 + .../server/grammer/EqlWhereAdapter.java | 24 +- .../server/grammer/EqlWhereListener.java | 8 +- .../server/grammer/antlr/EQLLexer.interp | 2 +- .../server/grammer/antlr/EQLLexer.java | 222 +++++++++--------- .../server/grammer/EqlParserTest.java | 48 +++- .../org/tests/query/TestQueryFilterMany.java | 19 ++ src/test/resources/EQL.g4 | 1 + 15 files changed, 279 insertions(+), 132 deletions(-) diff --git a/src/main/java/io/ebean/ExpressionFactory.java b/src/main/java/io/ebean/ExpressionFactory.java index 42177057d..a27955d92 100644 --- a/src/main/java/io/ebean/ExpressionFactory.java +++ b/src/main/java/io/ebean/ExpressionFactory.java @@ -536,4 +536,12 @@ public interface ExpressionFactory { */ Junction junction(Junction.Type type, Query query, ExpressionList parent); + /** + * Add the expressions to the given expression list. + * + * @param where The expression list to add the expressions to + * @param expressions The expressions that are parsed + * @param params Bind parameters to match ? or ?1 bind positions. + */ + void where(ExpressionList where, String expressions, Object[] params); } diff --git a/src/main/java/io/ebean/ExpressionList.java b/src/main/java/io/ebean/ExpressionList.java index 4480251e1..c40cd0845 100644 --- a/src/main/java/io/ebean/ExpressionList.java +++ b/src/main/java/io/ebean/ExpressionList.java @@ -489,7 +489,26 @@ public interface ExpressionList { * Add some filter predicate expressions to the many property. */ @Nonnull - ExpressionList filterMany(String prop); + ExpressionList filterMany(String manyProperty); + + /** + * Add filter expressions to the many property. + * + *
{@code
+   *
+   *   DB.find(Customer.class)
+   *   .where()
+   *   .eq("name", "Rob")
+   *   .filterMany("orders", "status = ?", Status.NEW)
+   *   .findList();
+   *
+   * }
+ * + * @param manyProperty The many property + * @param expressions Filter expressions with and, or and ? or ?1 type bind parameters + * @param params Bind parameters used in the expressions + */ + Query filterMany(String manyProperty, String expressions, Object... params); /** * Specify specific properties to fetch on the main/root bean (aka partial @@ -663,6 +682,14 @@ public interface ExpressionList { */ ExpressionList where(); + /** + * Add the expressions to this expression list. + * + * @param expressions The expressions that are parsed and added to this expression list + * @param params Bind parameters to match ? or ?1 bind positions. + */ + ExpressionList where(String expressions, Object... params); + /** * Path exists - for the given path in a JSON document. *
{@code
@@ -831,9 +858,9 @@ public interface ExpressionList {
    */
   ExpressionList inRange(String propertyName, Object value1, Object value2);
 
-    /**
-     * Between - property between the two given values.
-     */
+  /**
+   * Between - property between the two given values.
+   */
   ExpressionList between(String propertyName, Object value1, Object value2);
 
   /**
@@ -1327,7 +1354,7 @@ public interface ExpressionList {
    *
    * }
*

- * Note that we need to cast the Postgres array for UUID types like: + * Note that we need to cast the Postgres array for UUID types like: *

*
{@code
    *
@@ -1335,7 +1362,7 @@ public interface ExpressionList {
    *
    * }
* - * @param raw The raw expression that is typically a subquery + * @param raw The raw expression that is typically a subquery * @param values The values which is typically a list or set of id values. */ ExpressionList rawOrEmpty(String raw, Collection values); diff --git a/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionFactory.java b/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionFactory.java index e568c2cbd..2e234c844 100644 --- a/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionFactory.java +++ b/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionFactory.java @@ -16,6 +16,7 @@ import io.ebean.search.TextQueryString; import io.ebean.search.TextSimple; import io.ebeaninternal.api.SpiExpressionFactory; import io.ebeaninternal.api.SpiQuery; +import io.ebeaninternal.server.grammer.EqlParser; import java.util.Arrays; import java.util.Collection; @@ -151,6 +152,11 @@ public class DefaultExpressionFactory implements SpiExpressionFactory { return new BitwiseExpression(propertyName, BitwiseOp.AND, flags, "=", match); } + @Override + public void where(ExpressionList list, String expressions, Object[] params) { + EqlParser.parseWhere(expressions, list, this, params); + } + /** * Equal To - property equal to the given value. */ diff --git a/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java b/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java index 7e88b2897..e5b9fe230 100644 --- a/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java +++ b/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java @@ -470,8 +470,14 @@ public class DefaultExpressionList implements SpiExpressionList { } @Override - public ExpressionList filterMany(String prop) { - return query.filterMany(prop); + public ExpressionList filterMany(String manyProperty) { + return query.filterMany(manyProperty); + } + + @Override + public Query filterMany(String manyProperty, String expressions, Object... params) { + query.filterMany(manyProperty).where(expressions, params); + return query; } @Override @@ -745,6 +751,12 @@ public class DefaultExpressionList implements SpiExpressionList { return this; } + @Override + public ExpressionList where(String expressions, Object... params) { + expr.where(this, expressions, params); + return this; + } + @Override public ExpressionList bitwiseAny(String propertyName, long flags) { add(expr.bitwiseAny(propertyName, flags)); diff --git a/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java b/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java index 32fb51f20..2b31a746a 100644 --- a/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java +++ b/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java @@ -326,11 +326,21 @@ class JunctionExpression implements SpiJunction, SpiExpression, Expression return exprList.exampleLike(example); } + @Override + public ExpressionList where(String expressions, Object... params) { + throw new IllegalStateException("where not allowed on Junction expression list"); + } + @Override public ExpressionList filterMany(String prop) { throw new IllegalStateException("filterMany not allowed on Junction expression list"); } + @Override + public Query filterMany(String manyProperty, String expressions, Object... params) { + throw new IllegalStateException("filterMany not allowed on Junction expression list"); + } + @Override public Query usingTransaction(Transaction transaction) { return exprList.usingTransaction(transaction); diff --git a/src/main/java/io/ebeaninternal/server/grammer/EqlAdapter.java b/src/main/java/io/ebeaninternal/server/grammer/EqlAdapter.java index 503f4dc81..77287903b 100644 --- a/src/main/java/io/ebeaninternal/server/grammer/EqlAdapter.java +++ b/src/main/java/io/ebeaninternal/server/grammer/EqlAdapter.java @@ -36,6 +36,11 @@ class EqlAdapter extends EqlWhereListener { return query.createNamedParameter(parameterName); } + @Override + Object positionParam(String paramPosition) { + return query.createNamedParameter(paramPosition); + } + /** * Return the current expression list that expressions should be added to. */ diff --git a/src/main/java/io/ebeaninternal/server/grammer/EqlParser.java b/src/main/java/io/ebeaninternal/server/grammer/EqlParser.java index 949c3442c..8cd5089d6 100644 --- a/src/main/java/io/ebeaninternal/server/grammer/EqlParser.java +++ b/src/main/java/io/ebeaninternal/server/grammer/EqlParser.java @@ -36,7 +36,7 @@ public class EqlParser { EQLParser parser = new EQLParser(new CommonTokenStream(new EQLLexer(CharStreams.fromString(raw)))); parser.addErrorListener(errorListener); - new ParseTreeWalker().walk(new EqlWhereAdapter<>(where, expr), parser.conditional_expression()); + new ParseTreeWalker().walk(new EqlWhereAdapter<>(where, expr, params), parser.conditional_expression()); } static class ErrorListener extends BaseErrorListener { diff --git a/src/main/java/io/ebeaninternal/server/grammer/EqlValueType.java b/src/main/java/io/ebeaninternal/server/grammer/EqlValueType.java index a1156796c..7d9fc61a1 100644 --- a/src/main/java/io/ebeaninternal/server/grammer/EqlValueType.java +++ b/src/main/java/io/ebeaninternal/server/grammer/EqlValueType.java @@ -1,6 +1,7 @@ package io.ebeaninternal.server.grammer; enum EqlValueType { + POS_PARAM, NAMED_PARAM, STRING, BOOL, diff --git a/src/main/java/io/ebeaninternal/server/grammer/EqlWhereAdapter.java b/src/main/java/io/ebeaninternal/server/grammer/EqlWhereAdapter.java index 47ccf6a46..0620e3ee8 100644 --- a/src/main/java/io/ebeaninternal/server/grammer/EqlWhereAdapter.java +++ b/src/main/java/io/ebeaninternal/server/grammer/EqlWhereAdapter.java @@ -2,20 +2,29 @@ package io.ebeaninternal.server.grammer; import io.ebean.ExpressionFactory; import io.ebean.ExpressionList; +import io.ebeaninternal.server.util.ArrayStack; class EqlWhereAdapter extends EqlWhereListener { private final ExpressionList where; private final ExpressionFactory expr; + private final Object[] params; - EqlWhereAdapter(ExpressionList where, ExpressionFactory expr) { + private int paramIndex; + + EqlWhereAdapter(ExpressionList where, ExpressionFactory expr, Object[] params) { this.where = where; this.expr = expr; + this.params = params; } @Override ExpressionList peekExprList() { - return where; + if (whereStack == null) { + whereStack = new ArrayStack<>(); + whereStack.push(where); + } + return whereStack.peek(); } @Override @@ -23,8 +32,17 @@ class EqlWhereAdapter extends EqlWhereListener { return expr; } + @Override + Object positionParam(String paramPosition) { + if ("?".equals(paramPosition)) { + return params[paramIndex++]; + } + final int pos = Integer.parseInt(paramPosition.substring(1)); + return params[pos -1]; + } + @Override Object namedParam(String substring) { - return null; + throw new RuntimeException("Not supported"); } } diff --git a/src/main/java/io/ebeaninternal/server/grammer/EqlWhereListener.java b/src/main/java/io/ebeaninternal/server/grammer/EqlWhereListener.java index 0e2f5015f..2c623125b 100644 --- a/src/main/java/io/ebeaninternal/server/grammer/EqlWhereListener.java +++ b/src/main/java/io/ebeaninternal/server/grammer/EqlWhereListener.java @@ -37,7 +37,9 @@ abstract class EqlWhereListener extends EQLBaseListener { abstract ExpressionFactory expressionFactory(); - abstract Object namedParam(String substring); + abstract Object namedParam(String paramName); + + abstract Object positionParam(String paramPosition); /** * Push the expression list onto the appropriate stack. @@ -290,6 +292,8 @@ abstract class EqlWhereListener extends EQLBaseListener { char firstChar = Character.toLowerCase(valueAsText.charAt(0)); switch (firstChar) { + case '?': + return EqlValueType.POS_PARAM; case ':': return EqlValueType.NAMED_PARAM; case 't': @@ -394,6 +398,8 @@ abstract class EqlWhereListener extends EQLBaseListener { return new BigDecimal(value); case STRING: return unquote(value); + case POS_PARAM: + return positionParam(value); case NAMED_PARAM: return namedParam(value.substring(1)); default: diff --git a/src/main/java/io/ebeaninternal/server/grammer/antlr/EQLLexer.interp b/src/main/java/io/ebeaninternal/server/grammer/antlr/EQLLexer.interp index 971c21a1d..32fc89a55 100644 --- a/src/main/java/io/ebeaninternal/server/grammer/antlr/EQLLexer.interp +++ b/src/main/java/io/ebeaninternal/server/grammer/antlr/EQLLexer.interp @@ -227,4 +227,4 @@ mode names: DEFAULT_MODE atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 73, 585, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 7, 62, 468, 10, 62, 12, 62, 14, 62, 471, 11, 62, 3, 63, 3, 63, 7, 63, 475, 10, 63, 12, 63, 14, 63, 478, 11, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 5, 65, 526, 10, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 5, 66, 537, 10, 66, 3, 67, 5, 67, 540, 10, 67, 3, 67, 3, 67, 5, 67, 544, 10, 67, 3, 67, 3, 67, 5, 67, 548, 10, 67, 3, 68, 6, 68, 551, 10, 68, 13, 68, 14, 68, 552, 3, 68, 3, 68, 7, 68, 557, 10, 68, 12, 68, 14, 68, 560, 11, 68, 3, 69, 3, 69, 7, 69, 564, 10, 69, 12, 69, 14, 69, 567, 11, 69, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 7, 71, 575, 10, 71, 12, 71, 14, 71, 578, 11, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 2, 2, 73, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, 59, 31, 61, 32, 63, 33, 65, 34, 67, 35, 69, 36, 71, 37, 73, 38, 75, 39, 77, 40, 79, 41, 81, 42, 83, 43, 85, 44, 87, 45, 89, 46, 91, 47, 93, 48, 95, 49, 97, 50, 99, 51, 101, 52, 103, 53, 105, 54, 107, 55, 109, 56, 111, 57, 113, 58, 115, 59, 117, 60, 119, 61, 121, 62, 123, 63, 125, 64, 127, 65, 129, 66, 131, 67, 133, 68, 135, 69, 137, 70, 139, 71, 141, 72, 143, 73, 3, 2, 9, 5, 2, 67, 92, 97, 97, 99, 124, 6, 2, 50, 59, 67, 92, 97, 97, 99, 124, 7, 2, 48, 48, 50, 59, 67, 92, 97, 97, 99, 124, 3, 2, 50, 59, 3, 2, 51, 59, 3, 2, 41, 41, 5, 2, 11, 12, 15, 15, 34, 34, 2, 600, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, 2, 2, 2, 2, 139, 3, 2, 2, 2, 2, 141, 3, 2, 2, 2, 2, 143, 3, 2, 2, 2, 3, 145, 3, 2, 2, 2, 5, 147, 3, 2, 2, 2, 7, 149, 3, 2, 2, 2, 9, 156, 3, 2, 2, 2, 11, 165, 3, 2, 2, 2, 13, 171, 3, 2, 2, 2, 15, 177, 3, 2, 2, 2, 17, 180, 3, 2, 2, 2, 19, 182, 3, 2, 2, 2, 21, 188, 3, 2, 2, 2, 23, 194, 3, 2, 2, 2, 25, 199, 3, 2, 2, 2, 27, 203, 3, 2, 2, 2, 29, 208, 3, 2, 2, 2, 31, 214, 3, 2, 2, 2, 33, 221, 3, 2, 2, 2, 35, 227, 3, 2, 2, 2, 37, 229, 3, 2, 2, 2, 39, 235, 3, 2, 2, 2, 41, 240, 3, 2, 2, 2, 43, 243, 3, 2, 2, 2, 45, 247, 3, 2, 2, 2, 47, 251, 3, 2, 2, 2, 49, 254, 3, 2, 2, 2, 51, 262, 3, 2, 2, 2, 53, 270, 3, 2, 2, 2, 55, 273, 3, 2, 2, 2, 57, 276, 3, 2, 2, 2, 59, 281, 3, 2, 2, 2, 61, 288, 3, 2, 2, 2, 63, 298, 3, 2, 2, 2, 65, 306, 3, 2, 2, 2, 67, 312, 3, 2, 2, 2, 69, 320, 3, 2, 2, 2, 71, 331, 3, 2, 2, 2, 73, 340, 3, 2, 2, 2, 75, 345, 3, 2, 2, 2, 77, 351, 3, 2, 2, 2, 79, 360, 3, 2, 2, 2, 81, 370, 3, 2, 2, 2, 83, 381, 3, 2, 2, 2, 85, 393, 3, 2, 2, 2, 87, 402, 3, 2, 2, 2, 89, 412, 3, 2, 2, 2, 91, 414, 3, 2, 2, 2, 93, 417, 3, 2, 2, 2, 95, 419, 3, 2, 2, 2, 97, 422, 3, 2, 2, 2, 99, 425, 3, 2, 2, 2, 101, 428, 3, 2, 2, 2, 103, 432, 3, 2, 2, 2, 105, 434, 3, 2, 2, 2, 107, 437, 3, 2, 2, 2, 109, 440, 3, 2, 2, 2, 111, 443, 3, 2, 2, 2, 113, 447, 3, 2, 2, 2, 115, 450, 3, 2, 2, 2, 117, 453, 3, 2, 2, 2, 119, 456, 3, 2, 2, 2, 121, 460, 3, 2, 2, 2, 123, 464, 3, 2, 2, 2, 125, 472, 3, 2, 2, 2, 127, 479, 3, 2, 2, 2, 129, 525, 3, 2, 2, 2, 131, 536, 3, 2, 2, 2, 133, 547, 3, 2, 2, 2, 135, 550, 3, 2, 2, 2, 137, 561, 3, 2, 2, 2, 139, 568, 3, 2, 2, 2, 141, 570, 3, 2, 2, 2, 143, 581, 3, 2, 2, 2, 145, 146, 7, 42, 2, 2, 146, 4, 3, 2, 2, 2, 147, 148, 7, 43, 2, 2, 148, 6, 3, 2, 2, 2, 149, 150, 7, 117, 2, 2, 150, 151, 7, 103, 2, 2, 151, 152, 7, 110, 2, 2, 152, 153, 7, 103, 2, 2, 153, 154, 7, 101, 2, 2, 154, 155, 7, 118, 2, 2, 155, 8, 3, 2, 2, 2, 156, 157, 7, 102, 2, 2, 157, 158, 7, 107, 2, 2, 158, 159, 7, 117, 2, 2, 159, 160, 7, 118, 2, 2, 160, 161, 7, 107, 2, 2, 161, 162, 7, 112, 2, 2, 162, 163, 7, 101, 2, 2, 163, 164, 7, 118, 2, 2, 164, 10, 3, 2, 2, 2, 165, 166, 7, 121, 2, 2, 166, 167, 7, 106, 2, 2, 167, 168, 7, 103, 2, 2, 168, 169, 7, 116, 2, 2, 169, 170, 7, 103, 2, 2, 170, 12, 3, 2, 2, 2, 171, 172, 7, 113, 2, 2, 172, 173, 7, 116, 2, 2, 173, 174, 7, 102, 2, 2, 174, 175, 7, 103, 2, 2, 175, 176, 7, 116, 2, 2, 176, 14, 3, 2, 2, 2, 177, 178, 7, 100, 2, 2, 178, 179, 7, 123, 2, 2, 179, 16, 3, 2, 2, 2, 180, 181, 7, 46, 2, 2, 181, 18, 3, 2, 2, 2, 182, 183, 7, 112, 2, 2, 183, 184, 7, 119, 2, 2, 184, 185, 7, 110, 2, 2, 185, 186, 7, 110, 2, 2, 186, 187, 7, 117, 2, 2, 187, 20, 3, 2, 2, 2, 188, 189, 7, 104, 2, 2, 189, 190, 7, 107, 2, 2, 190, 191, 7, 116, 2, 2, 191, 192, 7, 117, 2, 2, 192, 193, 7, 118, 2, 2, 193, 22, 3, 2, 2, 2, 194, 195, 7, 110, 2, 2, 195, 196, 7, 99, 2, 2, 196, 197, 7, 117, 2, 2, 197, 198, 7, 118, 2, 2, 198, 24, 3, 2, 2, 2, 199, 200, 7, 99, 2, 2, 200, 201, 7, 117, 2, 2, 201, 202, 7, 101, 2, 2, 202, 26, 3, 2, 2, 2, 203, 204, 7, 102, 2, 2, 204, 205, 7, 103, 2, 2, 205, 206, 7, 117, 2, 2, 206, 207, 7, 101, 2, 2, 207, 28, 3, 2, 2, 2, 208, 209, 7, 110, 2, 2, 209, 210, 7, 107, 2, 2, 210, 211, 7, 111, 2, 2, 211, 212, 7, 107, 2, 2, 212, 213, 7, 118, 2, 2, 213, 30, 3, 2, 2, 2, 214, 215, 7, 113, 2, 2, 215, 216, 7, 104, 2, 2, 216, 217, 7, 104, 2, 2, 217, 218, 7, 117, 2, 2, 218, 219, 7, 103, 2, 2, 219, 220, 7, 118, 2, 2, 220, 32, 3, 2, 2, 2, 221, 222, 7, 104, 2, 2, 222, 223, 7, 103, 2, 2, 223, 224, 7, 118, 2, 2, 224, 225, 7, 101, 2, 2, 225, 226, 7, 106, 2, 2, 226, 34, 3, 2, 2, 2, 227, 228, 7, 45, 2, 2, 228, 36, 3, 2, 2, 2, 229, 230, 7, 115, 2, 2, 230, 231, 7, 119, 2, 2, 231, 232, 7, 103, 2, 2, 232, 233, 7, 116, 2, 2, 233, 234, 7, 123, 2, 2, 234, 38, 3, 2, 2, 2, 235, 236, 7, 110, 2, 2, 236, 237, 7, 99, 2, 2, 237, 238, 7, 124, 2, 2, 238, 239, 7, 123, 2, 2, 239, 40, 3, 2, 2, 2, 240, 241, 7, 113, 2, 2, 241, 242, 7, 116, 2, 2, 242, 42, 3, 2, 2, 2, 243, 244, 7, 99, 2, 2, 244, 245, 7, 112, 2, 2, 245, 246, 7, 102, 2, 2, 246, 44, 3, 2, 2, 2, 247, 248, 7, 112, 2, 2, 248, 249, 7, 113, 2, 2, 249, 250, 7, 118, 2, 2, 250, 46, 3, 2, 2, 2, 251, 252, 7, 107, 2, 2, 252, 253, 7, 112, 2, 2, 253, 48, 3, 2, 2, 2, 254, 255, 7, 100, 2, 2, 255, 256, 7, 103, 2, 2, 256, 257, 7, 118, 2, 2, 257, 258, 7, 121, 2, 2, 258, 259, 7, 103, 2, 2, 259, 260, 7, 103, 2, 2, 260, 261, 7, 112, 2, 2, 261, 50, 3, 2, 2, 2, 262, 263, 7, 107, 2, 2, 263, 264, 7, 112, 2, 2, 264, 265, 7, 116, 2, 2, 265, 266, 7, 99, 2, 2, 266, 267, 7, 112, 2, 2, 267, 268, 7, 105, 2, 2, 268, 269, 7, 103, 2, 2, 269, 52, 3, 2, 2, 2, 270, 271, 7, 118, 2, 2, 271, 272, 7, 113, 2, 2, 272, 54, 3, 2, 2, 2, 273, 274, 7, 107, 2, 2, 274, 275, 7, 117, 2, 2, 275, 56, 3, 2, 2, 2, 276, 277, 7, 112, 2, 2, 277, 278, 7, 119, 2, 2, 278, 279, 7, 110, 2, 2, 279, 280, 7, 110, 2, 2, 280, 58, 3, 2, 2, 2, 281, 282, 7, 107, 2, 2, 282, 283, 7, 117, 2, 2, 283, 284, 7, 80, 2, 2, 284, 285, 7, 119, 2, 2, 285, 286, 7, 110, 2, 2, 286, 287, 7, 110, 2, 2, 287, 60, 3, 2, 2, 2, 288, 289, 7, 107, 2, 2, 289, 290, 7, 117, 2, 2, 290, 291, 7, 80, 2, 2, 291, 292, 7, 113, 2, 2, 292, 293, 7, 118, 2, 2, 293, 294, 7, 80, 2, 2, 294, 295, 7, 119, 2, 2, 295, 296, 7, 110, 2, 2, 296, 297, 7, 110, 2, 2, 297, 62, 3, 2, 2, 2, 298, 299, 7, 112, 2, 2, 299, 300, 7, 113, 2, 2, 300, 301, 7, 118, 2, 2, 301, 302, 7, 80, 2, 2, 302, 303, 7, 119, 2, 2, 303, 304, 7, 110, 2, 2, 304, 305, 7, 110, 2, 2, 305, 64, 3, 2, 2, 2, 306, 307, 7, 103, 2, 2, 307, 308, 7, 111, 2, 2, 308, 309, 7, 114, 2, 2, 309, 310, 7, 118, 2, 2, 310, 311, 7, 123, 2, 2, 311, 66, 3, 2, 2, 2, 312, 313, 7, 107, 2, 2, 313, 314, 7, 117, 2, 2, 314, 315, 7, 71, 2, 2, 315, 316, 7, 111, 2, 2, 316, 317, 7, 114, 2, 2, 317, 318, 7, 118, 2, 2, 318, 319, 7, 123, 2, 2, 319, 68, 3, 2, 2, 2, 320, 321, 7, 107, 2, 2, 321, 322, 7, 117, 2, 2, 322, 323, 7, 80, 2, 2, 323, 324, 7, 113, 2, 2, 324, 325, 7, 118, 2, 2, 325, 326, 7, 71, 2, 2, 326, 327, 7, 111, 2, 2, 327, 328, 7, 114, 2, 2, 328, 329, 7, 118, 2, 2, 329, 330, 7, 123, 2, 2, 330, 70, 3, 2, 2, 2, 331, 332, 7, 112, 2, 2, 332, 333, 7, 113, 2, 2, 333, 334, 7, 118, 2, 2, 334, 335, 7, 71, 2, 2, 335, 336, 7, 111, 2, 2, 336, 337, 7, 114, 2, 2, 337, 338, 7, 118, 2, 2, 338, 339, 7, 123, 2, 2, 339, 72, 3, 2, 2, 2, 340, 341, 7, 110, 2, 2, 341, 342, 7, 107, 2, 2, 342, 343, 7, 109, 2, 2, 343, 344, 7, 103, 2, 2, 344, 74, 3, 2, 2, 2, 345, 346, 7, 107, 2, 2, 346, 347, 7, 110, 2, 2, 347, 348, 7, 107, 2, 2, 348, 349, 7, 109, 2, 2, 349, 350, 7, 103, 2, 2, 350, 76, 3, 2, 2, 2, 351, 352, 7, 101, 2, 2, 352, 353, 7, 113, 2, 2, 353, 354, 7, 112, 2, 2, 354, 355, 7, 118, 2, 2, 355, 356, 7, 99, 2, 2, 356, 357, 7, 107, 2, 2, 357, 358, 7, 112, 2, 2, 358, 359, 7, 117, 2, 2, 359, 78, 3, 2, 2, 2, 360, 361, 7, 107, 2, 2, 361, 362, 7, 101, 2, 2, 362, 363, 7, 113, 2, 2, 363, 364, 7, 112, 2, 2, 364, 365, 7, 118, 2, 2, 365, 366, 7, 99, 2, 2, 366, 367, 7, 107, 2, 2, 367, 368, 7, 112, 2, 2, 368, 369, 7, 117, 2, 2, 369, 80, 3, 2, 2, 2, 370, 371, 7, 117, 2, 2, 371, 372, 7, 118, 2, 2, 372, 373, 7, 99, 2, 2, 373, 374, 7, 116, 2, 2, 374, 375, 7, 118, 2, 2, 375, 376, 7, 117, 2, 2, 376, 377, 7, 89, 2, 2, 377, 378, 7, 107, 2, 2, 378, 379, 7, 118, 2, 2, 379, 380, 7, 106, 2, 2, 380, 82, 3, 2, 2, 2, 381, 382, 7, 107, 2, 2, 382, 383, 7, 117, 2, 2, 383, 384, 7, 118, 2, 2, 384, 385, 7, 99, 2, 2, 385, 386, 7, 116, 2, 2, 386, 387, 7, 118, 2, 2, 387, 388, 7, 117, 2, 2, 388, 389, 7, 89, 2, 2, 389, 390, 7, 107, 2, 2, 390, 391, 7, 118, 2, 2, 391, 392, 7, 106, 2, 2, 392, 84, 3, 2, 2, 2, 393, 394, 7, 103, 2, 2, 394, 395, 7, 112, 2, 2, 395, 396, 7, 102, 2, 2, 396, 397, 7, 117, 2, 2, 397, 398, 7, 89, 2, 2, 398, 399, 7, 107, 2, 2, 399, 400, 7, 118, 2, 2, 400, 401, 7, 106, 2, 2, 401, 86, 3, 2, 2, 2, 402, 403, 7, 107, 2, 2, 403, 404, 7, 103, 2, 2, 404, 405, 7, 112, 2, 2, 405, 406, 7, 102, 2, 2, 406, 407, 7, 117, 2, 2, 407, 408, 7, 89, 2, 2, 408, 409, 7, 107, 2, 2, 409, 410, 7, 118, 2, 2, 410, 411, 7, 106, 2, 2, 411, 88, 3, 2, 2, 2, 412, 413, 7, 63, 2, 2, 413, 90, 3, 2, 2, 2, 414, 415, 7, 103, 2, 2, 415, 416, 7, 115, 2, 2, 416, 92, 3, 2, 2, 2, 417, 418, 7, 64, 2, 2, 418, 94, 3, 2, 2, 2, 419, 420, 7, 105, 2, 2, 420, 421, 7, 118, 2, 2, 421, 96, 3, 2, 2, 2, 422, 423, 7, 64, 2, 2, 423, 424, 7, 63, 2, 2, 424, 98, 3, 2, 2, 2, 425, 426, 7, 105, 2, 2, 426, 427, 7, 103, 2, 2, 427, 100, 3, 2, 2, 2, 428, 429, 7, 105, 2, 2, 429, 430, 7, 118, 2, 2, 430, 431, 7, 103, 2, 2, 431, 102, 3, 2, 2, 2, 432, 433, 7, 62, 2, 2, 433, 104, 3, 2, 2, 2, 434, 435, 7, 110, 2, 2, 435, 436, 7, 118, 2, 2, 436, 106, 3, 2, 2, 2, 437, 438, 7, 62, 2, 2, 438, 439, 7, 63, 2, 2, 439, 108, 3, 2, 2, 2, 440, 441, 7, 110, 2, 2, 441, 442, 7, 103, 2, 2, 442, 110, 3, 2, 2, 2, 443, 444, 7, 110, 2, 2, 444, 445, 7, 118, 2, 2, 445, 446, 7, 103, 2, 2, 446, 112, 3, 2, 2, 2, 447, 448, 7, 62, 2, 2, 448, 449, 7, 64, 2, 2, 449, 114, 3, 2, 2, 2, 450, 451, 7, 35, 2, 2, 451, 452, 7, 63, 2, 2, 452, 116, 3, 2, 2, 2, 453, 454, 7, 112, 2, 2, 454, 455, 7, 103, 2, 2, 455, 118, 3, 2, 2, 2, 456, 457, 7, 107, 2, 2, 457, 458, 7, 103, 2, 2, 458, 459, 7, 115, 2, 2, 459, 120, 3, 2, 2, 2, 460, 461, 7, 107, 2, 2, 461, 462, 7, 112, 2, 2, 462, 463, 7, 103, 2, 2, 463, 122, 3, 2, 2, 2, 464, 465, 7, 60, 2, 2, 465, 469, 9, 2, 2, 2, 466, 468, 9, 3, 2, 2, 467, 466, 3, 2, 2, 2, 468, 471, 3, 2, 2, 2, 469, 467, 3, 2, 2, 2, 469, 470, 3, 2, 2, 2, 470, 124, 3, 2, 2, 2, 471, 469, 3, 2, 2, 2, 472, 476, 9, 2, 2, 2, 473, 475, 9, 4, 2, 2, 474, 473, 3, 2, 2, 2, 475, 478, 3, 2, 2, 2, 476, 474, 3, 2, 2, 2, 476, 477, 3, 2, 2, 2, 477, 126, 3, 2, 2, 2, 478, 476, 3, 2, 2, 2, 479, 480, 7, 98, 2, 2, 480, 481, 5, 125, 63, 2, 481, 482, 7, 98, 2, 2, 482, 128, 3, 2, 2, 2, 483, 484, 7, 117, 2, 2, 484, 485, 7, 119, 2, 2, 485, 486, 7, 111, 2, 2, 486, 487, 7, 42, 2, 2, 487, 488, 3, 2, 2, 2, 488, 489, 5, 125, 63, 2, 489, 490, 7, 43, 2, 2, 490, 526, 3, 2, 2, 2, 491, 492, 7, 111, 2, 2, 492, 493, 7, 99, 2, 2, 493, 494, 7, 122, 2, 2, 494, 495, 7, 42, 2, 2, 495, 496, 3, 2, 2, 2, 496, 497, 5, 125, 63, 2, 497, 498, 7, 43, 2, 2, 498, 526, 3, 2, 2, 2, 499, 500, 7, 111, 2, 2, 500, 501, 7, 107, 2, 2, 501, 502, 7, 112, 2, 2, 502, 503, 7, 42, 2, 2, 503, 504, 3, 2, 2, 2, 504, 505, 5, 125, 63, 2, 505, 506, 7, 43, 2, 2, 506, 526, 3, 2, 2, 2, 507, 508, 7, 99, 2, 2, 508, 509, 7, 120, 2, 2, 509, 510, 7, 105, 2, 2, 510, 511, 7, 42, 2, 2, 511, 512, 3, 2, 2, 2, 512, 513, 5, 125, 63, 2, 513, 514, 7, 43, 2, 2, 514, 526, 3, 2, 2, 2, 515, 516, 7, 101, 2, 2, 516, 517, 7, 113, 2, 2, 517, 518, 7, 119, 2, 2, 518, 519, 7, 112, 2, 2, 519, 520, 7, 118, 2, 2, 520, 521, 7, 42, 2, 2, 521, 522, 3, 2, 2, 2, 522, 523, 5, 125, 63, 2, 523, 524, 7, 43, 2, 2, 524, 526, 3, 2, 2, 2, 525, 483, 3, 2, 2, 2, 525, 491, 3, 2, 2, 2, 525, 499, 3, 2, 2, 2, 525, 507, 3, 2, 2, 2, 525, 515, 3, 2, 2, 2, 526, 130, 3, 2, 2, 2, 527, 528, 7, 118, 2, 2, 528, 529, 7, 116, 2, 2, 529, 530, 7, 119, 2, 2, 530, 537, 7, 103, 2, 2, 531, 532, 7, 104, 2, 2, 532, 533, 7, 99, 2, 2, 533, 534, 7, 110, 2, 2, 534, 535, 7, 117, 2, 2, 535, 537, 7, 103, 2, 2, 536, 527, 3, 2, 2, 2, 536, 531, 3, 2, 2, 2, 537, 132, 3, 2, 2, 2, 538, 540, 7, 47, 2, 2, 539, 538, 3, 2, 2, 2, 539, 540, 3, 2, 2, 2, 540, 541, 3, 2, 2, 2, 541, 548, 5, 135, 68, 2, 542, 544, 7, 47, 2, 2, 543, 542, 3, 2, 2, 2, 543, 544, 3, 2, 2, 2, 544, 545, 3, 2, 2, 2, 545, 548, 5, 137, 69, 2, 546, 548, 5, 139, 70, 2, 547, 539, 3, 2, 2, 2, 547, 543, 3, 2, 2, 2, 547, 546, 3, 2, 2, 2, 548, 134, 3, 2, 2, 2, 549, 551, 9, 5, 2, 2, 550, 549, 3, 2, 2, 2, 551, 552, 3, 2, 2, 2, 552, 550, 3, 2, 2, 2, 552, 553, 3, 2, 2, 2, 553, 554, 3, 2, 2, 2, 554, 558, 7, 48, 2, 2, 555, 557, 9, 5, 2, 2, 556, 555, 3, 2, 2, 2, 557, 560, 3, 2, 2, 2, 558, 556, 3, 2, 2, 2, 558, 559, 3, 2, 2, 2, 559, 136, 3, 2, 2, 2, 560, 558, 3, 2, 2, 2, 561, 565, 9, 6, 2, 2, 562, 564, 9, 5, 2, 2, 563, 562, 3, 2, 2, 2, 564, 567, 3, 2, 2, 2, 565, 563, 3, 2, 2, 2, 565, 566, 3, 2, 2, 2, 566, 138, 3, 2, 2, 2, 567, 565, 3, 2, 2, 2, 568, 569, 7, 50, 2, 2, 569, 140, 3, 2, 2, 2, 570, 576, 7, 41, 2, 2, 571, 575, 10, 7, 2, 2, 572, 573, 7, 41, 2, 2, 573, 575, 7, 41, 2, 2, 574, 571, 3, 2, 2, 2, 574, 572, 3, 2, 2, 2, 575, 578, 3, 2, 2, 2, 576, 574, 3, 2, 2, 2, 576, 577, 3, 2, 2, 2, 577, 579, 3, 2, 2, 2, 578, 576, 3, 2, 2, 2, 579, 580, 7, 41, 2, 2, 580, 142, 3, 2, 2, 2, 581, 582, 9, 8, 2, 2, 582, 583, 3, 2, 2, 2, 583, 584, 8, 72, 2, 2, 584, 144, 3, 2, 2, 2, 15, 2, 469, 476, 525, 536, 539, 543, 547, 552, 558, 565, 574, 576, 3, 8, 2, 2] \ No newline at end of file +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 73, 594, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 7, 62, 468, 10, 62, 12, 62, 14, 62, 471, 11, 62, 3, 62, 3, 62, 7, 62, 475, 10, 62, 12, 62, 14, 62, 478, 11, 62, 5, 62, 480, 10, 62, 3, 63, 3, 63, 7, 63, 484, 10, 63, 12, 63, 14, 63, 487, 11, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 5, 65, 535, 10, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 5, 66, 546, 10, 66, 3, 67, 5, 67, 549, 10, 67, 3, 67, 3, 67, 5, 67, 553, 10, 67, 3, 67, 3, 67, 5, 67, 557, 10, 67, 3, 68, 6, 68, 560, 10, 68, 13, 68, 14, 68, 561, 3, 68, 3, 68, 7, 68, 566, 10, 68, 12, 68, 14, 68, 569, 11, 68, 3, 69, 3, 69, 7, 69, 573, 10, 69, 12, 69, 14, 69, 576, 11, 69, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 7, 71, 584, 10, 71, 12, 71, 14, 71, 587, 11, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 2, 2, 73, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, 59, 31, 61, 32, 63, 33, 65, 34, 67, 35, 69, 36, 71, 37, 73, 38, 75, 39, 77, 40, 79, 41, 81, 42, 83, 43, 85, 44, 87, 45, 89, 46, 91, 47, 93, 48, 95, 49, 97, 50, 99, 51, 101, 52, 103, 53, 105, 54, 107, 55, 109, 56, 111, 57, 113, 58, 115, 59, 117, 60, 119, 61, 121, 62, 123, 63, 125, 64, 127, 65, 129, 66, 131, 67, 133, 68, 135, 69, 137, 70, 139, 71, 141, 72, 143, 73, 3, 2, 9, 5, 2, 67, 92, 97, 97, 99, 124, 6, 2, 50, 59, 67, 92, 97, 97, 99, 124, 7, 2, 48, 48, 50, 59, 67, 92, 97, 97, 99, 124, 3, 2, 50, 59, 3, 2, 51, 59, 3, 2, 41, 41, 5, 2, 11, 12, 15, 15, 34, 34, 2, 611, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, 2, 2, 2, 2, 139, 3, 2, 2, 2, 2, 141, 3, 2, 2, 2, 2, 143, 3, 2, 2, 2, 3, 145, 3, 2, 2, 2, 5, 147, 3, 2, 2, 2, 7, 149, 3, 2, 2, 2, 9, 156, 3, 2, 2, 2, 11, 165, 3, 2, 2, 2, 13, 171, 3, 2, 2, 2, 15, 177, 3, 2, 2, 2, 17, 180, 3, 2, 2, 2, 19, 182, 3, 2, 2, 2, 21, 188, 3, 2, 2, 2, 23, 194, 3, 2, 2, 2, 25, 199, 3, 2, 2, 2, 27, 203, 3, 2, 2, 2, 29, 208, 3, 2, 2, 2, 31, 214, 3, 2, 2, 2, 33, 221, 3, 2, 2, 2, 35, 227, 3, 2, 2, 2, 37, 229, 3, 2, 2, 2, 39, 235, 3, 2, 2, 2, 41, 240, 3, 2, 2, 2, 43, 243, 3, 2, 2, 2, 45, 247, 3, 2, 2, 2, 47, 251, 3, 2, 2, 2, 49, 254, 3, 2, 2, 2, 51, 262, 3, 2, 2, 2, 53, 270, 3, 2, 2, 2, 55, 273, 3, 2, 2, 2, 57, 276, 3, 2, 2, 2, 59, 281, 3, 2, 2, 2, 61, 288, 3, 2, 2, 2, 63, 298, 3, 2, 2, 2, 65, 306, 3, 2, 2, 2, 67, 312, 3, 2, 2, 2, 69, 320, 3, 2, 2, 2, 71, 331, 3, 2, 2, 2, 73, 340, 3, 2, 2, 2, 75, 345, 3, 2, 2, 2, 77, 351, 3, 2, 2, 2, 79, 360, 3, 2, 2, 2, 81, 370, 3, 2, 2, 2, 83, 381, 3, 2, 2, 2, 85, 393, 3, 2, 2, 2, 87, 402, 3, 2, 2, 2, 89, 412, 3, 2, 2, 2, 91, 414, 3, 2, 2, 2, 93, 417, 3, 2, 2, 2, 95, 419, 3, 2, 2, 2, 97, 422, 3, 2, 2, 2, 99, 425, 3, 2, 2, 2, 101, 428, 3, 2, 2, 2, 103, 432, 3, 2, 2, 2, 105, 434, 3, 2, 2, 2, 107, 437, 3, 2, 2, 2, 109, 440, 3, 2, 2, 2, 111, 443, 3, 2, 2, 2, 113, 447, 3, 2, 2, 2, 115, 450, 3, 2, 2, 2, 117, 453, 3, 2, 2, 2, 119, 456, 3, 2, 2, 2, 121, 460, 3, 2, 2, 2, 123, 479, 3, 2, 2, 2, 125, 481, 3, 2, 2, 2, 127, 488, 3, 2, 2, 2, 129, 534, 3, 2, 2, 2, 131, 545, 3, 2, 2, 2, 133, 556, 3, 2, 2, 2, 135, 559, 3, 2, 2, 2, 137, 570, 3, 2, 2, 2, 139, 577, 3, 2, 2, 2, 141, 579, 3, 2, 2, 2, 143, 590, 3, 2, 2, 2, 145, 146, 7, 42, 2, 2, 146, 4, 3, 2, 2, 2, 147, 148, 7, 43, 2, 2, 148, 6, 3, 2, 2, 2, 149, 150, 7, 117, 2, 2, 150, 151, 7, 103, 2, 2, 151, 152, 7, 110, 2, 2, 152, 153, 7, 103, 2, 2, 153, 154, 7, 101, 2, 2, 154, 155, 7, 118, 2, 2, 155, 8, 3, 2, 2, 2, 156, 157, 7, 102, 2, 2, 157, 158, 7, 107, 2, 2, 158, 159, 7, 117, 2, 2, 159, 160, 7, 118, 2, 2, 160, 161, 7, 107, 2, 2, 161, 162, 7, 112, 2, 2, 162, 163, 7, 101, 2, 2, 163, 164, 7, 118, 2, 2, 164, 10, 3, 2, 2, 2, 165, 166, 7, 121, 2, 2, 166, 167, 7, 106, 2, 2, 167, 168, 7, 103, 2, 2, 168, 169, 7, 116, 2, 2, 169, 170, 7, 103, 2, 2, 170, 12, 3, 2, 2, 2, 171, 172, 7, 113, 2, 2, 172, 173, 7, 116, 2, 2, 173, 174, 7, 102, 2, 2, 174, 175, 7, 103, 2, 2, 175, 176, 7, 116, 2, 2, 176, 14, 3, 2, 2, 2, 177, 178, 7, 100, 2, 2, 178, 179, 7, 123, 2, 2, 179, 16, 3, 2, 2, 2, 180, 181, 7, 46, 2, 2, 181, 18, 3, 2, 2, 2, 182, 183, 7, 112, 2, 2, 183, 184, 7, 119, 2, 2, 184, 185, 7, 110, 2, 2, 185, 186, 7, 110, 2, 2, 186, 187, 7, 117, 2, 2, 187, 20, 3, 2, 2, 2, 188, 189, 7, 104, 2, 2, 189, 190, 7, 107, 2, 2, 190, 191, 7, 116, 2, 2, 191, 192, 7, 117, 2, 2, 192, 193, 7, 118, 2, 2, 193, 22, 3, 2, 2, 2, 194, 195, 7, 110, 2, 2, 195, 196, 7, 99, 2, 2, 196, 197, 7, 117, 2, 2, 197, 198, 7, 118, 2, 2, 198, 24, 3, 2, 2, 2, 199, 200, 7, 99, 2, 2, 200, 201, 7, 117, 2, 2, 201, 202, 7, 101, 2, 2, 202, 26, 3, 2, 2, 2, 203, 204, 7, 102, 2, 2, 204, 205, 7, 103, 2, 2, 205, 206, 7, 117, 2, 2, 206, 207, 7, 101, 2, 2, 207, 28, 3, 2, 2, 2, 208, 209, 7, 110, 2, 2, 209, 210, 7, 107, 2, 2, 210, 211, 7, 111, 2, 2, 211, 212, 7, 107, 2, 2, 212, 213, 7, 118, 2, 2, 213, 30, 3, 2, 2, 2, 214, 215, 7, 113, 2, 2, 215, 216, 7, 104, 2, 2, 216, 217, 7, 104, 2, 2, 217, 218, 7, 117, 2, 2, 218, 219, 7, 103, 2, 2, 219, 220, 7, 118, 2, 2, 220, 32, 3, 2, 2, 2, 221, 222, 7, 104, 2, 2, 222, 223, 7, 103, 2, 2, 223, 224, 7, 118, 2, 2, 224, 225, 7, 101, 2, 2, 225, 226, 7, 106, 2, 2, 226, 34, 3, 2, 2, 2, 227, 228, 7, 45, 2, 2, 228, 36, 3, 2, 2, 2, 229, 230, 7, 115, 2, 2, 230, 231, 7, 119, 2, 2, 231, 232, 7, 103, 2, 2, 232, 233, 7, 116, 2, 2, 233, 234, 7, 123, 2, 2, 234, 38, 3, 2, 2, 2, 235, 236, 7, 110, 2, 2, 236, 237, 7, 99, 2, 2, 237, 238, 7, 124, 2, 2, 238, 239, 7, 123, 2, 2, 239, 40, 3, 2, 2, 2, 240, 241, 7, 113, 2, 2, 241, 242, 7, 116, 2, 2, 242, 42, 3, 2, 2, 2, 243, 244, 7, 99, 2, 2, 244, 245, 7, 112, 2, 2, 245, 246, 7, 102, 2, 2, 246, 44, 3, 2, 2, 2, 247, 248, 7, 112, 2, 2, 248, 249, 7, 113, 2, 2, 249, 250, 7, 118, 2, 2, 250, 46, 3, 2, 2, 2, 251, 252, 7, 107, 2, 2, 252, 253, 7, 112, 2, 2, 253, 48, 3, 2, 2, 2, 254, 255, 7, 100, 2, 2, 255, 256, 7, 103, 2, 2, 256, 257, 7, 118, 2, 2, 257, 258, 7, 121, 2, 2, 258, 259, 7, 103, 2, 2, 259, 260, 7, 103, 2, 2, 260, 261, 7, 112, 2, 2, 261, 50, 3, 2, 2, 2, 262, 263, 7, 107, 2, 2, 263, 264, 7, 112, 2, 2, 264, 265, 7, 116, 2, 2, 265, 266, 7, 99, 2, 2, 266, 267, 7, 112, 2, 2, 267, 268, 7, 105, 2, 2, 268, 269, 7, 103, 2, 2, 269, 52, 3, 2, 2, 2, 270, 271, 7, 118, 2, 2, 271, 272, 7, 113, 2, 2, 272, 54, 3, 2, 2, 2, 273, 274, 7, 107, 2, 2, 274, 275, 7, 117, 2, 2, 275, 56, 3, 2, 2, 2, 276, 277, 7, 112, 2, 2, 277, 278, 7, 119, 2, 2, 278, 279, 7, 110, 2, 2, 279, 280, 7, 110, 2, 2, 280, 58, 3, 2, 2, 2, 281, 282, 7, 107, 2, 2, 282, 283, 7, 117, 2, 2, 283, 284, 7, 80, 2, 2, 284, 285, 7, 119, 2, 2, 285, 286, 7, 110, 2, 2, 286, 287, 7, 110, 2, 2, 287, 60, 3, 2, 2, 2, 288, 289, 7, 107, 2, 2, 289, 290, 7, 117, 2, 2, 290, 291, 7, 80, 2, 2, 291, 292, 7, 113, 2, 2, 292, 293, 7, 118, 2, 2, 293, 294, 7, 80, 2, 2, 294, 295, 7, 119, 2, 2, 295, 296, 7, 110, 2, 2, 296, 297, 7, 110, 2, 2, 297, 62, 3, 2, 2, 2, 298, 299, 7, 112, 2, 2, 299, 300, 7, 113, 2, 2, 300, 301, 7, 118, 2, 2, 301, 302, 7, 80, 2, 2, 302, 303, 7, 119, 2, 2, 303, 304, 7, 110, 2, 2, 304, 305, 7, 110, 2, 2, 305, 64, 3, 2, 2, 2, 306, 307, 7, 103, 2, 2, 307, 308, 7, 111, 2, 2, 308, 309, 7, 114, 2, 2, 309, 310, 7, 118, 2, 2, 310, 311, 7, 123, 2, 2, 311, 66, 3, 2, 2, 2, 312, 313, 7, 107, 2, 2, 313, 314, 7, 117, 2, 2, 314, 315, 7, 71, 2, 2, 315, 316, 7, 111, 2, 2, 316, 317, 7, 114, 2, 2, 317, 318, 7, 118, 2, 2, 318, 319, 7, 123, 2, 2, 319, 68, 3, 2, 2, 2, 320, 321, 7, 107, 2, 2, 321, 322, 7, 117, 2, 2, 322, 323, 7, 80, 2, 2, 323, 324, 7, 113, 2, 2, 324, 325, 7, 118, 2, 2, 325, 326, 7, 71, 2, 2, 326, 327, 7, 111, 2, 2, 327, 328, 7, 114, 2, 2, 328, 329, 7, 118, 2, 2, 329, 330, 7, 123, 2, 2, 330, 70, 3, 2, 2, 2, 331, 332, 7, 112, 2, 2, 332, 333, 7, 113, 2, 2, 333, 334, 7, 118, 2, 2, 334, 335, 7, 71, 2, 2, 335, 336, 7, 111, 2, 2, 336, 337, 7, 114, 2, 2, 337, 338, 7, 118, 2, 2, 338, 339, 7, 123, 2, 2, 339, 72, 3, 2, 2, 2, 340, 341, 7, 110, 2, 2, 341, 342, 7, 107, 2, 2, 342, 343, 7, 109, 2, 2, 343, 344, 7, 103, 2, 2, 344, 74, 3, 2, 2, 2, 345, 346, 7, 107, 2, 2, 346, 347, 7, 110, 2, 2, 347, 348, 7, 107, 2, 2, 348, 349, 7, 109, 2, 2, 349, 350, 7, 103, 2, 2, 350, 76, 3, 2, 2, 2, 351, 352, 7, 101, 2, 2, 352, 353, 7, 113, 2, 2, 353, 354, 7, 112, 2, 2, 354, 355, 7, 118, 2, 2, 355, 356, 7, 99, 2, 2, 356, 357, 7, 107, 2, 2, 357, 358, 7, 112, 2, 2, 358, 359, 7, 117, 2, 2, 359, 78, 3, 2, 2, 2, 360, 361, 7, 107, 2, 2, 361, 362, 7, 101, 2, 2, 362, 363, 7, 113, 2, 2, 363, 364, 7, 112, 2, 2, 364, 365, 7, 118, 2, 2, 365, 366, 7, 99, 2, 2, 366, 367, 7, 107, 2, 2, 367, 368, 7, 112, 2, 2, 368, 369, 7, 117, 2, 2, 369, 80, 3, 2, 2, 2, 370, 371, 7, 117, 2, 2, 371, 372, 7, 118, 2, 2, 372, 373, 7, 99, 2, 2, 373, 374, 7, 116, 2, 2, 374, 375, 7, 118, 2, 2, 375, 376, 7, 117, 2, 2, 376, 377, 7, 89, 2, 2, 377, 378, 7, 107, 2, 2, 378, 379, 7, 118, 2, 2, 379, 380, 7, 106, 2, 2, 380, 82, 3, 2, 2, 2, 381, 382, 7, 107, 2, 2, 382, 383, 7, 117, 2, 2, 383, 384, 7, 118, 2, 2, 384, 385, 7, 99, 2, 2, 385, 386, 7, 116, 2, 2, 386, 387, 7, 118, 2, 2, 387, 388, 7, 117, 2, 2, 388, 389, 7, 89, 2, 2, 389, 390, 7, 107, 2, 2, 390, 391, 7, 118, 2, 2, 391, 392, 7, 106, 2, 2, 392, 84, 3, 2, 2, 2, 393, 394, 7, 103, 2, 2, 394, 395, 7, 112, 2, 2, 395, 396, 7, 102, 2, 2, 396, 397, 7, 117, 2, 2, 397, 398, 7, 89, 2, 2, 398, 399, 7, 107, 2, 2, 399, 400, 7, 118, 2, 2, 400, 401, 7, 106, 2, 2, 401, 86, 3, 2, 2, 2, 402, 403, 7, 107, 2, 2, 403, 404, 7, 103, 2, 2, 404, 405, 7, 112, 2, 2, 405, 406, 7, 102, 2, 2, 406, 407, 7, 117, 2, 2, 407, 408, 7, 89, 2, 2, 408, 409, 7, 107, 2, 2, 409, 410, 7, 118, 2, 2, 410, 411, 7, 106, 2, 2, 411, 88, 3, 2, 2, 2, 412, 413, 7, 63, 2, 2, 413, 90, 3, 2, 2, 2, 414, 415, 7, 103, 2, 2, 415, 416, 7, 115, 2, 2, 416, 92, 3, 2, 2, 2, 417, 418, 7, 64, 2, 2, 418, 94, 3, 2, 2, 2, 419, 420, 7, 105, 2, 2, 420, 421, 7, 118, 2, 2, 421, 96, 3, 2, 2, 2, 422, 423, 7, 64, 2, 2, 423, 424, 7, 63, 2, 2, 424, 98, 3, 2, 2, 2, 425, 426, 7, 105, 2, 2, 426, 427, 7, 103, 2, 2, 427, 100, 3, 2, 2, 2, 428, 429, 7, 105, 2, 2, 429, 430, 7, 118, 2, 2, 430, 431, 7, 103, 2, 2, 431, 102, 3, 2, 2, 2, 432, 433, 7, 62, 2, 2, 433, 104, 3, 2, 2, 2, 434, 435, 7, 110, 2, 2, 435, 436, 7, 118, 2, 2, 436, 106, 3, 2, 2, 2, 437, 438, 7, 62, 2, 2, 438, 439, 7, 63, 2, 2, 439, 108, 3, 2, 2, 2, 440, 441, 7, 110, 2, 2, 441, 442, 7, 103, 2, 2, 442, 110, 3, 2, 2, 2, 443, 444, 7, 110, 2, 2, 444, 445, 7, 118, 2, 2, 445, 446, 7, 103, 2, 2, 446, 112, 3, 2, 2, 2, 447, 448, 7, 62, 2, 2, 448, 449, 7, 64, 2, 2, 449, 114, 3, 2, 2, 2, 450, 451, 7, 35, 2, 2, 451, 452, 7, 63, 2, 2, 452, 116, 3, 2, 2, 2, 453, 454, 7, 112, 2, 2, 454, 455, 7, 103, 2, 2, 455, 118, 3, 2, 2, 2, 456, 457, 7, 107, 2, 2, 457, 458, 7, 103, 2, 2, 458, 459, 7, 115, 2, 2, 459, 120, 3, 2, 2, 2, 460, 461, 7, 107, 2, 2, 461, 462, 7, 112, 2, 2, 462, 463, 7, 103, 2, 2, 463, 122, 3, 2, 2, 2, 464, 465, 7, 60, 2, 2, 465, 469, 9, 2, 2, 2, 466, 468, 9, 3, 2, 2, 467, 466, 3, 2, 2, 2, 468, 471, 3, 2, 2, 2, 469, 467, 3, 2, 2, 2, 469, 470, 3, 2, 2, 2, 470, 480, 3, 2, 2, 2, 471, 469, 3, 2, 2, 2, 472, 476, 7, 65, 2, 2, 473, 475, 4, 50, 59, 2, 474, 473, 3, 2, 2, 2, 475, 478, 3, 2, 2, 2, 476, 474, 3, 2, 2, 2, 476, 477, 3, 2, 2, 2, 477, 480, 3, 2, 2, 2, 478, 476, 3, 2, 2, 2, 479, 464, 3, 2, 2, 2, 479, 472, 3, 2, 2, 2, 480, 124, 3, 2, 2, 2, 481, 485, 9, 2, 2, 2, 482, 484, 9, 4, 2, 2, 483, 482, 3, 2, 2, 2, 484, 487, 3, 2, 2, 2, 485, 483, 3, 2, 2, 2, 485, 486, 3, 2, 2, 2, 486, 126, 3, 2, 2, 2, 487, 485, 3, 2, 2, 2, 488, 489, 7, 98, 2, 2, 489, 490, 5, 125, 63, 2, 490, 491, 7, 98, 2, 2, 491, 128, 3, 2, 2, 2, 492, 493, 7, 117, 2, 2, 493, 494, 7, 119, 2, 2, 494, 495, 7, 111, 2, 2, 495, 496, 7, 42, 2, 2, 496, 497, 3, 2, 2, 2, 497, 498, 5, 125, 63, 2, 498, 499, 7, 43, 2, 2, 499, 535, 3, 2, 2, 2, 500, 501, 7, 111, 2, 2, 501, 502, 7, 99, 2, 2, 502, 503, 7, 122, 2, 2, 503, 504, 7, 42, 2, 2, 504, 505, 3, 2, 2, 2, 505, 506, 5, 125, 63, 2, 506, 507, 7, 43, 2, 2, 507, 535, 3, 2, 2, 2, 508, 509, 7, 111, 2, 2, 509, 510, 7, 107, 2, 2, 510, 511, 7, 112, 2, 2, 511, 512, 7, 42, 2, 2, 512, 513, 3, 2, 2, 2, 513, 514, 5, 125, 63, 2, 514, 515, 7, 43, 2, 2, 515, 535, 3, 2, 2, 2, 516, 517, 7, 99, 2, 2, 517, 518, 7, 120, 2, 2, 518, 519, 7, 105, 2, 2, 519, 520, 7, 42, 2, 2, 520, 521, 3, 2, 2, 2, 521, 522, 5, 125, 63, 2, 522, 523, 7, 43, 2, 2, 523, 535, 3, 2, 2, 2, 524, 525, 7, 101, 2, 2, 525, 526, 7, 113, 2, 2, 526, 527, 7, 119, 2, 2, 527, 528, 7, 112, 2, 2, 528, 529, 7, 118, 2, 2, 529, 530, 7, 42, 2, 2, 530, 531, 3, 2, 2, 2, 531, 532, 5, 125, 63, 2, 532, 533, 7, 43, 2, 2, 533, 535, 3, 2, 2, 2, 534, 492, 3, 2, 2, 2, 534, 500, 3, 2, 2, 2, 534, 508, 3, 2, 2, 2, 534, 516, 3, 2, 2, 2, 534, 524, 3, 2, 2, 2, 535, 130, 3, 2, 2, 2, 536, 537, 7, 118, 2, 2, 537, 538, 7, 116, 2, 2, 538, 539, 7, 119, 2, 2, 539, 546, 7, 103, 2, 2, 540, 541, 7, 104, 2, 2, 541, 542, 7, 99, 2, 2, 542, 543, 7, 110, 2, 2, 543, 544, 7, 117, 2, 2, 544, 546, 7, 103, 2, 2, 545, 536, 3, 2, 2, 2, 545, 540, 3, 2, 2, 2, 546, 132, 3, 2, 2, 2, 547, 549, 7, 47, 2, 2, 548, 547, 3, 2, 2, 2, 548, 549, 3, 2, 2, 2, 549, 550, 3, 2, 2, 2, 550, 557, 5, 135, 68, 2, 551, 553, 7, 47, 2, 2, 552, 551, 3, 2, 2, 2, 552, 553, 3, 2, 2, 2, 553, 554, 3, 2, 2, 2, 554, 557, 5, 137, 69, 2, 555, 557, 5, 139, 70, 2, 556, 548, 3, 2, 2, 2, 556, 552, 3, 2, 2, 2, 556, 555, 3, 2, 2, 2, 557, 134, 3, 2, 2, 2, 558, 560, 9, 5, 2, 2, 559, 558, 3, 2, 2, 2, 560, 561, 3, 2, 2, 2, 561, 559, 3, 2, 2, 2, 561, 562, 3, 2, 2, 2, 562, 563, 3, 2, 2, 2, 563, 567, 7, 48, 2, 2, 564, 566, 9, 5, 2, 2, 565, 564, 3, 2, 2, 2, 566, 569, 3, 2, 2, 2, 567, 565, 3, 2, 2, 2, 567, 568, 3, 2, 2, 2, 568, 136, 3, 2, 2, 2, 569, 567, 3, 2, 2, 2, 570, 574, 9, 6, 2, 2, 571, 573, 9, 5, 2, 2, 572, 571, 3, 2, 2, 2, 573, 576, 3, 2, 2, 2, 574, 572, 3, 2, 2, 2, 574, 575, 3, 2, 2, 2, 575, 138, 3, 2, 2, 2, 576, 574, 3, 2, 2, 2, 577, 578, 7, 50, 2, 2, 578, 140, 3, 2, 2, 2, 579, 585, 7, 41, 2, 2, 580, 584, 10, 7, 2, 2, 581, 582, 7, 41, 2, 2, 582, 584, 7, 41, 2, 2, 583, 580, 3, 2, 2, 2, 583, 581, 3, 2, 2, 2, 584, 587, 3, 2, 2, 2, 585, 583, 3, 2, 2, 2, 585, 586, 3, 2, 2, 2, 586, 588, 3, 2, 2, 2, 587, 585, 3, 2, 2, 2, 588, 589, 7, 41, 2, 2, 589, 142, 3, 2, 2, 2, 590, 591, 9, 8, 2, 2, 591, 592, 3, 2, 2, 2, 592, 593, 8, 72, 2, 2, 593, 144, 3, 2, 2, 2, 17, 2, 469, 476, 479, 485, 534, 545, 548, 552, 556, 561, 567, 574, 583, 585, 3, 8, 2, 2] \ No newline at end of file diff --git a/src/main/java/io/ebeaninternal/server/grammer/antlr/EQLLexer.java b/src/main/java/io/ebeaninternal/server/grammer/antlr/EQLLexer.java index f0d4414a5..149bdca4c 100644 --- a/src/main/java/io/ebeaninternal/server/grammer/antlr/EQLLexer.java +++ b/src/main/java/io/ebeaninternal/server/grammer/antlr/EQLLexer.java @@ -140,7 +140,7 @@ public class EQLLexer extends Lexer { public ATN getATN() { return _ATN; } public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2I\u0249\b\1\4\2\t"+ + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2I\u0252\b\1\4\2\t"+ "\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ @@ -167,76 +167,77 @@ public class EQLLexer extends Lexer { ",\3,\3,\3,\3,\3,\3,\3,\3-\3-\3.\3.\3.\3/\3/\3\60\3\60\3\60\3\61\3\61\3"+ "\61\3\62\3\62\3\62\3\63\3\63\3\63\3\63\3\64\3\64\3\65\3\65\3\65\3\66\3"+ "\66\3\66\3\67\3\67\3\67\38\38\38\38\39\39\39\3:\3:\3:\3;\3;\3;\3<\3<\3"+ - "<\3<\3=\3=\3=\3=\3>\3>\3>\7>\u01d4\n>\f>\16>\u01d7\13>\3?\3?\7?\u01db"+ - "\n?\f?\16?\u01de\13?\3@\3@\3@\3@\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3"+ - "A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3"+ - "A\3A\3A\3A\3A\3A\3A\5A\u020e\nA\3B\3B\3B\3B\3B\3B\3B\3B\3B\5B\u0219\n"+ - "B\3C\5C\u021c\nC\3C\3C\5C\u0220\nC\3C\3C\5C\u0224\nC\3D\6D\u0227\nD\r"+ - "D\16D\u0228\3D\3D\7D\u022d\nD\fD\16D\u0230\13D\3E\3E\7E\u0234\nE\fE\16"+ - "E\u0237\13E\3F\3F\3G\3G\3G\3G\7G\u023f\nG\fG\16G\u0242\13G\3G\3G\3H\3"+ - "H\3H\3H\2\2I\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16"+ - "\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34"+ - "\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g"+ - "\65i\66k\67m8o9q:s;u{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F"+ - "\u008bG\u008dH\u008fI\3\2\t\5\2C\\aac|\6\2\62;C\\aac|\7\2\60\60\62;C\\"+ - "aac|\3\2\62;\3\2\63;\3\2))\5\2\13\f\17\17\"\"\2\u0258\2\3\3\2\2\2\2\5"+ - "\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2"+ - "\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33"+ - "\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2"+ - "\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2"+ - "\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2"+ - "\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K"+ - "\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2"+ - "\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2"+ - "\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q"+ - "\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2"+ - "\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087"+ - "\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2"+ - "\2\3\u0091\3\2\2\2\5\u0093\3\2\2\2\7\u0095\3\2\2\2\t\u009c\3\2\2\2\13"+ - "\u00a5\3\2\2\2\r\u00ab\3\2\2\2\17\u00b1\3\2\2\2\21\u00b4\3\2\2\2\23\u00b6"+ - "\3\2\2\2\25\u00bc\3\2\2\2\27\u00c2\3\2\2\2\31\u00c7\3\2\2\2\33\u00cb\3"+ - "\2\2\2\35\u00d0\3\2\2\2\37\u00d6\3\2\2\2!\u00dd\3\2\2\2#\u00e3\3\2\2\2"+ - "%\u00e5\3\2\2\2\'\u00eb\3\2\2\2)\u00f0\3\2\2\2+\u00f3\3\2\2\2-\u00f7\3"+ - "\2\2\2/\u00fb\3\2\2\2\61\u00fe\3\2\2\2\63\u0106\3\2\2\2\65\u010e\3\2\2"+ - "\2\67\u0111\3\2\2\29\u0114\3\2\2\2;\u0119\3\2\2\2=\u0120\3\2\2\2?\u012a"+ - "\3\2\2\2A\u0132\3\2\2\2C\u0138\3\2\2\2E\u0140\3\2\2\2G\u014b\3\2\2\2I"+ - "\u0154\3\2\2\2K\u0159\3\2\2\2M\u015f\3\2\2\2O\u0168\3\2\2\2Q\u0172\3\2"+ - "\2\2S\u017d\3\2\2\2U\u0189\3\2\2\2W\u0192\3\2\2\2Y\u019c\3\2\2\2[\u019e"+ - "\3\2\2\2]\u01a1\3\2\2\2_\u01a3\3\2\2\2a\u01a6\3\2\2\2c\u01a9\3\2\2\2e"+ - "\u01ac\3\2\2\2g\u01b0\3\2\2\2i\u01b2\3\2\2\2k\u01b5\3\2\2\2m\u01b8\3\2"+ - "\2\2o\u01bb\3\2\2\2q\u01bf\3\2\2\2s\u01c2\3\2\2\2u\u01c5\3\2\2\2w\u01c8"+ - "\3\2\2\2y\u01cc\3\2\2\2{\u01d0\3\2\2\2}\u01d8\3\2\2\2\177\u01df\3\2\2"+ - "\2\u0081\u020d\3\2\2\2\u0083\u0218\3\2\2\2\u0085\u0223\3\2\2\2\u0087\u0226"+ - "\3\2\2\2\u0089\u0231\3\2\2\2\u008b\u0238\3\2\2\2\u008d\u023a\3\2\2\2\u008f"+ - "\u0245\3\2\2\2\u0091\u0092\7*\2\2\u0092\4\3\2\2\2\u0093\u0094\7+\2\2\u0094"+ - "\6\3\2\2\2\u0095\u0096\7u\2\2\u0096\u0097\7g\2\2\u0097\u0098\7n\2\2\u0098"+ - "\u0099\7g\2\2\u0099\u009a\7e\2\2\u009a\u009b\7v\2\2\u009b\b\3\2\2\2\u009c"+ - "\u009d\7f\2\2\u009d\u009e\7k\2\2\u009e\u009f\7u\2\2\u009f\u00a0\7v\2\2"+ - "\u00a0\u00a1\7k\2\2\u00a1\u00a2\7p\2\2\u00a2\u00a3\7e\2\2\u00a3\u00a4"+ - "\7v\2\2\u00a4\n\3\2\2\2\u00a5\u00a6\7y\2\2\u00a6\u00a7\7j\2\2\u00a7\u00a8"+ - "\7g\2\2\u00a8\u00a9\7t\2\2\u00a9\u00aa\7g\2\2\u00aa\f\3\2\2\2\u00ab\u00ac"+ - "\7q\2\2\u00ac\u00ad\7t\2\2\u00ad\u00ae\7f\2\2\u00ae\u00af\7g\2\2\u00af"+ - "\u00b0\7t\2\2\u00b0\16\3\2\2\2\u00b1\u00b2\7d\2\2\u00b2\u00b3\7{\2\2\u00b3"+ - "\20\3\2\2\2\u00b4\u00b5\7.\2\2\u00b5\22\3\2\2\2\u00b6\u00b7\7p\2\2\u00b7"+ - "\u00b8\7w\2\2\u00b8\u00b9\7n\2\2\u00b9\u00ba\7n\2\2\u00ba\u00bb\7u\2\2"+ - "\u00bb\24\3\2\2\2\u00bc\u00bd\7h\2\2\u00bd\u00be\7k\2\2\u00be\u00bf\7"+ - "t\2\2\u00bf\u00c0\7u\2\2\u00c0\u00c1\7v\2\2\u00c1\26\3\2\2\2\u00c2\u00c3"+ - "\7n\2\2\u00c3\u00c4\7c\2\2\u00c4\u00c5\7u\2\2\u00c5\u00c6\7v\2\2\u00c6"+ - "\30\3\2\2\2\u00c7\u00c8\7c\2\2\u00c8\u00c9\7u\2\2\u00c9\u00ca\7e\2\2\u00ca"+ - "\32\3\2\2\2\u00cb\u00cc\7f\2\2\u00cc\u00cd\7g\2\2\u00cd\u00ce\7u\2\2\u00ce"+ - "\u00cf\7e\2\2\u00cf\34\3\2\2\2\u00d0\u00d1\7n\2\2\u00d1\u00d2\7k\2\2\u00d2"+ - "\u00d3\7o\2\2\u00d3\u00d4\7k\2\2\u00d4\u00d5\7v\2\2\u00d5\36\3\2\2\2\u00d6"+ - "\u00d7\7q\2\2\u00d7\u00d8\7h\2\2\u00d8\u00d9\7h\2\2\u00d9\u00da\7u\2\2"+ - "\u00da\u00db\7g\2\2\u00db\u00dc\7v\2\2\u00dc \3\2\2\2\u00dd\u00de\7h\2"+ - "\2\u00de\u00df\7g\2\2\u00df\u00e0\7v\2\2\u00e0\u00e1\7e\2\2\u00e1\u00e2"+ - "\7j\2\2\u00e2\"\3\2\2\2\u00e3\u00e4\7-\2\2\u00e4$\3\2\2\2\u00e5\u00e6"+ - "\7s\2\2\u00e6\u00e7\7w\2\2\u00e7\u00e8\7g\2\2\u00e8\u00e9\7t\2\2\u00e9"+ - "\u00ea\7{\2\2\u00ea&\3\2\2\2\u00eb\u00ec\7n\2\2\u00ec\u00ed\7c\2\2\u00ed"+ - "\u00ee\7|\2\2\u00ee\u00ef\7{\2\2\u00ef(\3\2\2\2\u00f0\u00f1\7q\2\2\u00f1"+ - "\u00f2\7t\2\2\u00f2*\3\2\2\2\u00f3\u00f4\7c\2\2\u00f4\u00f5\7p\2\2\u00f5"+ - "\u00f6\7f\2\2\u00f6,\3\2\2\2\u00f7\u00f8\7p\2\2\u00f8\u00f9\7q\2\2\u00f9"+ - "\u00fa\7v\2\2\u00fa.\3\2\2\2\u00fb\u00fc\7k\2\2\u00fc\u00fd\7p\2\2\u00fd"+ - "\60\3\2\2\2\u00fe\u00ff\7d\2\2\u00ff\u0100\7g\2\2\u0100\u0101\7v\2\2\u0101"+ + "<\3<\3=\3=\3=\3=\3>\3>\3>\7>\u01d4\n>\f>\16>\u01d7\13>\3>\3>\7>\u01db"+ + "\n>\f>\16>\u01de\13>\5>\u01e0\n>\3?\3?\7?\u01e4\n?\f?\16?\u01e7\13?\3"+ + "@\3@\3@\3@\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3"+ + "A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\3A\5"+ + "A\u0217\nA\3B\3B\3B\3B\3B\3B\3B\3B\3B\5B\u0222\nB\3C\5C\u0225\nC\3C\3"+ + "C\5C\u0229\nC\3C\3C\5C\u022d\nC\3D\6D\u0230\nD\rD\16D\u0231\3D\3D\7D\u0236"+ + "\nD\fD\16D\u0239\13D\3E\3E\7E\u023d\nE\fE\16E\u0240\13E\3F\3F\3G\3G\3"+ + "G\3G\7G\u0248\nG\fG\16G\u024b\13G\3G\3G\3H\3H\3H\3H\2\2I\3\3\5\4\7\5\t"+ + "\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23"+ + "%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G"+ + "%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s;u{"+ + "?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008fI\3\2\t"+ + "\5\2C\\aac|\6\2\62;C\\aac|\7\2\60\60\62;C\\aac|\3\2\62;\3\2\63;\3\2))"+ + "\5\2\13\f\17\17\"\"\2\u0263\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3"+ + "\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2"+ + "\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37"+ + "\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3"+ + "\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2"+ + "\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C"+ + "\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2"+ + "\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2"+ + "\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i"+ + "\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2"+ + "\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081"+ + "\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2"+ + "\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\3\u0091\3\2\2\2\5\u0093"+ + "\3\2\2\2\7\u0095\3\2\2\2\t\u009c\3\2\2\2\13\u00a5\3\2\2\2\r\u00ab\3\2"+ + "\2\2\17\u00b1\3\2\2\2\21\u00b4\3\2\2\2\23\u00b6\3\2\2\2\25\u00bc\3\2\2"+ + "\2\27\u00c2\3\2\2\2\31\u00c7\3\2\2\2\33\u00cb\3\2\2\2\35\u00d0\3\2\2\2"+ + "\37\u00d6\3\2\2\2!\u00dd\3\2\2\2#\u00e3\3\2\2\2%\u00e5\3\2\2\2\'\u00eb"+ + "\3\2\2\2)\u00f0\3\2\2\2+\u00f3\3\2\2\2-\u00f7\3\2\2\2/\u00fb\3\2\2\2\61"+ + "\u00fe\3\2\2\2\63\u0106\3\2\2\2\65\u010e\3\2\2\2\67\u0111\3\2\2\29\u0114"+ + "\3\2\2\2;\u0119\3\2\2\2=\u0120\3\2\2\2?\u012a\3\2\2\2A\u0132\3\2\2\2C"+ + "\u0138\3\2\2\2E\u0140\3\2\2\2G\u014b\3\2\2\2I\u0154\3\2\2\2K\u0159\3\2"+ + "\2\2M\u015f\3\2\2\2O\u0168\3\2\2\2Q\u0172\3\2\2\2S\u017d\3\2\2\2U\u0189"+ + "\3\2\2\2W\u0192\3\2\2\2Y\u019c\3\2\2\2[\u019e\3\2\2\2]\u01a1\3\2\2\2_"+ + "\u01a3\3\2\2\2a\u01a6\3\2\2\2c\u01a9\3\2\2\2e\u01ac\3\2\2\2g\u01b0\3\2"+ + "\2\2i\u01b2\3\2\2\2k\u01b5\3\2\2\2m\u01b8\3\2\2\2o\u01bb\3\2\2\2q\u01bf"+ + "\3\2\2\2s\u01c2\3\2\2\2u\u01c5\3\2\2\2w\u01c8\3\2\2\2y\u01cc\3\2\2\2{"+ + "\u01df\3\2\2\2}\u01e1\3\2\2\2\177\u01e8\3\2\2\2\u0081\u0216\3\2\2\2\u0083"+ + "\u0221\3\2\2\2\u0085\u022c\3\2\2\2\u0087\u022f\3\2\2\2\u0089\u023a\3\2"+ + "\2\2\u008b\u0241\3\2\2\2\u008d\u0243\3\2\2\2\u008f\u024e\3\2\2\2\u0091"+ + "\u0092\7*\2\2\u0092\4\3\2\2\2\u0093\u0094\7+\2\2\u0094\6\3\2\2\2\u0095"+ + "\u0096\7u\2\2\u0096\u0097\7g\2\2\u0097\u0098\7n\2\2\u0098\u0099\7g\2\2"+ + "\u0099\u009a\7e\2\2\u009a\u009b\7v\2\2\u009b\b\3\2\2\2\u009c\u009d\7f"+ + "\2\2\u009d\u009e\7k\2\2\u009e\u009f\7u\2\2\u009f\u00a0\7v\2\2\u00a0\u00a1"+ + "\7k\2\2\u00a1\u00a2\7p\2\2\u00a2\u00a3\7e\2\2\u00a3\u00a4\7v\2\2\u00a4"+ + "\n\3\2\2\2\u00a5\u00a6\7y\2\2\u00a6\u00a7\7j\2\2\u00a7\u00a8\7g\2\2\u00a8"+ + "\u00a9\7t\2\2\u00a9\u00aa\7g\2\2\u00aa\f\3\2\2\2\u00ab\u00ac\7q\2\2\u00ac"+ + "\u00ad\7t\2\2\u00ad\u00ae\7f\2\2\u00ae\u00af\7g\2\2\u00af\u00b0\7t\2\2"+ + "\u00b0\16\3\2\2\2\u00b1\u00b2\7d\2\2\u00b2\u00b3\7{\2\2\u00b3\20\3\2\2"+ + "\2\u00b4\u00b5\7.\2\2\u00b5\22\3\2\2\2\u00b6\u00b7\7p\2\2\u00b7\u00b8"+ + "\7w\2\2\u00b8\u00b9\7n\2\2\u00b9\u00ba\7n\2\2\u00ba\u00bb\7u\2\2\u00bb"+ + "\24\3\2\2\2\u00bc\u00bd\7h\2\2\u00bd\u00be\7k\2\2\u00be\u00bf\7t\2\2\u00bf"+ + "\u00c0\7u\2\2\u00c0\u00c1\7v\2\2\u00c1\26\3\2\2\2\u00c2\u00c3\7n\2\2\u00c3"+ + "\u00c4\7c\2\2\u00c4\u00c5\7u\2\2\u00c5\u00c6\7v\2\2\u00c6\30\3\2\2\2\u00c7"+ + "\u00c8\7c\2\2\u00c8\u00c9\7u\2\2\u00c9\u00ca\7e\2\2\u00ca\32\3\2\2\2\u00cb"+ + "\u00cc\7f\2\2\u00cc\u00cd\7g\2\2\u00cd\u00ce\7u\2\2\u00ce\u00cf\7e\2\2"+ + "\u00cf\34\3\2\2\2\u00d0\u00d1\7n\2\2\u00d1\u00d2\7k\2\2\u00d2\u00d3\7"+ + "o\2\2\u00d3\u00d4\7k\2\2\u00d4\u00d5\7v\2\2\u00d5\36\3\2\2\2\u00d6\u00d7"+ + "\7q\2\2\u00d7\u00d8\7h\2\2\u00d8\u00d9\7h\2\2\u00d9\u00da\7u\2\2\u00da"+ + "\u00db\7g\2\2\u00db\u00dc\7v\2\2\u00dc \3\2\2\2\u00dd\u00de\7h\2\2\u00de"+ + "\u00df\7g\2\2\u00df\u00e0\7v\2\2\u00e0\u00e1\7e\2\2\u00e1\u00e2\7j\2\2"+ + "\u00e2\"\3\2\2\2\u00e3\u00e4\7-\2\2\u00e4$\3\2\2\2\u00e5\u00e6\7s\2\2"+ + "\u00e6\u00e7\7w\2\2\u00e7\u00e8\7g\2\2\u00e8\u00e9\7t\2\2\u00e9\u00ea"+ + "\7{\2\2\u00ea&\3\2\2\2\u00eb\u00ec\7n\2\2\u00ec\u00ed\7c\2\2\u00ed\u00ee"+ + "\7|\2\2\u00ee\u00ef\7{\2\2\u00ef(\3\2\2\2\u00f0\u00f1\7q\2\2\u00f1\u00f2"+ + "\7t\2\2\u00f2*\3\2\2\2\u00f3\u00f4\7c\2\2\u00f4\u00f5\7p\2\2\u00f5\u00f6"+ + "\7f\2\2\u00f6,\3\2\2\2\u00f7\u00f8\7p\2\2\u00f8\u00f9\7q\2\2\u00f9\u00fa"+ + "\7v\2\2\u00fa.\3\2\2\2\u00fb\u00fc\7k\2\2\u00fc\u00fd\7p\2\2\u00fd\60"+ + "\3\2\2\2\u00fe\u00ff\7d\2\2\u00ff\u0100\7g\2\2\u0100\u0101\7v\2\2\u0101"+ "\u0102\7y\2\2\u0102\u0103\7g\2\2\u0103\u0104\7g\2\2\u0104\u0105\7p\2\2"+ "\u0105\62\3\2\2\2\u0106\u0107\7k\2\2\u0107\u0108\7p\2\2\u0108\u0109\7"+ "t\2\2\u0109\u010a\7c\2\2\u010a\u010b\7p\2\2\u010b\u010c\7i\2\2\u010c\u010d"+ @@ -292,44 +293,47 @@ public class EQLLexer extends Lexer { "\7s\2\2\u01cbx\3\2\2\2\u01cc\u01cd\7k\2\2\u01cd\u01ce\7p\2\2\u01ce\u01cf"+ "\7g\2\2\u01cfz\3\2\2\2\u01d0\u01d1\7<\2\2\u01d1\u01d5\t\2\2\2\u01d2\u01d4"+ "\t\3\2\2\u01d3\u01d2\3\2\2\2\u01d4\u01d7\3\2\2\2\u01d5\u01d3\3\2\2\2\u01d5"+ - "\u01d6\3\2\2\2\u01d6|\3\2\2\2\u01d7\u01d5\3\2\2\2\u01d8\u01dc\t\2\2\2"+ - "\u01d9\u01db\t\4\2\2\u01da\u01d9\3\2\2\2\u01db\u01de\3\2\2\2\u01dc\u01da"+ - "\3\2\2\2\u01dc\u01dd\3\2\2\2\u01dd~\3\2\2\2\u01de\u01dc\3\2\2\2\u01df"+ - "\u01e0\7b\2\2\u01e0\u01e1\5}?\2\u01e1\u01e2\7b\2\2\u01e2\u0080\3\2\2\2"+ - "\u01e3\u01e4\7u\2\2\u01e4\u01e5\7w\2\2\u01e5\u01e6\7o\2\2\u01e6\u01e7"+ - "\7*\2\2\u01e7\u01e8\3\2\2\2\u01e8\u01e9\5}?\2\u01e9\u01ea\7+\2\2\u01ea"+ - "\u020e\3\2\2\2\u01eb\u01ec\7o\2\2\u01ec\u01ed\7c\2\2\u01ed\u01ee\7z\2"+ - "\2\u01ee\u01ef\7*\2\2\u01ef\u01f0\3\2\2\2\u01f0\u01f1\5}?\2\u01f1\u01f2"+ - "\7+\2\2\u01f2\u020e\3\2\2\2\u01f3\u01f4\7o\2\2\u01f4\u01f5\7k\2\2\u01f5"+ - "\u01f6\7p\2\2\u01f6\u01f7\7*\2\2\u01f7\u01f8\3\2\2\2\u01f8\u01f9\5}?\2"+ - "\u01f9\u01fa\7+\2\2\u01fa\u020e\3\2\2\2\u01fb\u01fc\7c\2\2\u01fc\u01fd"+ - "\7x\2\2\u01fd\u01fe\7i\2\2\u01fe\u01ff\7*\2\2\u01ff\u0200\3\2\2\2\u0200"+ - "\u0201\5}?\2\u0201\u0202\7+\2\2\u0202\u020e\3\2\2\2\u0203\u0204\7e\2\2"+ - "\u0204\u0205\7q\2\2\u0205\u0206\7w\2\2\u0206\u0207\7p\2\2\u0207\u0208"+ - "\7v\2\2\u0208\u0209\7*\2\2\u0209\u020a\3\2\2\2\u020a\u020b\5}?\2\u020b"+ - "\u020c\7+\2\2\u020c\u020e\3\2\2\2\u020d\u01e3\3\2\2\2\u020d\u01eb\3\2"+ - "\2\2\u020d\u01f3\3\2\2\2\u020d\u01fb\3\2\2\2\u020d\u0203\3\2\2\2\u020e"+ - "\u0082\3\2\2\2\u020f\u0210\7v\2\2\u0210\u0211\7t\2\2\u0211\u0212\7w\2"+ - "\2\u0212\u0219\7g\2\2\u0213\u0214\7h\2\2\u0214\u0215\7c\2\2\u0215\u0216"+ - "\7n\2\2\u0216\u0217\7u\2\2\u0217\u0219\7g\2\2\u0218\u020f\3\2\2\2\u0218"+ - "\u0213\3\2\2\2\u0219\u0084\3\2\2\2\u021a\u021c\7/\2\2\u021b\u021a\3\2"+ - "\2\2\u021b\u021c\3\2\2\2\u021c\u021d\3\2\2\2\u021d\u0224\5\u0087D\2\u021e"+ - "\u0220\7/\2\2\u021f\u021e\3\2\2\2\u021f\u0220\3\2\2\2\u0220\u0221\3\2"+ - "\2\2\u0221\u0224\5\u0089E\2\u0222\u0224\5\u008bF\2\u0223\u021b\3\2\2\2"+ - "\u0223\u021f\3\2\2\2\u0223\u0222\3\2\2\2\u0224\u0086\3\2\2\2\u0225\u0227"+ - "\t\5\2\2\u0226\u0225\3\2\2\2\u0227\u0228\3\2\2\2\u0228\u0226\3\2\2\2\u0228"+ - "\u0229\3\2\2\2\u0229\u022a\3\2\2\2\u022a\u022e\7\60\2\2\u022b\u022d\t"+ - "\5\2\2\u022c\u022b\3\2\2\2\u022d\u0230\3\2\2\2\u022e\u022c\3\2\2\2\u022e"+ - "\u022f\3\2\2\2\u022f\u0088\3\2\2\2\u0230\u022e\3\2\2\2\u0231\u0235\t\6"+ - "\2\2\u0232\u0234\t\5\2\2\u0233\u0232\3\2\2\2\u0234\u0237\3\2\2\2\u0235"+ - "\u0233\3\2\2\2\u0235\u0236\3\2\2\2\u0236\u008a\3\2\2\2\u0237\u0235\3\2"+ - "\2\2\u0238\u0239\7\62\2\2\u0239\u008c\3\2\2\2\u023a\u0240\7)\2\2\u023b"+ - "\u023f\n\7\2\2\u023c\u023d\7)\2\2\u023d\u023f\7)\2\2\u023e\u023b\3\2\2"+ - "\2\u023e\u023c\3\2\2\2\u023f\u0242\3\2\2\2\u0240\u023e\3\2\2\2\u0240\u0241"+ - "\3\2\2\2\u0241\u0243\3\2\2\2\u0242\u0240\3\2\2\2\u0243\u0244\7)\2\2\u0244"+ - "\u008e\3\2\2\2\u0245\u0246\t\b\2\2\u0246\u0247\3\2\2\2\u0247\u0248\bH"+ - "\2\2\u0248\u0090\3\2\2\2\17\2\u01d5\u01dc\u020d\u0218\u021b\u021f\u0223"+ - "\u0228\u022e\u0235\u023e\u0240\3\b\2\2"; + "\u01d6\3\2\2\2\u01d6\u01e0\3\2\2\2\u01d7\u01d5\3\2\2\2\u01d8\u01dc\7A"+ + "\2\2\u01d9\u01db\4\62;\2\u01da\u01d9\3\2\2\2\u01db\u01de\3\2\2\2\u01dc"+ + "\u01da\3\2\2\2\u01dc\u01dd\3\2\2\2\u01dd\u01e0\3\2\2\2\u01de\u01dc\3\2"+ + "\2\2\u01df\u01d0\3\2\2\2\u01df\u01d8\3\2\2\2\u01e0|\3\2\2\2\u01e1\u01e5"+ + "\t\2\2\2\u01e2\u01e4\t\4\2\2\u01e3\u01e2\3\2\2\2\u01e4\u01e7\3\2\2\2\u01e5"+ + "\u01e3\3\2\2\2\u01e5\u01e6\3\2\2\2\u01e6~\3\2\2\2\u01e7\u01e5\3\2\2\2"+ + "\u01e8\u01e9\7b\2\2\u01e9\u01ea\5}?\2\u01ea\u01eb\7b\2\2\u01eb\u0080\3"+ + "\2\2\2\u01ec\u01ed\7u\2\2\u01ed\u01ee\7w\2\2\u01ee\u01ef\7o\2\2\u01ef"+ + "\u01f0\7*\2\2\u01f0\u01f1\3\2\2\2\u01f1\u01f2\5}?\2\u01f2\u01f3\7+\2\2"+ + "\u01f3\u0217\3\2\2\2\u01f4\u01f5\7o\2\2\u01f5\u01f6\7c\2\2\u01f6\u01f7"+ + "\7z\2\2\u01f7\u01f8\7*\2\2\u01f8\u01f9\3\2\2\2\u01f9\u01fa\5}?\2\u01fa"+ + "\u01fb\7+\2\2\u01fb\u0217\3\2\2\2\u01fc\u01fd\7o\2\2\u01fd\u01fe\7k\2"+ + "\2\u01fe\u01ff\7p\2\2\u01ff\u0200\7*\2\2\u0200\u0201\3\2\2\2\u0201\u0202"+ + "\5}?\2\u0202\u0203\7+\2\2\u0203\u0217\3\2\2\2\u0204\u0205\7c\2\2\u0205"+ + "\u0206\7x\2\2\u0206\u0207\7i\2\2\u0207\u0208\7*\2\2\u0208\u0209\3\2\2"+ + "\2\u0209\u020a\5}?\2\u020a\u020b\7+\2\2\u020b\u0217\3\2\2\2\u020c\u020d"+ + "\7e\2\2\u020d\u020e\7q\2\2\u020e\u020f\7w\2\2\u020f\u0210\7p\2\2\u0210"+ + "\u0211\7v\2\2\u0211\u0212\7*\2\2\u0212\u0213\3\2\2\2\u0213\u0214\5}?\2"+ + "\u0214\u0215\7+\2\2\u0215\u0217\3\2\2\2\u0216\u01ec\3\2\2\2\u0216\u01f4"+ + "\3\2\2\2\u0216\u01fc\3\2\2\2\u0216\u0204\3\2\2\2\u0216\u020c\3\2\2\2\u0217"+ + "\u0082\3\2\2\2\u0218\u0219\7v\2\2\u0219\u021a\7t\2\2\u021a\u021b\7w\2"+ + "\2\u021b\u0222\7g\2\2\u021c\u021d\7h\2\2\u021d\u021e\7c\2\2\u021e\u021f"+ + "\7n\2\2\u021f\u0220\7u\2\2\u0220\u0222\7g\2\2\u0221\u0218\3\2\2\2\u0221"+ + "\u021c\3\2\2\2\u0222\u0084\3\2\2\2\u0223\u0225\7/\2\2\u0224\u0223\3\2"+ + "\2\2\u0224\u0225\3\2\2\2\u0225\u0226\3\2\2\2\u0226\u022d\5\u0087D\2\u0227"+ + "\u0229\7/\2\2\u0228\u0227\3\2\2\2\u0228\u0229\3\2\2\2\u0229\u022a\3\2"+ + "\2\2\u022a\u022d\5\u0089E\2\u022b\u022d\5\u008bF\2\u022c\u0224\3\2\2\2"+ + "\u022c\u0228\3\2\2\2\u022c\u022b\3\2\2\2\u022d\u0086\3\2\2\2\u022e\u0230"+ + "\t\5\2\2\u022f\u022e\3\2\2\2\u0230\u0231\3\2\2\2\u0231\u022f\3\2\2\2\u0231"+ + "\u0232\3\2\2\2\u0232\u0233\3\2\2\2\u0233\u0237\7\60\2\2\u0234\u0236\t"+ + "\5\2\2\u0235\u0234\3\2\2\2\u0236\u0239\3\2\2\2\u0237\u0235\3\2\2\2\u0237"+ + "\u0238\3\2\2\2\u0238\u0088\3\2\2\2\u0239\u0237\3\2\2\2\u023a\u023e\t\6"+ + "\2\2\u023b\u023d\t\5\2\2\u023c\u023b\3\2\2\2\u023d\u0240\3\2\2\2\u023e"+ + "\u023c\3\2\2\2\u023e\u023f\3\2\2\2\u023f\u008a\3\2\2\2\u0240\u023e\3\2"+ + "\2\2\u0241\u0242\7\62\2\2\u0242\u008c\3\2\2\2\u0243\u0249\7)\2\2\u0244"+ + "\u0248\n\7\2\2\u0245\u0246\7)\2\2\u0246\u0248\7)\2\2\u0247\u0244\3\2\2"+ + "\2\u0247\u0245\3\2\2\2\u0248\u024b\3\2\2\2\u0249\u0247\3\2\2\2\u0249\u024a"+ + "\3\2\2\2\u024a\u024c\3\2\2\2\u024b\u0249\3\2\2\2\u024c\u024d\7)\2\2\u024d"+ + "\u008e\3\2\2\2\u024e\u024f\t\b\2\2\u024f\u0250\3\2\2\2\u0250\u0251\bH"+ + "\2\2\u0251\u0090\3\2\2\2\21\2\u01d5\u01dc\u01df\u01e5\u0216\u0221\u0224"+ + "\u0228\u022c\u0231\u0237\u023e\u0247\u0249\3\b\2\2"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/src/test/java/io/ebeaninternal/server/grammer/EqlParserTest.java b/src/test/java/io/ebeaninternal/server/grammer/EqlParserTest.java index 9d0bf98e2..eac2aefdf 100644 --- a/src/test/java/io/ebeaninternal/server/grammer/EqlParserTest.java +++ b/src/test/java/io/ebeaninternal/server/grammer/EqlParserTest.java @@ -691,15 +691,45 @@ public class EqlParserTest extends BaseTestCase { } } -// @Test -// public void where_withParams() { -// -// final Query query = where("name = ? and smallnote istartsWith ?", "Rob", "Foo"); -// query.findList(); -// if (isH2()) { -// assertThat(query.getGeneratedSql()).contains(" from o_customer t0 where t0.name is not null"); -// } -// } + @Test + public void where_withParams() { + + final Query query = where("id isNotNull and name = ? and smallnote istartsWith ?", "Rob", "Foo"); + query.findList(); + if (isH2()) { + assertThat(query.getGeneratedSql()).contains("where (t0.id is not null and t0.name = ? and lower(t0.smallnote) like ? escape'|' )"); + } + } + + @Test + public void where_withParamsQuPos() { + + final Query query = where("name = ?1 and smallnote istartsWith ?2 and name like ?1", "Rob", "Foo"); + query.findList(); + if (isH2()) { + assertThat(query.getGeneratedSql()).contains(" where (t0.name = ? and lower(t0.smallnote) like ? escape'|' and t0.name like ? escape'' )"); + } + } + + @Test + public void where_orSimple() { + + final Query query = where("id isNotNull or name = ?", "Rob", "Foo"); + query.findList(); + if (isH2()) { + assertThat(query.getGeneratedSql()).contains("where (t0.id is not null or t0.name = ?)"); + } + } + + @Test + public void where_orWithParams() { + + final Query query = where("(id isNotNull or name = ?) and smallnote istartsWith ?", "Rob", "Foo"); + query.findList(); + if (isH2()) { + assertThat(query.getGeneratedSql()).contains("where ((t0.id is not null or t0.name = ?) and lower(t0.smallnote) like ? escape'|' )"); + } + } private Query where(String where, Object... params) { diff --git a/src/test/java/org/tests/query/TestQueryFilterMany.java b/src/test/java/org/tests/query/TestQueryFilterMany.java index 448bcd173..2dff48308 100644 --- a/src/test/java/org/tests/query/TestQueryFilterMany.java +++ b/src/test/java/org/tests/query/TestQueryFilterMany.java @@ -176,4 +176,23 @@ public class TestQueryFilterMany extends BaseTestCase { platformAssertIn(sql.get(2), " from contact_note t0 where (t0.contact_id)"); assertThat(sql.get(2)).contains(" and lower(t0.title) like"); } + + @Test + public void testFilterManyUsingExpression() { + + ResetBasicData.reset(); + LoggedSqlCollector.start(); + + Ebean.find(Customer.class) + .where() + .filterMany("contacts", "firstName isNotNull and email istartsWith ?", "rob") + .findList(); + + List sql = LoggedSqlCollector.stop(); + + assertThat(sql).hasSize(2); + assertThat(sql.get(0)).contains(" from o_customer t0"); + assertThat(sql.get(1)).contains("from contact t0 where "); + assertThat(sql.get(1)).contains("and (t0.first_name is not null and lower(t0.email) like ? escape'|' )"); + } } diff --git a/src/test/resources/EQL.g4 b/src/test/resources/EQL.g4 index 3b6d1d702..121425b92 100644 --- a/src/test/resources/EQL.g4 +++ b/src/test/resources/EQL.g4 @@ -215,6 +215,7 @@ literal INPUT_VARIABLE : ':' ('a' .. 'z' | 'A' .. 'Z' | '_') ('a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_')* + | '?' ('0' .. '9')* ; PATH_VARIABLE