diff --git a/.github/workflows/mongodb-connector.yml b/.github/workflows/mongodb-connector.yml new file mode 100644 index 0000000000000..015e5f5aaeb6a --- /dev/null +++ b/.github/workflows/mongodb-connector.yml @@ -0,0 +1,87 @@ +name: MongoDB Connector E2E + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + paths: + - '.github/workflows/entrypoint.yaml' + - '.github/workflows/mongodb-connector.yml' + - 'Makefile' + - 'go.mod' + - 'go.sum' + - 'optools/mongodb_ci.bash' + - 'etc/launch-mongodb-local/**' + - 'etc/launch/**' + - 'test/mongodb/**' + - 'pkg/sql/mongodb/**' + - 'pkg/sql/colexec/mongoscan/**' + - 'pkg/sql/colexec/timewin/**' + - 'pkg/sql/colexec/aggexec/**' + - 'pkg/sql/plan/**' + - 'pkg/sql/compile/**' + - 'pkg/frontend/**' + - 'pkg/sql/parsers/**' + - 'pkg/config/**' + - 'pkg/defines/**' + - 'pkg/bootstrap/**' + - 'pkg/cnservice/**' + - 'pkg/clusterservice/**' + - 'pkg/queryservice/**' + - 'pkg/vm/**' + - 'pkg/pb/plan/**' + - 'pkg/pb/pipeline/**' + - 'pkg/pb/query/**' + - 'pkg/util/metric/v2/**' + - 'proto/plan.proto' + - 'proto/pipeline.proto' + - 'proto/query.proto' + - 'vendor/go.mongodb.org/**' + - 'vendor/github.com/xdg-go/**' + - 'vendor/github.com/youmark/pkcs8/**' + - 'vendor/github.com/montanaflynn/stats/**' + - 'vendor/github.com/klauspost/compress/**' + - 'vendor/github.com/golang/snappy/**' + - 'vendor/modules.txt' + workflow_dispatch: + +permissions: + contents: read + +jobs: + mongodb-e2e-local: + name: MongoDB E2E Local + runs-on: ubuntu-latest + timeout-minutes: 45 + env: + MO_MONGODB_REPORT_DIR: test/mongodb/reports/e2e-${{ github.run_id }} + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + + - name: Run MongoDB connector E2E + run: make test-mongodb-e2e-local + + - name: Summarize MongoDB E2E + if: always() + run: | + { + echo "## MongoDB connector E2E" + echo "" + echo "Artifact: \`mongodb-e2e-local-${{ github.sha }}-${{ github.run_id }}\`" + echo "" + if [ -f "${MO_MONGODB_REPORT_DIR}/summary.md" ]; then + cat "${MO_MONGODB_REPORT_DIR}/summary.md" + else + echo "No summary was created." + fi + } >> "$GITHUB_STEP_SUMMARY" + + - uses: actions/upload-artifact@v4 + if: always() + with: + name: mongodb-e2e-local-${{ github.sha }}-${{ github.run_id }} + path: test/mongodb/reports/** diff --git a/.gitignore b/.gitignore index 2234003ad2ba9..da7951428f2e6 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,12 @@ *.py !pkg/iceberg/metadata/testdata/generate_golden_vectors.py !optools/iceberg_external_runner.py +!suites/scenarios/14_issue_regression/issue_25599_proxy_disconnect_cancel.py +!suites/scenarios/14_issue_regression/issue_25599_proxy_disconnect_cancel_test.py +!optools/mongodb_changed_files.py +!test/mongodb/compare_results.py +!test/mongodb/test_changes.py +!test/mongodb/test_compare_results.py *.sh !etc/launch-minio-local/tier-b/seed-nyc-tlc-iceberg.sh bin/ diff --git a/Makefile b/Makefile index 82db9bc5a4fdc..b4deaeb37f756 100644 --- a/Makefile +++ b/Makefile @@ -421,6 +421,14 @@ test-iceberg-readiness: test-iceberg-e2e-local: @optools/iceberg_ci.bash e2e-local +.PHONY: test-mongodb-e2e-local +test-mongodb-e2e-local: + @optools/mongodb_ci.bash e2e-local + +.PHONY: test-mongodb-unit +test-mongodb-unit: + @optools/mongodb_ci.bash unit + .PHONY: test-iceberg-local test-iceberg-local: @optools/iceberg_ci.bash local diff --git a/etc/launch-mongodb-local/README.md b/etc/launch-mongodb-local/README.md new file mode 100644 index 0000000000000..65d7c7bd75137 --- /dev/null +++ b/etc/launch-mongodb-local/README.md @@ -0,0 +1,7 @@ +# Local MongoDB connector fixture + +`optools/mongodb_ci.bash` is the only supported entry point. It creates a unique Compose project, port, keyfile, credentials, MongoDB volume, MO data directory and report directory; waits for a writable ReplicaSet primary; seeds a read-only MongoDB user; and cleans everything on exit. + +The connector uses a direct connection to the published localhost port for this single-node fixture. Production ReplicaSets should use normal discovery and a dedicated read-only role with only `find`, `listCollections`, `listIndexes` and `collStats` on the mapped databases/collections. Do not grant write or cluster-administration roles to a MatrixOne source identity. + +The built-in environment resolver is intended for local/controlled deployments. System-account references must start with `secret://env/MO_MONGODB_`; tenant account `N` is restricted to `secret://env/MO_MONGODB_ACCOUNT_N_`, preventing one tenant from naming another tenant's or an unrelated process secret. Production secret-manager implementations receive the account ID and must enforce an equivalent namespace and authorization check. diff --git a/etc/launch-mongodb-local/compose.yaml b/etc/launch-mongodb-local/compose.yaml new file mode 100644 index 0000000000000..402cde072ebe1 --- /dev/null +++ b/etc/launch-mongodb-local/compose.yaml @@ -0,0 +1,31 @@ +# Copyright 2026 Matrix Origin +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. + +services: + mongo: + image: mongo@sha256:95a98776f273721a295b03098578b06bc10281bb56aa828c77e9f60ecc70b150 + entrypoint: ["bash", "-c", "cp /run/key-source /tmp/mongodb-keyfile && chown mongodb:mongodb /tmp/mongodb-keyfile && chmod 400 /tmp/mongodb-keyfile && exec /usr/local/bin/docker-entrypoint.sh \"$$@\"", "--"] + command: ["mongod", "--replSet", "rs0", "--bind_ip_all", "--auth", "--keyFile", "/tmp/mongodb-keyfile"] + ports: + - "127.0.0.1:${MONGODB_PORT}:27017" + environment: + MONGO_INITDB_ROOT_USERNAME: ${MONGODB_ROOT_USER} + MONGO_INITDB_ROOT_PASSWORD: ${MONGODB_ROOT_PASSWORD} + volumes: + - mongodb-data:/data/db + - ${MONGODB_KEYFILE}:/run/key-source:ro + healthcheck: + test: ["CMD-SHELL", "mongosh --quiet --username $$MONGO_INITDB_ROOT_USERNAME --password $$MONGO_INITDB_ROOT_PASSWORD --authenticationDatabase admin --eval 'quit(db.adminCommand({ping:1}).ok ? 0 : 2)' >/dev/null"] + interval: 2s + timeout: 5s + retries: 60 + networks: [mongodb-e2e] + +volumes: + mongodb-data: + +networks: + mongodb-e2e: + driver: bridge diff --git a/etc/launch-mongodb-local/init_and_seed.js b/etc/launch-mongodb-local/init_and_seed.js new file mode 100644 index 0000000000000..5614d08ce9061 --- /dev/null +++ b/etc/launch-mongodb-local/init_and_seed.js @@ -0,0 +1,27 @@ +// Copyright 2026 Matrix Origin +// Licensed under the Apache License, Version 2.0. + +const source = db.getSiblingDB("mongodb_source"); +if (!source.getUser("mo_reader")) { + source.createUser({ + user: "mo_reader", + pwd: process.env.MONGODB_READER_PASSWORD, + roles: [{role: "read", db: "mongodb_source"}] + }); +} +if (!source.getUser("mo_reader_next")) { + source.createUser({ + user: "mo_reader_next", + pwd: process.env.MONGODB_READER_NEXT_PASSWORD, + roles: [{role: "read", db: "mongodb_source"}] + }); +} +source.events.drop(); +source.events.insertMany([ + {_id: ObjectId("64b000000000000000000001"), device_id: "device-001", site_id: "site-east", ts: ISODate("2026-07-27T10:00:05Z"), measurement: 10.0, source_batch: "batch-001"}, + {_id: ObjectId("64b000000000000000000002"), device_id: "device-001", site_id: "site-east", ts: ISODate("2026-07-27T10:00:35Z"), measurement: 14.0, source_batch: null}, + {_id: ObjectId("64b000000000000000000003"), device_id: "device-001", site_id: "site-east", ts: ISODate("2026-07-27T10:02:05Z"), measurement: 20.0}, + {_id: ObjectId("64b000000000000000000004"), device_id: "device-001", site_id: "site-west", ts: ISODate("2026-07-27T10:00:15Z"), measurement: 30.0, source_batch: "batch-002"}, + {_id: ObjectId("64b000000000000000000005"), device_id: "device-002", site_id: "site-east", ts: ISODate("2026-07-27T10:01:00Z"), measurement: "malformed"} +]); +source.events.createIndex({ts: 1, _id: 1}); diff --git a/go.mod b/go.mod index da803b01bb71c..ed05968c2dc8d 100644 --- a/go.mod +++ b/go.mod @@ -97,6 +97,7 @@ require ( github.com/unum-cloud/usearch/golang v0.0.0-20260524141737-9fd6b0115dcd github.com/xeipuuv/gojsonschema v1.2.0 github.com/yanyiwu/gojieba v1.4.7 + go.mongodb.org/mongo-driver/v2 v2.8.0 go.starlark.net v0.0.0-20250701195324-d457b4515e0e go.uber.org/automaxprocs v1.5.3 go.uber.org/ratelimit v0.2.0 @@ -241,9 +242,13 @@ require ( github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/valyala/fastrand v1.1.0 // indirect github.com/valyala/histogram v1.2.0 // indirect + github.com/xdg-go/pbkdf2 v1.0.0 // indirect + github.com/xdg-go/scram v1.2.0 // indirect + github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect diff --git a/go.sum b/go.sum index a8b3d2a026cde..8e3df73c07925 100644 --- a/go.sum +++ b/go.sum @@ -902,6 +902,12 @@ github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tz github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.2.0 h1:bYKF2AEwG5rqd1BumT4gAnvwU/M9nBp2pTSxeZw7Wvs= +github.com/xdg-go/scram v1.2.0/go.mod h1:3dlrS0iBaWKYVt2ZfA4cj48umJZ+cAEbR6/SjLA88I8= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -916,6 +922,8 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1: github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yanyiwu/gojieba v1.4.7 h1:2YkXELcYLTE0SJetq6xv4MjpEikWga6VpFn4jIFFQ/k= github.com/yanyiwu/gojieba v1.4.7/go.mod h1:JUq4DddFVGdHXJHxxepxRmhrKlDpaBxR8O28v6fKYLY= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= @@ -926,6 +934,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.mongodb.org/mongo-driver/v2 v2.8.0 h1:CxWDGQYY8QQwNjAl/aq2sfWakdnWZynnqJ9F4DhHbP8= +go.mongodb.org/mongo-driver/v2 v2.8.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 h1:A3SayB3rNyt+1S6qpI9mHPkeHTZbD7XILEqWnYZb2l0= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0/go.mod h1:27iA5uvhuRNmalO+iEUdVn5ZMj2qy10Mm+XRIpRmyuU= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.45.0 h1:2ea0IkZBsWH+HA2GkD+7+hRw2u97jzdFyRtXuO14a1s= @@ -1137,6 +1147,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= diff --git a/optools/iceberg_ci.bash b/optools/iceberg_ci.bash index 0a7eb61193ba7..faa3bdff22a21 100755 --- a/optools/iceberg_ci.bash +++ b/optools/iceberg_ci.bash @@ -365,13 +365,13 @@ preflight() { fi if contains_profile tier-d; then - require_env MO_ICEBERG_NESR - [[ "$MO_ICEBERG_NESR" == "1" ]] || die "MO_ICEBERG_NESR must be 1 for tier-d profile" - require_file MO_ICEBERG_NESR_SCENARIOS - require_sql_template MO_ICEBERG_NESR_MO_SQL_CMD - require_sql_template MO_ICEBERG_NESR_EXTERNAL_SQL_CMD - require_file MO_ICEBERG_NESR_EXPECTED_KPI - require_env MO_ICEBERG_NESR_RESIDENCY_ERROR + require_env MO_ICEBERG_REFERENCE + [[ "$MO_ICEBERG_REFERENCE" == "1" ]] || die "MO_ICEBERG_REFERENCE must be 1 for tier-d profile" + require_file MO_ICEBERG_REFERENCE_SCENARIOS + require_sql_template MO_ICEBERG_REFERENCE_MO_SQL_CMD + require_sql_template MO_ICEBERG_REFERENCE_EXTERNAL_SQL_CMD + require_file MO_ICEBERG_REFERENCE_EXPECTED_KPI + require_env MO_ICEBERG_REFERENCE_RESIDENCY_ERROR fi log "preflight passed for MO_ICEBERG_CI_PROFILE=${profile}" @@ -432,9 +432,9 @@ run_remaining_external_if_enabled() { fi if contains_profile tier-d; then - run_external_profile tier-d "$MO_ICEBERG_NESR_SCENARIOS" + run_external_profile tier-d "$MO_ICEBERG_REFERENCE_SCENARIOS" else - log "tier-d profile not enabled; skipping NESR scenarios" + log "tier-d profile not enabled; skipping reference scenarios" fi } @@ -444,7 +444,7 @@ validate_external_templates() { "${ROOT_DIR}/test/iceberg/credential_vending_scenarios.example.json" \ "${ROOT_DIR}/test/iceberg/tier_b_public_dataset_scenarios.example.json" \ "${ROOT_DIR}/test/iceberg/tier_c_sandbox_scenarios.example.json" \ - "${ROOT_DIR}/test/iceberg/tier_d_nesr_scenarios.example.json"; do + "${ROOT_DIR}/test/iceberg/tier_d_reference_scenarios.example.json"; do run python3 "${ROOT_DIR}/optools/iceberg_external_runner.py" \ --profile template \ --scenario-file "$template" \ @@ -876,14 +876,14 @@ profiles = [ "name": "tier-d", "tests": ["ICE-TEST-135"], "required_env": [ - "MO_ICEBERG_NESR", - "MO_ICEBERG_NESR_SCENARIOS", - "MO_ICEBERG_NESR_MO_SQL_CMD", - "MO_ICEBERG_NESR_EXTERNAL_SQL_CMD", - "MO_ICEBERG_NESR_EXPECTED_KPI", - "MO_ICEBERG_NESR_RESIDENCY_ERROR", + "MO_ICEBERG_REFERENCE", + "MO_ICEBERG_REFERENCE_SCENARIOS", + "MO_ICEBERG_REFERENCE_MO_SQL_CMD", + "MO_ICEBERG_REFERENCE_EXTERNAL_SQL_CMD", + "MO_ICEBERG_REFERENCE_EXPECTED_KPI", + "MO_ICEBERG_REFERENCE_RESIDENCY_ERROR", ], - "help": "NESR de-identified demo data and expected KPI file are required.", + "help": "Reference-profile de-identified demo data and expected KPI file are required.", }, { "name": "golden-real", diff --git a/optools/mongodb_ci.bash b/optools/mongodb_ci.bash new file mode 100755 index 0000000000000..6c6b94eccb607 --- /dev/null +++ b/optools/mongodb_ci.bash @@ -0,0 +1,194 @@ +#!/usr/bin/env bash +# Copyright 2026 Matrix Origin +# Licensed under the Apache License, Version 2.0. + +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +PROFILE="${1:-e2e-local}" +REPORT_DIR="${MO_MONGODB_REPORT_DIR:-${ROOT_DIR}/test/mongodb/reports/ci_$(date -u +%Y%m%dT%H%M%SZ)}" +TMP_DIR="" +MO_PID="" + +log() { printf '[mongodb-ci] %s\n' "$*"; } +die() { printf '[mongodb-ci] ERROR: %s\n' "$*" >&2; exit 1; } +require() { command -v "$1" >/dev/null 2>&1 || die "required command not found: $1"; } + +sanitize() { + local source="$1" target="$2" + if [[ ! -f "$source" ]]; then printf 'not captured\n' >"$target"; return; fi + sed -E \ + -e 's#mongodb(\+srv)?://[^[:space:]]+#mongodb://#g' \ + -e 's#(password|credential|token|secret)[=:][^ ,}\"]+#\1=#Ig' \ + -e 's#MO_MONGODB_E2E_CREDENTIAL[^[:space:]]*#MO_MONGODB_E2E_CREDENTIAL=#g' \ + "$source" >"$target" +} + +collect() { + [[ -n "$TMP_DIR" ]] || return + mkdir -p "$REPORT_DIR" + sanitize "$TMP_DIR/mo-service.log" "$REPORT_DIR/mo-service.log" + if command -v docker >/dev/null 2>&1; then + MONGODB_PORT="${MONGODB_PORT:-27017}" MONGODB_ROOT_USER="${MONGODB_ROOT_USER:-x}" \ + MONGODB_ROOT_PASSWORD="${MONGODB_ROOT_PASSWORD:-x}" MONGODB_KEYFILE="${MONGODB_KEYFILE:-/dev/null}" \ + docker compose -p "${COMPOSE_PROJECT_NAME:-mo-mongodb-unused}" -f "$ROOT_DIR/etc/launch-mongodb-local/compose.yaml" logs --no-color \ + >"$TMP_DIR/mongodb.log" 2>&1 || true + sanitize "$TMP_DIR/mongodb.log" "$REPORT_DIR/mongodb.log" + docker inspect "${COMPOSE_PROJECT_NAME:-mo-mongodb-unused}-mongo-1" >"$TMP_DIR/docker-inspect.json" 2>&1 || true + sanitize "$TMP_DIR/docker-inspect.json" "$REPORT_DIR/docker-inspect.json" + fi +} + +cleanup() { + local status=$? + # Cleanup must continue even when artifact collection itself fails. Preserve + # the original test status and make every teardown action best-effort. + set +e + if [[ -n "$MO_PID" ]] && kill -0 "$MO_PID" >/dev/null 2>&1; then + kill "$MO_PID" >/dev/null 2>&1 || true + for _ in {1..40}; do + kill -0 "$MO_PID" >/dev/null 2>&1 || break + sleep 0.25 + done + if kill -0 "$MO_PID" >/dev/null 2>&1; then + kill -KILL "$MO_PID" >/dev/null 2>&1 || true + fi + wait "$MO_PID" >/dev/null 2>&1 || true + fi + collect + if [[ -n "$TMP_DIR" ]]; then + MONGODB_PORT="${MONGODB_PORT:-27017}" MONGODB_ROOT_USER="${MONGODB_ROOT_USER:-x}" \ + MONGODB_ROOT_PASSWORD="${MONGODB_ROOT_PASSWORD:-x}" MONGODB_KEYFILE="${MONGODB_KEYFILE:-/dev/null}" \ + docker compose -p "${COMPOSE_PROJECT_NAME:-mo-mongodb-unused}" -f "$ROOT_DIR/etc/launch-mongodb-local/compose.yaml" down --volumes --remove-orphans >/dev/null 2>&1 || true + # TMP_DIR is created by the exact mktemp template below. Refuse a broad + # deletion if that invariant is ever changed or corrupted. + if [[ -d "$TMP_DIR" && "$(basename "$TMP_DIR")" == mo-mongodb-e2e.* ]]; then + rm -rf -- "$TMP_DIR" + else + log "refusing to remove unexpected temporary path: $TMP_DIR" + fi + fi + return "$status" +} + +free_port() { + python3 - <<'PY' +import socket +s = socket.socket() +s.bind(("127.0.0.1", 0)) +print(s.getsockname()[1]) +s.close() +PY +} + +wait_mongo() { + local deadline=$((SECONDS + 120)) + until docker compose -p "$COMPOSE_PROJECT_NAME" -f "$ROOT_DIR/etc/launch-mongodb-local/compose.yaml" exec -T mongo \ + mongosh --quiet -u "$MONGODB_ROOT_USER" -p "$MONGODB_ROOT_PASSWORD" --authenticationDatabase admin \ + --eval 'quit(db.adminCommand({ping:1}).ok ? 0 : 2)' >/dev/null 2>&1; do + (( SECONDS < deadline )) || die "MongoDB did not become healthy" + sleep 1 + done +} + +wait_primary() { + local deadline=$((SECONDS + 120)) + until docker compose -p "$COMPOSE_PROJECT_NAME" -f "$ROOT_DIR/etc/launch-mongodb-local/compose.yaml" exec -T mongo \ + mongosh --quiet -u "$MONGODB_ROOT_USER" -p "$MONGODB_ROOT_PASSWORD" --authenticationDatabase admin \ + --eval 'quit(db.hello().isWritablePrimary ? 0 : 2)' >/dev/null 2>&1; do + (( SECONDS < deadline )) || die "ReplicaSet did not elect a writable primary" + sleep 1 + done +} + +generate_mo_config() { + local source_dir="$ROOT_DIR/etc/launch" + local generated_dir="$TMP_DIR/mo-config" + mkdir -p "$generated_dir" + for name in log tn; do + sed -e "s#\./mo-data#$TMP_DIR/mo-data#g" -e "s#\"mo-data/#\"$TMP_DIR/mo-data/#g" \ + "$source_dir/$name.toml" >"$generated_dir/$name.toml" + done + sed -e "s#\./mo-data#$TMP_DIR/mo-data#g" -e "s#\"mo-data/#\"$TMP_DIR/mo-data/#g" \ + "$source_dir/cn.toml" | awk -v port="$MO_PORT" ' + /^\[cn\.frontend\.iceberg\]$/ && !inserted { + print "[cn.frontend]" + print "port = " port + print "" + inserted = 1 + } + { print } + END { if (!inserted) exit 42 } + ' >"$generated_dir/cn.toml" + { + printf '\n[cn.frontend.mongodb]\n' + printf 'enable = true\nallow-loopback = true\n' + printf 'connect-timeout = "10s"\nserver-selection-timeout = "10s"\nsocket-timeout = "30s"\n' + printf 'batch-rows = 2\nmax-source-concurrency = 2\n' + } >>"$generated_dir/cn.toml" + sed -e "s#\./etc/launch/log.toml#$generated_dir/log.toml#" \ + -e "s#\./etc/launch/tn.toml#$generated_dir/tn.toml#" \ + -e "s#\./etc/launch/cn.toml#$generated_dir/cn.toml#" \ + "$source_dir/launch.toml" >"$generated_dir/launch.toml" +} + +run_e2e() { + require docker; require go; require python3; require openssl + mkdir -p "$REPORT_DIR" + TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/mo-mongodb-e2e.XXXXXX")" + trap cleanup EXIT + export COMPOSE_PROJECT_NAME="mo-mongodb-$(basename "$TMP_DIR" | tr '[:upper:].' '[:lower:]-')" + export MONGODB_PORT="$(free_port)" MO_PORT="$(free_port)" + export MONGODB_ROOT_USER="root_$(openssl rand -hex 6)" + export MONGODB_ROOT_PASSWORD="$(openssl rand -hex 24)" + export MONGODB_READER_PASSWORD="$(openssl rand -hex 24)" + export MONGODB_READER_NEXT_PASSWORD="$(openssl rand -hex 24)" + export MONGODB_KEYFILE="$TMP_DIR/mongodb-keyfile" + openssl rand -base64 756 >"$MONGODB_KEYFILE" + chmod 600 "$MONGODB_KEYFILE" + + docker compose -p "$COMPOSE_PROJECT_NAME" -f "$ROOT_DIR/etc/launch-mongodb-local/compose.yaml" up -d + wait_mongo + docker compose -p "$COMPOSE_PROJECT_NAME" -f "$ROOT_DIR/etc/launch-mongodb-local/compose.yaml" exec -T mongo \ + mongosh --quiet -u "$MONGODB_ROOT_USER" -p "$MONGODB_ROOT_PASSWORD" --authenticationDatabase admin \ + --eval 'try { rs.status() } catch (_) { rs.initiate({_id:"rs0",members:[{_id:0,host:"mongo:27017"}]}) }' >/dev/null + wait_primary + docker compose -p "$COMPOSE_PROJECT_NAME" -f "$ROOT_DIR/etc/launch-mongodb-local/compose.yaml" exec -T \ + -e MONGODB_READER_PASSWORD="$MONGODB_READER_PASSWORD" \ + -e MONGODB_READER_NEXT_PASSWORD="$MONGODB_READER_NEXT_PASSWORD" mongo \ + mongosh --quiet -u "$MONGODB_ROOT_USER" -p "$MONGODB_ROOT_PASSWORD" --authenticationDatabase admin \ + <"$ROOT_DIR/etc/launch-mongodb-local/init_and_seed.js" >/dev/null + + (cd "$ROOT_DIR" && make build) + generate_mo_config + export MO_MONGODB_E2E_CREDENTIAL="{\"Username\":\"mo_reader\",\"Password\":\"$MONGODB_READER_PASSWORD\"}" + export MO_MONGODB_E2E_CREDENTIAL_NEXT="{\"Username\":\"mo_reader_next\",\"Password\":\"$MONGODB_READER_NEXT_PASSWORD\"}" + if [[ "$(uname -s)" == Darwin ]]; then + export DYLD_LIBRARY_PATH="$ROOT_DIR/cgo:$ROOT_DIR/thirdparties/install/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}" + else + export LD_LIBRARY_PATH="$ROOT_DIR/cgo:$ROOT_DIR/thirdparties/install/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" + fi + "$ROOT_DIR/mo-service" -launch "$TMP_DIR/mo-config/launch.toml" >"$TMP_DIR/mo-service.log" 2>&1 & + MO_PID=$! + (cd "$ROOT_DIR" && go run ./test/mongodb/mongodb_e2e_local.go \ + --dsn "root:111@tcp(127.0.0.1:$MO_PORT)/?timeout=5s&readTimeout=30s&writeTimeout=30s" \ + --mongo-host "127.0.0.1:$MONGODB_PORT" --report-dir "$REPORT_DIR") +} + +run_unit() { + (cd "$ROOT_DIR" && make build >/dev/null) + (cd "$ROOT_DIR" && python3 -m unittest discover -s test/mongodb -p 'test_*.py') + (cd "$ROOT_DIR" && .agents/skills/mo-dev/scripts/mo-cgo-test -count=1 -timeout=10m \ + ./pkg/sql/mongodb ./pkg/sql/colexec/mongoscan ./pkg/sql/colexec/aggexec ./pkg/sql/colexec/timewin \ + ./pkg/sql/parsers/dialect/mysql ./pkg/sql/plan ./pkg/sql/compile ./pkg/frontend) +} + +case "$PROFILE" in + unit) run_unit ;; + e2e-local) run_e2e ;; + nightly) + run_unit + run_e2e + ;; + *) die "unknown profile: $PROFILE" ;; +esac diff --git a/pkg/backup/backup_protection_test.go b/pkg/backup/backup_protection_test.go index 8dc6f50bdba6a..a890d19203561 100644 --- a/pkg/backup/backup_protection_test.go +++ b/pkg/backup/backup_protection_test.go @@ -34,6 +34,32 @@ import ( "github.com/stretchr/testify/require" ) +const backupProtectionCheckpointTimeout = 30 * time.Second + +// forceBackupProtectionCheckpoint waits for the checkpoint that covers the +// requested timestamp. ForceCheckpoint already waits for that semantic +// postcondition; a second poll of runner/WAL idleness is both weaker and prone +// to fixed-delay flakes under a contended CI runner. +func forceBackupProtectionCheckpoint(t *testing.T, db *testutil.TestEngine) { + t.Helper() + + target := db.TxnMgr.Now() + ctx, cancel := context.WithTimeout(t.Context(), backupProtectionCheckpointTimeout) + defer cancel() + require.NoError(t, db.DB.ForceCheckpoint(ctx, target)) + + checkpoint := db.BGCheckpointRunner.MaxIncrementalCheckpoint() + require.NotNil(t, checkpoint) + end := checkpoint.GetEnd() + require.Truef( + t, + end.GE(&target), + "latest checkpoint %s does not cover requested timestamp %s", + end.ToString(), + target.ToString(), + ) +} + // TestBackupProtectionCheckpointProtection tests that protected checkpoints are not deleted by GC func TestBackupProtectionCheckpointProtection(t *testing.T) { defer testutils.AfterTest(t)() @@ -72,10 +98,7 @@ func TestBackupProtectionCheckpointProtection(t *testing.T) { require.NoError(t, txn.Commit(context.Background())) // Force checkpoint to create checkpoint files - db.ForceCheckpoint() - testutils.WaitExpect(5000, func() bool { - return db.AllCheckpointsFinished() - }) + forceBackupProtectionCheckpoint(t, db) // Get all checkpoints before backup allCheckpointsBefore := db.BGCheckpointRunner.GetAllCheckpoints() @@ -156,10 +179,7 @@ func TestBackupProtectionMetadataFileFiltering(t *testing.T) { require.NoError(t, txn.Commit(context.Background())) // Force checkpoint - db.ForceCheckpoint() - testutils.WaitExpect(5000, func() bool { - return db.AllCheckpointsFinished() - }) + forceBackupProtectionCheckpoint(t, db) // Get backup time point allCheckpoints := db.BGCheckpointRunner.GetAllCheckpoints() @@ -233,10 +253,7 @@ func TestBackupProtectionMetadataFileFiltering(t *testing.T) { require.NoError(t, err) require.NoError(t, txn.Commit(context.Background())) - db.ForceCheckpoint() - testutils.WaitExpect(5000, func() bool { - return db.AllCheckpointsFinished() - }) + forceBackupProtectionCheckpoint(t, db) // List checkpoint files after creating new checkpoint entriesAfter, err := fileservice.SortedList(db.Opts.Fs.List(ctx, ckpDir)) @@ -384,10 +401,7 @@ func TestBackupProtectionCheckpointFiltering(t *testing.T) { require.NoError(t, err) require.NoError(t, txn.Commit(context.Background())) - db.ForceCheckpoint() - testutils.WaitExpect(5000, func() bool { - return db.AllCheckpointsFinished() - }) + forceBackupProtectionCheckpoint(t, db) time.Sleep(10 * time.Millisecond) // Ensure different timestamps } diff --git a/pkg/bootstrap/upgrade.go b/pkg/bootstrap/upgrade.go index 1bdb596f5bb60..4f8c545f89b3f 100644 --- a/pkg/bootstrap/upgrade.go +++ b/pkg/bootstrap/upgrade.go @@ -32,6 +32,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/bootstrap/versions/v4_0_3" "github.com/matrixorigin/matrixone/pkg/bootstrap/versions/v4_0_4" "github.com/matrixorigin/matrixone/pkg/bootstrap/versions/v4_0_5" + "github.com/matrixorigin/matrixone/pkg/bootstrap/versions/v4_0_6" ) // initUpgrade all versions need create a upgrade handle in pkg/bootstrap/versions @@ -57,6 +58,7 @@ func (s *service) initUpgrade() { s.handles = append(s.handles, v4_0_3.Handler) s.handles = append(s.handles, v4_0_4.Handler) s.handles = append(s.handles, v4_0_5.Handler) + s.handles = append(s.handles, v4_0_6.Handler) } func (s *service) getFinalVersionHandle() VersionHandle { diff --git a/pkg/bootstrap/versions/v4_0_6/cluster_upgrade_list.go b/pkg/bootstrap/versions/v4_0_6/cluster_upgrade_list.go new file mode 100644 index 0000000000000..868048a57b735 --- /dev/null +++ b/pkg/bootstrap/versions/v4_0_6/cluster_upgrade_list.go @@ -0,0 +1,18 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package v4_0_6 + +import "github.com/matrixorigin/matrixone/pkg/bootstrap/versions" + +var clusterUpgEntries = []versions.UpgradeEntry{} diff --git a/pkg/bootstrap/versions/v4_0_6/log.go b/pkg/bootstrap/versions/v4_0_6/log.go new file mode 100644 index 0000000000000..82e3eea411fe2 --- /dev/null +++ b/pkg/bootstrap/versions/v4_0_6/log.go @@ -0,0 +1,21 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package v4_0_6 + +import ( + "github.com/matrixorigin/matrixone/pkg/common/log" + "github.com/matrixorigin/matrixone/pkg/common/runtime" +) + +func getLogger(sid string) *log.MOLogger { return runtime.ServiceRuntime(sid).Logger() } diff --git a/pkg/bootstrap/versions/v4_0_6/tenant_upgrade_list.go b/pkg/bootstrap/versions/v4_0_6/tenant_upgrade_list.go new file mode 100644 index 0000000000000..5283d3a56088f --- /dev/null +++ b/pkg/bootstrap/versions/v4_0_6/tenant_upgrade_list.go @@ -0,0 +1,38 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package v4_0_6 + +import ( + "github.com/matrixorigin/matrixone/pkg/bootstrap/versions" + "github.com/matrixorigin/matrixone/pkg/catalog" + "github.com/matrixorigin/matrixone/pkg/sql/mongodb" + "github.com/matrixorigin/matrixone/pkg/util/executor" +) + +var tenantUpgEntries = []versions.UpgradeEntry{ + newMongoDBCatalogTable(mongodb.TableConnections, mongodb.ConnectionsDDL), + newMongoDBCatalogTable(mongodb.TableMappings, mongodb.MappingsDDL), +} + +func newMongoDBCatalogTable(name, ddl string) versions.UpgradeEntry { + return versions.UpgradeEntry{ + Schema: catalog.MO_CATALOG, + TableName: name, + UpgType: versions.CREATE_NEW_TABLE, + UpgSql: ddl, + CheckFunc: func(txn executor.TxnExecutor, accountID uint32) (bool, error) { + return versions.CheckTableDefinition(txn, accountID, catalog.MO_CATALOG, name) + }, + } +} diff --git a/pkg/bootstrap/versions/v4_0_6/upgrade.go b/pkg/bootstrap/versions/v4_0_6/upgrade.go new file mode 100644 index 0000000000000..9bb1c7c3e52cc --- /dev/null +++ b/pkg/bootstrap/versions/v4_0_6/upgrade.go @@ -0,0 +1,72 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package v4_0_6 + +import ( + "context" + "time" + + "go.uber.org/zap" + + "github.com/matrixorigin/matrixone/pkg/bootstrap/versions" + "github.com/matrixorigin/matrixone/pkg/catalog" + "github.com/matrixorigin/matrixone/pkg/common/moerr" + "github.com/matrixorigin/matrixone/pkg/util/executor" +) + +var Handler *versionHandle + +func init() { + Handler = &versionHandle{metadata: versions.Version{ + Version: "4.0.6", + MinUpgradeVersion: "4.0.5", + UpgradeCluster: versions.Yes, + UpgradeTenant: versions.Yes, + VersionOffset: uint32(len(tenantUpgEntries) + len(clusterUpgEntries)), + }} +} + +type versionHandle struct{ metadata versions.Version } + +func (v *versionHandle) Metadata() versions.Version { return v.metadata } + +func (v *versionHandle) Prepare(_ context.Context, txn executor.TxnExecutor, _ bool) error { + txn.Use(catalog.MO_CATALOG) + return nil +} + +func (v *versionHandle) HandleTenantUpgrade(_ context.Context, tenantID int32, txn executor.TxnExecutor) error { + for _, entry := range tenantUpgEntries { + start := time.Now() + if err := entry.Upgrade(txn, uint32(tenantID)); err != nil { + getLogger(txn.Txn().TxnOptions().CN).Error("tenant upgrade entry execute error", zap.Error(err), zap.Int32("tenantId", tenantID), zap.String("version", v.metadata.Version), zap.String("upgrade entry", entry.String())) + return err + } + getLogger(txn.Txn().TxnOptions().CN).Info("tenant upgrade entry complete", zap.String("upgrade entry", entry.String()), zap.Int64("time cost(ms)", time.Since(start).Milliseconds()), zap.String("toVersion", v.metadata.Version)) + } + return nil +} + +func (v *versionHandle) HandleClusterUpgrade(_ context.Context, txn executor.TxnExecutor) error { + for _, entry := range clusterUpgEntries { + if err := entry.Upgrade(txn, uint32(txn.Txn().TxnOptions().AccountID)); err != nil { + return err + } + } + return nil +} + +func (v *versionHandle) HandleCreateFrameworkDeps(executor.TxnExecutor) error { + return moerr.NewInternalErrorNoCtxf("Only v1.2.0 can initialize upgrade framework, current version is:%s", v.metadata.Version) +} diff --git a/pkg/bootstrap/versions/v4_0_6/upgrade_test.go b/pkg/bootstrap/versions/v4_0_6/upgrade_test.go new file mode 100644 index 0000000000000..2371f4cb563b9 --- /dev/null +++ b/pkg/bootstrap/versions/v4_0_6/upgrade_test.go @@ -0,0 +1,41 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v4_0_6 + +import ( + "strings" + "testing" + + "github.com/matrixorigin/matrixone/pkg/bootstrap/versions" + "github.com/matrixorigin/matrixone/pkg/sql/mongodb" + "github.com/stretchr/testify/require" +) + +func TestMongoDBCatalogUpgradeEntries(t *testing.T) { + require.Len(t, tenantUpgEntries, 2) + require.Empty(t, clusterUpgEntries) + require.Equal(t, mongodb.TableConnections, tenantUpgEntries[0].TableName) + require.Equal(t, mongodb.TableMappings, tenantUpgEntries[1].TableName) + for _, entry := range tenantUpgEntries { + require.Equal(t, versions.CREATE_NEW_TABLE, entry.UpgType) + require.Contains(t, strings.ToLower(entry.UpgSql), "create table mo_catalog.") + } + + meta := Handler.Metadata() + require.Equal(t, "4.0.6", meta.Version) + require.Equal(t, "4.0.5", meta.MinUpgradeVersion) + require.Equal(t, versions.Yes, meta.UpgradeTenant) + require.Equal(t, uint32(len(tenantUpgEntries)+len(clusterUpgEntries)), meta.VersionOffset) +} diff --git a/pkg/cdc/table_change_stream_test.go b/pkg/cdc/table_change_stream_test.go index 093fb2e6f17a1..26eb8bcd446e3 100644 --- a/pkg/cdc/table_change_stream_test.go +++ b/pkg/cdc/table_change_stream_test.go @@ -893,20 +893,20 @@ func TestTableChangeStream_Run_ContextCancel(t *testing.T) { h := newTableStreamHarness(t) defer h.Close() - tail := createTestBatch(t, h.MP(), types.BuildTS(10, 0), []int32{1}) - h.SetCollectBatches([]changeBatch{ - {insert: tail, hint: engine.ChangesHandle_Tail_done}, - {insert: nil, hint: engine.ChangesHandle_Tail_done}, + ready := make(chan struct{}) + h.SetCollectFactory(func(fromTs, toTs types.TS) (engine.ChangesHandle, error) { + return &blockingChangesHandle{ready: ready}, nil }) ar := h.NewActiveRoutine() errCh, done := h.RunStreamAsync(ar) - require.Eventually(t, func() bool { - return len(h.CollectCallsSnapshot()) > 0 - }, time.Second, 10*time.Millisecond, "stream should begin collecting before cancellation") - - opsBefore := h.Sinker().opsSnapshot() + select { + case <-ready: + case <-time.After(2 * time.Second): + t.Fatal("collector did not block before context cancellation") + } + require.Empty(t, h.Sinker().opsSnapshot(), "blocked collector should not produce sink operations") h.Cancel() done() @@ -923,7 +923,7 @@ func TestTableChangeStream_Run_ContextCancel(t *testing.T) { } require.False(t, h.Stream().GetRetryable(), "cancel should not mark stream retryable") - require.Equal(t, opsBefore, h.Sinker().opsSnapshot(), "cancel should not produce additional sink operations") + require.Empty(t, h.Sinker().opsSnapshot(), "cancel should not produce sink or cleanup operations") } // Test ActiveRoutine Pause diff --git a/pkg/cnservice/server.go b/pkg/cnservice/server.go index 01a4000bbd3db..19031130b1cff 100644 --- a/pkg/cnservice/server.go +++ b/pkg/cnservice/server.go @@ -62,6 +62,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/sql/colexec" "github.com/matrixorigin/matrixone/pkg/sql/compile" sqliceberg "github.com/matrixorigin/matrixone/pkg/sql/iceberg" + sqlmongodb "github.com/matrixorigin/matrixone/pkg/sql/mongodb" "github.com/matrixorigin/matrixone/pkg/txn/client" "github.com/matrixorigin/matrixone/pkg/txn/clock" "github.com/matrixorigin/matrixone/pkg/txn/rpc" @@ -126,6 +127,9 @@ func NewService( if err := cfg.Frontend.Iceberg.Validate(ctx); err != nil { return nil, err } + if err := cfg.Frontend.MongoDB.Validate(ctx); err != nil { + return nil, err + } cfg.Frontend.SetMaxMessageSize(uint64(cfg.RPC.MaxMessageSize)) configKVMap, _ := dumpCnConfig(*cfg) @@ -421,44 +425,51 @@ func (s *service) Close() error { defer logutil.LogClose(s.logger, "cnservice")() s.stopper.Stop() - if err := s.bootstrapService.Close(); err != nil { - return err - } - if err := s.stopFrontend(); err != nil { - return err - } - if err := s.stopTask(); err != nil { - return err - } - if err := s.stopRPCs(); err != nil { - return err - } - // stop I/O pipeline - ioutil.Stop(s.cfg.UUID) - if s.gossipNode != nil { - if err := s.gossipNode.Leave(time.Second); err != nil { - return err - } - } + return closeCNServiceSteps( + s.bootstrapService.Close, + s.stopFrontend, + // Frontend shutdown stops accepting interactive work, while stopTask + // drains scheduled ingestion statements. Only after both producers have + // stopped may the MongoDB pool disconnect clients still leased by a + // MongoScan operator. + s.stopTask, + s.closeMongoDBRuntime, + s.stopRPCs, + func() error { + // stop I/O pipeline + ioutil.Stop(s.cfg.UUID) + return nil + }, + func() error { + if s.gossipNode != nil { + return s.gossipNode.Leave(time.Second) + } + return nil + }, + s.server.Close, + s.lockService.Close, + func() error { + if s.shardService != nil { + return s.shardService.Close() + } + return nil + }, + func() error { + if s.pipelines.client != nil { + return s.pipelines.client.Close() + } + return nil + }, + ) +} - if err := s.server.Close(); err != nil { - return err - } - if err := s.lockService.Close(); err != nil { - return err - } - if s.shardService != nil { - if err := s.shardService.Close(); err != nil { - return err - } - } - if s.pipelines.client != nil { - if err := s.pipelines.client.Close(); err != nil { - return err - } +func closeCNServiceSteps(steps ...func() error) error { + var err error + for _, step := range steps { + err = errors.Join(err, step()) } - return nil + return err } // ID implements the frontend.BaseService interface. @@ -1069,6 +1080,59 @@ func (s *service) initInternalSQlExecutor(mp *mpool.MPool) { s.pu.GetTaskService(), ) runtime.ServiceRuntime(s.cfg.UUID).SetGlobalVariables(runtime.InternalSQLExecutor, s.sqlExecutor) + s.initMongoDBRuntime() +} + +func (s *service) initMongoDBRuntime() { + parameters := s.pu.SV.MongoDB + allowedAccounts := make(map[uint32]struct{}, len(parameters.AllowedAccounts)) + for _, accountID := range parameters.AllowedAccounts { + allowedAccounts[accountID] = struct{}{} + } + config := sqlmongodb.RuntimeConfig{ + Enable: parameters.Enable, EnablePerAccount: parameters.EnablePerAccount, + AllowedAccounts: allowedAccounts, AllowLoopback: parameters.AllowLoopback, + AllowedHostSuffixes: append([]string(nil), parameters.AllowedHostSuffixes...), + AllowedCIDRs: append([]string(nil), parameters.AllowedCIDRs...), + ConnectTimeout: parameters.ConnectTimeout.Duration, + ServerSelectionTimeout: parameters.ServerSelectionTimeout.Duration, + SocketTimeout: parameters.SocketTimeout.Duration, + MaxPoolSize: parameters.MaxPoolSize, MinPoolSize: parameters.MinPoolSize, + MaxConnecting: parameters.MaxConnecting, MaxCachedClients: parameters.MaxCachedClients, + BatchRows: parameters.BatchRows, + MaxBatchBytes: parameters.MaxBatchBytes, MaxValueBytes: parameters.MaxValueBytes, + MaxScanRows: parameters.MaxScanRows, MaxScanBytes: parameters.MaxScanBytes, + MaxConversionErrors: parameters.MaxConversionErrors, MaxConversionErrorRate: parameters.MaxConversionErrorRate, + MaxSourceConcurrency: parameters.MaxSourceConcurrency, + } + dependencies := &sqlmongodb.RuntimeDependencies{ + Config: config, + Connections: sqlmongodb.CatalogConnectionResolver{Executor: s.sqlExecutor}, + Mappings: sqlmongodb.CatalogMappingResolver{Executor: s.sqlExecutor}, + Secrets: sqlmongodb.EnvSecretResolver{}, + Pool: sqlmongodb.NewValidatedClientPool( + sqlmongodb.OfficialClientFactory{}, + sqlmongodb.CatalogConnectionResolver{Executor: s.sqlExecutor}, + config.MaxCachedClients, + ), + Limiter: sqlmongodb.NewSourceLimiter(config.MaxSourceConcurrency), + } + runtime.ServiceRuntime(s.cfg.UUID).SetGlobalVariables(sqlmongodb.RuntimeDependenciesKey, dependencies) +} + +func (s *service) closeMongoDBRuntime() error { + rt := runtime.ServiceRuntime(s.cfg.UUID) + value, ok := rt.GetGlobalVariables(sqlmongodb.RuntimeDependenciesKey) + if !ok { + return nil + } + dependencies, ok := value.(*sqlmongodb.RuntimeDependencies) + if !ok || dependencies == nil || dependencies.Pool == nil { + return nil + } + ctx, cancel := context.WithTimeoutCause(context.Background(), 10*time.Second, moerr.CauseShutdown) + defer cancel() + return dependencies.Pool.Close(ctx) } func (s *service) initIncrService() { diff --git a/pkg/cnservice/server_query.go b/pkg/cnservice/server_query.go index c49e2cedc4592..58c61bcff065a 100644 --- a/pkg/cnservice/server_query.go +++ b/pkg/cnservice/server_query.go @@ -39,6 +39,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/perfcounter" "github.com/matrixorigin/matrixone/pkg/queryservice" qclient "github.com/matrixorigin/matrixone/pkg/queryservice/client" + sqlmongodb "github.com/matrixorigin/matrixone/pkg/sql/mongodb" "github.com/matrixorigin/matrixone/pkg/sql/plan/function/ctl" "github.com/matrixorigin/matrixone/pkg/txn/client" "github.com/matrixorigin/matrixone/pkg/util/fault" @@ -105,6 +106,7 @@ func (s *service) initQueryCommandHandler() { s.queryService.AddHandleFunc(query.CmdMethod_MinTimestamp, s.handleGetMinTimestamp, false) s.queryService.AddHandleFunc(query.CmdMethod_CtlPrefetchOnSubscribed, s.handleCtlPrefetchOnSubscribed, false) s.queryService.AddHandleFunc(query.CmdMethod_IcebergCacheInvalidate, s.handleIcebergCacheInvalidate, false) + s.queryService.AddHandleFunc(query.CmdMethod_MongoDBClientRetire, s.handleMongoDBClientRetire, false) } func (s *service) handleKillConn(ctx context.Context, req *query.Request, resp *query.Response, _ *morpc.Buffer) error { @@ -678,6 +680,32 @@ func (s *service) handleIcebergCacheInvalidate( return nil } +func (s *service) handleMongoDBClientRetire( + ctx context.Context, req *query.Request, resp *query.Response, _ *morpc.Buffer, +) error { + if req == nil { + return moerr.NewInternalError(ctx, "invalid MongoDB client retirement request") + } + value, ok := moruntime.ServiceRuntime(s.serviceID()).GetGlobalVariables(sqlmongodb.RuntimeDependenciesKey) + if !ok || value == nil { + resp.MongoDBClientRetireResponse.Success = true + return nil + } + dependencies, ok := value.(*sqlmongodb.RuntimeDependencies) + if !ok { + return moerr.NewInternalError(ctx, "invalid MongoDB runtime dependencies") + } + payload := req.GetMongoDBClientRetireRequest() + if err := (sqlmongodb.ClientRetirement{ + AccountID: payload.AccountID, ConnectionID: payload.ConnectionID, + VersionExclusive: payload.VersionExclusive, + }).Apply(dependencies.Pool); err != nil { + return err + } + resp.MongoDBClientRetireResponse.Success = true + return nil +} + func (s *service) serviceID() string { if s == nil || s.cfg == nil { return "" diff --git a/pkg/cnservice/server_query_test.go b/pkg/cnservice/server_query_test.go index bf186446a61c5..d35c05f181770 100644 --- a/pkg/cnservice/server_query_test.go +++ b/pkg/cnservice/server_query_test.go @@ -48,6 +48,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/pb/task" "github.com/matrixorigin/matrixone/pkg/queryservice" "github.com/matrixorigin/matrixone/pkg/shardservice" + sqlmongodb "github.com/matrixorigin/matrixone/pkg/sql/mongodb" "github.com/matrixorigin/matrixone/pkg/sql/plan/function/ctl" "github.com/matrixorigin/matrixone/pkg/taskservice" "github.com/matrixorigin/matrixone/pkg/testutil" @@ -1271,6 +1272,54 @@ func Test_service_handleIcebergCacheInvalidate(t *testing.T) { }, handler.req) } +func Test_service_handleMongoDBClientRetire(t *testing.T) { + const serviceID = "mongodb-retire-handler" + rt := moruntime.DefaultRuntime() + moruntime.SetupServiceBasedRuntime(serviceID, rt) + factory := &cnMongoDBClientFactory{} + pool := sqlmongodb.NewClientPool(factory) + t.Cleanup(func() { require.NoError(t, pool.Close(context.Background())) }) + rt.SetGlobalVariables(sqlmongodb.RuntimeDependenciesKey, &sqlmongodb.RuntimeDependencies{Pool: pool}) + defer rt.SetGlobalVariables(sqlmongodb.RuntimeDependenciesKey, nil) + + lease, err := pool.Acquire(t.Context(), sqlmongodb.Connection{ + AccountID: 7, ConnectionID: 9, Version: 3, + }, sqlmongodb.Credentials{}, sqlmongodb.RuntimeConfig{}) + require.NoError(t, err) + require.NoError(t, lease.Release(t.Context())) + + s := &service{cfg: &Config{UUID: serviceID}} + var resp query.Response + err = s.handleMongoDBClientRetire(t.Context(), &query.Request{ + MongoDBClientRetireRequest: query.MongoDBClientRetireRequest{AccountID: 7}, + }, &resp, nil) + require.NoError(t, err) + require.True(t, resp.MongoDBClientRetireResponse.Success) + require.Equal(t, 1, factory.client.disconnects) +} + +type cnMongoDBClientFactory struct { + client *cnMongoDBClient +} + +func (f *cnMongoDBClientFactory) Connect( + context.Context, sqlmongodb.Connection, sqlmongodb.Credentials, sqlmongodb.RuntimeConfig, +) (sqlmongodb.Client, error) { + f.client = &cnMongoDBClient{} + return f.client, nil +} + +type cnMongoDBClient struct { + disconnects int +} + +func (*cnMongoDBClient) Collection(string, string) sqlmongodb.Collection { return nil } +func (*cnMongoDBClient) Ping(context.Context) error { return nil } +func (c *cnMongoDBClient) Disconnect(context.Context) error { + c.disconnects++ + return nil +} + type fakeIcebergCacheInvalidationHandler struct { req api.CacheInvalidationRequest removed int diff --git a/pkg/config/configuration.go b/pkg/config/configuration.go index 32be2889e4813..50f77f2b6fefe 100644 --- a/pkg/config/configuration.go +++ b/pkg/config/configuration.go @@ -16,8 +16,10 @@ package config import ( "context" + "net" "os" "path/filepath" + "strings" "sync" "sync/atomic" "time" @@ -254,6 +256,105 @@ type IcebergParameters struct { EnableOrphanGC bool `toml:"enable-orphan-gc" user_setting:"advanced"` } +type MongoDBParameters struct { + Enable bool `toml:"enable" user_setting:"advanced"` + EnablePerAccount bool `toml:"enable-per-account" user_setting:"advanced"` + AllowedAccounts []uint32 `toml:"allowed-accounts" user_setting:"advanced"` + AllowLoopback bool `toml:"allow-loopback" user_setting:"advanced"` + AllowedHostSuffixes []string `toml:"allowed-host-suffixes" user_setting:"advanced"` + AllowedCIDRs []string `toml:"allowed-cidrs" user_setting:"advanced"` + ConnectTimeout toml.Duration `toml:"connect-timeout" user_setting:"advanced"` + ServerSelectionTimeout toml.Duration `toml:"server-selection-timeout" user_setting:"advanced"` + SocketTimeout toml.Duration `toml:"socket-timeout" user_setting:"advanced"` + MaxPoolSize uint64 `toml:"max-pool-size" user_setting:"advanced"` + MinPoolSize uint64 `toml:"min-pool-size" user_setting:"advanced"` + MaxConnecting uint64 `toml:"max-connecting" user_setting:"advanced"` + MaxCachedClients int `toml:"max-cached-clients" user_setting:"advanced"` + BatchRows int32 `toml:"batch-rows" user_setting:"advanced"` + MaxBatchBytes int64 `toml:"max-batch-bytes" user_setting:"advanced"` + MaxValueBytes int64 `toml:"max-value-bytes" user_setting:"advanced"` + MaxScanRows int64 `toml:"max-scan-rows" user_setting:"advanced"` + MaxScanBytes int64 `toml:"max-scan-bytes" user_setting:"advanced"` + MaxConversionErrors int64 `toml:"max-conversion-errors" user_setting:"advanced"` + MaxConversionErrorRate float64 `toml:"max-conversion-error-rate" user_setting:"advanced"` + MaxSourceConcurrency int `toml:"max-source-concurrency" user_setting:"advanced"` +} + +func (parameters *MongoDBParameters) SetDefaultValues() { + if parameters.ConnectTimeout.Duration == 0 { + parameters.ConnectTimeout.Duration = 10 * time.Second + } + if parameters.ServerSelectionTimeout.Duration == 0 { + parameters.ServerSelectionTimeout.Duration = 10 * time.Second + } + if parameters.SocketTimeout.Duration == 0 { + parameters.SocketTimeout.Duration = 30 * time.Second + } + if parameters.MaxPoolSize == 0 { + parameters.MaxPoolSize = 32 + } + if parameters.MaxConnecting == 0 { + parameters.MaxConnecting = 2 + } + if parameters.MaxCachedClients == 0 { + parameters.MaxCachedClients = 64 + } + if parameters.BatchRows == 0 { + parameters.BatchRows = 8192 + } + if parameters.MaxBatchBytes == 0 { + parameters.MaxBatchBytes = 64 << 20 + } + if parameters.MaxValueBytes == 0 { + parameters.MaxValueBytes = 16 << 20 + } + if parameters.MaxScanRows == 0 { + parameters.MaxScanRows = 50_000_000 + } + if parameters.MaxScanBytes == 0 { + parameters.MaxScanBytes = 32 << 30 + } + if parameters.MaxConversionErrors == 0 { + parameters.MaxConversionErrors = 1_000 + } + if parameters.MaxConversionErrorRate == 0 { + parameters.MaxConversionErrorRate = 0.10 + } + if parameters.MaxSourceConcurrency == 0 { + parameters.MaxSourceConcurrency = 4 + } +} + +func (parameters MongoDBParameters) Validate(ctx context.Context) error { + if parameters.ConnectTimeout.Duration <= 0 || parameters.ServerSelectionTimeout.Duration <= 0 || parameters.SocketTimeout.Duration <= 0 { + return moerr.NewBadConfig(ctx, "mongodb timeouts must be greater than zero") + } + if parameters.MaxPoolSize == 0 || parameters.MaxConnecting == 0 || parameters.MaxCachedClients <= 0 || parameters.MinPoolSize > parameters.MaxPoolSize { + return moerr.NewBadConfig(ctx, "mongodb pool limits are invalid") + } + if parameters.BatchRows <= 0 || parameters.MaxBatchBytes <= 0 || parameters.MaxValueBytes <= 0 || parameters.MaxValueBytes > parameters.MaxBatchBytes { + return moerr.NewBadConfig(ctx, "mongodb batch/value limits are invalid") + } + if parameters.MaxScanRows <= 0 || parameters.MaxScanBytes <= 0 || parameters.MaxSourceConcurrency <= 0 { + return moerr.NewBadConfig(ctx, "mongodb source protection limits must be greater than zero") + } + if parameters.MaxConversionErrors <= 0 || parameters.MaxConversionErrorRate <= 0 || parameters.MaxConversionErrorRate > 1 { + return moerr.NewBadConfig(ctx, "mongodb conversion error limits are invalid") + } + for _, raw := range parameters.AllowedHostSuffixes { + suffix := strings.Trim(strings.TrimSpace(raw), ".") + if suffix == "" || net.ParseIP(suffix) != nil || strings.ContainsAny(suffix, "*/@: \t\r\n") { + return moerr.NewBadConfig(ctx, "mongodb allowed host suffix is invalid") + } + } + for _, raw := range parameters.AllowedCIDRs { + if _, _, err := net.ParseCIDR(strings.TrimSpace(raw)); err != nil { + return moerr.NewBadConfig(ctx, "mongodb allowed CIDR is invalid") + } + } + return nil +} + func (ip *IcebergParameters) SetDefaultValues() { if ip.ManifestCacheBytes == 0 { ip.ManifestCacheBytes = 256 << 20 @@ -505,6 +606,7 @@ type FrontendParameters struct { SidecarURL string `toml:"sidecarUrl" user_setting:"advanced"` Iceberg IcebergParameters `toml:"iceberg" user_setting:"advanced"` + MongoDB MongoDBParameters `toml:"mongodb" user_setting:"advanced"` } func (fp *FrontendParameters) SetDefaultValues() { @@ -663,6 +765,7 @@ func (fp *FrontendParameters) SetDefaultValues() { } fp.Iceberg.SetDefaultValues() + fp.MongoDB.SetDefaultValues() } func (fp *FrontendParameters) SetMaxMessageSize(size uint64) { diff --git a/pkg/config/mongodb_test.go b/pkg/config/mongodb_test.go new file mode 100644 index 0000000000000..5024b9df9f1a7 --- /dev/null +++ b/pkg/config/mongodb_test.go @@ -0,0 +1,48 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package config + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestMongoDBParametersDefaultsAndValidation(t *testing.T) { + var parameters MongoDBParameters + parameters.SetDefaultValues() + require.NoError(t, parameters.Validate(t.Context())) + require.Positive(t, parameters.MaxConversionErrors) + require.InDelta(t, 0.10, parameters.MaxConversionErrorRate, 0) + parameters.MaxValueBytes = parameters.MaxBatchBytes + 1 + require.Error(t, parameters.Validate(t.Context())) + parameters.MaxValueBytes = 1 + parameters.MaxConversionErrorRate = 1.1 + require.Error(t, parameters.Validate(t.Context())) +} + +func TestMongoDBParametersRejectMalformedEndpointPolicy(t *testing.T) { + var parameters MongoDBParameters + parameters.SetDefaultValues() + parameters.AllowedHostSuffixes = []string{"mongo.example"} + parameters.AllowedCIDRs = []string{"10.0.0.0/8"} + require.NoError(t, parameters.Validate(t.Context())) + + parameters.AllowedHostSuffixes = []string{"*.mongo.example"} + require.ErrorContains(t, parameters.Validate(t.Context()), "host suffix") + parameters.AllowedHostSuffixes = []string{"mongo.example"} + parameters.AllowedCIDRs = []string{"not-a-cidr"} + require.ErrorContains(t, parameters.Validate(t.Context()), "CIDR") +} diff --git a/pkg/defines/const.go b/pkg/defines/const.go index b719a371b7f1b..d11bb939ea899 100644 --- a/pkg/defines/const.go +++ b/pkg/defines/const.go @@ -52,7 +52,8 @@ const ( MORPCVersion2 int64 = 2 MORPCVersion3 int64 = 3 // start from 1.3.0 MORPCVersion4 int64 = 4 // start from 2.0.1 - MORPCLatestVersion = MORPCVersion4 + MORPCVersion5 int64 = 5 // adds MongoDB client retirement RPC + MORPCLatestVersion = MORPCVersion5 ) // DefaultLockWaitTimeoutSeconds is shared by the frontend default and by diff --git a/pkg/embed/cluster_test.go b/pkg/embed/cluster_test.go index 9572cbe698c23..a258cc4dcfcce 100644 --- a/pkg/embed/cluster_test.go +++ b/pkg/embed/cluster_test.go @@ -149,6 +149,38 @@ func TestBaseClusterOnlyStartOnce(t *testing.T) { require.Equal(t, id1, id2) } +func TestBaseClusterHAKeeperTimeouts(t *testing.T) { + require.NoError(t, RunBaseClusterTests(func(c Cluster) { + var cnCount, tnCount, logCount int + c.ForeachServices(func(svc ServiceOperator) bool { + cfg := svc.GetServiceConfig() + switch svc.ServiceType() { + case metadata.ServiceType_CN: + cnCount++ + require.Equal(t, basicClusterHAKeeperHeartbeatTimeout, cfg.CN.HAKeeper.HeatbeatTimeout.Duration) + case metadata.ServiceType_TN: + tnCount++ + require.NotNil(t, cfg.TN_please_use_getTNServiceConfig) + require.Equal( + t, + basicClusterHAKeeperHeartbeatTimeout, + cfg.TN_please_use_getTNServiceConfig.HAKeeper.HeatbeatTimeout.Duration, + ) + case metadata.ServiceType_LOG: + logCount++ + require.Equal(t, basicClusterHAKeeperStoreTimeout, cfg.LogService.HAKeeperConfig.TNStoreTimeout.Duration) + require.Equal(t, basicClusterHAKeeperStoreTimeout, cfg.LogService.HAKeeperConfig.CNStoreTimeout.Duration) + } + return true + }) + + require.Equal(t, 3, cnCount) + require.Equal(t, 1, tnCount) + require.Equal(t, 1, logCount) + require.Less(t, basicClusterHAKeeperHeartbeatTimeout, basicClusterHAKeeperStoreTimeout) + })) +} + func TestRestartCN(t *testing.T) { t.SkipNow() RunBaseClusterTests( diff --git a/pkg/embed/testing.go b/pkg/embed/testing.go index c79580d17a97c..74e9aa7428326 100644 --- a/pkg/embed/testing.go +++ b/pkg/embed/testing.go @@ -17,6 +17,9 @@ package embed import ( "context" "fmt" + "sync" + "time" + mruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" "github.com/matrixorigin/matrixone/pkg/config" "github.com/matrixorigin/matrixone/pkg/frontend" @@ -24,7 +27,6 @@ import ( "github.com/matrixorigin/matrixone/pkg/pb/metadata" "github.com/matrixorigin/matrixone/pkg/taskservice" "github.com/matrixorigin/matrixone/pkg/util/metric/stats" - "sync" ) var ( @@ -37,6 +39,41 @@ func init() { stats.SkipPanicONDuplicate.Store(true) } +const ( + basicClusterHAKeeperHeartbeatTimeout = 30 * time.Second + basicClusterHAKeeperStoreTimeout = 60 * time.Second +) + +func configureBaseClusterService(svc ServiceOperator) { + svc.Adjust(func(config *ServiceConfig) { + switch svc.ServiceType() { + case metadata.ServiceType_CN: + config.CN.LockService.MaxFixedSliceSize = 10001 + config.CN.LockService.MaxLockRowCount = 10000 + config.CN.Frontend.SkipCheckUser = true + config.CN.Frontend.Iceberg.Enable = true + config.CN.Frontend.Iceberg.EnableWrite = true + config.CN.Frontend.Iceberg.EnableDelete = true + config.CN.Frontend.Iceberg.EnableDML = true + config.CN.Frontend.Iceberg.EnableMaintenance = true + config.CN.HAKeeper.HeatbeatTimeout.Duration = basicClusterHAKeeperHeartbeatTimeout + case metadata.ServiceType_TN: + if config.TN_please_use_getTNServiceConfig != nil { + config.TN_please_use_getTNServiceConfig.HAKeeper.HeatbeatTimeout.Duration = + basicClusterHAKeeperHeartbeatTimeout + } + if config.TNCompatible != nil && + config.TNCompatible != config.TN_please_use_getTNServiceConfig { + config.TNCompatible.HAKeeper.HeatbeatTimeout.Duration = + basicClusterHAKeeperHeartbeatTimeout + } + case metadata.ServiceType_LOG: + config.LogService.HAKeeperConfig.TNStoreTimeout.Duration = basicClusterHAKeeperStoreTimeout + config.LogService.HAKeeperConfig.CNStoreTimeout.Duration = basicClusterHAKeeperStoreTimeout + } + }) +} + // RunBaseClusterTests starting an integration test for a 1 log, 1tn, 3cn base cluster is very slow // due to the amount of time it takes to start a cluster (10-20s) when there are a very large number // of test cases. So for some special cases that don't need to be restarted, a basicCluster can be @@ -55,22 +92,7 @@ func RunBaseClusterTests( c, err = NewCluster( WithCNCount(3), WithTesting(), - WithPreStart(func(svc ServiceOperator) { - if svc.ServiceType() == metadata.ServiceType_CN { - svc.Adjust( - func(config *ServiceConfig) { - config.CN.LockService.MaxFixedSliceSize = 10001 - config.CN.LockService.MaxLockRowCount = 10000 - config.CN.Frontend.SkipCheckUser = true - config.CN.Frontend.Iceberg.Enable = true - config.CN.Frontend.Iceberg.EnableWrite = true - config.CN.Frontend.Iceberg.EnableDelete = true - config.CN.Frontend.Iceberg.EnableDML = true - config.CN.Frontend.Iceberg.EnableMaintenance = true - }, - ) - } - }), + WithPreStart(configureBaseClusterService), ) if err != nil { return diff --git a/pkg/frontend/authenticate.go b/pkg/frontend/authenticate.go index 1bc2f4e1ef9f8..b2f3bb1f1bd07 100644 --- a/pkg/frontend/authenticate.go +++ b/pkg/frontend/authenticate.go @@ -52,6 +52,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/pb/timestamp" "github.com/matrixorigin/matrixone/pkg/queryservice" icebergsql "github.com/matrixorigin/matrixone/pkg/sql/iceberg" + "github.com/matrixorigin/matrixone/pkg/sql/mongodb" "github.com/matrixorigin/matrixone/pkg/sql/parsers" "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect" "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect/mysql" @@ -1007,6 +1008,8 @@ var ( icebergsql.TablePublishJobs: 0, icebergsql.TableOrphanFiles: 0, icebergsql.TableMaintenanceJobs: 0, + mongodb.TableConnections: 0, + mongodb.TableMappings: 0, } createDbInformationSchemaSql = "create database information_schema;" createAutoTableSql = MoCatalogMoAutoIncrTableDDL @@ -1065,6 +1068,8 @@ var ( icebergsql.PublishJobsDDL, icebergsql.OrphanFilesDDL, icebergsql.MaintenanceJobsDDL, + mongodb.ConnectionsDDL, + mongodb.MappingsDDL, } // drop tables for the tenant @@ -1096,6 +1101,10 @@ var ( `drop table if exists mo_catalog.mo_iceberg_principal_map;`, `drop table if exists mo_catalog.mo_iceberg_catalogs;`, } + dropMongoDBSqls = []string{ + `drop table if exists mo_catalog.mo_mongodb_tables;`, + `drop table if exists mo_catalog.mo_mongodb_connections;`, + } dropMoMysqlCompatibilityModeSql = `drop table if exists mo_catalog.mo_mysql_compatibility_mode;` dropAutoIcrColSql = fmt.Sprintf("drop table if exists mo_catalog.`%s`;", catalog.MOAutoIncrTable) dropMoIndexes = fmt.Sprintf("drop table if exists `%s`.`%s`;", catalog.MO_CATALOG, catalog.MO_INDEXES) @@ -4279,6 +4288,14 @@ func doDropAccount(ctx context.Context, bh BackgroundExec, ses *Session, da *dro } } + for _, sql = range dropMongoDBSqls { + ses.Infof(ctx, "dropAccount %s sql: %s", da.Name, sql) + rtnErr = bh.Exec(deleteCtx, sql) + if rtnErr != nil { + return rtnErr + } + } + ses.Infof(ctx, "dropAccount %s sql: %s", da.Name, getSubsSql) // alter sub_account field in mo_pubs which contains accountName subInfos, rtnErr := getSubInfosFromSub(deleteCtx, bh, "") @@ -4431,6 +4448,9 @@ func doDropAccount(ctx context.Context, bh BackgroundExec, ses *Session, da *dro if !hasAccount { return err } + if !inTxn { + retireMongoDBClients(ctx, ses.GetService(), mongodb.ClientRetirement{AccountID: uint32(accountId)}) + } // if drop the account, add the account to kill queue ses.getRoutineManager().accountRoutine.EnKillQueue(accountId, version) @@ -6381,7 +6401,8 @@ func determinePrivilegeSetOfStatement(stmt tree.Statement) *privilege { writeDatabaseAndTableDirectly = true dbName = string(st.Name) writeDatabaseTargets = append(writeDatabaseTargets, string(st.Name)) - case *tree.CreateIcebergCatalog, *tree.AlterIcebergCatalog, *tree.DropIcebergCatalog: + case *tree.CreateIcebergCatalog, *tree.AlterIcebergCatalog, *tree.DropIcebergCatalog, + *tree.CreateMongoDBConnection, *tree.AlterMongoDBConnection, *tree.DropMongoDBConnection: objType = objectTypeNone kind = privilegeKindSpecial special = specialTagAdmin @@ -9925,6 +9946,9 @@ func authenticateUserCanExecuteStatementWithObjectTypeNone(ctx context.Context, *tree.ShowIcebergCatalogs, *tree.ShowIcebergNamespaces, *tree.ShowIcebergTables: yes, err := checkIcebergCatalogPrivilege() return yes, stats, err + case *tree.CreateMongoDBConnection, *tree.AlterMongoDBConnection, *tree.DropMongoDBConnection, + *tree.ShowMongoDBConnections: + return tenant.IsAdminRole(), stats, nil } } diff --git a/pkg/frontend/mongodb.go b/pkg/frontend/mongodb.go new file mode 100644 index 0000000000000..8ccf6bc7f97de --- /dev/null +++ b/pkg/frontend/mongodb.go @@ -0,0 +1,474 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package frontend + +import ( + "context" + "strconv" + "strings" + + "github.com/matrixorigin/matrixone/pkg/clusterservice" + "github.com/matrixorigin/matrixone/pkg/common/moerr" + moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" + "github.com/matrixorigin/matrixone/pkg/config" + "github.com/matrixorigin/matrixone/pkg/defines" + "github.com/matrixorigin/matrixone/pkg/sql/mongodb" + "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" +) + +func handleCreateMongoDBConnection(ctx context.Context, ses *Session, stmt *tree.CreateMongoDBConnection) (err error) { + if err := ensureMongoDBFeatureEnabledForSession(ctx, ses); err != nil { + return err + } + options, err := mongoDBOptionsToMap(ctx, stmt.Options) + if err != nil { + return err + } + connection, err := mongoDBConnectionFromOptions(ctx, ses.GetAccountId(), string(stmt.Name), options, nil, mongoDBParametersForService(ses.GetService())) + if err != nil { + return err + } + bh := ses.GetBackgroundExec(ctx) + defer bh.Close() + if err = bh.Exec(ctx, "begin;"); err != nil { + return err + } + defer func() { err = finishTxn(ctx, bh, err) }() + existing, found, err := queryMongoDBConnectionByNameForUpdate(ctx, bh, connection.AccountID, connection.Name) + if err != nil { + return err + } + if found { + if stmt.IfNotExists { + return nil + } + return moerr.NewInvalidInputf(ctx, "MongoDB connection %s already exists", existing.Name) + } + return bh.Exec(ctx, mongodb.InsertConnectionSQL(connection)) +} + +func handleAlterMongoDBConnection(ctx context.Context, ses *Session, stmt *tree.AlterMongoDBConnection) (err error) { + if err := ensureMongoDBFeatureEnabledForSession(ctx, ses); err != nil { + return err + } + var options map[string]string + if stmt.Action == tree.AlterMongoDBConnectionSet { + options, err = mongoDBOptionsToMap(ctx, stmt.Options) + if err != nil { + return err + } + if len(options) == 0 { + return moerr.NewInvalidInput(ctx, "ALTER MONGODB CONNECTION SET requires at least one option") + } + } else if len(stmt.Options) != 0 { + return moerr.NewInvalidInput(ctx, "ALTER MONGODB CONNECTION ENABLE/DISABLE does not accept options") + } + bh := ses.GetBackgroundExec(ctx) + defer bh.Close() + if err = bh.Exec(ctx, "begin;"); err != nil { + return err + } + var retireConnectionID, retireBeforeVersion uint64 + defer func() { + err = finishTxn(ctx, bh, err) + if err == nil && retireConnectionID != 0 { + retireMongoDBClients(ctx, ses.GetService(), mongodb.ClientRetirement{ + AccountID: ses.GetAccountId(), ConnectionID: retireConnectionID, + VersionExclusive: retireBeforeVersion, + }) + } + }() + existing, found, err := queryMongoDBConnectionByNameForUpdate(ctx, bh, ses.GetAccountId(), string(stmt.Name)) + if err != nil { + return err + } + if !found { + return moerr.NewInvalidInputf(ctx, "MongoDB connection %s does not exist", string(stmt.Name)) + } + switch stmt.Action { + case tree.AlterMongoDBConnectionDisable: + if existing.Disabled { + return nil + } + err = bh.Exec(ctx, mongodb.DisableConnectionSQL(existing.AccountID, existing.Name)) + case tree.AlterMongoDBConnectionEnable: + if !existing.Disabled { + return nil + } + if err := mongodb.ValidateConnection(ctx, existing, mongoDBRuntimeConfig(mongoDBParametersForService(ses.GetService()))); err != nil { + return err + } + err = bh.Exec(ctx, mongodb.EnableConnectionSQL(existing.AccountID, existing.Name)) + case tree.AlterMongoDBConnectionSet: + var updated mongodb.Connection + updated, err = mongoDBConnectionFromOptions(ctx, ses.GetAccountId(), string(stmt.Name), options, &existing, mongoDBParametersForService(ses.GetService())) + if err == nil { + err = bh.Exec(ctx, mongodb.UpdateConnectionSQL(updated)) + } + default: + return moerr.NewInvalidInput(ctx, "ALTER MONGODB CONNECTION has an invalid action") + } + if err == nil { + retireConnectionID = existing.ConnectionID + retireBeforeVersion = existing.Version + 1 + } + return err +} + +func handleDropMongoDBConnection(ctx context.Context, ses *Session, stmt *tree.DropMongoDBConnection) (err error) { + if err := ensureMongoDBFeatureEnabledForSession(ctx, ses); err != nil { + return err + } + accountID := ses.GetAccountId() + bh := ses.GetBackgroundExec(ctx) + defer bh.Close() + if err = bh.Exec(ctx, "begin;"); err != nil { + return err + } + var retiredConnectionID uint64 + defer func() { + err = finishTxn(ctx, bh, err) + if err == nil && retiredConnectionID != 0 { + retireMongoDBClients(ctx, ses.GetService(), mongodb.ClientRetirement{ + AccountID: accountID, ConnectionID: retiredConnectionID, + }) + } + }() + connection, found, err := queryMongoDBConnectionByNameForUpdate(ctx, bh, accountID, string(stmt.Name)) + if err != nil { + return err + } + if !found { + if stmt.IfExists { + return nil + } + return moerr.NewInvalidInputf(ctx, "MongoDB connection %s does not exist", string(stmt.Name)) + } + results, err := ExeSqlInBgSes(ctx, bh, mongodb.ConnectionDependencyCountSQL(accountID, connection.ConnectionID)) + if err != nil { + return err + } + if execResultArrayHasData(results) { + count, countErr := results[0].GetUint64(ctx, 0, 0) + if countErr != nil { + return countErr + } + if count != 0 { + return moerr.NewInvalidInputf(ctx, "MongoDB connection %s is referenced by %d external table mappings", connection.Name, count) + } + } + err = bh.Exec(ctx, mongodb.DeleteConnectionSQL(accountID, connection.ConnectionID)) + if err == nil { + retiredConnectionID = connection.ConnectionID + } + return err +} + +func retireMongoDBClients(ctx context.Context, service string, retirement mongodb.ClientRetirement) { + if dependencies := mongoDBRuntimeDependencies(service); dependencies != nil && dependencies.Pool != nil { + _ = retirement.Apply(dependencies.Pool) + } + pu := getPuIfPresent(service) + if pu == nil || pu.QueryClient == nil { + return + } + value, ok := moruntime.ServiceRuntime(pu.QueryClient.ServiceID()).GetGlobalVariables(moruntime.ClusterService) + if !ok { + return + } + cluster, ok := value.(clusterservice.MOCluster) + if !ok || cluster == nil { + return + } + mongodb.ClusterRemoteClientRetirer{ + Cluster: cluster, QueryClient: pu.QueryClient, + }.Retire(ctx, retirement) +} + +func finishTxnAndRetireMongoDBAccounts( + ctx context.Context, + bh BackgroundExec, + service string, + accountIDs []uint32, + err error, +) error { + err = finishTxn(ctx, bh, err) + if err != nil { + return err + } + for _, accountID := range accountIDs { + retireMongoDBClients(ctx, service, mongodb.ClientRetirement{AccountID: accountID}) + } + return nil +} + +func markMongoDBAccountForRetirement(accountIDs *[]uint32, accountID uint32) { + if accountIDs == nil { + return + } + for _, existing := range *accountIDs { + if existing == accountID { + return + } + } + *accountIDs = append(*accountIDs, accountID) +} + +func mongoDBRuntimeDependencies(service string) *mongodb.RuntimeDependencies { + for _, serviceID := range []string{service, ""} { + runtime := moruntime.ServiceRuntime(serviceID) + if runtime == nil { + continue + } + value, ok := runtime.GetGlobalVariables(mongodb.RuntimeDependenciesKey) + if !ok { + continue + } + if dependencies, typeOK := value.(*mongodb.RuntimeDependencies); typeOK { + return dependencies + } + } + return nil +} + +func handleShowMongoDBConnections(ctx context.Context, ses *Session, stmt *tree.ShowMongoDBConnections) error { + if stmt != nil && (stmt.Like != nil || stmt.Where != nil) { + return moerr.NewNotSupported(ctx, "SHOW MONGODB CONNECTIONS with LIKE/WHERE") + } + if err := ensureMongoDBFeatureEnabledForSession(ctx, ses); err != nil { + return err + } + sql := "select name,discovery_mode,auth_mechanism,tls_mode,read_preference,read_concern,version,cast(disabled_at is not null as unsigned) " + + "from mo_catalog." + mongodb.TableConnections + " where account_id=" + strconv.FormatUint(uint64(ses.GetAccountId()), 10) + " order by name" + return showIcebergQuery(ctx, ses, sql, []icebergShowColumn{ + {name: "name", typ: defines.MYSQL_TYPE_VARCHAR}, + {name: "discovery_mode", typ: defines.MYSQL_TYPE_VARCHAR}, + {name: "auth_mechanism", typ: defines.MYSQL_TYPE_VARCHAR}, + {name: "tls_mode", typ: defines.MYSQL_TYPE_VARCHAR}, + {name: "read_preference", typ: defines.MYSQL_TYPE_VARCHAR}, + {name: "read_concern", typ: defines.MYSQL_TYPE_VARCHAR}, + {name: "version", typ: defines.MYSQL_TYPE_LONGLONG}, + {name: "disabled", typ: defines.MYSQL_TYPE_LONGLONG}, + }) +} + +func ensureMongoDBFeatureEnabledForSession(ctx context.Context, ses interface { + GetService() string + GetAccountId() uint32 +}) error { + if ses == nil { + return moerr.NewInvalidInput(ctx, "MongoDB connection DDL requires a session") + } + pu := icebergParameterUnitForService(ses.GetService()) + if pu == nil || pu.SV == nil { + return moerr.NewNotSupported(ctx, "MongoDB external tables are disabled because runtime configuration is unavailable") + } + parameters := pu.SV.MongoDB + if !parameters.Enable { + return moerr.NewNotSupported(ctx, "MongoDB external tables are disabled") + } + if !parameters.EnablePerAccount { + return nil + } + if ses.GetAccountId() == 0 { + return nil + } + for _, accountID := range parameters.AllowedAccounts { + if accountID == ses.GetAccountId() { + return nil + } + } + return moerr.NewNotSupported(ctx, "MongoDB external tables are disabled for this account") +} + +func mongoDBOptionsToMap(ctx context.Context, options tree.MongoDBOptions) (map[string]string, error) { + values := make(map[string]string, len(options)) + for _, option := range options { + if option == nil { + continue + } + key := strings.ToLower(strings.TrimSpace(string(option.Key))) + value := strings.TrimSpace(option.Val) + if key == "" || value == "" && !mongoDBConnectionOptionMayBeCleared(key) { + return nil, moerr.NewInvalidInput(ctx, "MongoDB connection option key and value cannot be empty") + } + if _, exists := values[key]; exists { + return nil, moerr.NewInvalidInputf(ctx, "duplicate MongoDB connection option %s", key) + } + switch key { + case "hosts", "srv_host", "replica_set", "auth_source", "auth_mechanism", "credential_secret_ref", + "tls_mode", "tls_ca_secret_ref", "read_preference", "read_concern", "max_staleness_seconds", "options_json": + default: + return nil, moerr.NewInvalidInputf(ctx, "unsupported MongoDB connection option %s", key) + } + values[key] = value + } + return values, nil +} + +func mongoDBConnectionOptionMayBeCleared(key string) bool { + switch key { + case "hosts", "srv_host", "replica_set", "tls_ca_secret_ref", "options_json": + return true + default: + return false + } +} + +func mongoDBConnectionFromOptions( + ctx context.Context, + accountID uint32, + name string, + options map[string]string, + existing *mongodb.Connection, + parameters config.MongoDBParameters, +) (mongodb.Connection, error) { + connection := mongodb.Connection{AccountID: accountID, Name: name, Version: 1} + if existing != nil { + connection = *existing + } + setString := func(key string, target *string) { + if value, ok := options[key]; ok { + *target = value + } + } + setString("hosts", &connection.Hosts) + setString("srv_host", &connection.SRVHost) + setString("replica_set", &connection.ReplicaSet) + setString("auth_source", &connection.AuthSource) + setString("auth_mechanism", &connection.AuthMechanism) + setString("credential_secret_ref", &connection.CredentialSecretRef) + setString("tls_mode", &connection.TLSMode) + setString("tls_ca_secret_ref", &connection.TLSCASecretRef) + setString("read_preference", &connection.ReadPreference) + setString("read_concern", &connection.ReadConcern) + setString("options_json", &connection.OptionsJSON) + _, readPreferenceChanged := options["read_preference"] + _, maxStalenessSpecified := options["max_staleness_seconds"] + if value, ok := options["max_staleness_seconds"]; ok { + parsed, err := strconv.ParseInt(value, 10, 64) + if err != nil || parsed < 0 { + return mongodb.Connection{}, moerr.NewInvalidInput(ctx, "MongoDB max_staleness_seconds must be non-negative") + } + connection.MaxStalenessSeconds = parsed + } + if connection.AuthSource == "" { + connection.AuthSource = "admin" + } + if connection.AuthMechanism == "" { + connection.AuthMechanism = "SCRAM-SHA-256" + } + if connection.TLSMode == "" { + connection.TLSMode = "required" + } + if connection.ReadPreference == "" { + connection.ReadPreference = "secondaryPreferred" + } + if !maxStalenessSpecified && (existing == nil || readPreferenceChanged) { + switch strings.ToLower(connection.ReadPreference) { + case "secondary", "secondarypreferred", "nearest": + connection.MaxStalenessSeconds = 120 + default: + connection.MaxStalenessSeconds = 0 + } + } + if connection.ReadConcern == "" { + connection.ReadConcern = "majority" + } + if connection.SRVHost != "" { + connection.DiscoveryMode = mongodb.DiscoverySRV + } else { + connection.DiscoveryMode = mongodb.DiscoverySeeds + } + runtimeConfig := mongoDBRuntimeConfig(parameters) + if err := mongodb.ValidateConnection(ctx, connection, runtimeConfig); err != nil { + return mongodb.Connection{}, err + } + return connection, nil +} + +func mongoDBParametersForService(service string) config.MongoDBParameters { + if pu := icebergParameterUnitForService(service); pu != nil && pu.SV != nil { + return pu.SV.MongoDB + } + return config.MongoDBParameters{} +} + +func mongoDBRuntimeConfig(parameters config.MongoDBParameters) mongodb.RuntimeConfig { + allowed := make(map[uint32]struct{}, len(parameters.AllowedAccounts)) + for _, accountID := range parameters.AllowedAccounts { + allowed[accountID] = struct{}{} + } + return mongodb.RuntimeConfig{ + Enable: parameters.Enable, EnablePerAccount: parameters.EnablePerAccount, AllowedAccounts: allowed, + AllowLoopback: parameters.AllowLoopback, AllowedHostSuffixes: parameters.AllowedHostSuffixes, AllowedCIDRs: parameters.AllowedCIDRs, + } +} + +func queryMongoDBConnectionByNameForUpdate(ctx context.Context, bh BackgroundExec, accountID uint32, name string) (mongodb.Connection, bool, error) { + return queryMongoDBConnectionByNameSQL(ctx, bh, mongodb.GetConnectionByNameForUpdateSQL(accountID, name)) +} + +func queryMongoDBConnectionByNameSQL(ctx context.Context, bh BackgroundExec, sql string) (mongodb.Connection, bool, error) { + results, err := ExeSqlInBgSes(ctx, bh, sql) + if err != nil || !execResultArrayHasData(results) { + return mongodb.Connection{}, false, err + } + result := results[0] + stringAt := func(column uint64) (string, error) { + isNull, err := result.ColumnIsNull(ctx, 0, column) + if err != nil || isNull { + return "", err + } + return result.GetString(ctx, 0, column) + } + accountID, err := result.GetUint64(ctx, 0, 0) + if err != nil || accountID > uint64(^uint32(0)) { + return mongodb.Connection{}, false, moerr.NewInternalError(ctx, "MongoDB catalog connection has an invalid account ID") + } + connection := mongodb.Connection{AccountID: uint32(accountID)} + connection.ConnectionID, err = result.GetUint64(ctx, 0, 1) + if err != nil { + return mongodb.Connection{}, false, err + } + fields := []*string{&connection.Name, &connection.DiscoveryMode, &connection.Hosts, &connection.SRVHost, &connection.ReplicaSet, + &connection.AuthSource, &connection.AuthMechanism, &connection.CredentialSecretRef, &connection.TLSMode, &connection.TLSCASecretRef, + &connection.ReadPreference, &connection.ReadConcern} + for i, target := range fields { + *target, err = stringAt(uint64(i + 2)) + if err != nil { + return mongodb.Connection{}, false, err + } + } + maxStaleness, err := result.GetInt64(ctx, 0, 14) + if err != nil { + return mongodb.Connection{}, false, err + } + connection.MaxStalenessSeconds = maxStaleness + connection.OptionsJSON, err = stringAt(15) + if err != nil { + return mongodb.Connection{}, false, err + } + connection.Version, err = result.GetUint64(ctx, 0, 16) + if err != nil { + return mongodb.Connection{}, false, err + } + disabled, err := result.GetUint64(ctx, 0, 17) + if err != nil { + return mongodb.Connection{}, false, err + } + connection.Disabled = disabled != 0 + return connection, true, nil +} diff --git a/pkg/frontend/mongodb_test.go b/pkg/frontend/mongodb_test.go new file mode 100644 index 0000000000000..9426121da1cba --- /dev/null +++ b/pkg/frontend/mongodb_test.go @@ -0,0 +1,630 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package frontend + +import ( + "context" + "errors" + "fmt" + "sync/atomic" + "testing" + + moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" + "github.com/matrixorigin/matrixone/pkg/config" + "github.com/matrixorigin/matrixone/pkg/sql/mongodb" + "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" + "github.com/stretchr/testify/require" +) + +const mongoDBTestAccountID = uint32(7) + +var mongoDBTestServiceSequence atomic.Uint64 + +func newMongoDBHandlerTestSession(t *testing.T) (*Session, *backgroundExecTest) { + t.Helper() + service := "mongodb-handler-" + t.Name() + InitServerLevelVars(service) + setPu(service, &config.ParameterUnit{SV: &config.FrontendParameters{MongoDB: config.MongoDBParameters{ + Enable: true, + AllowLoopback: true, + }}}) + ses := &Session{feSessionImpl: feSessionImpl{service: service}} + ses.SetAccountId(mongoDBTestAccountID) + bh := &backgroundExecTest{} + bh.init() + previous := NewBackgroundExec + NewBackgroundExec = func(context.Context, FeSession, ...*BackgroundExecOption) BackgroundExec { + return bh + } + t.Cleanup(func() { NewBackgroundExec = previous }) + return ses, bh +} + +func mongoDBTestConnection(disabled bool) mongodb.Connection { + return mongodb.Connection{ + AccountID: mongoDBTestAccountID, + ConnectionID: 23, + Name: "source", + DiscoveryMode: mongodb.DiscoverySeeds, + Hosts: "127.0.0.1:27017", + AuthSource: "admin", + AuthMechanism: "SCRAM-SHA-256", + CredentialSecretRef: "secret://env/MONGO", + TLSMode: "disabled", + ReadPreference: "primary", + ReadConcern: "majority", + Version: 4, + Disabled: disabled, + } +} + +func mongoDBConnectionResult(connection *mongodb.Connection) *MysqlResultSet { + result := &MysqlResultSet{} + for range 18 { + result.AddColumn(&MysqlColumn{}) + } + if connection == nil { + return result + } + disabled := uint64(0) + if connection.Disabled { + disabled = 1 + } + result.AddRow([]interface{}{ + uint64(connection.AccountID), connection.ConnectionID, connection.Name, connection.DiscoveryMode, + connection.Hosts, connection.SRVHost, connection.ReplicaSet, connection.AuthSource, + connection.AuthMechanism, connection.CredentialSecretRef, connection.TLSMode, connection.TLSCASecretRef, + connection.ReadPreference, connection.ReadConcern, connection.MaxStalenessSeconds, connection.OptionsJSON, + connection.Version, disabled, + }) + return result +} + +func mongoDBCountResult(value interface{}) *MysqlResultSet { + result := &MysqlResultSet{} + result.AddColumn(&MysqlColumn{}) + if value != nil { + result.AddRow([]interface{}{value}) + } + return result +} + +func stubMongoDBCatalogQueries( + t *testing.T, + connection *mongodb.Connection, + lookupErr error, + dependencyResult *MysqlResultSet, + dependencyErr error, +) { + t.Helper() + previous := ExeSqlInBgSes + ExeSqlInBgSes = func(_ context.Context, _ BackgroundExec, sql string) ([]ExecResult, error) { + switch sql { + case mongodb.GetConnectionByNameForUpdateSQL(mongoDBTestAccountID, "source"): + if lookupErr != nil { + return nil, lookupErr + } + return []ExecResult{mongoDBConnectionResult(connection)}, nil + case mongodb.ConnectionDependencyCountSQL(mongoDBTestAccountID, 23): + if dependencyErr != nil { + return nil, dependencyErr + } + if dependencyResult == nil { + dependencyResult = mongoDBCountResult(nil) + } + return []ExecResult{dependencyResult}, nil + default: + t.Fatalf("unexpected MongoDB catalog query: %s", sql) + return nil, nil + } + } + t.Cleanup(func() { ExeSqlInBgSes = previous }) +} + +func mongoDBCreateOptions() tree.MongoDBOptions { + return tree.MongoDBOptions{ + tree.NewMongoDBOption("hosts", "127.0.0.1:27017"), + tree.NewMongoDBOption("credential_secret_ref", "secret://env/MONGO"), + tree.NewMongoDBOption("tls_mode", "disabled"), + tree.NewMongoDBOption("read_preference", "primary"), + } +} + +func TestMongoDBConnectionCreateLifecycle(t *testing.T) { + t.Run("create", func(t *testing.T) { + ses, bh := newMongoDBHandlerTestSession(t) + stubMongoDBCatalogQueries(t, nil, nil, nil, nil) + stmt := &tree.CreateMongoDBConnection{Name: "source", Options: mongoDBCreateOptions()} + require.NoError(t, handleCreateMongoDBConnection(t.Context(), ses, stmt)) + expected := mongoDBTestConnection(false) + expected.Version = 1 + require.Equal(t, []string{"begin;", mongodb.InsertConnectionSQL(expected), "commit;"}, bh.executedSQLs) + }) + + t.Run("existing if not exists", func(t *testing.T) { + ses, bh := newMongoDBHandlerTestSession(t) + connection := mongoDBTestConnection(false) + stubMongoDBCatalogQueries(t, &connection, nil, nil, nil) + err := handleCreateMongoDBConnection(t.Context(), ses, &tree.CreateMongoDBConnection{ + Name: "source", IfNotExists: true, Options: mongoDBCreateOptions(), + }) + require.NoError(t, err) + require.Equal(t, []string{"begin;", "commit;"}, bh.executedSQLs) + }) + + t.Run("duplicate rolls back", func(t *testing.T) { + ses, bh := newMongoDBHandlerTestSession(t) + connection := mongoDBTestConnection(false) + stubMongoDBCatalogQueries(t, &connection, nil, nil, nil) + err := handleCreateMongoDBConnection(t.Context(), ses, &tree.CreateMongoDBConnection{Name: "source", Options: mongoDBCreateOptions()}) + require.ErrorContains(t, err, "already exists") + require.Equal(t, []string{"begin;", "rollback;"}, bh.executedSQLs) + }) + + t.Run("begin and lookup errors", func(t *testing.T) { + ses, bh := newMongoDBHandlerTestSession(t) + beginErr := errors.New("begin failed") + bh.sql2err["begin;"] = beginErr + err := handleCreateMongoDBConnection(t.Context(), ses, &tree.CreateMongoDBConnection{Name: "source", Options: mongoDBCreateOptions()}) + require.ErrorIs(t, err, beginErr) + require.Equal(t, []string{"begin;"}, bh.executedSQLs) + }) + + t.Run("lookup error rolls back", func(t *testing.T) { + ses, bh := newMongoDBHandlerTestSession(t) + lookupErr := errors.New("lookup failed") + stubMongoDBCatalogQueries(t, nil, lookupErr, nil, nil) + err := handleCreateMongoDBConnection(t.Context(), ses, &tree.CreateMongoDBConnection{Name: "source", Options: mongoDBCreateOptions()}) + require.ErrorIs(t, err, lookupErr) + require.Equal(t, []string{"begin;", "rollback;"}, bh.executedSQLs) + }) +} + +func TestMongoDBConnectionAlterLifecycle(t *testing.T) { + t.Run("disable and already disabled", func(t *testing.T) { + for _, disabled := range []bool{false, true} { + t.Run(map[bool]string{false: "disable", true: "no-op"}[disabled], func(t *testing.T) { + ses, bh := newMongoDBHandlerTestSession(t) + connection := mongoDBTestConnection(disabled) + stubMongoDBCatalogQueries(t, &connection, nil, nil, nil) + err := handleAlterMongoDBConnection(t.Context(), ses, &tree.AlterMongoDBConnection{ + Name: "source", Action: tree.AlterMongoDBConnectionDisable, + }) + require.NoError(t, err) + if disabled { + require.Equal(t, []string{"begin;", "commit;"}, bh.executedSQLs) + } else { + require.Equal(t, []string{"begin;", mongodb.DisableConnectionSQL(mongoDBTestAccountID, "source"), "commit;"}, bh.executedSQLs) + } + }) + } + }) + + t.Run("enable and already enabled", func(t *testing.T) { + for _, disabled := range []bool{true, false} { + t.Run(map[bool]string{true: "enable", false: "no-op"}[disabled], func(t *testing.T) { + ses, bh := newMongoDBHandlerTestSession(t) + connection := mongoDBTestConnection(disabled) + stubMongoDBCatalogQueries(t, &connection, nil, nil, nil) + err := handleAlterMongoDBConnection(t.Context(), ses, &tree.AlterMongoDBConnection{ + Name: "source", Action: tree.AlterMongoDBConnectionEnable, + }) + require.NoError(t, err) + if disabled { + require.Equal(t, []string{"begin;", mongodb.EnableConnectionSQL(mongoDBTestAccountID, "source"), "commit;"}, bh.executedSQLs) + } else { + require.Equal(t, []string{"begin;", "commit;"}, bh.executedSQLs) + } + }) + } + }) + + t.Run("set", func(t *testing.T) { + ses, bh := newMongoDBHandlerTestSession(t) + connection := mongoDBTestConnection(false) + stubMongoDBCatalogQueries(t, &connection, nil, nil, nil) + err := handleAlterMongoDBConnection(t.Context(), ses, &tree.AlterMongoDBConnection{ + Name: "source", Action: tree.AlterMongoDBConnectionSet, + Options: tree.MongoDBOptions{tree.NewMongoDBOption("read_concern", "local")}, + }) + require.NoError(t, err) + connection.ReadConcern = "local" + require.Equal(t, []string{"begin;", mongodb.UpdateConnectionSQL(connection), "commit;"}, bh.executedSQLs) + }) + + t.Run("missing and invalid action roll back", func(t *testing.T) { + for _, tc := range []struct { + name string + connection *mongodb.Connection + action tree.AlterMongoDBConnectionAction + want string + }{ + {name: "missing", action: tree.AlterMongoDBConnectionDisable, want: "does not exist"}, + {name: "invalid action", connection: func() *mongodb.Connection { c := mongoDBTestConnection(false); return &c }(), action: 99, want: "invalid action"}, + } { + t.Run(tc.name, func(t *testing.T) { + ses, bh := newMongoDBHandlerTestSession(t) + stubMongoDBCatalogQueries(t, tc.connection, nil, nil, nil) + err := handleAlterMongoDBConnection(t.Context(), ses, &tree.AlterMongoDBConnection{Name: "source", Action: tc.action}) + require.ErrorContains(t, err, tc.want) + require.Equal(t, []string{"begin;", "rollback;"}, bh.executedSQLs) + }) + } + }) + + t.Run("statement validation", func(t *testing.T) { + ses, _ := newMongoDBHandlerTestSession(t) + err := handleAlterMongoDBConnection(t.Context(), ses, &tree.AlterMongoDBConnection{Name: "source", Action: tree.AlterMongoDBConnectionSet}) + require.ErrorContains(t, err, "requires at least one option") + err = handleAlterMongoDBConnection(t.Context(), ses, &tree.AlterMongoDBConnection{ + Name: "source", Action: tree.AlterMongoDBConnectionEnable, + Options: tree.MongoDBOptions{tree.NewMongoDBOption("hosts", "127.0.0.1:27017")}, + }) + require.ErrorContains(t, err, "does not accept options") + }) +} + +func TestMongoDBConnectionDropLifecycle(t *testing.T) { + t.Run("drop", func(t *testing.T) { + ses, bh := newMongoDBHandlerTestSession(t) + connection := mongoDBTestConnection(false) + stubMongoDBCatalogQueries(t, &connection, nil, mongoDBCountResult(uint64(0)), nil) + require.NoError(t, handleDropMongoDBConnection(t.Context(), ses, &tree.DropMongoDBConnection{Name: "source"})) + require.Equal(t, []string{"begin;", mongodb.DeleteConnectionSQL(mongoDBTestAccountID, 23), "commit;"}, bh.executedSQLs) + }) + + t.Run("missing", func(t *testing.T) { + for _, ifExists := range []bool{true, false} { + t.Run(map[bool]string{true: "if exists", false: "error"}[ifExists], func(t *testing.T) { + ses, bh := newMongoDBHandlerTestSession(t) + stubMongoDBCatalogQueries(t, nil, nil, nil, nil) + err := handleDropMongoDBConnection(t.Context(), ses, &tree.DropMongoDBConnection{Name: "source", IfExists: ifExists}) + if ifExists { + require.NoError(t, err) + require.Equal(t, []string{"begin;", "commit;"}, bh.executedSQLs) + } else { + require.ErrorContains(t, err, "does not exist") + require.Equal(t, []string{"begin;", "rollback;"}, bh.executedSQLs) + } + }) + } + }) + + t.Run("dependencies block drop", func(t *testing.T) { + ses, bh := newMongoDBHandlerTestSession(t) + connection := mongoDBTestConnection(false) + stubMongoDBCatalogQueries(t, &connection, nil, mongoDBCountResult(uint64(2)), nil) + err := handleDropMongoDBConnection(t.Context(), ses, &tree.DropMongoDBConnection{Name: "source"}) + require.ErrorContains(t, err, "referenced by 2") + require.Equal(t, []string{"begin;", "rollback;"}, bh.executedSQLs) + }) + + t.Run("dependency query and conversion errors", func(t *testing.T) { + for _, tc := range []struct { + name string + result *MysqlResultSet + err error + }{ + {name: "query", err: errors.New("dependency query failed")}, + {name: "conversion", result: mongoDBCountResult(struct{}{})}, + } { + t.Run(tc.name, func(t *testing.T) { + ses, bh := newMongoDBHandlerTestSession(t) + connection := mongoDBTestConnection(false) + stubMongoDBCatalogQueries(t, &connection, nil, tc.result, tc.err) + err := handleDropMongoDBConnection(t.Context(), ses, &tree.DropMongoDBConnection{Name: "source"}) + require.Error(t, err) + require.Equal(t, []string{"begin;", "rollback;"}, bh.executedSQLs) + }) + } + }) +} + +func TestMongoDBConnectionCatalogResultValidation(t *testing.T) { + previous := ExeSqlInBgSes + t.Cleanup(func() { ExeSqlInBgSes = previous }) + + result := mongoDBConnectionResult(nil) + result.AddRow([]interface{}{uint64(^uint32(0)) + 1, uint64(23), "source", "seeds", "host", "", "", "admin", "SCRAM-SHA-256", "ref", "required", "", "primary", "majority", int64(0), "", uint64(1), uint64(0)}) + ExeSqlInBgSes = func(context.Context, BackgroundExec, string) ([]ExecResult, error) { + return []ExecResult{result}, nil + } + _, found, err := queryMongoDBConnectionByNameSQL(t.Context(), nil, "select invalid account") + require.False(t, found) + require.ErrorContains(t, err, "invalid account ID") +} + +func TestShowMongoDBConnectionsValidation(t *testing.T) { + require.ErrorContains(t, handleShowMongoDBConnections(t.Context(), nil, &tree.ShowMongoDBConnections{Like: &tree.ComparisonExpr{}}), "LIKE/WHERE") + service := "mongodb-show-" + t.Name() + InitServerLevelVars(service) + setPu(service, &config.ParameterUnit{SV: &config.FrontendParameters{}}) + require.ErrorContains(t, handleShowMongoDBConnections(t.Context(), &Session{ + feSessionImpl: feSessionImpl{service: service}, + }, nil), "are disabled") +} + +func TestMongoDBTableMappingRequiresConnectionUsageFallback(t *testing.T) { + stmt := &tree.CreateTable{MongoDBParam: &tree.MongoDBTableParam{}} + require.False(t, canCreateMongoDBTableMapping(stmt, &TenantInfo{Tenant: "tenant", DefaultRole: "readonly"})) + require.True(t, canCreateMongoDBTableMapping(stmt, &TenantInfo{Tenant: "tenant", DefaultRole: accountAdminRoleName})) + require.True(t, canCreateMongoDBTableMapping(&tree.CreateTable{}, &TenantInfo{Tenant: "tenant", DefaultRole: "readonly"})) +} + +func TestMongoDBReadPreferenceStalenessDefaults(t *testing.T) { + parameters := config.MongoDBParameters{AllowLoopback: true} + base := map[string]string{ + "hosts": "127.0.0.1:27017", "credential_secret_ref": "secret://env/MONGO", "tls_mode": "disabled", + } + primary := cloneStringMap(base) + primary["read_preference"] = "primary" + connection, err := mongoDBConnectionFromOptions(t.Context(), 1, "source", primary, nil, parameters) + require.NoError(t, err) + require.Zero(t, connection.MaxStalenessSeconds) + + secondary, err := mongoDBConnectionFromOptions(t.Context(), 1, "source", base, nil, parameters) + require.NoError(t, err) + require.Equal(t, int64(120), secondary.MaxStalenessSeconds) + + invalid := cloneStringMap(primary) + invalid["max_staleness_seconds"] = "120" + _, err = mongoDBConnectionFromOptions(t.Context(), 1, "source", invalid, nil, parameters) + require.Error(t, err) +} + +func TestMongoDBConnectionCanSwitchDiscoveryMode(t *testing.T) { + parameters := config.MongoDBParameters{ + AllowLoopback: true, + AllowedHostSuffixes: []string{"mongo.example"}, + } + existing, err := mongoDBConnectionFromOptions(t.Context(), 1, "source", map[string]string{ + "hosts": "127.0.0.1:27017", + "credential_secret_ref": "secret://env/MONGO", + "tls_mode": "disabled", + "read_preference": "primary", + }, nil, parameters) + require.NoError(t, err) + + options, err := mongoDBOptionsToMap(t.Context(), tree.MongoDBOptions{ + tree.NewMongoDBOption("hosts", ""), + tree.NewMongoDBOption("srv_host", "cluster.mongo.example"), + tree.NewMongoDBOption("options_json", ""), + }) + require.NoError(t, err) + updated, err := mongoDBConnectionFromOptions(t.Context(), 1, "source", options, &existing, parameters) + require.NoError(t, err) + require.Empty(t, updated.Hosts) + require.Equal(t, "cluster.mongo.example", updated.SRVHost) + require.Equal(t, mongodb.DiscoverySRV, updated.DiscoveryMode) +} + +func TestMongoDBSystemTablesAreInitializedAndDroppedForTenants(t *testing.T) { + for _, table := range mongodb.SystemTableDDLs { + require.Contains(t, predefinedTables, table.Name) + require.Contains(t, createSqls, table.DDL) + require.NotContains(t, dropSqls, "drop table if exists mo_catalog."+table.Name+";") + require.Contains(t, dropMongoDBSqls, "drop table if exists mo_catalog."+table.Name+";") + } +} + +func TestMongoDBConnectionOptionValidation(t *testing.T) { + ctx := t.Context() + values, err := mongoDBOptionsToMap(ctx, tree.MongoDBOptions{ + nil, + tree.NewMongoDBOption(" HOSTS ", " mongo.example:27017 "), + tree.NewMongoDBOption("options_json", ""), + }) + require.NoError(t, err) + require.Equal(t, "mongo.example:27017", values["hosts"]) + require.Contains(t, values, "options_json") + require.True(t, mongoDBConnectionOptionMayBeCleared("srv_host")) + require.False(t, mongoDBConnectionOptionMayBeCleared("credential_secret_ref")) + + for _, tc := range []struct { + name string + options tree.MongoDBOptions + want string + }{ + {name: "empty key", options: tree.MongoDBOptions{tree.NewMongoDBOption("", "value")}, want: "cannot be empty"}, + {name: "empty required value", options: tree.MongoDBOptions{tree.NewMongoDBOption("auth_source", "")}, want: "cannot be empty"}, + {name: "duplicate", options: tree.MongoDBOptions{tree.NewMongoDBOption("hosts", "one"), tree.NewMongoDBOption("HOSTS", "two")}, want: "duplicate"}, + {name: "unsupported", options: tree.MongoDBOptions{tree.NewMongoDBOption("password", "secret")}, want: "unsupported"}, + } { + t.Run(tc.name, func(t *testing.T) { + _, err := mongoDBOptionsToMap(t.Context(), tc.options) + require.ErrorContains(t, err, tc.want) + }) + } +} + +func TestMongoDBConnectionOptionDefaultsAndFailures(t *testing.T) { + parameters := config.MongoDBParameters{AllowLoopback: true, AllowedHostSuffixes: []string{"mongo.example"}} + base := map[string]string{ + "hosts": "127.0.0.1:27017", "credential_secret_ref": "secret://env/MONGO", "tls_mode": "disabled", + } + connection, err := mongoDBConnectionFromOptions(t.Context(), 9, "source", base, nil, parameters) + require.NoError(t, err) + require.Equal(t, "admin", connection.AuthSource) + require.Equal(t, "SCRAM-SHA-256", connection.AuthMechanism) + require.Equal(t, "secondaryPreferred", connection.ReadPreference) + require.Equal(t, "majority", connection.ReadConcern) + require.Equal(t, mongodb.DiscoverySeeds, connection.DiscoveryMode) + require.Equal(t, uint64(1), connection.Version) + + for _, value := range []string{"not-a-number", "-1"} { + invalid := cloneStringMap(base) + invalid["max_staleness_seconds"] = value + _, err := mongoDBConnectionFromOptions(t.Context(), 9, "source", invalid, nil, parameters) + require.ErrorContains(t, err, "must be non-negative") + } + + updated, err := mongoDBConnectionFromOptions(t.Context(), 9, "source", map[string]string{ + "read_preference": "primary", "max_staleness_seconds": "0", + }, &connection, parameters) + require.NoError(t, err) + require.Zero(t, updated.MaxStalenessSeconds) + + invalidEndpoint := cloneStringMap(base) + invalidEndpoint["hosts"] = "blocked.example:27017" + _, err = mongoDBConnectionFromOptions(t.Context(), 9, "source", invalidEndpoint, nil, parameters) + require.ErrorContains(t, err, "allowlist") +} + +type mongoDBFeatureSession struct { + service string + accountID uint32 +} + +func (s mongoDBFeatureSession) GetService() string { return s.service } +func (s mongoDBFeatureSession) GetAccountId() uint32 { return s.accountID } + +func TestMongoDBFeatureGateAndRuntimeConfiguration(t *testing.T) { + require.ErrorContains(t, ensureMongoDBFeatureEnabledForSession(t.Context(), nil), "requires a session") + + missingService := "mongodb-missing-" + t.Name() + require.ErrorContains(t, ensureMongoDBFeatureEnabledForSession(t.Context(), mongoDBFeatureSession{service: missingService}), "configuration is unavailable") + + service := "mongodb-gate-" + t.Name() + InitServerLevelVars(service) + parameters := config.MongoDBParameters{} + setPu(service, &config.ParameterUnit{SV: &config.FrontendParameters{MongoDB: parameters}}) + require.ErrorContains(t, ensureMongoDBFeatureEnabledForSession(t.Context(), mongoDBFeatureSession{service: service, accountID: 7}), "are disabled") + + parameters.Enable = true + setPu(service, &config.ParameterUnit{SV: &config.FrontendParameters{MongoDB: parameters}}) + require.NoError(t, ensureMongoDBFeatureEnabledForSession(t.Context(), mongoDBFeatureSession{service: service, accountID: 7})) + + parameters.EnablePerAccount = true + parameters.AllowedAccounts = []uint32{7} + parameters.AllowLoopback = true + parameters.AllowedHostSuffixes = []string{"mongo.example"} + parameters.AllowedCIDRs = []string{"10.0.0.0/8"} + setPu(service, &config.ParameterUnit{SV: &config.FrontendParameters{MongoDB: parameters}}) + require.NoError(t, ensureMongoDBFeatureEnabledForSession(t.Context(), mongoDBFeatureSession{service: service, accountID: 0})) + require.NoError(t, ensureMongoDBFeatureEnabledForSession(t.Context(), mongoDBFeatureSession{service: service, accountID: 7})) + require.ErrorContains(t, ensureMongoDBFeatureEnabledForSession(t.Context(), mongoDBFeatureSession{service: service, accountID: 8}), "this account") + require.Equal(t, parameters, mongoDBParametersForService(service)) + + runtimeConfig := mongoDBRuntimeConfig(parameters) + require.True(t, runtimeConfig.Enable) + require.True(t, runtimeConfig.EnablePerAccount) + require.True(t, runtimeConfig.AllowLoopback) + require.Contains(t, runtimeConfig.AllowedAccounts, uint32(7)) + require.Equal(t, []string{"mongo.example"}, runtimeConfig.AllowedHostSuffixes) + require.Equal(t, []string{"10.0.0.0/8"}, runtimeConfig.AllowedCIDRs) + require.Equal(t, config.MongoDBParameters{}, mongoDBParametersForService(missingService)) +} + +type frontendMongoDBClientFactory struct{} + +func (frontendMongoDBClientFactory) Connect(context.Context, mongodb.Connection, mongodb.Credentials, mongodb.RuntimeConfig) (mongodb.Client, error) { + return nil, nil +} + +type retirementFrontendMongoDBClientFactory struct { + client *retirementFrontendMongoDBClient +} + +func (f *retirementFrontendMongoDBClientFactory) Connect( + context.Context, mongodb.Connection, mongodb.Credentials, mongodb.RuntimeConfig, +) (mongodb.Client, error) { + f.client = &retirementFrontendMongoDBClient{} + return f.client, nil +} + +type retirementFrontendMongoDBClient struct { + disconnects int +} + +func (*retirementFrontendMongoDBClient) Collection(string, string) mongodb.Collection { return nil } +func (*retirementFrontendMongoDBClient) Ping(context.Context) error { return nil } +func (c *retirementFrontendMongoDBClient) Disconnect(context.Context) error { + c.disconnects++ + return nil +} + +func TestFinishTxnAndRetireMongoDBAccounts(t *testing.T) { + for _, tc := range []struct { + name string + txnErr error + wantSQL string + wantRetired int + }{ + {name: "commit", wantSQL: "commit;", wantRetired: 1}, + {name: "rollback", txnErr: errors.New("restore failed"), wantSQL: "rollback;"}, + } { + t.Run(tc.name, func(t *testing.T) { + service := "mongodb-restore-retirement-" + tc.name + rt := moruntime.DefaultRuntime() + moruntime.SetupServiceBasedRuntime(service, rt) + factory := &retirementFrontendMongoDBClientFactory{} + pool := mongodb.NewClientPool(factory) + t.Cleanup(func() { require.NoError(t, pool.Close(context.Background())) }) + rt.SetGlobalVariables(mongodb.RuntimeDependenciesKey, &mongodb.RuntimeDependencies{Pool: pool}) + + lease, err := pool.Acquire(t.Context(), mongodb.Connection{ + AccountID: 7, ConnectionID: 9, Version: 1, + }, mongodb.Credentials{}, mongodb.RuntimeConfig{}) + require.NoError(t, err) + require.NoError(t, lease.Release(t.Context())) + + bh := &backgroundExecTest{} + bh.init() + err = finishTxnAndRetireMongoDBAccounts(t.Context(), bh, service, []uint32{7}, tc.txnErr) + if tc.txnErr == nil { + require.NoError(t, err) + } else { + require.ErrorIs(t, err, tc.txnErr) + } + require.Equal(t, []string{tc.wantSQL}, bh.executedSQLs) + require.Equal(t, tc.wantRetired, factory.client.disconnects) + }) + } +} + +func TestMongoDBRuntimeDependencyLookupAndRetirement(t *testing.T) { + missingService := fmt.Sprintf("mongodb-no-runtime-%s-%d", t.Name(), mongoDBTestServiceSequence.Add(1)) + require.NotPanics(t, func() { _ = mongoDBRuntimeDependencies(missingService) }) + service := "mongodb-runtime-" + t.Name() + moruntime.SetupServiceBasedRuntime(service, moruntime.DefaultRuntime()) + moruntime.ServiceRuntime(service).SetGlobalVariables(mongodb.RuntimeDependenciesKey, "wrong-type") + require.Nil(t, mongoDBRuntimeDependencies(service)) + + dependencies := &mongodb.RuntimeDependencies{Pool: mongodb.NewClientPool(frontendMongoDBClientFactory{})} + moruntime.ServiceRuntime(service).SetGlobalVariables(mongodb.RuntimeDependenciesKey, dependencies) + require.Same(t, dependencies, mongoDBRuntimeDependencies(service)) + retireMongoDBClients(t.Context(), service, mongodb.ClientRetirement{AccountID: 7, ConnectionID: 12, VersionExclusive: 3}) + retireMongoDBClients(t.Context(), service, mongodb.ClientRetirement{AccountID: 7, ConnectionID: 12}) + retireMongoDBClients(t.Context(), service, mongodb.ClientRetirement{AccountID: 7}) + retireMongoDBClients(t.Context(), missingService, mongodb.ClientRetirement{AccountID: 7, ConnectionID: 12}) +} + +func TestMarkMongoDBAccountForRetirement(t *testing.T) { + require.NotPanics(t, func() { markMongoDBAccountForRetirement(nil, 7) }) + + accountIDs := []uint32{7} + markMongoDBAccountForRetirement(&accountIDs, 7) + markMongoDBAccountForRetirement(&accountIDs, 9) + markMongoDBAccountForRetirement(&accountIDs, 9) + require.Equal(t, []uint32{7, 9}, accountIDs) +} + +func cloneStringMap(source map[string]string) map[string]string { + result := make(map[string]string, len(source)) + for key, value := range source { + result[key] = value + } + return result +} diff --git a/pkg/frontend/mysql_cmd_executor.go b/pkg/frontend/mysql_cmd_executor.go index f83aa47187f92..9df0cf1e57244 100644 --- a/pkg/frontend/mysql_cmd_executor.go +++ b/pkg/frontend/mysql_cmd_executor.go @@ -273,7 +273,8 @@ var RecordStatement = func(ctx context.Context, ses *Session, proc *process.Proc func redactStatementTextForLogging(statement tree.Statement, text string) string { switch statement.(type) { - case *tree.CreateIcebergCatalog, *tree.AlterIcebergCatalog: + case *tree.CreateIcebergCatalog, *tree.AlterIcebergCatalog, + *tree.CreateMongoDBConnection, *tree.AlterMongoDBConnection: return tree.String(statement, dialect.MYSQL) default: return text @@ -3110,6 +3111,12 @@ func authenticateUserCanExecuteStatement(reqCtx context.Context, ses *Session, s } if ses.GetTenantInfo() != nil { ses.SetPrivilege(determinePrivilegeSetOfStatement(stmt)) + if !canCreateMongoDBTableMapping(stmt, ses.GetTenantInfo()) { + // The privilege model has no external-connection USAGE object yet. + // Fail closed instead of letting any ordinary CREATE TABLE holder use + // an administrator's connection against an arbitrary collection. + return stats, moerr.NewInternalError(reqCtx, "MongoDB external table creation requires account admin until connection USAGE privileges are available") + } // can or not execute in retricted status if ses.getRoutine() != nil && ses.getRoutine().isRestricted() && !ses.GetPrivilege().canExecInRestricted { @@ -3155,6 +3162,14 @@ func authenticateUserCanExecuteStatement(reqCtx context.Context, ses *Session, s return stats, nil } +func canCreateMongoDBTableMapping(stmt tree.Statement, tenant *TenantInfo) bool { + create, ok := stmt.(*tree.CreateTable) + if !ok || create.MongoDBParam == nil { + return true + } + return tenant != nil && tenant.IsAdminRole() +} + // authenticateCanExecuteStatementAndPlan checks the user can execute the statement and its plan func authenticateCanExecuteStatementAndPlan(reqCtx context.Context, ses *Session, stmt tree.Statement, p *plan.Plan) (statistic.StatsArray, error) { var stats statistic.StatsArray diff --git a/pkg/frontend/pitr.go b/pkg/frontend/pitr.go index c7e2c6ff3feb9..8680e4fb4ef33 100644 --- a/pkg/frontend/pitr.go +++ b/pkg/frontend/pitr.go @@ -918,12 +918,13 @@ func doRestorePitr(ctx context.Context, ses *Session, stmt *tree.RestorePitr) (s }() var ( - restoreLevel tree.RestoreLevel - ts int64 - pitrExist bool - sortedFkTbls []string - fkTableMap map[string]*tableInfo - accountRecord *accountRecord + restoreLevel tree.RestoreLevel + ts int64 + pitrExist bool + sortedFkTbls []string + fkTableMap map[string]*tableInfo + accountRecord *accountRecord + retiredMongoDBAccountIDs []uint32 ) // resolve timestamp ts, err = doResolveTimeStamp(stmt.TimeStamp) @@ -945,7 +946,7 @@ func doRestorePitr(ctx context.Context, ses *Session, stmt *tree.RestorePitr) (s return stats, err } defer func() { - err = finishTxn(ctx, bh, err) + err = finishTxnAndRetireMongoDBAccounts(ctx, bh, ses.GetService(), retiredMongoDBAccountIDs, err) }() // check if the pitr exists @@ -1067,6 +1068,7 @@ func doRestorePitr(ctx context.Context, ses *Session, stmt *tree.RestorePitr) (s if rtnErr = CancelCheck(ctx); rtnErr != nil { return } + markMongoDBAccountForRetirement(&retiredMongoDBAccountIDs, toAccountId) return rtnErr } @@ -1128,7 +1130,7 @@ func doRestorePitr(ctx context.Context, ses *Session, stmt *tree.RestorePitr) (s case tree.RESTORELEVELCLUSTER: ctx = context.WithValue(ctx, tree.CloneLevelCtxKey{}, tree.RestoreCloneLevelCluster) subDbToRestore := make(map[string]*subDbRestoreRecord) - if err = restoreToCluster(ctx, ses, bh, pitrName, ts, subDbToRestore); err != nil { + if err = restoreToCluster(ctx, ses, bh, pitrName, ts, subDbToRestore, &retiredMongoDBAccountIDs); err != nil { return } if err = restorePubsWithSnapshotName(ctx, ses.GetService(), bh, pitrName, ts); err != nil { @@ -1146,6 +1148,7 @@ func doRestorePitr(ctx context.Context, ses *Session, stmt *tree.RestorePitr) (s if err = restoreToAccountWithPitr(ctx, ses.GetService(), bh, pitrName, ts, fkTableMap, viewMap, tenantInfo.TenantID); err != nil { return } + markMongoDBAccountForRetirement(&retiredMongoDBAccountIDs, tenantInfo.TenantID) case tree.RESTORELEVELDATABASE: ctx = context.WithValue(ctx, tree.CloneLevelCtxKey{}, tree.RestoreCloneLevelDatabase) if err = restoreToDatabaseWithPitr(ctx, ses.GetService(), bh, pitrName, ts, dbName, fkTableMap, viewMap, tenantInfo.TenantID); err != nil { diff --git a/pkg/frontend/self_handle.go b/pkg/frontend/self_handle.go index 7264733e3be8c..6b1389000cd14 100644 --- a/pkg/frontend/self_handle.go +++ b/pkg/frontend/self_handle.go @@ -197,6 +197,22 @@ func execInFrontend(ses *Session, execCtx *ExecCtx) (stats statistic.StatsArray, if err = handleShowIcebergTables(execCtx.reqCtx, ses, st); err != nil { return } + case *tree.CreateMongoDBConnection: + if err = handleCreateMongoDBConnection(execCtx.reqCtx, ses, st); err != nil { + return + } + case *tree.AlterMongoDBConnection: + if err = handleAlterMongoDBConnection(execCtx.reqCtx, ses, st); err != nil { + return + } + case *tree.DropMongoDBConnection: + if err = handleDropMongoDBConnection(execCtx.reqCtx, ses, st); err != nil { + return + } + case *tree.ShowMongoDBConnections: + if err = handleShowMongoDBConnections(execCtx.reqCtx, ses, st); err != nil { + return + } case *tree.Deallocate: ses.EnterFPrint(FPDeallocate) defer ses.ExitFPrint(FPDeallocate) diff --git a/pkg/frontend/server.go b/pkg/frontend/server.go index 21ed4263277f7..f1106d5022a36 100644 --- a/pkg/frontend/server.go +++ b/pkg/frontend/server.go @@ -558,6 +558,19 @@ func SetPUForExternalUT(service string, pu *config.ParameterUnit) { setPu(service, pu) } +func getPuIfPresent(service string) *config.ParameterUnit { + vars := getServerLevelVars(service) + if vars == nil { + return nil + } + value := vars.Pu.Load() + if value == nil { + return nil + } + pu, _ := value.(*config.ParameterUnit) + return pu +} + func getPu(service string) *config.ParameterUnit { return getServerLevelVars(service).Pu.Load().(*config.ParameterUnit) } diff --git a/pkg/frontend/snapshot.go b/pkg/frontend/snapshot.go index 19c3acb8ed143..a8a18fde11179 100644 --- a/pkg/frontend/snapshot.go +++ b/pkg/frontend/snapshot.go @@ -588,12 +588,13 @@ func doRestoreSnapshot(ctx context.Context, ses *Session, stmt *tree.RestoreSnap var restoreAccount uint32 var toAccountId uint32 + var retiredMongoDBAccountIDs []uint32 // restore as a txn if err = bh.Exec(ctx, "begin;"); err != nil { return stats, err } defer func() { - err = finishTxn(ctx, bh, err) + err = finishTxnAndRetireMongoDBAccounts(ctx, bh, ses.GetService(), retiredMongoDBAccountIDs, err) }() // check snapshot @@ -623,7 +624,7 @@ func doRestoreSnapshot(ctx context.Context, ses *Session, stmt *tree.RestoreSnap // restore cluster subDbToRestore := make(map[string]*subDbRestoreRecord) - if err = restoreToCluster(ctx, ses, bh, snapshotName, snapshot.ts, subDbToRestore); err != nil { + if err = restoreToCluster(ctx, ses, bh, snapshotName, snapshot.ts, subDbToRestore, &retiredMongoDBAccountIDs); err != nil { return } @@ -648,6 +649,7 @@ func doRestoreSnapshot(ctx context.Context, ses *Session, stmt *tree.RestoreSnap if err != nil { return stats, err } + markMongoDBAccountForRetirement(&retiredMongoDBAccountIDs, toAccountId) return } @@ -706,6 +708,7 @@ func doRestoreSnapshot(ctx context.Context, ses *Session, stmt *tree.RestoreSnap nil); err != nil { return stats, err } + markMongoDBAccountForRetirement(&retiredMongoDBAccountIDs, toAccountId) case tree.RESTORELEVELDATABASE: ctx = context.WithValue(ctx, tree.CloneLevelCtxKey{}, tree.RestoreCloneLevelDatabase) @@ -2513,6 +2516,7 @@ func restoreToCluster(ctx context.Context, snapshotName string, snapshotTs int64, subDbToRestore map[string]*subDbRestoreRecord, + retiredMongoDBAccountIDs *[]uint32, ) (err error) { getLogger(ses.GetService()).Debug(fmt.Sprintf("[%s] start to restore cluster, restore timestamp: %d", snapshotName, snapshotTs)) @@ -2568,6 +2572,7 @@ func restoreToCluster(ctx context.Context, if err != nil { return err } + markMongoDBAccountForRetirement(retiredMongoDBAccountIDs, uint32(account.accountId)) } // get restore accounts exists in snapshot @@ -2586,6 +2591,7 @@ func restoreToCluster(ctx context.Context, if err = restoreAccountUsingClusterSnapshotToNew(ctx, ses, bh, snapshotName, snapshotTs, account, uint64(newAccountId), subDbToRestore, isRestoreToCluster, isNeedToCleanToDatabase); err != nil { return err } + markMongoDBAccountForRetirement(retiredMongoDBAccountIDs, newAccountId) getLogger(ses.GetService()).Debug(fmt.Sprintf("[%s] restore account: %v, account id: %d success", snapshotName, account.accountName, account.accountId)) } diff --git a/pkg/iscp/iteration.go b/pkg/iscp/iteration.go index 8a06dfb4b9325..5a1c009216ecc 100644 --- a/pkg/iscp/iteration.go +++ b/pkg/iscp/iteration.go @@ -218,6 +218,7 @@ func ExecuteIteration( // injection is for ut if msg, injected := objectio.ISCPExecutorInjected(); injected && msg == "collectChanges" { err = moerr.NewInternalErrorNoCtx(msg) + objectio.WaitForISCPExecutorFault(ctx, msg) } // injection is for ut if msg, injected := objectio.ISCPExecutorInjected(); injected && strings.HasPrefix(msg, "iteration:") { @@ -388,6 +389,7 @@ func runISCPTaskIterationConsumers( // injection is for ut if msg, injected := objectio.ISCPExecutorInjected(); injected && msg == "changesNext" { err = moerr.NewInternalErrorNoCtx(msg) + objectio.WaitForISCPExecutorFault(ctxWithCancel, msg) } if err != nil { jobNames := "" diff --git a/pkg/iscp/mock_consumer.go b/pkg/iscp/mock_consumer.go index fa2c813ba5dd4..a37ab2752719d 100644 --- a/pkg/iscp/mock_consumer.go +++ b/pkg/iscp/mock_consumer.go @@ -220,12 +220,14 @@ func (s *interalSqlConsumer) Consume(ctx context.Context, data DataRetriever) er } if msg, injected := objectio.ISCPExecutorInjected(); injected && msg == "consume" { + objectio.WaitForISCPExecutorFault(ctx, msg) return moerr.NewInternalErrorNoCtx(msg) } if msg, injected := objectio.ISCPExecutorInjected(); injected && strings.HasPrefix(msg, "consumeWithJobName") { strs := strings.Split(msg, ":") for i := 1; i < len(strs); i++ { if s.jobName == strs[i] { + objectio.WaitForISCPExecutorFault(ctx, msg) return moerr.NewInternalErrorNoCtx(strs[0]) } } diff --git a/pkg/objectio/injects.go b/pkg/objectio/injects.go index 9ba17f0867f93..47c6126274c91 100644 --- a/pkg/objectio/injects.go +++ b/pkg/objectio/injects.go @@ -449,6 +449,18 @@ func ISCPExecutorInjected() (string, bool) { return sarg, injected } +// ISCPExecutorFaultWaitKey identifies the optional phase barrier for one +// executor fault. Tests install the barrier before enabling the matching fault, +// then observe its waiter to prove that the asynchronous worker reached the +// intended failure point. +func ISCPExecutorFaultWaitKey(msg string) string { + return FJ_CDCExecutor + ":" + msg +} + +func WaitForISCPExecutorFault(_ context.Context, msg string) { + WaitInjected(ISCPExecutorFaultWaitKey(msg)) +} + func CDCScanTableInjected() (string, bool) { _, sarg, injected := fault.TriggerFault(FJ_CDCScanTable) return sarg, injected diff --git a/pkg/pb/pipeline/pipeline.pb.go b/pkg/pb/pipeline/pipeline.pb.go index 9f77fbe5a15c8..2bee21ae8a9a1 100644 --- a/pkg/pb/pipeline/pipeline.pb.go +++ b/pkg/pb/pipeline/pipeline.pb.go @@ -4568,6 +4568,7 @@ type Instruction struct { MultiUpdate *MultiUpdate `protobuf:"bytes,52,opt,name=multi_update,json=multiUpdate,proto3" json:"multi_update,omitempty"` PostDml *PostDml `protobuf:"bytes,53,opt,name=post_dml,json=postDml,proto3" json:"post_dml,omitempty"` SpillMem int64 `protobuf:"varint,54,opt,name=spill_mem,json=spillMem,proto3" json:"spill_mem,omitempty"` + MongodbScan *plan.MongoScan `protobuf:"bytes,55,opt,name=mongodb_scan,json=mongodbScan,proto3" json:"mongodb_scan,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -4934,6 +4935,13 @@ func (m *Instruction) GetSpillMem() int64 { return 0 } +func (m *Instruction) GetMongodbScan() *plan.MongoScan { + if m != nil { + return m.MongodbScan + } + return nil +} + type AnalysisList struct { List []*plan.AnalyzeInfo `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -6098,471 +6106,472 @@ func init() { func init() { proto.RegisterFile("pipeline.proto", fileDescriptor_7ac67a7adf3df9c7) } var fileDescriptor_7ac67a7adf3df9c7 = []byte{ - // 7410 bytes of a gzipped FileDescriptorProto + // 7435 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7c, 0x4d, 0x8f, 0x1c, 0x47, - 0x96, 0x98, 0xea, 0xbb, 0xea, 0xd5, 0x47, 0x57, 0x47, 0x7f, 0x95, 0x48, 0x49, 0xa4, 0x4a, 0x22, - 0xd5, 0x43, 0x51, 0x4d, 0xb2, 0x25, 0xcd, 0x68, 0x67, 0x76, 0x76, 0xb6, 0xd9, 0x4d, 0x8e, 0x7a, - 0xd4, 0x4d, 0xf6, 0x66, 0x37, 0x2d, 0x40, 0x80, 0x9d, 0xc8, 0xce, 0x8c, 0xaa, 0x4a, 0x75, 0x56, - 0x66, 0x32, 0x23, 0x92, 0xec, 0xe6, 0xc9, 0x80, 0x0d, 0x18, 0xf0, 0xc5, 0x47, 0x2f, 0x7c, 0x9a, - 0x83, 0x01, 0xaf, 0x6d, 0x18, 0x3e, 0x18, 0xeb, 0xdf, 0xb0, 0xb0, 0x01, 0x63, 0x2f, 0xf6, 0xd1, - 0x30, 0x66, 0x8f, 0x06, 0x7c, 0x30, 0x60, 0x63, 0x2f, 0x06, 0x8c, 0xf7, 0x22, 0x22, 0x33, 0xeb, - 0x83, 0xd4, 0x87, 0x8d, 0xbd, 0xec, 0x9c, 0x2a, 0xe3, 0xbd, 0x17, 0x91, 0x91, 0x11, 0x2f, 0xde, - 0x77, 0x14, 0xf4, 0x62, 0x3f, 0xe6, 0x81, 0x1f, 0xf2, 0x9d, 0x38, 0x89, 0x64, 0xc4, 0x9a, 0xa6, - 0x7d, 0xed, 0x93, 0xb1, 0x2f, 0x27, 0xe9, 0xf9, 0x8e, 0x1b, 0x4d, 0xef, 0x8d, 0xa3, 0x71, 0x74, - 0x8f, 0x08, 0xce, 0xd3, 0x11, 0xb5, 0xa8, 0x41, 0x4f, 0xaa, 0xe3, 0x35, 0x08, 0x22, 0xf7, 0xc2, - 0x3c, 0xc7, 0x81, 0x13, 0xea, 0xe7, 0x15, 0xe9, 0x4f, 0xb9, 0x90, 0xce, 0x34, 0xd6, 0x80, 0x96, - 0xbc, 0xd4, 0xb8, 0xe1, 0x7f, 0xac, 0x40, 0xe3, 0x98, 0x0b, 0xe1, 0x8c, 0x39, 0x1b, 0x42, 0x45, - 0xf8, 0xde, 0xa0, 0x74, 0xb3, 0xb4, 0xdd, 0xdb, 0xed, 0xef, 0x64, 0xd3, 0x3a, 0x95, 0x8e, 0x4c, - 0x85, 0x85, 0x48, 0xa4, 0x71, 0xa7, 0xde, 0xa0, 0x3c, 0x4f, 0x73, 0xcc, 0xe5, 0x24, 0xf2, 0x2c, - 0x44, 0xb2, 0x3e, 0x54, 0x78, 0x92, 0x0c, 0x2a, 0x37, 0x4b, 0xdb, 0x1d, 0x0b, 0x1f, 0x19, 0x83, - 0xaa, 0xe7, 0x48, 0x67, 0x50, 0x25, 0x10, 0x3d, 0xb3, 0x0f, 0xa1, 0x17, 0x27, 0x91, 0x6b, 0xfb, - 0xe1, 0x28, 0xb2, 0x09, 0x5b, 0x23, 0x6c, 0x07, 0xa1, 0x87, 0xe1, 0x28, 0x3a, 0x40, 0xaa, 0x01, - 0x34, 0x9c, 0xd0, 0x09, 0xae, 0x04, 0x1f, 0xd4, 0x09, 0x6d, 0x9a, 0xac, 0x07, 0x65, 0xdf, 0x1b, - 0x34, 0x6e, 0x96, 0xb6, 0xab, 0x56, 0xd9, 0xf7, 0xf0, 0x1d, 0x69, 0xea, 0x7b, 0x83, 0xa6, 0x7a, - 0x07, 0x3e, 0xb3, 0x21, 0x74, 0x42, 0xce, 0xbd, 0x27, 0x91, 0xb4, 0x78, 0x1c, 0x5c, 0x0d, 0x5a, - 0x37, 0x4b, 0xdb, 0x4d, 0x6b, 0x06, 0xc6, 0xae, 0x41, 0xd3, 0xe3, 0xe7, 0xe9, 0xf8, 0x58, 0x8c, - 0x07, 0x70, 0xb3, 0xb4, 0xdd, 0xb2, 0xb2, 0x36, 0x3b, 0x83, 0xad, 0x84, 0x3f, 0x4f, 0xb9, 0x90, - 0xdc, 0xb3, 0x25, 0x77, 0x12, 0x2f, 0x7a, 0x19, 0xda, 0xd3, 0xc8, 0xe3, 0x83, 0x36, 0xad, 0xc0, - 0x3b, 0xc5, 0x55, 0x4a, 0xb8, 0x33, 0x3d, 0xd3, 0x44, 0xc7, 0x91, 0xc7, 0xad, 0x8d, 0xac, 0x73, - 0x11, 0xcc, 0x2c, 0xd8, 0x74, 0x5c, 0x97, 0xc7, 0x8b, 0x83, 0x76, 0xbe, 0xc7, 0xa0, 0xeb, 0xa6, - 0x6f, 0x11, 0xfa, 0xf3, 0xea, 0x9f, 0xfe, 0xf6, 0xc6, 0x5b, 0xc3, 0x67, 0xd0, 0xda, 0x8f, 0xc2, - 0x90, 0xbb, 0x32, 0x4a, 0xd8, 0x0d, 0x68, 0x9b, 0x71, 0x6c, 0xbd, 0xad, 0x35, 0x0b, 0x0c, 0xe8, - 0xd0, 0x63, 0x1f, 0xc1, 0x8a, 0x6b, 0xa8, 0x6d, 0x3f, 0xf4, 0xf8, 0x25, 0xed, 0x6b, 0xcd, 0xea, - 0x65, 0xe0, 0x43, 0x84, 0x0e, 0xff, 0x59, 0x05, 0x1a, 0xa7, 0x93, 0x74, 0x34, 0x0a, 0x38, 0xfb, - 0x10, 0xba, 0xfa, 0x71, 0x3f, 0x0a, 0x0e, 0xbd, 0x4b, 0x3d, 0xee, 0x2c, 0x90, 0xdd, 0x84, 0xb6, - 0x06, 0x9c, 0x5d, 0xc5, 0x5c, 0x0f, 0x5b, 0x04, 0xcd, 0x8e, 0x73, 0xec, 0x87, 0xc4, 0x2e, 0x15, - 0x6b, 0x16, 0x38, 0x47, 0xe5, 0x5c, 0x12, 0x07, 0xcd, 0x52, 0x39, 0xf4, 0xb6, 0xbd, 0xc0, 0x7f, - 0xc1, 0x2d, 0x3e, 0xde, 0x0f, 0x25, 0xf1, 0x51, 0xcd, 0x2a, 0x82, 0xd8, 0x2e, 0x6c, 0x08, 0xd5, - 0xc5, 0x4e, 0x9c, 0x70, 0xcc, 0x85, 0x9d, 0xfa, 0xa1, 0xfc, 0xe9, 0x67, 0x83, 0xfa, 0xcd, 0xca, - 0x76, 0xd5, 0x5a, 0xd3, 0x48, 0x8b, 0x70, 0xcf, 0x08, 0xc5, 0xee, 0xc3, 0xfa, 0x5c, 0x1f, 0xd5, - 0xa5, 0x71, 0xb3, 0xb2, 0x5d, 0xb1, 0xd8, 0x4c, 0x97, 0x43, 0xea, 0xf1, 0x08, 0x56, 0x93, 0x34, - 0xc4, 0xd3, 0xf6, 0xd8, 0x0f, 0x24, 0x4f, 0x4e, 0x63, 0xee, 0x12, 0x3f, 0xb6, 0x77, 0xb7, 0x76, - 0xe8, 0x40, 0x5a, 0xf3, 0x68, 0x6b, 0xb1, 0x07, 0xbb, 0x9b, 0x2d, 0xde, 0xa3, 0xcb, 0x38, 0x21, - 0xa6, 0x6d, 0xef, 0x82, 0x1a, 0x00, 0x21, 0x56, 0x11, 0x3d, 0xfc, 0xeb, 0x32, 0x34, 0x0f, 0x7c, - 0x11, 0x3b, 0xd2, 0x9d, 0xb0, 0x2d, 0x68, 0x8c, 0xd2, 0xd0, 0xcd, 0xf7, 0xbb, 0x8e, 0xcd, 0x43, - 0x8f, 0xfd, 0x21, 0xac, 0x04, 0x91, 0xeb, 0x04, 0x76, 0xb6, 0xb5, 0x83, 0xf2, 0xcd, 0xca, 0x76, - 0x7b, 0x77, 0x2d, 0x67, 0xb6, 0x8c, 0x75, 0xac, 0x1e, 0xd1, 0xe6, 0xac, 0xf4, 0x4b, 0xe8, 0x27, - 0x7c, 0x1a, 0x49, 0x5e, 0xe8, 0x5e, 0xa1, 0xee, 0x2c, 0xef, 0xfe, 0x75, 0xe2, 0xc4, 0x4f, 0x90, - 0x43, 0x57, 0x14, 0x6d, 0xde, 0xfd, 0x41, 0x61, 0xf5, 0xf9, 0xd8, 0xf6, 0xbd, 0x4b, 0x9b, 0x5e, - 0x30, 0xa8, 0xde, 0xac, 0x6c, 0xd7, 0xf2, 0xa5, 0xe4, 0xe3, 0x43, 0xef, 0xf2, 0x08, 0x31, 0xec, - 0x53, 0xd8, 0x9c, 0xef, 0xa2, 0x46, 0x1d, 0xd4, 0xa8, 0xcf, 0xda, 0x4c, 0x1f, 0x8b, 0x50, 0xec, - 0x7d, 0xe8, 0x98, 0x4e, 0x12, 0xd9, 0xae, 0xae, 0x18, 0x41, 0x14, 0xd8, 0x6e, 0x0b, 0x1a, 0xbe, - 0xb0, 0x85, 0x1f, 0x5e, 0x90, 0xe8, 0x68, 0x5a, 0x75, 0x5f, 0x9c, 0xfa, 0xe1, 0x05, 0x7b, 0x1b, - 0x9a, 0x09, 0x77, 0x15, 0xa6, 0x49, 0x98, 0x46, 0xc2, 0x5d, 0x42, 0x6d, 0x01, 0x3e, 0xda, 0xae, - 0xe4, 0x5a, 0x80, 0xd4, 0x13, 0xee, 0xee, 0x4b, 0x3e, 0x14, 0x50, 0x3b, 0xe6, 0xc9, 0x98, 0xa3, - 0x0c, 0xc1, 0x8e, 0xa7, 0xae, 0x13, 0xd2, 0xba, 0x37, 0xad, 0xac, 0x8d, 0x12, 0x2c, 0x76, 0x12, - 0xe9, 0x3b, 0x01, 0x1d, 0x83, 0xa6, 0x65, 0x9a, 0xec, 0x3a, 0xb4, 0x84, 0x74, 0x12, 0x89, 0x5f, - 0x47, 0xec, 0x5f, 0xb3, 0x9a, 0x04, 0xc0, 0x13, 0xb4, 0x05, 0x0d, 0x1e, 0x7a, 0x84, 0xaa, 0xaa, - 0x9d, 0xe4, 0xa1, 0x77, 0xe8, 0x5d, 0x0e, 0xff, 0x5d, 0x09, 0xba, 0xc7, 0x69, 0x20, 0xfd, 0xbd, - 0x64, 0x9c, 0xf2, 0x69, 0x28, 0x51, 0xf2, 0x1d, 0xf8, 0x42, 0xea, 0x37, 0xd3, 0x33, 0xdb, 0x86, - 0xd6, 0xaf, 0x93, 0x28, 0x8d, 0x89, 0x83, 0xd4, 0x4e, 0x17, 0x39, 0x28, 0x47, 0x22, 0xb7, 0x3d, - 0x4d, 0x3c, 0x9e, 0x3c, 0xbc, 0x22, 0xda, 0xca, 0x02, 0x6d, 0x11, 0xcd, 0xde, 0x81, 0xd6, 0x29, - 0x8f, 0x9d, 0xc4, 0x41, 0x16, 0xa8, 0x92, 0xb8, 0xcc, 0x01, 0xf8, 0xad, 0x44, 0x7c, 0xe8, 0xe9, - 0x43, 0x68, 0x9a, 0xc3, 0x31, 0xb4, 0xf6, 0xc6, 0xe3, 0x84, 0x8f, 0x1d, 0x49, 0xa2, 0x3b, 0x8a, - 0x69, 0xba, 0x15, 0xab, 0x1c, 0xc5, 0xa4, 0x1e, 0xf0, 0x03, 0xd4, 0xfa, 0xd0, 0x33, 0x7b, 0x0f, - 0xaa, 0x7c, 0xf9, 0x7c, 0x08, 0xce, 0x36, 0xa1, 0xee, 0x46, 0xe1, 0xc8, 0x1f, 0x6b, 0xa5, 0xa2, - 0x5b, 0xc3, 0x7f, 0x55, 0x81, 0x1a, 0x7d, 0x1c, 0x2e, 0x2f, 0x0a, 0x7a, 0x9b, 0xbf, 0x70, 0x02, - 0xb3, 0x2b, 0x08, 0x78, 0xf4, 0xc2, 0x09, 0xd8, 0x4d, 0xa8, 0xe1, 0x30, 0x62, 0xc9, 0xda, 0x28, - 0x04, 0xbb, 0x0d, 0x35, 0x64, 0x22, 0x31, 0x3b, 0x03, 0x64, 0xa2, 0x87, 0xd5, 0xbf, 0xf8, 0xaf, - 0x37, 0xde, 0xb2, 0x14, 0x9a, 0x7d, 0x04, 0x55, 0x67, 0x3c, 0x16, 0xc4, 0xcb, 0x33, 0xc7, 0x29, - 0xfb, 0x5e, 0x8b, 0x08, 0xd8, 0xe7, 0xd0, 0x52, 0xfb, 0x86, 0xd4, 0x35, 0xa2, 0xde, 0x2a, 0x28, - 0xd0, 0xe2, 0x96, 0x5a, 0x39, 0x25, 0xae, 0xb8, 0x2f, 0xf4, 0x81, 0x27, 0x8e, 0x6e, 0x5a, 0x39, - 0x00, 0x35, 0x5c, 0x9c, 0xf0, 0xbd, 0x20, 0x88, 0xdc, 0x53, 0xff, 0x15, 0xd7, 0xfa, 0x70, 0x06, - 0xc6, 0x6e, 0x43, 0xef, 0x44, 0xb1, 0x9c, 0xc5, 0x45, 0x1a, 0x48, 0xa1, 0x75, 0xe4, 0x1c, 0x94, - 0xed, 0x00, 0x9b, 0x81, 0x9c, 0xd1, 0xe7, 0xb7, 0x6e, 0x56, 0xb6, 0xbb, 0xd6, 0x12, 0x0c, 0xfb, - 0x00, 0xba, 0x63, 0x5c, 0x69, 0x3f, 0x1c, 0xdb, 0xa3, 0xc0, 0x41, 0xf5, 0x59, 0x41, 0xf5, 0x6a, - 0x80, 0x8f, 0x03, 0x67, 0x4c, 0x4c, 0x1e, 0xfb, 0x41, 0x60, 0x4f, 0xf9, 0x94, 0x94, 0x66, 0xc5, - 0x6a, 0x12, 0xe0, 0x98, 0x4f, 0x87, 0xff, 0xba, 0x0a, 0xf5, 0xc3, 0x50, 0xf0, 0x44, 0xe2, 0x11, - 0x72, 0x46, 0x23, 0xee, 0x4a, 0xae, 0x44, 0x57, 0xd5, 0xca, 0xda, 0xb8, 0x04, 0x67, 0xd1, 0xd7, - 0x89, 0x2f, 0xf9, 0xe9, 0xa7, 0x9a, 0x49, 0x72, 0x00, 0xbb, 0x03, 0xab, 0x8e, 0xe7, 0xd9, 0x86, - 0xda, 0x4e, 0xa2, 0x97, 0x82, 0x8e, 0x53, 0xd3, 0x5a, 0x71, 0x3c, 0x6f, 0x4f, 0xc3, 0xad, 0xe8, - 0xa5, 0x60, 0xef, 0x43, 0x25, 0xe1, 0x23, 0x62, 0x99, 0xf6, 0xee, 0x8a, 0xda, 0xd2, 0xa7, 0xe7, - 0xdf, 0x72, 0x57, 0x5a, 0x7c, 0x64, 0x21, 0x8e, 0xad, 0x43, 0xcd, 0x91, 0x32, 0x51, 0x5b, 0xd4, - 0xb2, 0x54, 0x83, 0xed, 0xc0, 0x1a, 0x1d, 0x5b, 0xe9, 0x47, 0xa1, 0x2d, 0x9d, 0xf3, 0x00, 0x75, - 0xaa, 0xd0, 0xea, 0x63, 0x35, 0x43, 0x9d, 0x21, 0xe6, 0xd0, 0x13, 0xa8, 0x70, 0xe6, 0xe9, 0x43, - 0x67, 0xca, 0x05, 0x69, 0x8f, 0x96, 0xb5, 0x36, 0xdb, 0xe3, 0x09, 0xa2, 0x70, 0x3d, 0xf3, 0x3e, - 0x78, 0xf0, 0x9b, 0x74, 0x86, 0x3a, 0x19, 0x10, 0xe5, 0xc2, 0x06, 0xd4, 0x7d, 0x61, 0xf3, 0xd0, - 0xd3, 0xb2, 0xa8, 0xe6, 0x8b, 0x47, 0xa1, 0xc7, 0x3e, 0x86, 0x96, 0x7a, 0x8b, 0xc7, 0x47, 0x64, - 0xc6, 0xb4, 0x77, 0x7b, 0x9a, 0x63, 0x11, 0x7c, 0xc0, 0x47, 0x56, 0x53, 0xea, 0x27, 0xb4, 0x0c, - 0x64, 0x64, 0xf3, 0x4b, 0xc9, 0x93, 0xd0, 0x09, 0x68, 0x57, 0x9a, 0x16, 0xc8, 0xe8, 0x91, 0x86, - 0xb0, 0xcf, 0x61, 0xcb, 0x60, 0x6d, 0x21, 0xa7, 0xd2, 0x4e, 0x43, 0xff, 0xd2, 0x0e, 0x9d, 0x30, - 0x22, 0x13, 0xa5, 0x62, 0xad, 0x1b, 0xf4, 0xa9, 0x9c, 0xca, 0x67, 0xa1, 0x7f, 0xf9, 0xc4, 0x09, - 0x23, 0xb6, 0x0d, 0xfd, 0xac, 0x9b, 0x7c, 0x45, 0x1f, 0x3c, 0xe8, 0x92, 0x8c, 0xe8, 0x19, 0xf8, - 0xd9, 0x2b, 0xfc, 0x56, 0x14, 0xef, 0x45, 0xca, 0x68, 0x34, 0x12, 0x5c, 0xda, 0x82, 0xbb, 0x83, - 0x1e, 0x7d, 0xf3, 0x5a, 0x4e, 0xff, 0x94, 0x70, 0xa7, 0xdc, 0x1d, 0xfe, 0x83, 0x12, 0xb4, 0xe9, - 0x5c, 0x3c, 0x8b, 0x3d, 0x14, 0x23, 0x1f, 0x40, 0x77, 0x76, 0xd3, 0x15, 0xdf, 0x74, 0x9c, 0xe2, - 0x8e, 0x6f, 0x42, 0x7d, 0xcf, 0xc5, 0xc5, 0x23, 0xc6, 0xe9, 0x5a, 0xba, 0xc5, 0x7e, 0x06, 0x2b, - 0x29, 0x0d, 0x63, 0xbb, 0xf2, 0xd2, 0x0e, 0x50, 0xfc, 0xa8, 0x83, 0xae, 0xb9, 0x42, 0xbd, 0x63, - 0x5f, 0x5e, 0x5a, 0xdd, 0xd4, 0x3c, 0x1e, 0xf9, 0x42, 0x0e, 0xdf, 0x85, 0xda, 0x5e, 0x92, 0x38, - 0x57, 0xc4, 0x28, 0xf8, 0x30, 0x28, 0x91, 0x46, 0x52, 0x8d, 0xa1, 0x0b, 0x95, 0x63, 0x27, 0x66, - 0xb7, 0xa0, 0x3c, 0x8d, 0x09, 0xd3, 0xde, 0xdd, 0x28, 0x9c, 0x72, 0x27, 0xde, 0x39, 0x8e, 0x1f, - 0x85, 0x32, 0xb9, 0xb2, 0xca, 0xd3, 0xf8, 0xda, 0xe7, 0xd0, 0xd0, 0x4d, 0xb4, 0x9a, 0x2f, 0xf8, - 0x15, 0x7d, 0x43, 0xcb, 0xc2, 0x47, 0x7c, 0xc1, 0x0b, 0x27, 0x48, 0x8d, 0xf9, 0xa4, 0x1a, 0x3f, - 0x2f, 0x7f, 0x51, 0x1a, 0xfe, 0xaf, 0x2a, 0x34, 0x0f, 0x78, 0xc0, 0xe9, 0x4b, 0x86, 0xd0, 0x29, - 0xf2, 0xb8, 0x59, 0x85, 0x19, 0xbe, 0x1f, 0x42, 0x47, 0xe9, 0x48, 0xea, 0xc5, 0xf5, 0x21, 0x9a, - 0x81, 0xa1, 0xf0, 0x3e, 0x7c, 0x98, 0xba, 0x17, 0x5c, 0xd2, 0xe9, 0xe9, 0x5a, 0xa6, 0x89, 0x98, - 0x27, 0x1a, 0x53, 0x55, 0x18, 0xdd, 0x64, 0xef, 0x00, 0x24, 0xd1, 0x4b, 0xdb, 0x57, 0x8a, 0x4a, - 0xc9, 0xfc, 0x66, 0x12, 0xbd, 0x3c, 0x44, 0x55, 0xf5, 0x37, 0x72, 0x68, 0x7e, 0x06, 0x83, 0xc2, - 0xa1, 0x41, 0x73, 0xd5, 0xf6, 0x43, 0xfb, 0x1c, 0xad, 0x21, 0x7d, 0x7e, 0xf2, 0x31, 0xc9, 0x9a, - 0x3d, 0x0c, 0x1f, 0x92, 0xa9, 0xa4, 0x45, 0x41, 0xeb, 0x0d, 0xa2, 0x60, 0xa9, 0x64, 0x81, 0xe5, - 0x92, 0xe5, 0x21, 0xc0, 0x29, 0x1f, 0x4f, 0x79, 0x28, 0x8f, 0x9d, 0x78, 0xd0, 0xa6, 0x8d, 0x1f, - 0xe6, 0x1b, 0x6f, 0x76, 0x6b, 0x27, 0x27, 0x52, 0x5c, 0x50, 0xe8, 0x85, 0xf6, 0x8b, 0xeb, 0x84, - 0xb6, 0x4c, 0xd2, 0xd0, 0x75, 0xa4, 0x72, 0x07, 0x9a, 0x56, 0xdb, 0x75, 0xc2, 0x33, 0x0d, 0x2a, - 0x1c, 0xff, 0x6e, 0xf1, 0xf8, 0xdf, 0x86, 0x95, 0x38, 0xf1, 0xa7, 0x4e, 0x72, 0x65, 0x5f, 0xf0, - 0x2b, 0xda, 0x0c, 0x75, 0x90, 0xba, 0x1a, 0xfc, 0x15, 0xbf, 0x3a, 0xf4, 0x2e, 0xaf, 0xfd, 0x12, - 0x56, 0xe6, 0x26, 0xf0, 0x83, 0xf8, 0xee, 0xb7, 0x15, 0x68, 0x9d, 0x24, 0x5c, 0x8b, 0xec, 0x1b, - 0xd0, 0x16, 0xee, 0x84, 0x4f, 0x1d, 0x75, 0xd2, 0xd5, 0x08, 0xa0, 0x40, 0x74, 0xca, 0x67, 0x84, - 0x52, 0xf9, 0x3b, 0x84, 0x52, 0x1f, 0x2a, 0xca, 0x0e, 0xc2, 0xc3, 0x84, 0x8f, 0xb9, 0x24, 0xae, - 0x16, 0x25, 0xf1, 0x4d, 0xe8, 0x4c, 0x1c, 0x61, 0x3b, 0xa9, 0x8c, 0x6c, 0x37, 0x0a, 0x88, 0xe9, - 0x9a, 0x16, 0x4c, 0x1c, 0xb1, 0x97, 0xca, 0x68, 0x3f, 0x0a, 0xd8, 0xbb, 0x00, 0x6e, 0x14, 0x68, - 0xa1, 0xa2, 0x8d, 0xc0, 0x96, 0x1b, 0x05, 0x4a, 0x92, 0x20, 0x57, 0x72, 0x21, 0xfd, 0xa9, 0xa3, - 0xb7, 0xd4, 0x76, 0xa3, 0x34, 0x94, 0xa4, 0x39, 0x2b, 0xd6, 0x6a, 0x86, 0xb2, 0xa2, 0x97, 0xfb, - 0x88, 0x60, 0xf7, 0xa1, 0xe7, 0x46, 0xd3, 0xd8, 0x8e, 0x71, 0x65, 0xc9, 0x26, 0x69, 0x2e, 0x58, - 0xe4, 0x1d, 0xa4, 0x38, 0xb9, 0xe0, 0xca, 0x48, 0xda, 0x85, 0x15, 0x37, 0x48, 0x85, 0xe4, 0x89, - 0x7d, 0xae, 0xbb, 0x2c, 0x1a, 0xf1, 0x5d, 0x4d, 0xa2, 0x0d, 0xab, 0x21, 0x74, 0x7d, 0x61, 0x47, - 0x81, 0x67, 0x2b, 0x71, 0xa3, 0xf9, 0xac, 0xed, 0x8b, 0xa7, 0x81, 0xa7, 0x05, 0x9e, 0xa2, 0x09, - 0xf9, 0x4b, 0x43, 0xd3, 0x36, 0x34, 0x4f, 0xf8, 0x4b, 0x45, 0x33, 0xfc, 0x2f, 0x65, 0x68, 0x9c, - 0x44, 0x42, 0x1e, 0x4c, 0x03, 0xc3, 0xe2, 0xa5, 0x1f, 0xca, 0xe2, 0xe5, 0xe5, 0x2c, 0xbe, 0x84, - 0xc9, 0x2a, 0x4b, 0x98, 0x0c, 0xd5, 0x40, 0x91, 0x8e, 0x98, 0x43, 0x99, 0x8a, 0xbd, 0x9c, 0x90, - 0x18, 0xe4, 0x3a, 0xda, 0x36, 0xb6, 0xa7, 0x64, 0x92, 0xda, 0xc8, 0xa6, 0x2f, 0xb4, 0x3c, 0x52, - 0x48, 0x9f, 0x78, 0x4d, 0x1b, 0x3e, 0x4d, 0x5f, 0x68, 0xde, 0xfb, 0x03, 0x78, 0x3b, 0xeb, 0x69, - 0xbf, 0xf4, 0xe5, 0x24, 0x4a, 0xa5, 0x3d, 0x22, 0x1f, 0x4a, 0x68, 0xcb, 0x7e, 0xd3, 0x8c, 0xf4, - 0xb5, 0x42, 0x2b, 0x0f, 0x8b, 0xec, 0xb0, 0x51, 0x1a, 0x04, 0xb6, 0xe4, 0x97, 0x52, 0x6f, 0xe5, - 0x40, 0xad, 0x8d, 0x5e, 0xb7, 0xc7, 0x69, 0x10, 0x9c, 0xf1, 0x4b, 0x89, 0xc2, 0xbf, 0x39, 0xd2, - 0x8d, 0xe1, 0x3f, 0xad, 0x02, 0x1c, 0x45, 0xee, 0xc5, 0x99, 0x93, 0x8c, 0xb9, 0x44, 0x7f, 0xc1, - 0x48, 0x34, 0x2d, 0x71, 0x1b, 0x52, 0xc9, 0x31, 0xb6, 0x0b, 0x9b, 0xe6, 0xfb, 0x91, 0x0f, 0xd1, - 0x77, 0x51, 0x22, 0x49, 0x1f, 0x28, 0xa6, 0xb1, 0xca, 0x57, 0x26, 0x79, 0xc4, 0xbe, 0xc8, 0xd7, - 0x16, 0xfb, 0xc8, 0xab, 0x98, 0xd6, 0x76, 0x99, 0xdd, 0xd9, 0xcd, 0xbb, 0x9f, 0x5d, 0xc5, 0xec, - 0x3e, 0x6c, 0x24, 0x7c, 0x94, 0x70, 0x31, 0xb1, 0xa5, 0x28, 0xbe, 0x4c, 0xb9, 0x0d, 0xab, 0x1a, - 0x79, 0x26, 0xb2, 0x77, 0xdd, 0x87, 0x0d, 0xb5, 0x52, 0xf3, 0xd3, 0x53, 0xf2, 0x7b, 0x55, 0x21, - 0x8b, 0xb3, 0x7b, 0x17, 0x28, 0xb6, 0xa4, 0x64, 0xb2, 0x31, 0x42, 0x03, 0x5a, 0x8c, 0xf3, 0x80, - 0xa3, 0x7d, 0xb6, 0x3f, 0x41, 0x3f, 0xf8, 0x80, 0x8f, 0xf4, 0xe2, 0xe7, 0x00, 0x36, 0x84, 0xea, - 0x71, 0xe4, 0x71, 0x5a, 0xea, 0xde, 0x6e, 0x6f, 0x87, 0xa2, 0x54, 0xb8, 0x92, 0x14, 0xce, 0x20, - 0x1c, 0xfb, 0x08, 0x68, 0x38, 0xc5, 0x7e, 0x8b, 0x67, 0xa5, 0x89, 0x48, 0xe2, 0xc1, 0xfb, 0xb0, - 0x91, 0xcf, 0xc4, 0x76, 0xa4, 0x2d, 0x27, 0x9c, 0xc4, 0xa1, 0x3a, 0x2e, 0xab, 0xd9, 0xa4, 0xf6, - 0xe4, 0xd9, 0x84, 0xa3, 0x68, 0xdc, 0x86, 0x46, 0x74, 0xfe, 0xad, 0x8d, 0x07, 0xa1, 0xbd, 0xfc, - 0x20, 0xd4, 0xa3, 0xf3, 0x6f, 0x2d, 0x3e, 0x62, 0x3f, 0x2d, 0xaa, 0x92, 0xb9, 0xa5, 0xe9, 0xd0, - 0xd2, 0xac, 0x67, 0xf8, 0xc2, 0xea, 0x0c, 0xbf, 0x80, 0x3a, 0x7e, 0xce, 0xd3, 0x98, 0xed, 0x40, - 0x43, 0x12, 0x7b, 0x08, 0xad, 0xfa, 0xd7, 0x73, 0x0d, 0x90, 0xf3, 0x8e, 0x65, 0x88, 0x86, 0x16, - 0xac, 0x64, 0xe2, 0xf4, 0x59, 0xe8, 0x3f, 0x4f, 0x39, 0xfb, 0x15, 0xac, 0xc6, 0x09, 0xd7, 0x6c, - 0x6f, 0xa7, 0x17, 0x68, 0x9e, 0xe8, 0x13, 0xbc, 0xae, 0xb9, 0x34, 0xeb, 0x71, 0x81, 0x1c, 0xda, - 0x8b, 0x67, 0xda, 0xc3, 0x6f, 0x60, 0x2b, 0xa3, 0x38, 0xe5, 0x6e, 0x14, 0x7a, 0x4e, 0x72, 0x45, - 0x9a, 0x6f, 0x6e, 0x6c, 0xf1, 0x43, 0xc6, 0x3e, 0xa5, 0xb1, 0xff, 0x45, 0x09, 0xda, 0x8f, 0xd3, - 0x57, 0xaf, 0xae, 0xd4, 0x59, 0x62, 0x1d, 0x28, 0x3d, 0xa1, 0x01, 0xca, 0x56, 0xe9, 0x09, 0x9a, - 0x5a, 0x27, 0x17, 0x78, 0xae, 0x89, 0xcf, 0x5b, 0x96, 0x6e, 0xa1, 0x27, 0x75, 0x72, 0x71, 0xf6, - 0x06, 0x8e, 0x56, 0x68, 0x74, 0x01, 0x1e, 0xa6, 0x7e, 0x80, 0xa6, 0x83, 0x66, 0xde, 0xac, 0x8d, - 0xbe, 0xc9, 0xe1, 0x48, 0x4d, 0xe5, 0x71, 0x12, 0x4d, 0xd5, 0x62, 0x69, 0x91, 0xb1, 0x04, 0x33, - 0xfc, 0xeb, 0x2a, 0x34, 0xbf, 0x74, 0xc4, 0xe4, 0x37, 0x91, 0x1f, 0xb2, 0xfb, 0xd0, 0xfa, 0x36, - 0xf2, 0x43, 0x15, 0x14, 0x50, 0xe1, 0xcd, 0x35, 0x35, 0x89, 0x27, 0x91, 0xc7, 0x77, 0x90, 0x06, - 0x67, 0x63, 0x35, 0xbf, 0xd5, 0x4f, 0x5a, 0xd2, 0x26, 0xfe, 0x78, 0x22, 0x6d, 0x04, 0x6a, 0x91, - 0xd8, 0xf6, 0x85, 0x85, 0x30, 0x1a, 0xf5, 0x1d, 0x40, 0xa5, 0x33, 0xb1, 0xa3, 0xd0, 0x8e, 0x2f, - 0xb4, 0xc3, 0xd1, 0x44, 0xc8, 0xd3, 0xf0, 0xe4, 0x02, 0x8f, 0x8c, 0x2f, 0x6c, 0x1d, 0x7a, 0xa0, - 0xcf, 0x99, 0xf1, 0xdb, 0x3e, 0x84, 0x1e, 0xaa, 0x7a, 0x71, 0xe1, 0xc7, 0x76, 0x9c, 0x44, 0xe7, - 0xe6, 0x5b, 0xd0, 0x00, 0x38, 0xbd, 0xf0, 0xe3, 0x13, 0x84, 0x91, 0x86, 0xd5, 0x01, 0x0d, 0x94, - 0xb6, 0x4a, 0x95, 0x81, 0x06, 0xe1, 0xb2, 0x50, 0xd4, 0x22, 0x50, 0xe6, 0x6b, 0x83, 0x34, 0x67, - 0x23, 0xe1, 0x01, 0xda, 0xa9, 0x88, 0x42, 0x1e, 0x26, 0x54, 0x53, 0xa1, 0xdc, 0x48, 0xa1, 0x7e, - 0x02, 0x10, 0xf0, 0x91, 0xb4, 0x91, 0x39, 0x94, 0x83, 0x37, 0x17, 0x1d, 0x40, 0xec, 0x3e, 0x22, - 0xd9, 0xc7, 0xd0, 0x56, 0xab, 0xa0, 0x68, 0x61, 0x81, 0x16, 0x08, 0xad, 0x88, 0xef, 0x40, 0x3b, - 0x8c, 0x42, 0x9b, 0x3f, 0x27, 0x6a, 0x7d, 0xdc, 0x66, 0x06, 0x0e, 0xa3, 0xf0, 0xd1, 0x73, 0x24, - 0x66, 0xf7, 0xf4, 0x1c, 0x94, 0x8f, 0xdd, 0x79, 0x8d, 0x8f, 0x4d, 0x33, 0x51, 0xde, 0xe6, 0x03, - 0x33, 0x13, 0xd5, 0xa3, 0xfb, 0x9a, 0x1e, 0x6a, 0x3e, 0xaa, 0xcb, 0x4d, 0xe8, 0xd0, 0xbe, 0x4f, - 0x9d, 0xd8, 0x96, 0xce, 0x58, 0x9b, 0x44, 0x80, 0xb0, 0x63, 0x27, 0x3e, 0x73, 0xc6, 0xcc, 0x82, - 0xb7, 0x75, 0xfc, 0x4d, 0x2b, 0x0f, 0xfb, 0x1c, 0x39, 0x4e, 0xad, 0xda, 0x8a, 0xf1, 0xd1, 0x97, - 0x47, 0xee, 0x36, 0x67, 0x22, 0x77, 0xc4, 0xa9, 0xe4, 0x20, 0xfc, 0xf3, 0x32, 0x34, 0x8f, 0xa2, - 0x28, 0xfe, 0x91, 0xac, 0x57, 0xdc, 0xd2, 0xf2, 0xeb, 0xb7, 0xb4, 0x32, 0xbb, 0xa5, 0x73, 0x4b, - 0x5f, 0xfd, 0xfe, 0x4b, 0x5f, 0xfb, 0xc1, 0x4b, 0x5f, 0xff, 0x11, 0x4b, 0xdf, 0x98, 0x5f, 0xfa, - 0x61, 0x03, 0x6a, 0xa7, 0x5c, 0x3e, 0x8d, 0x87, 0xff, 0xb6, 0x09, 0xad, 0x03, 0xee, 0xa5, 0x6a, - 0xc1, 0x8a, 0x9f, 0x5f, 0x7a, 0xfd, 0xe7, 0x97, 0x67, 0x3f, 0x1f, 0xf5, 0x87, 0xe1, 0xe8, 0x25, - 0x21, 0xa3, 0xa6, 0x61, 0x68, 0x64, 0xfd, 0x9c, 0x9f, 0x75, 0xcc, 0x66, 0x66, 0x99, 0x32, 0x76, - 0x7e, 0x33, 0x6f, 0xd4, 0x7e, 0x14, 0x6f, 0xcc, 0x49, 0x85, 0x85, 0x68, 0xce, 0x77, 0xae, 0xda, - 0xbc, 0x44, 0x68, 0x2e, 0x48, 0x84, 0x23, 0x58, 0x8b, 0x42, 0xdb, 0x4b, 0xe3, 0xc0, 0x47, 0x87, - 0xc1, 0x76, 0x94, 0xf3, 0xdb, 0x32, 0x99, 0x85, 0x8c, 0xf5, 0x9e, 0x86, 0x07, 0x86, 0x48, 0xb9, - 0xc4, 0xd6, 0x6a, 0x34, 0x0f, 0x42, 0x31, 0xe5, 0xe1, 0xd6, 0x90, 0x3a, 0x24, 0x43, 0x4e, 0xa5, - 0x48, 0x3a, 0x04, 0xdd, 0x8f, 0x02, 0x12, 0xf0, 0x5f, 0xc0, 0x4a, 0x4e, 0xa5, 0x78, 0xa4, 0xfd, - 0x1a, 0x1e, 0xe9, 0x9a, 0x8e, 0x8a, 0x4d, 0xfe, 0x26, 0xa4, 0xc0, 0x27, 0xb0, 0x66, 0x3c, 0x7d, - 0xad, 0xd3, 0x69, 0x07, 0x7b, 0xc4, 0x41, 0x7d, 0xed, 0xdc, 0x93, 0x3a, 0xa7, 0x2d, 0xfa, 0x05, - 0xac, 0x17, 0xc8, 0xd1, 0x78, 0x2f, 0x4a, 0x83, 0x22, 0xaf, 0xac, 0x66, 0x7d, 0xb1, 0x79, 0xa4, - 0xa2, 0x96, 0x6d, 0x8f, 0x07, 0xe6, 0x45, 0x83, 0xbe, 0xf2, 0x3d, 0x3c, 0x1e, 0xe8, 0xbc, 0xc8, - 0x31, 0x7c, 0x88, 0x26, 0x3e, 0xe2, 0x5d, 0x27, 0x96, 0x69, 0xc2, 0xed, 0x38, 0x70, 0x5c, 0x3e, - 0x89, 0x02, 0x8f, 0x27, 0xf9, 0xe4, 0x56, 0x69, 0x72, 0x37, 0xa2, 0xc0, 0xdb, 0x8f, 0x82, 0x7d, - 0x45, 0x79, 0x92, 0x13, 0x9a, 0xb9, 0xee, 0xc1, 0x7b, 0x0b, 0xc3, 0xa1, 0xe2, 0xc8, 0x07, 0x62, - 0x34, 0xd0, 0xdb, 0xb3, 0x03, 0x21, 0x89, 0x19, 0xe2, 0x01, 0x6c, 0xa8, 0xbd, 0x53, 0xcc, 0x7d, - 0xc1, 0x79, 0x6c, 0x07, 0x8e, 0x90, 0x83, 0x35, 0xa5, 0x5b, 0x09, 0x49, 0x0c, 0xfc, 0x15, 0xe7, - 0xf1, 0x91, 0xa3, 0xde, 0xaa, 0xba, 0x68, 0xf3, 0x9b, 0xfa, 0xcc, 0xac, 0xed, 0xba, 0x7a, 0x2b, - 0x51, 0x29, 0x1b, 0x1c, 0x3b, 0x17, 0x16, 0xf9, 0x0f, 0xe1, 0xfa, 0xcc, 0x10, 0x53, 0x27, 0xb9, - 0xc8, 0xed, 0xd1, 0xc1, 0x06, 0xad, 0xdb, 0x56, 0xa1, 0xff, 0x31, 0x11, 0xa8, 0x11, 0x86, 0xff, - 0xa3, 0x06, 0x3d, 0xd2, 0xc3, 0xbf, 0x17, 0x1b, 0xbf, 0x17, 0x1b, 0x7f, 0x0b, 0xc4, 0xc6, 0xf0, - 0xef, 0x97, 0xa0, 0x71, 0x92, 0x44, 0x5e, 0xea, 0xca, 0x1f, 0xc9, 0xe9, 0xb3, 0x1c, 0x54, 0xf9, - 0x2e, 0x0e, 0xaa, 0x2e, 0xa8, 0xeb, 0x7f, 0x59, 0x82, 0x96, 0x9e, 0xc2, 0xd1, 0xee, 0x8f, 0x9c, - 0x44, 0x9e, 0xd3, 0x29, 0x2d, 0xcd, 0xe9, 0x7c, 0xe7, 0x2c, 0x90, 0xb1, 0x5e, 0xa8, 0x7c, 0x75, - 0x14, 0x2b, 0x9b, 0xaa, 0xa6, 0x18, 0x4b, 0x41, 0x9f, 0xc6, 0xb8, 0x77, 0xc3, 0x97, 0xd0, 0x22, - 0x87, 0x87, 0x24, 0xc3, 0x26, 0xd4, 0x13, 0x4a, 0x5a, 0xe8, 0x89, 0xea, 0xd6, 0x9b, 0xcf, 0x69, - 0xf9, 0xc7, 0x99, 0x7e, 0xff, 0xa1, 0x0c, 0x5d, 0xf2, 0x3e, 0x1f, 0xa7, 0xa1, 0x3a, 0x09, 0x59, - 0x0c, 0xab, 0x34, 0x1b, 0xc3, 0xaa, 0x26, 0xe8, 0x24, 0xaa, 0xd7, 0x74, 0xd4, 0x6b, 0xf6, 0xa3, - 0xe0, 0x80, 0x8f, 0x2c, 0xc2, 0xe0, 0x52, 0x39, 0xc9, 0x58, 0x2c, 0x4b, 0x7f, 0x21, 0x1c, 0xbf, - 0x2a, 0x76, 0x12, 0x67, 0x2a, 0x4c, 0xfa, 0x4b, 0xb5, 0x18, 0x83, 0x2a, 0x9d, 0x37, 0xb5, 0x2c, - 0xf4, 0xac, 0x03, 0x29, 0xc2, 0x0f, 0xc7, 0x99, 0xf0, 0x68, 0x52, 0xd6, 0x73, 0x1c, 0x70, 0x76, - 0x00, 0x4c, 0x45, 0x4d, 0x13, 0xee, 0xa0, 0x0a, 0xa2, 0x71, 0x48, 0x82, 0xb4, 0x77, 0x37, 0xd5, - 0x6b, 0x69, 0x2d, 0x2d, 0x42, 0x9f, 0x20, 0xd6, 0xea, 0xfb, 0x73, 0x90, 0x25, 0x8b, 0xa9, 0xf4, - 0x50, 0xe6, 0x7d, 0x7c, 0xef, 0xc5, 0x24, 0xe5, 0x44, 0x8b, 0xb9, 0x07, 0x1b, 0x26, 0x21, 0x81, - 0xe2, 0x62, 0x17, 0xcf, 0x02, 0xb9, 0xb1, 0xe6, 0x1b, 0x4b, 0x85, 0x6f, 0x5c, 0x87, 0x5a, 0xb1, - 0x82, 0x41, 0x35, 0x86, 0xb7, 0xa0, 0x3d, 0xf2, 0x03, 0xae, 0x43, 0x81, 0xb8, 0x68, 0x3a, 0x28, - 0x58, 0xa2, 0x1c, 0xbe, 0x6e, 0x0d, 0xff, 0xbc, 0x04, 0x5b, 0xb1, 0x93, 0x3c, 0x4f, 0xb9, 0xa4, - 0x80, 0x20, 0x25, 0xb0, 0x6c, 0x31, 0x71, 0x12, 0x0f, 0x0f, 0x0e, 0x0d, 0xa1, 0x46, 0x57, 0x49, - 0xf5, 0x16, 0x42, 0xd4, 0x5c, 0x6e, 0xc3, 0x4a, 0xa1, 0x87, 0x74, 0x12, 0x13, 0xe4, 0xe9, 0x26, - 0xd1, 0x4b, 0xca, 0x43, 0x9e, 0x22, 0x10, 0x1d, 0xca, 0x9c, 0x8e, 0x93, 0xb6, 0xa1, 0xdc, 0xb4, - 0xa1, 0x7a, 0x14, 0x7a, 0x78, 0x72, 0xc2, 0x74, 0xaa, 0x62, 0x20, 0xaa, 0xce, 0xa1, 0x11, 0xa6, - 0x53, 0x0a, 0x7b, 0xac, 0x43, 0xed, 0xfc, 0x4a, 0x92, 0xb5, 0x8e, 0x70, 0xd5, 0x18, 0xfe, 0x65, - 0x0d, 0xd6, 0x0e, 0x5d, 0x7e, 0xce, 0x93, 0xf1, 0x81, 0x23, 0x9d, 0xc7, 0x7e, 0xc0, 0xcf, 0x1c, - 0x71, 0x81, 0x1b, 0x4e, 0x73, 0x8e, 0x1d, 0x39, 0xd1, 0xab, 0xd4, 0x44, 0xc0, 0x89, 0x23, 0x27, - 0xa8, 0x0a, 0x08, 0x39, 0x8a, 0x92, 0xa9, 0x0e, 0x49, 0xb5, 0x2c, 0xfa, 0xc6, 0xc7, 0x04, 0xc9, - 0x7a, 0x0b, 0xff, 0x15, 0xd7, 0x55, 0x19, 0xd4, 0x9b, 0x72, 0x89, 0xef, 0x43, 0x27, 0xe1, 0x6e, - 0x94, 0x78, 0x3a, 0x6a, 0xaa, 0xe6, 0xd9, 0x56, 0x30, 0x15, 0x2f, 0xbd, 0x03, 0x79, 0x68, 0xdf, - 0x16, 0x31, 0xa7, 0x6a, 0x04, 0x15, 0x5a, 0x5a, 0xc9, 0x10, 0xb8, 0xf3, 0x87, 0x1e, 0xfb, 0xbb, - 0xd0, 0xcf, 0x69, 0x29, 0xce, 0x6c, 0xdc, 0x8b, 0xdd, 0x3c, 0x72, 0xb2, 0xe4, 0x13, 0x77, 0x4e, - 0x4c, 0xaf, 0xbf, 0x43, 0x9d, 0x54, 0x2c, 0x3d, 0x1f, 0x5e, 0x41, 0xd9, 0x07, 0xd0, 0x15, 0x71, - 0xe0, 0x4b, 0xcd, 0x00, 0x42, 0xd7, 0x6e, 0x74, 0x08, 0xa8, 0xc2, 0xc1, 0x62, 0xd9, 0x16, 0x36, - 0xbf, 0xd7, 0x16, 0xb6, 0x16, 0xb7, 0xf0, 0x27, 0xd0, 0x77, 0x13, 0xee, 0xf1, 0x50, 0xfa, 0x4e, - 0x60, 0x0b, 0x37, 0x8a, 0x8d, 0xea, 0x5b, 0xc9, 0xe1, 0xa7, 0x08, 0x66, 0x3f, 0x85, 0x2d, 0x37, - 0x0a, 0x25, 0x0f, 0xa5, 0x2d, 0xf8, 0xf3, 0x94, 0x87, 0x2e, 0xb7, 0xc3, 0x74, 0x7a, 0xce, 0x13, - 0x9d, 0x26, 0xdd, 0xd0, 0xe8, 0x53, 0x8d, 0x7d, 0x42, 0x48, 0x76, 0x1f, 0xd6, 0xd5, 0xf6, 0xcc, - 0x75, 0x52, 0x89, 0x39, 0x46, 0x3b, 0x35, 0xdb, 0x63, 0x07, 0xd6, 0x26, 0x8e, 0xb0, 0x13, 0x2e, - 0x7c, 0x2f, 0x75, 0x02, 0x7d, 0x42, 0x75, 0x02, 0x61, 0x75, 0xe2, 0x08, 0x4b, 0x63, 0x74, 0x54, - 0xe7, 0x3e, 0xac, 0xcf, 0xd1, 0xda, 0x13, 0x47, 0x4c, 0xc8, 0x7d, 0x6e, 0x59, 0x2c, 0x99, 0xa1, - 0xfe, 0xd2, 0x11, 0x93, 0x6b, 0x0f, 0x61, 0x7d, 0xd9, 0x86, 0x7c, 0x57, 0x6e, 0xa1, 0x55, 0xc8, - 0x2d, 0xe8, 0x0a, 0xa6, 0xff, 0x59, 0x86, 0x0d, 0xb3, 0xdf, 0x64, 0xf8, 0x65, 0x4c, 0x7d, 0x83, - 0x74, 0x24, 0x1a, 0x8b, 0x99, 0x2f, 0xdd, 0xb2, 0x40, 0x81, 0xc8, 0x71, 0xde, 0x86, 0xbe, 0x26, - 0xc8, 0x99, 0x5f, 0xbd, 0xa5, 0xe7, 0x65, 0x43, 0xd1, 0x11, 0xa0, 0x0f, 0x1c, 0xf1, 0x04, 0xd7, - 0xc8, 0xa3, 0xda, 0x33, 0xea, 0x42, 0xcc, 0x4e, 0x1f, 0x68, 0x70, 0x86, 0xe5, 0xd8, 0x5d, 0x60, - 0xfc, 0x79, 0xea, 0x04, 0xbe, 0xbc, 0xb2, 0x47, 0x3e, 0x0f, 0x3c, 0x4a, 0x64, 0xa9, 0xf2, 0x95, - 0xbe, 0xc1, 0x3c, 0x46, 0xc4, 0xa1, 0x27, 0x0a, 0x33, 0xd1, 0xf9, 0x91, 0xec, 0x00, 0xe8, 0x99, - 0x9c, 0x12, 0xf8, 0xd0, 0x5b, 0x7e, 0x56, 0xea, 0xcb, 0xcf, 0xca, 0x47, 0xb0, 0x32, 0xbf, 0xe7, - 0x2a, 0x67, 0xd1, 0x13, 0xb3, 0xfb, 0xbd, 0x8c, 0x09, 0x9b, 0x4b, 0x99, 0x50, 0x2f, 0xfa, 0xff, - 0x2e, 0xc3, 0xba, 0x5e, 0xf4, 0xfd, 0x28, 0x48, 0xa7, 0xa8, 0x6d, 0x63, 0x3f, 0x1c, 0xa3, 0x42, - 0x9e, 0x46, 0xca, 0x2c, 0x29, 0x88, 0x3f, 0x98, 0x46, 0x99, 0x2c, 0xde, 0x86, 0xbe, 0xaf, 0x7a, - 0x66, 0xeb, 0x62, 0x8a, 0xc8, 0x34, 0x5c, 0xaf, 0x0a, 0x72, 0xa1, 0x08, 0x9d, 0x58, 0x4c, 0x22, - 0xa9, 0x49, 0x49, 0x88, 0xab, 0x35, 0x5f, 0x35, 0x28, 0xa2, 0x26, 0xeb, 0xf0, 0x2e, 0x30, 0x37, - 0x4d, 0x12, 0x3c, 0x1f, 0x05, 0x72, 0x95, 0x47, 0xe8, 0x6b, 0x4c, 0x4e, 0xfd, 0x01, 0x34, 0xa6, - 0x51, 0x6e, 0x11, 0xcc, 0x18, 0x77, 0x56, 0x7d, 0x1a, 0x11, 0x87, 0x5c, 0x43, 0xab, 0xe5, 0x79, - 0xea, 0x27, 0xdc, 0x33, 0x7a, 0xd0, 0xb4, 0xb5, 0x92, 0x9c, 0xf8, 0x9e, 0xc7, 0x43, 0x1d, 0xc3, - 0x6e, 0xfa, 0xe2, 0x4b, 0x6a, 0xe3, 0x36, 0x79, 0x7c, 0xe4, 0xa4, 0x81, 0xb4, 0xc3, 0x34, 0xa0, - 0x53, 0x11, 0xe8, 0x2a, 0xa1, 0x15, 0x8d, 0x78, 0x92, 0x06, 0x78, 0x22, 0x02, 0xbd, 0xa5, 0xa4, - 0x4b, 0x90, 0x05, 0xed, 0x89, 0x1f, 0x4a, 0x12, 0x15, 0x2d, 0xda, 0x52, 0x44, 0x20, 0x13, 0x7e, - 0xe9, 0x87, 0x72, 0xf8, 0x67, 0x65, 0xd8, 0xd4, 0x0b, 0x7f, 0xaa, 0x17, 0x40, 0xeb, 0x47, 0xb2, - 0xd8, 0xcd, 0x72, 0xe9, 0x14, 0x43, 0xc5, 0x02, 0x03, 0x3a, 0xa4, 0x09, 0xe7, 0xdc, 0x55, 0xd6, - 0xd5, 0x43, 0x86, 0xaf, 0xee, 0x02, 0x5b, 0xe0, 0x2b, 0xa1, 0x63, 0x46, 0xfd, 0x39, 0xc6, 0x12, - 0xec, 0x33, 0xd8, 0x9c, 0x72, 0xe9, 0xd0, 0x41, 0x08, 0x22, 0xd7, 0xa1, 0x5e, 0x74, 0xe4, 0xd5, - 0x72, 0xaf, 0x1b, 0xec, 0x91, 0x46, 0xe2, 0xa1, 0xc7, 0x77, 0x4c, 0x9d, 0xd0, 0x1f, 0x71, 0x21, - 0x49, 0xcf, 0xab, 0x1e, 0xca, 0xf0, 0xe8, 0x1b, 0x0c, 0x6a, 0x72, 0xa2, 0x26, 0x8b, 0x71, 0xa4, - 0x36, 0xb1, 0x4e, 0x34, 0x8d, 0x84, 0x8f, 0xf4, 0xde, 0x75, 0x71, 0xaf, 0x42, 0x3f, 0x1c, 0xab, - 0x32, 0xc8, 0x86, 0xb2, 0xe9, 0x0c, 0xf0, 0x38, 0xf2, 0xf8, 0xf0, 0x4f, 0xab, 0x19, 0x8f, 0x9e, - 0x68, 0xf8, 0xa9, 0x74, 0xa4, 0x60, 0xb7, 0xa0, 0x97, 0x4d, 0x5e, 0xe9, 0x48, 0xb5, 0x56, 0x5d, - 0x03, 0x7d, 0x88, 0x40, 0x64, 0xbf, 0xd9, 0xd9, 0x2a, 0xda, 0xb2, 0xca, 0xfa, 0x15, 0xa7, 0xab, - 0xe8, 0x71, 0x58, 0x43, 0xaf, 0x48, 0x75, 0x81, 0xa2, 0x81, 0x2a, 0xb2, 0x4f, 0xf2, 0x45, 0x10, - 0xb6, 0xe0, 0x81, 0x2a, 0x60, 0xa9, 0xce, 0x8e, 0x2a, 0x4e, 0x35, 0x02, 0x8f, 0x66, 0x4e, 0x1e, - 0x27, 0x69, 0xc8, 0x3d, 0xad, 0xd2, 0x57, 0x32, 0xf8, 0x09, 0x81, 0x71, 0xc2, 0x99, 0x64, 0x2a, - 0x0c, 0x5d, 0x57, 0x43, 0x7b, 0x5a, 0x32, 0xe5, 0x43, 0x23, 0x8f, 0xe6, 0xf4, 0x7a, 0x6c, 0x25, - 0x20, 0x56, 0x32, 0x6a, 0x3d, 0xf6, 0xcf, 0x60, 0x90, 0xd1, 0xaa, 0xaf, 0xcb, 0x5f, 0xd0, 0x54, - 0xca, 0xc7, 0x74, 0xa1, 0xcf, 0xcc, 0x5e, 0xf2, 0x29, 0x6c, 0xce, 0x77, 0xd4, 0x6f, 0x6a, 0x51, - 0xb7, 0xb5, 0x99, 0x6e, 0xf9, 0x97, 0x64, 0xfb, 0xeb, 0x3a, 0xee, 0x84, 0xdb, 0x13, 0x5f, 0xaa, - 0x44, 0x7a, 0xc5, 0x5a, 0x35, 0xa8, 0x7d, 0xc4, 0x7c, 0xe9, 0x4b, 0xb1, 0x84, 0x7e, 0xea, 0x0b, - 0xa1, 0xb5, 0xe2, 0x2c, 0xfd, 0xb1, 0x2f, 0xc4, 0xf0, 0x9f, 0x00, 0x74, 0x8c, 0xa5, 0x48, 0x25, - 0x77, 0x77, 0x8b, 0x46, 0x77, 0x7b, 0xb7, 0x6f, 0xac, 0x67, 0x24, 0xd9, 0x93, 0x32, 0x31, 0x69, - 0x07, 0x65, 0x8c, 0xcf, 0xd8, 0x3b, 0x65, 0x32, 0x10, 0x72, 0x7b, 0x67, 0x0f, 0x56, 0x0b, 0x16, - 0xa4, 0x2d, 0x23, 0xe9, 0x04, 0xda, 0x28, 0x2f, 0x94, 0x75, 0x14, 0x48, 0xac, 0x15, 0x6c, 0x28, - 0xdb, 0xe2, 0x0c, 0xa9, 0xd1, 0xd8, 0x77, 0xa3, 0xc0, 0x14, 0x88, 0xcd, 0x19, 0xfb, 0x88, 0xa1, - 0x84, 0x75, 0xc2, 0xd1, 0x77, 0x14, 0xcf, 0x03, 0x7d, 0x82, 0x5a, 0x0a, 0x72, 0xfa, 0x3c, 0xc8, - 0x26, 0x48, 0xc6, 0x74, 0x9d, 0xfc, 0x08, 0x9a, 0x20, 0xf9, 0x54, 0x9f, 0x40, 0x3b, 0x4a, 0xfc, - 0xb1, 0x4f, 0x19, 0x2b, 0x65, 0xe0, 0xcc, 0xbf, 0x04, 0x14, 0xc1, 0x3e, 0xbe, 0x6a, 0x08, 0x75, - 0xad, 0xfe, 0x17, 0x93, 0xd8, 0x1a, 0x83, 0x06, 0x91, 0x90, 0x89, 0xef, 0x4a, 0x9c, 0x8e, 0x3a, - 0x91, 0xaa, 0xd6, 0xa8, 0xab, 0xc0, 0xa7, 0xcf, 0x03, 0x4a, 0xda, 0xdd, 0x86, 0x15, 0x97, 0xd4, - 0x85, 0x3a, 0x50, 0x01, 0x0f, 0x69, 0x4f, 0x6b, 0x56, 0x57, 0x81, 0x71, 0x7e, 0x47, 0x3c, 0xd4, - 0x75, 0x4d, 0x4e, 0x10, 0xa0, 0xc7, 0x18, 0x39, 0x9e, 0x4e, 0x5b, 0x77, 0x0c, 0xf0, 0x28, 0x72, - 0x3c, 0xf6, 0x73, 0xb8, 0x86, 0x38, 0x9b, 0x4f, 0x63, 0x79, 0x85, 0xfa, 0x8d, 0x27, 0xbe, 0x6b, - 0x3b, 0xc2, 0x7e, 0xc5, 0x93, 0x48, 0x57, 0x42, 0x6c, 0x22, 0xc5, 0x23, 0x24, 0x78, 0xa2, 0xf0, - 0x7b, 0xe2, 0x1b, 0x9e, 0x44, 0xec, 0x1b, 0x4a, 0xdc, 0x2d, 0x33, 0xdf, 0x8d, 0xab, 0xff, 0x7e, - 0xbe, 0x57, 0xaf, 0xa1, 0xa4, 0x32, 0x11, 0x44, 0x58, 0xc6, 0xe8, 0xa3, 0xfe, 0xec, 0x2b, 0x60, - 0x46, 0xc1, 0x11, 0xe7, 0x4b, 0x47, 0x5c, 0x08, 0x8a, 0x02, 0xb4, 0x77, 0xdf, 0x7d, 0xa3, 0x8d, - 0x6a, 0x19, 0xcd, 0x88, 0x40, 0x04, 0x08, 0xf6, 0x27, 0xb0, 0x9e, 0x0d, 0xa6, 0x6d, 0x19, 0x1a, - 0x4e, 0x05, 0x09, 0x6e, 0x2c, 0x0e, 0x37, 0x63, 0x02, 0x59, 0x66, 0x26, 0x0a, 0xac, 0x86, 0xfc, - 0x35, 0xac, 0x98, 0x21, 0xd5, 0xaa, 0x8b, 0x41, 0x9f, 0x46, 0x7b, 0x6f, 0x61, 0xb4, 0x19, 0xdd, - 0x9e, 0xe9, 0x67, 0x05, 0xc5, 0x0f, 0xcd, 0x34, 0xb9, 0xd1, 0x32, 0x83, 0x55, 0xe2, 0x91, 0x9b, - 0x0b, 0x23, 0xcd, 0x29, 0x2b, 0xcb, 0x4c, 0xc1, 0xc0, 0xd9, 0x03, 0xd8, 0x30, 0x83, 0x45, 0x94, - 0x67, 0xb5, 0xfd, 0x88, 0x52, 0xb0, 0x4c, 0x99, 0x58, 0x1a, 0xa9, 0x72, 0xb0, 0x87, 0x91, 0xc5, - 0x47, 0xec, 0x97, 0x70, 0xdd, 0x74, 0x51, 0x5a, 0x98, 0x3c, 0xd2, 0xec, 0xa3, 0xd6, 0x48, 0x77, - 0x0d, 0x34, 0x89, 0xd2, 0xcb, 0xe8, 0x81, 0x9a, 0xe9, 0x6f, 0x43, 0x9f, 0xaa, 0x3d, 0x71, 0x5b, - 0xa3, 0xc4, 0xf3, 0x43, 0x27, 0x18, 0xac, 0x13, 0xd7, 0xf4, 0x10, 0x6e, 0x45, 0x2f, 0x9f, 0x2a, - 0x28, 0x3b, 0x83, 0x4d, 0xf3, 0xa2, 0x4c, 0xcc, 0x08, 0x54, 0x25, 0x14, 0x76, 0x5c, 0xb6, 0x70, - 0x33, 0x0a, 0xc7, 0x32, 0x5b, 0x38, 0xab, 0x86, 0x0e, 0xe0, 0xc6, 0xdc, 0xd6, 0x4e, 0x9d, 0x4b, - 0x7b, 0xca, 0xa7, 0x51, 0x72, 0xa5, 0x15, 0xc8, 0x26, 0x09, 0xb0, 0xeb, 0x33, 0x9b, 0x78, 0xec, - 0x5c, 0x1e, 0x13, 0x8d, 0x52, 0x27, 0xbf, 0x82, 0x77, 0xe6, 0x46, 0x51, 0xc5, 0x93, 0x3c, 0x74, - 0xce, 0x03, 0xee, 0x0d, 0xb6, 0xe8, 0x8b, 0xde, 0x9e, 0x19, 0xe2, 0x14, 0x29, 0x1e, 0x29, 0x02, - 0x6d, 0xd0, 0xb9, 0x00, 0xea, 0xe6, 0x00, 0x89, 0xc3, 0x8f, 0xa0, 0x21, 0xcf, 0x03, 0x2a, 0xc2, - 0x29, 0x2d, 0x2d, 0xc2, 0xa9, 0xcb, 0x73, 0x14, 0x14, 0x05, 0xff, 0x58, 0xa9, 0x45, 0xdd, 0x42, - 0xa3, 0x3d, 0xf0, 0xa7, 0xbe, 0xd4, 0x2a, 0x50, 0x35, 0x86, 0xe7, 0xd0, 0xa2, 0x11, 0xe8, 0x1d, - 0x59, 0xb5, 0x6c, 0xe9, 0xcd, 0xd5, 0xb2, 0x9f, 0x40, 0x47, 0xbb, 0x14, 0xaf, 0x2b, 0xbf, 0x6d, - 0x2b, 0x3c, 0x3e, 0x8b, 0xe1, 0x5d, 0x68, 0x91, 0x3f, 0x41, 0xef, 0xb8, 0x01, 0x6d, 0xaa, 0xeb, - 0xb2, 0xcf, 0x83, 0xc8, 0xbd, 0x30, 0x1e, 0x00, 0x81, 0x1e, 0x22, 0x64, 0x08, 0xd0, 0x7c, 0x16, - 0xfa, 0x51, 0xb8, 0x17, 0x04, 0xc3, 0xbf, 0xaa, 0x43, 0x0b, 0x0d, 0x0f, 0x0a, 0xce, 0xa0, 0xef, - 0x46, 0xdc, 0x41, 0x09, 0xdb, 0xa9, 0x13, 0xeb, 0x7a, 0xe0, 0x36, 0x02, 0x91, 0xea, 0xd8, 0x89, - 0xe7, 0xf2, 0xb9, 0xe5, 0xb9, 0x7c, 0xee, 0xfb, 0xea, 0x2a, 0x89, 0xaa, 0x2c, 0xe3, 0xa6, 0xc0, - 0x94, 0x06, 0x78, 0xa8, 0x40, 0x68, 0x10, 0x11, 0x89, 0x13, 0x90, 0x11, 0x85, 0x2e, 0x5a, 0x20, - 0x74, 0xea, 0x97, 0x98, 0x73, 0x4f, 0x23, 0x4e, 0xb9, 0x12, 0xfa, 0x85, 0x88, 0x5c, 0x6d, 0x3e, - 0x22, 0x77, 0x07, 0xc0, 0x8d, 0x42, 0x8f, 0xec, 0xb4, 0xb9, 0x94, 0x9b, 0xca, 0xbb, 0xe6, 0xd8, - 0xef, 0x11, 0xff, 0xfd, 0x08, 0xfa, 0x19, 0x05, 0x9a, 0x61, 0x6e, 0x98, 0x39, 0xb9, 0x9a, 0xca, - 0xe2, 0xa3, 0xfd, 0x50, 0xce, 0x07, 0x8a, 0x5b, 0x0b, 0x81, 0xe2, 0x5f, 0xc3, 0xda, 0x5c, 0xa4, - 0x07, 0xcd, 0x4b, 0x5d, 0x72, 0xfa, 0x43, 0x6e, 0x39, 0xbc, 0x0d, 0x4d, 0xaa, 0xe0, 0xf1, 0xd2, - 0x58, 0x2b, 0x84, 0x86, 0x2f, 0x28, 0xa0, 0xff, 0xba, 0x60, 0x74, 0xe7, 0xff, 0x57, 0x30, 0xba, - 0xfb, 0xfd, 0x82, 0xd1, 0xbd, 0xef, 0x17, 0x8c, 0x9e, 0x0b, 0xde, 0xae, 0xcc, 0xe7, 0x7c, 0x5e, - 0x9b, 0x61, 0xe9, 0xbf, 0x36, 0xc3, 0xf2, 0x1d, 0xe9, 0x91, 0xd5, 0x37, 0xa6, 0x47, 0xbe, 0x47, - 0x7e, 0x86, 0x7d, 0x57, 0x7e, 0xe6, 0x36, 0xac, 0xc8, 0xc4, 0x71, 0x2f, 0x94, 0xbb, 0x73, 0xc1, - 0xaf, 0x84, 0xce, 0x07, 0x75, 0x09, 0x8c, 0xce, 0xce, 0x57, 0xfc, 0x4a, 0x0c, 0x9f, 0x01, 0x90, - 0x1f, 0x48, 0x9f, 0xf6, 0x3a, 0xde, 0x28, 0xfd, 0x50, 0xde, 0x18, 0xfe, 0x9f, 0x12, 0xc0, 0xa9, - 0x33, 0x8d, 0x55, 0x20, 0x95, 0xfd, 0x31, 0xb4, 0x05, 0xb5, 0x8a, 0x69, 0xf4, 0x82, 0xb6, 0xcc, - 0x49, 0xf5, 0x23, 0x79, 0x7d, 0x20, 0xb2, 0x67, 0x62, 0x6b, 0x35, 0x42, 0x56, 0xe0, 0x56, 0x33, - 0x04, 0x14, 0x60, 0xbb, 0x05, 0x3d, 0x4d, 0x10, 0xf3, 0xc4, 0xe5, 0xa1, 0x92, 0x75, 0x25, 0xab, - 0xab, 0xa0, 0x27, 0x0a, 0xc8, 0x1e, 0x64, 0x64, 0x46, 0x2f, 0x2d, 0xe6, 0x82, 0x74, 0x17, 0xad, - 0x98, 0x86, 0xbb, 0xe6, 0x53, 0x68, 0x22, 0x4d, 0xa8, 0xe2, 0xfb, 0xfa, 0x6f, 0xb1, 0x36, 0x34, - 0xf4, 0xa8, 0xfd, 0x12, 0xeb, 0x42, 0x8b, 0x6e, 0x92, 0x10, 0xae, 0x3c, 0xfc, 0x47, 0xab, 0xd0, - 0x3e, 0x0c, 0x85, 0x4c, 0x52, 0xc5, 0xc2, 0xf9, 0x85, 0x89, 0x1a, 0x5d, 0x98, 0xd0, 0xb5, 0x92, - 0xea, 0x33, 0xa8, 0x56, 0xf2, 0x13, 0x68, 0xe8, 0xab, 0x39, 0x3a, 0xba, 0xbe, 0xf4, 0x5e, 0x8f, - 0xa1, 0x61, 0x3b, 0xd0, 0xf4, 0xf4, 0x9d, 0x21, 0x5d, 0x2b, 0x50, 0xb8, 0xc8, 0x63, 0x6e, 0x13, - 0x59, 0x19, 0x0d, 0x7b, 0x1f, 0x2a, 0xce, 0x78, 0xac, 0x5d, 0xeb, 0x95, 0x9c, 0x94, 0x2c, 0x25, - 0x0b, 0x71, 0xec, 0x1e, 0xb4, 0x48, 0x7c, 0x52, 0xb9, 0x4c, 0x7d, 0x7e, 0x4c, 0x53, 0x8b, 0xa3, - 0x24, 0x2a, 0x05, 0xe6, 0xef, 0x41, 0x2b, 0x88, 0xa2, 0x58, 0x75, 0x68, 0xcc, 0x77, 0x30, 0x15, - 0x14, 0x56, 0x33, 0x30, 0xb5, 0x14, 0xb7, 0xa1, 0x8e, 0x36, 0x78, 0x14, 0x6b, 0xdb, 0xb5, 0x30, - 0x0f, 0xaa, 0x24, 0xb0, 0x6a, 0x02, 0x7f, 0xd8, 0x2e, 0x80, 0xe2, 0x7f, 0x1a, 0xb9, 0x35, 0xbf, - 0x1c, 0x59, 0xd2, 0x10, 0x0f, 0xa9, 0xc9, 0x1f, 0x3e, 0x84, 0xbe, 0x4a, 0x10, 0x15, 0x7a, 0x82, - 0xa9, 0x0d, 0x34, 0x3d, 0x67, 0x73, 0x8e, 0x56, 0x2f, 0x99, 0xcd, 0x41, 0x7e, 0x0c, 0x8d, 0x58, - 0x65, 0x48, 0x48, 0xc2, 0xb4, 0x77, 0x57, 0xf3, 0xae, 0x3a, 0x75, 0x62, 0x19, 0x0a, 0xf6, 0x47, - 0xd0, 0x53, 0x35, 0x6c, 0x23, 0x9d, 0x2a, 0xa0, 0xf0, 0xda, 0xcc, 0x95, 0x90, 0x99, 0x4c, 0x82, - 0xd5, 0x95, 0x33, 0x89, 0x85, 0x5f, 0x40, 0x37, 0x2f, 0xd1, 0x77, 0x9d, 0x90, 0xe4, 0x0e, 0x85, - 0xec, 0x4d, 0xf7, 0xa2, 0x4b, 0x64, 0x75, 0x78, 0xd1, 0x41, 0xda, 0x86, 0xba, 0xae, 0xab, 0xec, - 0x53, 0xaf, 0xc2, 0x45, 0x4e, 0x55, 0x49, 0x65, 0x69, 0x3c, 0xae, 0x65, 0x5e, 0x32, 0x46, 0xd6, - 0xdb, 0xcc, 0x5a, 0x66, 0xf5, 0x62, 0x56, 0x2b, 0x2b, 0x15, 0x63, 0x8f, 0x66, 0x4b, 0xd8, 0x54, - 0xa9, 0xd6, 0x1a, 0x75, 0x7d, 0x7b, 0x49, 0x57, 0x55, 0xb1, 0x65, 0xad, 0xc4, 0x73, 0x95, 0x70, - 0x77, 0xa1, 0x19, 0x25, 0x1e, 0xd5, 0xd0, 0x52, 0x42, 0x99, 0xd6, 0x93, 0x2a, 0xf7, 0xd4, 0x7d, - 0x24, 0x12, 0x1e, 0x8d, 0x48, 0x35, 0xd0, 0xb0, 0x88, 0x93, 0x88, 0x4c, 0x4d, 0x12, 0x71, 0x1b, - 0x8b, 0x86, 0x85, 0xc6, 0x93, 0x80, 0xfb, 0x10, 0x1a, 0xa6, 0x5a, 0x74, 0x73, 0x81, 0xd2, 0xa0, - 0xd8, 0xa7, 0xb0, 0x32, 0x2b, 0xd0, 0xc4, 0x60, 0x6b, 0x81, 0xba, 0x37, 0x23, 0xbf, 0x50, 0x1b, - 0x6b, 0x6b, 0x69, 0xb0, 0xe0, 0x61, 0x29, 0x04, 0x3a, 0x61, 0xda, 0xce, 0x7a, 0x7b, 0xd1, 0x09, - 0xd3, 0x36, 0xd7, 0x00, 0x1a, 0xbe, 0x78, 0xec, 0x27, 0x42, 0x0e, 0xae, 0x19, 0xed, 0x48, 0x4d, - 0xb4, 0xd2, 0x7c, 0x81, 0x6a, 0x62, 0x70, 0xdd, 0xdc, 0x60, 0x23, 0xa5, 0x71, 0x07, 0xea, 0xba, - 0x92, 0xf6, 0xe6, 0xc2, 0x89, 0xd6, 0xd5, 0xe7, 0x96, 0xa6, 0x60, 0x3f, 0x81, 0x06, 0x95, 0x51, - 0x46, 0xf1, 0xe0, 0xfd, 0x79, 0x0e, 0x50, 0xb5, 0x8c, 0x56, 0x3d, 0x50, 0x35, 0x8d, 0x1f, 0x43, - 0xc3, 0x18, 0x29, 0xc3, 0x79, 0xae, 0xd6, 0xc6, 0x8a, 0x65, 0x28, 0xd8, 0x2d, 0xa8, 0x4d, 0x51, - 0x8e, 0x0d, 0x3e, 0x98, 0x3f, 0xa1, 0x4a, 0xbc, 0x29, 0x2c, 0xfb, 0x1c, 0xda, 0x82, 0xec, 0x53, - 0xc5, 0xba, 0x1f, 0x9a, 0x12, 0xc4, 0xd9, 0x6b, 0xaf, 0xc4, 0xb8, 0x20, 0x72, 0x43, 0xf6, 0xef, - 0xc1, 0xb5, 0x62, 0xfd, 0xa2, 0x29, 0x6e, 0xd4, 0xc1, 0xc9, 0x5b, 0x34, 0xca, 0xfb, 0x4b, 0x38, - 0x6c, 0xb6, 0x0c, 0xd2, 0xda, 0x8a, 0x5f, 0x53, 0x1f, 0xf9, 0x79, 0xa6, 0x25, 0xf0, 0x50, 0x0e, - 0x6e, 0x2f, 0x4c, 0x2b, 0xd3, 0x33, 0x46, 0x77, 0x90, 0x7a, 0xfa, 0x02, 0x3a, 0xa3, 0xf4, 0xd5, - 0xab, 0x2b, 0x13, 0x58, 0xff, 0x88, 0xfa, 0x15, 0xc2, 0x03, 0x85, 0x92, 0x49, 0xab, 0x3d, 0x2a, - 0xd4, 0x4f, 0x6e, 0x41, 0xc3, 0x0d, 0x6d, 0xc7, 0xf3, 0x92, 0xc1, 0xb6, 0x2a, 0x99, 0x74, 0xc3, - 0x3d, 0xcf, 0xa3, 0xbb, 0xbb, 0x51, 0xcc, 0xe9, 0x52, 0x9d, 0xed, 0x7b, 0x83, 0x9f, 0x28, 0x7d, - 0x65, 0x40, 0x87, 0x1e, 0x5d, 0xee, 0x35, 0x3e, 0xb5, 0xef, 0x0d, 0xee, 0xe8, 0xcb, 0xbd, 0x1a, - 0x74, 0xe8, 0xa1, 0xbd, 0x8a, 0x0e, 0x88, 0x81, 0x0c, 0x3e, 0x56, 0xc9, 0x8a, 0xa9, 0x73, 0x79, - 0xa2, 0x41, 0x78, 0xb6, 0x55, 0xea, 0x8f, 0xa4, 0xdd, 0xdd, 0xf9, 0xb3, 0x9d, 0xa5, 0x50, 0xad, - 0x96, 0x9f, 0x65, 0x53, 0x49, 0x1e, 0x90, 0x04, 0xb3, 0x83, 0xdd, 0xc1, 0x27, 0x8b, 0xf2, 0x40, - 0x67, 0x88, 0x51, 0x1e, 0x98, 0x64, 0xf1, 0x2e, 0x80, 0x12, 0x75, 0xb4, 0xd9, 0x3b, 0xf3, 0x7d, - 0x32, 0x27, 0xc2, 0x52, 0xb7, 0x05, 0x68, 0xab, 0x77, 0x01, 0x28, 0x35, 0xa0, 0xfa, 0xdc, 0x9b, - 0xef, 0x93, 0x39, 0x05, 0x56, 0xeb, 0x45, 0xe6, 0x1f, 0xdc, 0x83, 0x56, 0x8a, 0xe6, 0x3f, 0x1a, - 0xe0, 0x83, 0xfb, 0xf3, 0x67, 0xc0, 0x78, 0x06, 0x56, 0x33, 0xd5, 0x4f, 0xf8, 0x12, 0x52, 0x59, - 0x64, 0xbd, 0x0c, 0x1e, 0xcc, 0xbf, 0x24, 0x73, 0x1f, 0x2c, 0xd2, 0x6c, 0xca, 0x93, 0xf8, 0x1c, - 0xda, 0x6a, 0xd1, 0x54, 0xa7, 0xdd, 0x79, 0x1e, 0xc9, 0xcd, 0x21, 0x4b, 0xad, 0xae, 0xea, 0x76, - 0x0b, 0x6a, 0x4e, 0x1c, 0x07, 0x57, 0x83, 0x4f, 0xe7, 0x0f, 0xc6, 0x1e, 0x82, 0x2d, 0x85, 0x45, - 0x56, 0x9a, 0xa6, 0x81, 0xf4, 0x4d, 0x81, 0xff, 0x67, 0xf3, 0xac, 0x54, 0xb8, 0xff, 0x64, 0xb5, - 0xa7, 0x85, 0xcb, 0x50, 0x77, 0xa1, 0x19, 0x47, 0x42, 0xda, 0xde, 0x34, 0x18, 0x7c, 0xbe, 0xa0, - 0x7d, 0x54, 0x61, 0xbb, 0xd5, 0x88, 0xf5, 0xcd, 0x80, 0x99, 0x5b, 0x79, 0x3f, 0x9d, 0xbd, 0x95, - 0xa7, 0x7c, 0xc8, 0xdf, 0x54, 0x9b, 0xab, 0x7d, 0x36, 0xfc, 0x1c, 0x3a, 0x7b, 0x74, 0xe1, 0xde, - 0x17, 0x24, 0x37, 0x6f, 0x41, 0x35, 0x4b, 0xfa, 0x67, 0x02, 0x99, 0x28, 0x5e, 0xf1, 0xc3, 0x70, - 0x14, 0x59, 0x84, 0x1e, 0xfe, 0xfb, 0x2a, 0xd4, 0x4f, 0xa3, 0x34, 0x71, 0xf9, 0x77, 0xdf, 0x12, - 0x79, 0xd7, 0xb0, 0x47, 0x98, 0x97, 0x0e, 0x2b, 0x4e, 0x20, 0xf4, 0x7c, 0xd1, 0x63, 0x2b, 0xaf, - 0x27, 0x58, 0x87, 0x9a, 0x72, 0x05, 0x55, 0x98, 0x5a, 0x35, 0xe8, 0x68, 0xa4, 0x62, 0x42, 0xb7, - 0xea, 0x75, 0xe2, 0xa5, 0x6a, 0x81, 0x01, 0x1d, 0x7a, 0x14, 0x8f, 0x32, 0x04, 0x74, 0xf6, 0xea, - 0x3a, 0xde, 0xac, 0x81, 0x74, 0x02, 0x4d, 0xad, 0x42, 0xe3, 0x35, 0xb5, 0x0a, 0xef, 0x41, 0x35, - 0x34, 0x55, 0xed, 0x19, 0x9e, 0xae, 0x3f, 0x13, 0x9c, 0xdd, 0x81, 0xec, 0x6a, 0x8b, 0x36, 0x41, - 0x5e, 0x7f, 0xf5, 0x65, 0x17, 0x5a, 0xd9, 0x5f, 0x34, 0x68, 0xab, 0x63, 0x7d, 0x27, 0xff, 0xd3, - 0x86, 0x33, 0xf3, 0x64, 0xe5, 0x64, 0x6f, 0xce, 0xb8, 0xb7, 0x7f, 0x54, 0xc6, 0x5d, 0xbb, 0x64, - 0x6e, 0x14, 0x0a, 0xa9, 0x23, 0x6e, 0x0d, 0x5f, 0xec, 0x63, 0x93, 0xfd, 0x01, 0x74, 0x13, 0xee, - 0xbe, 0xb0, 0xa7, 0x62, 0xac, 0x5e, 0xd1, 0x2d, 0x5e, 0x96, 0x9b, 0x8a, 0xf1, 0x97, 0x54, 0x0d, - 0xa0, 0x3d, 0xa4, 0x36, 0xd2, 0x1e, 0x8b, 0x31, 0x8d, 0xfa, 0x31, 0xac, 0x4e, 0xf9, 0xf4, 0x9c, - 0x27, 0x62, 0xe2, 0xc7, 0x46, 0x46, 0xf6, 0xa8, 0x6a, 0xa1, 0x9f, 0x23, 0xd4, 0x5c, 0x86, 0xff, - 0xb8, 0x04, 0x4d, 0x5c, 0x45, 0xe4, 0x25, 0xc6, 0xa0, 0x3a, 0x75, 0xe3, 0x54, 0x1b, 0xbe, 0xf4, - 0xac, 0xff, 0xf6, 0x41, 0x71, 0x89, 0xfe, 0xdb, 0x07, 0xda, 0x43, 0x95, 0x47, 0xa2, 0x67, 0x75, - 0xe5, 0xfa, 0x8a, 0x42, 0x8d, 0x8a, 0x33, 0x4c, 0x93, 0x6d, 0x40, 0xdd, 0x0d, 0xc9, 0xfb, 0x55, - 0xf9, 0xb8, 0x9a, 0x1b, 0xa2, 0xd7, 0xab, 0xc0, 0x79, 0x89, 0x75, 0xcd, 0x0d, 0x0f, 0xbd, 0xcb, - 0xe1, 0xbf, 0x29, 0xc1, 0xea, 0x49, 0x12, 0xb9, 0x5c, 0x88, 0x23, 0x54, 0xdc, 0x94, 0xfb, 0xc0, - 0x37, 0x52, 0xa8, 0x58, 0xa5, 0x19, 0xe8, 0x19, 0x79, 0x58, 0x85, 0x26, 0x32, 0xf7, 0xa2, 0x62, - 0xb5, 0x08, 0x42, 0xde, 0x45, 0x86, 0x2e, 0xe4, 0xd4, 0x15, 0x9a, 0x82, 0xcc, 0xb7, 0xa0, 0x97, - 0x67, 0x6b, 0x0a, 0xe9, 0xff, 0xfc, 0x3a, 0x28, 0x8d, 0x72, 0x03, 0xda, 0xba, 0x48, 0x83, 0x86, - 0x51, 0x79, 0x03, 0x50, 0x20, 0x1c, 0x67, 0x38, 0x81, 0xfe, 0x49, 0xc2, 0x63, 0x27, 0xe1, 0x54, - 0x95, 0x41, 0x6b, 0xb8, 0x09, 0xf5, 0x80, 0x87, 0x63, 0x5d, 0x08, 0x50, 0xb1, 0x74, 0x2b, 0xfb, - 0x4b, 0x8e, 0x72, 0xe1, 0x2f, 0x39, 0x70, 0x2d, 0x13, 0xee, 0xe8, 0x7f, 0xee, 0xa0, 0x67, 0x3c, - 0x63, 0xe8, 0x03, 0x2a, 0x47, 0xa7, 0x69, 0xa9, 0xc6, 0xf0, 0x3f, 0x55, 0xa0, 0xad, 0x57, 0x86, - 0xde, 0xa2, 0x76, 0xa5, 0x94, 0xed, 0x4a, 0x1f, 0x2a, 0xe2, 0x79, 0xa0, 0xb7, 0x09, 0x1f, 0xd9, - 0xa7, 0x50, 0x09, 0xfc, 0xa9, 0x76, 0x4e, 0xae, 0xcf, 0x68, 0x8c, 0xd9, 0xf5, 0xd5, 0x2c, 0x84, - 0xd4, 0x28, 0xa6, 0xe8, 0xe6, 0x29, 0x32, 0xab, 0x5e, 0x13, 0x94, 0xde, 0x97, 0x78, 0x22, 0x70, - 0x51, 0x1d, 0x97, 0xaa, 0x10, 0xcc, 0x31, 0xef, 0x5a, 0x2d, 0x0d, 0x39, 0xf4, 0xd8, 0x67, 0xd0, - 0xcc, 0xe2, 0x98, 0xc6, 0x1d, 0x91, 0x97, 0xe1, 0xce, 0xfe, 0x93, 0xb3, 0xcb, 0xd0, 0x04, 0x2a, - 0xf5, 0xcb, 0x32, 0x4a, 0xf6, 0x47, 0xd0, 0x11, 0x5c, 0x08, 0x75, 0x99, 0x70, 0x14, 0xe9, 0xe3, - 0xbf, 0x51, 0xf4, 0x34, 0x08, 0x8b, 0x5f, 0x6d, 0x98, 0x5d, 0xe4, 0x20, 0xf6, 0x25, 0xf4, 0x4c, - 0xff, 0x20, 0x1a, 0x8f, 0xb3, 0x38, 0xfb, 0xf5, 0x85, 0x11, 0x8e, 0x08, 0x5d, 0x18, 0xa7, 0x2b, - 0x8a, 0x08, 0xf6, 0x6b, 0xe8, 0xc5, 0x6a, 0x33, 0x6d, 0x5d, 0xe9, 0xa3, 0xc4, 0xc8, 0xb5, 0x19, - 0x03, 0x67, 0x66, 0xb3, 0xf3, 0x0b, 0x42, 0x39, 0x5c, 0x2c, 0x5e, 0x93, 0x55, 0x89, 0x97, 0x99, - 0x6b, 0xb2, 0xc3, 0xff, 0x5c, 0x86, 0x76, 0xe1, 0xd3, 0xe8, 0xdf, 0x54, 0x04, 0x4f, 0x4c, 0x8d, - 0x0d, 0x3e, 0x23, 0x6c, 0x12, 0x09, 0x53, 0x32, 0x42, 0xcf, 0x08, 0x4b, 0xa2, 0x2c, 0x75, 0x4e, - 0xcf, 0xf8, 0x42, 0xed, 0x67, 0xaa, 0x8b, 0xcc, 0xb4, 0x73, 0x55, 0xab, 0x93, 0x03, 0x0f, 0x3d, - 0xfa, 0xdb, 0x15, 0x47, 0x3a, 0xe7, 0x8e, 0x30, 0xc5, 0x4a, 0x59, 0x1b, 0xcf, 0xef, 0x0b, 0x9e, - 0xe0, 0x5c, 0x4c, 0xaa, 0x50, 0x37, 0x91, 0x21, 0x48, 0xe4, 0xbd, 0x8a, 0x42, 0x95, 0x26, 0xec, - 0x58, 0x4d, 0x04, 0x7c, 0x13, 0x85, 0xd4, 0x4d, 0x6f, 0xbf, 0x4e, 0x77, 0x9b, 0x26, 0x0a, 0xb6, - 0xe7, 0x29, 0x47, 0x4b, 0xd1, 0xa3, 0xeb, 0x0e, 0x2d, 0xab, 0x41, 0x6d, 0x95, 0x81, 0x27, 0x4b, - 0xf8, 0xa5, 0xe3, 0x4b, 0xe2, 0xb3, 0x28, 0x95, 0x7a, 0x85, 0x56, 0x10, 0xf1, 0xb5, 0xe3, 0xcb, - 0x33, 0x05, 0x66, 0x0f, 0xf4, 0xe5, 0xa3, 0x22, 0xad, 0x8d, 0x66, 0xbc, 0x8a, 0x5f, 0xb1, 0x39, - 0xfa, 0x53, 0x2e, 0x87, 0xff, 0xbd, 0x04, 0xab, 0x0b, 0x1b, 0x8e, 0x76, 0x1f, 0x6e, 0xb6, 0x49, - 0xec, 0x76, 0xac, 0x3a, 0x36, 0x0f, 0x3d, 0x42, 0xc8, 0xa9, 0x34, 0x29, 0x5d, 0x44, 0xc8, 0x29, - 0x72, 0xf3, 0x06, 0xd4, 0xe5, 0x25, 0x2d, 0xa6, 0x3a, 0x9c, 0x35, 0x79, 0x89, 0xab, 0xb8, 0x87, - 0x3e, 0xf4, 0xd8, 0x0e, 0xf8, 0x0b, 0x1e, 0xd0, 0x32, 0xf7, 0x76, 0x3f, 0x7c, 0x03, 0xa7, 0xed, - 0x1c, 0x45, 0xe3, 0x23, 0xa4, 0x45, 0xaf, 0x5a, 0x3d, 0x0d, 0x7f, 0x03, 0x4d, 0x03, 0x65, 0x2d, - 0xa8, 0x1d, 0xf0, 0xf3, 0x74, 0xdc, 0x7f, 0x8b, 0x35, 0xa1, 0x8a, 0x3d, 0xfa, 0x25, 0x7c, 0xfa, - 0xda, 0x49, 0xc2, 0x7e, 0x19, 0xd1, 0x8f, 0x92, 0x24, 0x4a, 0xfa, 0x15, 0x7c, 0x3c, 0x71, 0x42, - 0xdf, 0xed, 0x57, 0xf1, 0xf1, 0xb1, 0x23, 0x9d, 0xa0, 0x5f, 0x1b, 0xfe, 0x79, 0x0d, 0x9a, 0x27, - 0xfa, 0xed, 0xec, 0x00, 0xba, 0xd9, 0xff, 0xcf, 0x2c, 0x8f, 0xdb, 0x9c, 0xcc, 0x3f, 0x50, 0xdc, - 0xa6, 0x13, 0x17, 0x5a, 0xf3, 0xff, 0x62, 0x53, 0x5e, 0xf8, 0x17, 0x9b, 0x77, 0xa0, 0xf2, 0x3c, - 0xb9, 0x9a, 0xad, 0x29, 0x3c, 0x09, 0x9c, 0xd0, 0x42, 0x30, 0x7b, 0x00, 0x6d, 0x4a, 0xdb, 0x08, - 0x32, 0x46, 0x74, 0xac, 0xa3, 0xf8, 0xdf, 0x46, 0x04, 0xb7, 0x00, 0x89, 0xb4, 0xc1, 0xb2, 0x03, - 0x4d, 0x77, 0xe2, 0x07, 0x5e, 0xc2, 0x43, 0x5d, 0xaf, 0xcb, 0x16, 0xa7, 0x6c, 0x65, 0x34, 0xec, - 0x8f, 0xa1, 0xef, 0xe7, 0xb1, 0x9a, 0x3c, 0x4b, 0x37, 0x23, 0x36, 0x0a, 0xd1, 0x1c, 0x6b, 0xa5, - 0x40, 0x4e, 0x1a, 0x32, 0xbf, 0xd4, 0xdb, 0x28, 0x5e, 0xea, 0x55, 0xff, 0x55, 0x42, 0x6a, 0xac, - 0x99, 0x79, 0x7a, 0xa8, 0xc5, 0x6e, 0x6b, 0xdb, 0xa3, 0x35, 0x6f, 0xe3, 0x1a, 0xcd, 0xa9, 0x6d, - 0x90, 0x0f, 0xa1, 0x87, 0x36, 0x8d, 0xad, 0x4c, 0x21, 0x14, 0x67, 0xa0, 0xff, 0x51, 0x20, 0x15, - 0x93, 0x03, 0x34, 0x86, 0x90, 0x19, 0x6f, 0x41, 0xcf, 0x7c, 0x8b, 0x2e, 0xea, 0x6a, 0xeb, 0x2c, - 0x9e, 0x86, 0xaa, 0xb2, 0xae, 0x1d, 0x58, 0x73, 0x27, 0x4e, 0x18, 0xf2, 0xc0, 0x3e, 0x4f, 0x47, - 0x23, 0xa3, 0x85, 0x3a, 0x14, 0x4a, 0x5c, 0xd5, 0xa8, 0x87, 0x84, 0x21, 0xa5, 0x36, 0x84, 0x6e, - 0xe8, 0x07, 0x2a, 0x5e, 0x4e, 0x1a, 0xb7, 0x4b, 0x94, 0xed, 0xd0, 0x0f, 0x28, 0x60, 0x8e, 0x7a, - 0xf7, 0x57, 0xd0, 0x4f, 0x53, 0xdf, 0x13, 0xb6, 0x8c, 0xcc, 0xdf, 0xbc, 0xe8, 0xa8, 0x6b, 0x21, - 0x8e, 0xf1, 0x2c, 0xf5, 0xbd, 0xb3, 0x48, 0xff, 0xd1, 0x4b, 0x97, 0xe8, 0x4d, 0x73, 0xf8, 0x2b, - 0xe8, 0x14, 0x79, 0x07, 0x79, 0x91, 0x1c, 0xcd, 0xfe, 0x5b, 0x0c, 0xa0, 0xfe, 0x24, 0x4a, 0xa6, - 0x4e, 0xd0, 0x2f, 0xe1, 0xb3, 0xba, 0xea, 0xde, 0x2f, 0xb3, 0x0e, 0x34, 0x8d, 0x07, 0xd4, 0xaf, - 0xe8, 0x7c, 0xc9, 0x2f, 0xa0, 0x69, 0xfe, 0xbd, 0x86, 0xfe, 0x36, 0x24, 0xf2, 0xb8, 0xb2, 0x0c, - 0x75, 0xf1, 0x1c, 0x02, 0xc8, 0x2a, 0x34, 0x7f, 0x32, 0x55, 0xce, 0xff, 0x64, 0x6a, 0xf8, 0x27, - 0xd0, 0x29, 0x4e, 0xd1, 0x04, 0xe7, 0x4a, 0x79, 0x70, 0x6e, 0x49, 0x2f, 0x4a, 0xea, 0x26, 0xd1, - 0xd4, 0x2e, 0x18, 0x2f, 0x4d, 0x04, 0xe0, 0x6b, 0x86, 0xff, 0xb0, 0x04, 0x35, 0xf2, 0x0b, 0x48, - 0xc9, 0xe1, 0x43, 0x7e, 0x82, 0x6a, 0x56, 0x8b, 0x20, 0xff, 0x0f, 0x97, 0x85, 0xb2, 0x64, 0x4d, - 0xf5, 0x8d, 0xc9, 0x9a, 0x3b, 0x7f, 0x56, 0x82, 0xba, 0xfa, 0x63, 0x2f, 0xb6, 0x0a, 0xdd, 0x67, - 0xe1, 0x45, 0x18, 0xbd, 0x0c, 0x15, 0xa0, 0xff, 0x16, 0x5b, 0x83, 0x15, 0xb3, 0xf6, 0xfa, 0x1f, - 0xc4, 0xfa, 0x25, 0xd6, 0x87, 0x0e, 0xed, 0xae, 0x81, 0x94, 0xd9, 0x3b, 0x30, 0xd0, 0x7a, 0xea, - 0x20, 0x0a, 0xf9, 0x93, 0x48, 0xfa, 0xa3, 0x2b, 0x83, 0xad, 0xb0, 0x15, 0x68, 0x9f, 0xca, 0x28, - 0x3e, 0xe5, 0xa1, 0xe7, 0x87, 0xe3, 0x7e, 0x95, 0x0d, 0x60, 0xdd, 0x8c, 0xaa, 0xa2, 0x00, 0x8f, - 0xfd, 0xd0, 0x17, 0x93, 0x7e, 0x8d, 0x5d, 0x87, 0xad, 0x65, 0x98, 0x3d, 0xf7, 0xa2, 0x5f, 0xbf, - 0xf3, 0x19, 0xb0, 0xc5, 0xff, 0xca, 0xc2, 0xd1, 0x8f, 0xf8, 0xd8, 0x71, 0xaf, 0xf6, 0x83, 0x48, - 0x20, 0x53, 0x74, 0xa1, 0x95, 0xf7, 0x2a, 0xdd, 0x79, 0x0c, 0x75, 0xf5, 0xe7, 0x66, 0x85, 0xef, - 0x53, 0x80, 0xfe, 0x5b, 0xd8, 0x19, 0x85, 0xb9, 0x1f, 0x8e, 0x9f, 0xf0, 0x4b, 0xa9, 0x04, 0xe1, - 0x91, 0x23, 0x64, 0xbf, 0xcc, 0x7a, 0x00, 0xfa, 0x13, 0x1e, 0x85, 0x5e, 0xbf, 0xf2, 0x70, 0xff, - 0x2f, 0x7e, 0xf7, 0x5e, 0xe9, 0x2f, 0x7f, 0xf7, 0x5e, 0xe9, 0xbf, 0xfd, 0xee, 0xbd, 0xb7, 0x7e, - 0xfb, 0x57, 0xef, 0x95, 0xbe, 0x79, 0x50, 0xf8, 0xeb, 0xb6, 0xa9, 0x23, 0x13, 0xff, 0x52, 0x25, - 0xe1, 0x4d, 0x23, 0xe4, 0xf7, 0xe2, 0x8b, 0xf1, 0xbd, 0xf8, 0xfc, 0x9e, 0xe1, 0xf3, 0xf3, 0x3a, - 0xfd, 0x23, 0xdb, 0xa7, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x38, 0xb0, 0xbb, 0xfc, 0x10, 0x4e, - 0x00, 0x00, + 0x96, 0x98, 0xaa, 0xeb, 0xfb, 0xd5, 0x47, 0x57, 0x47, 0x37, 0xc9, 0x12, 0x29, 0x89, 0x54, 0x49, + 0xa4, 0x7a, 0x28, 0xaa, 0x49, 0xb6, 0xa4, 0x19, 0xed, 0xcc, 0xce, 0xce, 0x36, 0x9b, 0xe4, 0xa8, + 0x47, 0xdd, 0x64, 0x6f, 0x76, 0xd3, 0x02, 0x04, 0xd8, 0x89, 0xec, 0xcc, 0xa8, 0xaa, 0x54, 0x67, + 0x65, 0x24, 0x33, 0x22, 0xc9, 0x6e, 0x9e, 0x0c, 0xd8, 0x27, 0x5f, 0x7c, 0xf4, 0xc2, 0xa7, 0x39, + 0x18, 0xf0, 0xda, 0x86, 0xe1, 0x83, 0xb1, 0xbe, 0xf8, 0x0f, 0x2c, 0x6c, 0xc0, 0xd8, 0x8b, 0x7d, + 0x34, 0x8c, 0xd9, 0xa3, 0x01, 0x1f, 0x0c, 0xd8, 0xd8, 0x8b, 0x01, 0xe3, 0xbd, 0x88, 0xc8, 0xcc, + 0xaa, 0x6a, 0x52, 0x1f, 0x36, 0xf6, 0xb2, 0x73, 0xaa, 0x8c, 0xf7, 0x5e, 0x44, 0x46, 0x46, 0xbc, + 0x78, 0xdf, 0x51, 0xd0, 0x4f, 0xc2, 0x84, 0x47, 0x61, 0xcc, 0xb7, 0x92, 0x54, 0x28, 0xc1, 0x5a, + 0xb6, 0x7d, 0xf5, 0x93, 0x49, 0xa8, 0xa6, 0xd9, 0xc9, 0x96, 0x2f, 0x66, 0x77, 0x27, 0x62, 0x22, + 0xee, 0x12, 0xc1, 0x49, 0x36, 0xa6, 0x16, 0x35, 0xe8, 0x49, 0x77, 0xbc, 0x0a, 0x91, 0xf0, 0x4f, + 0xed, 0x73, 0x12, 0x79, 0xb1, 0x79, 0x5e, 0x55, 0xe1, 0x8c, 0x4b, 0xe5, 0xcd, 0x12, 0x03, 0x68, + 0xab, 0x33, 0x83, 0x1b, 0xfd, 0xc7, 0x2a, 0x34, 0x0f, 0xb8, 0x94, 0xde, 0x84, 0xb3, 0x11, 0x54, + 0x65, 0x18, 0x0c, 0x2b, 0x37, 0x2a, 0x9b, 0xfd, 0xed, 0xc1, 0x56, 0x3e, 0xad, 0x23, 0xe5, 0xa9, + 0x4c, 0x3a, 0x88, 0x44, 0x1a, 0x7f, 0x16, 0x0c, 0x57, 0x16, 0x69, 0x0e, 0xb8, 0x9a, 0x8a, 0xc0, + 0x41, 0x24, 0x1b, 0x40, 0x95, 0xa7, 0xe9, 0xb0, 0x7a, 0xa3, 0xb2, 0xd9, 0x75, 0xf0, 0x91, 0x31, + 0xa8, 0x05, 0x9e, 0xf2, 0x86, 0x35, 0x02, 0xd1, 0x33, 0xfb, 0x10, 0xfa, 0x49, 0x2a, 0x7c, 0x37, + 0x8c, 0xc7, 0xc2, 0x25, 0x6c, 0x9d, 0xb0, 0x5d, 0x84, 0xee, 0xc5, 0x63, 0xf1, 0x10, 0xa9, 0x86, + 0xd0, 0xf4, 0x62, 0x2f, 0x3a, 0x97, 0x7c, 0xd8, 0x20, 0xb4, 0x6d, 0xb2, 0x3e, 0xac, 0x84, 0xc1, + 0xb0, 0x79, 0xa3, 0xb2, 0x59, 0x73, 0x56, 0xc2, 0x00, 0xdf, 0x91, 0x65, 0x61, 0x30, 0x6c, 0xe9, + 0x77, 0xe0, 0x33, 0x1b, 0x41, 0x37, 0xe6, 0x3c, 0x78, 0x22, 0x94, 0xc3, 0x93, 0xe8, 0x7c, 0xd8, + 0xbe, 0x51, 0xd9, 0x6c, 0x39, 0x73, 0x30, 0x76, 0x15, 0x5a, 0x01, 0x3f, 0xc9, 0x26, 0x07, 0x72, + 0x32, 0x84, 0x1b, 0x95, 0xcd, 0xb6, 0x93, 0xb7, 0xd9, 0x31, 0x5c, 0x49, 0xf9, 0xf3, 0x8c, 0x4b, + 0xc5, 0x03, 0x57, 0x71, 0x2f, 0x0d, 0xc4, 0xcb, 0xd8, 0x9d, 0x89, 0x80, 0x0f, 0x3b, 0xb4, 0x02, + 0xef, 0x94, 0x57, 0x29, 0xe5, 0xde, 0xec, 0xd8, 0x10, 0x1d, 0x88, 0x80, 0x3b, 0x97, 0xf2, 0xce, + 0x65, 0x30, 0x73, 0xe0, 0xb2, 0xe7, 0xfb, 0x3c, 0x59, 0x1e, 0xb4, 0xfb, 0x3d, 0x06, 0xdd, 0xb0, + 0x7d, 0xcb, 0xd0, 0x9f, 0xd7, 0xfe, 0xf4, 0xb7, 0xd7, 0xdf, 0x1a, 0x3d, 0x83, 0xf6, 0xae, 0x88, + 0x63, 0xee, 0x2b, 0x91, 0xb2, 0xeb, 0xd0, 0xb1, 0xe3, 0xb8, 0x66, 0x5b, 0xeb, 0x0e, 0x58, 0xd0, + 0x5e, 0xc0, 0x3e, 0x82, 0x55, 0xdf, 0x52, 0xbb, 0x61, 0x1c, 0xf0, 0x33, 0xda, 0xd7, 0xba, 0xd3, + 0xcf, 0xc1, 0x7b, 0x08, 0x1d, 0xfd, 0xd3, 0x2a, 0x34, 0x8f, 0xa6, 0xd9, 0x78, 0x1c, 0x71, 0xf6, + 0x21, 0xf4, 0xcc, 0xe3, 0xae, 0x88, 0xf6, 0x82, 0x33, 0x33, 0xee, 0x3c, 0x90, 0xdd, 0x80, 0x8e, + 0x01, 0x1c, 0x9f, 0x27, 0xdc, 0x0c, 0x5b, 0x06, 0xcd, 0x8f, 0x73, 0x10, 0xc6, 0xc4, 0x2e, 0x55, + 0x67, 0x1e, 0xb8, 0x40, 0xe5, 0x9d, 0x11, 0x07, 0xcd, 0x53, 0x79, 0xf4, 0xb6, 0x9d, 0x28, 0x7c, + 0xc1, 0x1d, 0x3e, 0xd9, 0x8d, 0x15, 0xf1, 0x51, 0xdd, 0x29, 0x83, 0xd8, 0x36, 0x5c, 0x92, 0xba, + 0x8b, 0x9b, 0x7a, 0xf1, 0x84, 0x4b, 0x37, 0x0b, 0x63, 0xf5, 0xd3, 0xcf, 0x86, 0x8d, 0x1b, 0xd5, + 0xcd, 0x9a, 0xb3, 0x6e, 0x90, 0x0e, 0xe1, 0x9e, 0x11, 0x8a, 0xdd, 0x83, 0x8d, 0x85, 0x3e, 0xba, + 0x4b, 0xf3, 0x46, 0x75, 0xb3, 0xea, 0xb0, 0xb9, 0x2e, 0x7b, 0xd4, 0xe3, 0x11, 0xac, 0xa5, 0x59, + 0x8c, 0xa7, 0xed, 0x71, 0x18, 0x29, 0x9e, 0x1e, 0x25, 0xdc, 0x27, 0x7e, 0xec, 0x6c, 0x5f, 0xd9, + 0xa2, 0x03, 0xe9, 0x2c, 0xa2, 0x9d, 0xe5, 0x1e, 0xec, 0x4e, 0xbe, 0x78, 0x8f, 0xce, 0x92, 0x94, + 0x98, 0xb6, 0xb3, 0x0d, 0x7a, 0x00, 0x84, 0x38, 0x65, 0xf4, 0xe8, 0xaf, 0x57, 0xa0, 0xf5, 0x30, + 0x94, 0x89, 0xa7, 0xfc, 0x29, 0xbb, 0x02, 0xcd, 0x71, 0x16, 0xfb, 0xc5, 0x7e, 0x37, 0xb0, 0xb9, + 0x17, 0xb0, 0x3f, 0x84, 0xd5, 0x48, 0xf8, 0x5e, 0xe4, 0xe6, 0x5b, 0x3b, 0x5c, 0xb9, 0x51, 0xdd, + 0xec, 0x6c, 0xaf, 0x17, 0xcc, 0x96, 0xb3, 0x8e, 0xd3, 0x27, 0xda, 0x82, 0x95, 0x7e, 0x09, 0x83, + 0x94, 0xcf, 0x84, 0xe2, 0xa5, 0xee, 0x55, 0xea, 0xce, 0x8a, 0xee, 0x5f, 0xa7, 0x5e, 0xf2, 0x04, + 0x39, 0x74, 0x55, 0xd3, 0x16, 0xdd, 0xef, 0x97, 0x56, 0x9f, 0x4f, 0xdc, 0x30, 0x38, 0x73, 0xe9, + 0x05, 0xc3, 0xda, 0x8d, 0xea, 0x66, 0xbd, 0x58, 0x4a, 0x3e, 0xd9, 0x0b, 0xce, 0xf6, 0x11, 0xc3, + 0x3e, 0x85, 0xcb, 0x8b, 0x5d, 0xf4, 0xa8, 0xc3, 0x3a, 0xf5, 0x59, 0x9f, 0xeb, 0xe3, 0x10, 0x8a, + 0xbd, 0x0f, 0x5d, 0xdb, 0x49, 0x21, 0xdb, 0x35, 0x34, 0x23, 0xc8, 0x12, 0xdb, 0x5d, 0x81, 0x66, + 0x28, 0x5d, 0x19, 0xc6, 0xa7, 0x24, 0x3a, 0x5a, 0x4e, 0x23, 0x94, 0x47, 0x61, 0x7c, 0xca, 0xde, + 0x86, 0x56, 0xca, 0x7d, 0x8d, 0x69, 0x11, 0xa6, 0x99, 0x72, 0x9f, 0x50, 0x57, 0x00, 0x1f, 0x5d, + 0x5f, 0x71, 0x23, 0x40, 0x1a, 0x29, 0xf7, 0x77, 0x15, 0x1f, 0x49, 0xa8, 0x1f, 0xf0, 0x74, 0xc2, + 0x51, 0x86, 0x60, 0xc7, 0x23, 0xdf, 0x8b, 0x69, 0xdd, 0x5b, 0x4e, 0xde, 0x46, 0x09, 0x96, 0x78, + 0xa9, 0x0a, 0xbd, 0x88, 0x8e, 0x41, 0xcb, 0xb1, 0x4d, 0x76, 0x0d, 0xda, 0x52, 0x79, 0xa9, 0xc2, + 0xaf, 0x23, 0xf6, 0xaf, 0x3b, 0x2d, 0x02, 0xe0, 0x09, 0xba, 0x02, 0x4d, 0x1e, 0x07, 0x84, 0xaa, + 0xe9, 0x9d, 0xe4, 0x71, 0xb0, 0x17, 0x9c, 0x8d, 0xfe, 0x6d, 0x05, 0x7a, 0x07, 0x59, 0xa4, 0xc2, + 0x9d, 0x74, 0x92, 0xf1, 0x59, 0xac, 0x50, 0xf2, 0x3d, 0x0c, 0xa5, 0x32, 0x6f, 0xa6, 0x67, 0xb6, + 0x09, 0xed, 0x5f, 0xa7, 0x22, 0x4b, 0x88, 0x83, 0xf4, 0x4e, 0x97, 0x39, 0xa8, 0x40, 0x22, 0xb7, + 0x3d, 0x4d, 0x03, 0x9e, 0x3e, 0x38, 0x27, 0xda, 0xea, 0x12, 0x6d, 0x19, 0xcd, 0xde, 0x81, 0xf6, + 0x11, 0x4f, 0xbc, 0xd4, 0x43, 0x16, 0xa8, 0x91, 0xb8, 0x2c, 0x00, 0xf8, 0xad, 0x44, 0xbc, 0x17, + 0x98, 0x43, 0x68, 0x9b, 0xa3, 0x09, 0xb4, 0x77, 0x26, 0x93, 0x94, 0x4f, 0x3c, 0x45, 0xa2, 0x5b, + 0x24, 0x34, 0xdd, 0xaa, 0xb3, 0x22, 0x12, 0x52, 0x0f, 0xf8, 0x01, 0x7a, 0x7d, 0xe8, 0x99, 0xbd, + 0x07, 0x35, 0x7e, 0xf1, 0x7c, 0x08, 0xce, 0x2e, 0x43, 0xc3, 0x17, 0xf1, 0x38, 0x9c, 0x18, 0xa5, + 0x62, 0x5a, 0xa3, 0x7f, 0x59, 0x85, 0x3a, 0x7d, 0x1c, 0x2e, 0x2f, 0x0a, 0x7a, 0x97, 0xbf, 0xf0, + 0x22, 0xbb, 0x2b, 0x08, 0x78, 0xf4, 0xc2, 0x8b, 0xd8, 0x0d, 0xa8, 0xe3, 0x30, 0xf2, 0x82, 0xb5, + 0xd1, 0x08, 0x76, 0x0b, 0xea, 0xc8, 0x44, 0x72, 0x7e, 0x06, 0xc8, 0x44, 0x0f, 0x6a, 0x7f, 0xf1, + 0x5f, 0xaf, 0xbf, 0xe5, 0x68, 0x34, 0xfb, 0x08, 0x6a, 0xde, 0x64, 0x22, 0x89, 0x97, 0xe7, 0x8e, + 0x53, 0xfe, 0xbd, 0x0e, 0x11, 0xb0, 0xcf, 0xa1, 0xad, 0xf7, 0x0d, 0xa9, 0xeb, 0x44, 0x7d, 0xa5, + 0xa4, 0x40, 0xcb, 0x5b, 0xea, 0x14, 0x94, 0xb8, 0xe2, 0xa1, 0x34, 0x07, 0x9e, 0x38, 0xba, 0xe5, + 0x14, 0x00, 0xd4, 0x70, 0x49, 0xca, 0x77, 0xa2, 0x48, 0xf8, 0x47, 0xe1, 0x2b, 0x6e, 0xf4, 0xe1, + 0x1c, 0x8c, 0xdd, 0x82, 0xfe, 0xa1, 0x66, 0x39, 0x87, 0xcb, 0x2c, 0x52, 0xd2, 0xe8, 0xc8, 0x05, + 0x28, 0xdb, 0x02, 0x36, 0x07, 0x39, 0xa6, 0xcf, 0x6f, 0xdf, 0xa8, 0x6e, 0xf6, 0x9c, 0x0b, 0x30, + 0xec, 0x03, 0xe8, 0x4d, 0x70, 0xa5, 0xc3, 0x78, 0xe2, 0x8e, 0x23, 0x0f, 0xd5, 0x67, 0x15, 0xd5, + 0xab, 0x05, 0x3e, 0x8e, 0xbc, 0x09, 0x31, 0x79, 0x12, 0x46, 0x91, 0x3b, 0xe3, 0x33, 0x52, 0x9a, + 0x55, 0xa7, 0x45, 0x80, 0x03, 0x3e, 0x1b, 0xfd, 0xab, 0x1a, 0x34, 0xf6, 0x62, 0xc9, 0x53, 0x85, + 0x47, 0xc8, 0x1b, 0x8f, 0xb9, 0xaf, 0xb8, 0x16, 0x5d, 0x35, 0x27, 0x6f, 0xe3, 0x12, 0x1c, 0x8b, + 0xaf, 0xd3, 0x50, 0xf1, 0xa3, 0x4f, 0x0d, 0x93, 0x14, 0x00, 0x76, 0x1b, 0xd6, 0xbc, 0x20, 0x70, + 0x2d, 0xb5, 0x9b, 0x8a, 0x97, 0x92, 0x8e, 0x53, 0xcb, 0x59, 0xf5, 0x82, 0x60, 0xc7, 0xc0, 0x1d, + 0xf1, 0x52, 0xb2, 0xf7, 0xa1, 0x9a, 0xf2, 0x31, 0xb1, 0x4c, 0x67, 0x7b, 0x55, 0x6f, 0xe9, 0xd3, + 0x93, 0x6f, 0xb9, 0xaf, 0x1c, 0x3e, 0x76, 0x10, 0xc7, 0x36, 0xa0, 0xee, 0x29, 0x95, 0xea, 0x2d, + 0x6a, 0x3b, 0xba, 0xc1, 0xb6, 0x60, 0x9d, 0x8e, 0xad, 0x0a, 0x45, 0xec, 0x2a, 0xef, 0x24, 0x42, + 0x9d, 0x2a, 0x8d, 0xfa, 0x58, 0xcb, 0x51, 0xc7, 0x88, 0xd9, 0x0b, 0x24, 0x2a, 0x9c, 0x45, 0xfa, + 0xd8, 0x9b, 0x71, 0x49, 0xda, 0xa3, 0xed, 0xac, 0xcf, 0xf7, 0x78, 0x82, 0x28, 0x5c, 0xcf, 0xa2, + 0x0f, 0x1e, 0xfc, 0x16, 0x9d, 0xa1, 0x6e, 0x0e, 0x44, 0xb9, 0x70, 0x09, 0x1a, 0xa1, 0x74, 0x79, + 0x1c, 0x18, 0x59, 0x54, 0x0f, 0xe5, 0xa3, 0x38, 0x60, 0x1f, 0x43, 0x5b, 0xbf, 0x25, 0xe0, 0x63, + 0x32, 0x63, 0x3a, 0xdb, 0x7d, 0xc3, 0xb1, 0x08, 0x7e, 0xc8, 0xc7, 0x4e, 0x4b, 0x99, 0x27, 0xb4, + 0x0c, 0x94, 0x70, 0xf9, 0x99, 0xe2, 0x69, 0xec, 0x45, 0xb4, 0x2b, 0x2d, 0x07, 0x94, 0x78, 0x64, + 0x20, 0xec, 0x73, 0xb8, 0x62, 0xb1, 0xae, 0x54, 0x33, 0xe5, 0x66, 0x71, 0x78, 0xe6, 0xc6, 0x5e, + 0x2c, 0xc8, 0x44, 0xa9, 0x3a, 0x1b, 0x16, 0x7d, 0xa4, 0x66, 0xea, 0x59, 0x1c, 0x9e, 0x3d, 0xf1, + 0x62, 0xc1, 0x36, 0x61, 0x90, 0x77, 0x53, 0xaf, 0xe8, 0x83, 0x87, 0x3d, 0x92, 0x11, 0x7d, 0x0b, + 0x3f, 0x7e, 0x85, 0xdf, 0x8a, 0xe2, 0xbd, 0x4c, 0x29, 0xc6, 0x63, 0xc9, 0x95, 0x2b, 0xb9, 0x3f, + 0xec, 0xd3, 0x37, 0xaf, 0x17, 0xf4, 0x4f, 0x09, 0x77, 0xc4, 0xfd, 0xd1, 0x3f, 0xa8, 0x40, 0x87, + 0xce, 0xc5, 0xb3, 0x24, 0x40, 0x31, 0xf2, 0x01, 0xf4, 0xe6, 0x37, 0x5d, 0xf3, 0x4d, 0xd7, 0x2b, + 0xef, 0xf8, 0x65, 0x68, 0xec, 0xf8, 0xb8, 0x78, 0xc4, 0x38, 0x3d, 0xc7, 0xb4, 0xd8, 0xcf, 0x60, + 0x35, 0xa3, 0x61, 0x5c, 0x5f, 0x9d, 0xb9, 0x11, 0x8a, 0x1f, 0x7d, 0xd0, 0x0d, 0x57, 0xe8, 0x77, + 0xec, 0xaa, 0x33, 0xa7, 0x97, 0xd9, 0xc7, 0xfd, 0x50, 0xaa, 0xd1, 0xbb, 0x50, 0xdf, 0x49, 0x53, + 0xef, 0x9c, 0x18, 0x05, 0x1f, 0x86, 0x15, 0xd2, 0x48, 0xba, 0x31, 0xf2, 0xa1, 0x7a, 0xe0, 0x25, + 0xec, 0x26, 0xac, 0xcc, 0x12, 0xc2, 0x74, 0xb6, 0x2f, 0x95, 0x4e, 0xb9, 0x97, 0x6c, 0x1d, 0x24, + 0x8f, 0x62, 0x95, 0x9e, 0x3b, 0x2b, 0xb3, 0xe4, 0xea, 0xe7, 0xd0, 0x34, 0x4d, 0xb4, 0x9a, 0x4f, + 0xf9, 0x39, 0x7d, 0x43, 0xdb, 0xc1, 0x47, 0x7c, 0xc1, 0x0b, 0x2f, 0xca, 0xac, 0xf9, 0xa4, 0x1b, + 0x3f, 0x5f, 0xf9, 0xa2, 0x32, 0xfa, 0x5f, 0x35, 0x68, 0x3d, 0xe4, 0x11, 0xa7, 0x2f, 0x19, 0x41, + 0xb7, 0xcc, 0xe3, 0x76, 0x15, 0xe6, 0xf8, 0x7e, 0x04, 0x5d, 0xad, 0x23, 0xa9, 0x17, 0x37, 0x87, + 0x68, 0x0e, 0x86, 0xc2, 0x7b, 0xef, 0x41, 0xe6, 0x9f, 0x72, 0x45, 0xa7, 0xa7, 0xe7, 0xd8, 0x26, + 0x62, 0x9e, 0x18, 0x4c, 0x4d, 0x63, 0x4c, 0x93, 0xbd, 0x03, 0x90, 0x8a, 0x97, 0x6e, 0xa8, 0x15, + 0x95, 0x96, 0xf9, 0xad, 0x54, 0xbc, 0xdc, 0x43, 0x55, 0xf5, 0x37, 0x72, 0x68, 0x7e, 0x06, 0xc3, + 0xd2, 0xa1, 0x41, 0x73, 0xd5, 0x0d, 0x63, 0xf7, 0x04, 0xad, 0x21, 0x73, 0x7e, 0x8a, 0x31, 0xc9, + 0x9a, 0xdd, 0x8b, 0x1f, 0x90, 0xa9, 0x64, 0x44, 0x41, 0xfb, 0x0d, 0xa2, 0xe0, 0x42, 0xc9, 0x02, + 0x17, 0x4b, 0x96, 0x07, 0x00, 0x47, 0x7c, 0x32, 0xe3, 0xb1, 0x3a, 0xf0, 0x92, 0x61, 0x87, 0x36, + 0x7e, 0x54, 0x6c, 0xbc, 0xdd, 0xad, 0xad, 0x82, 0x48, 0x73, 0x41, 0xa9, 0x17, 0xda, 0x2f, 0xbe, + 0x17, 0xbb, 0x2a, 0xcd, 0x62, 0xdf, 0x53, 0xda, 0x1d, 0x68, 0x39, 0x1d, 0xdf, 0x8b, 0x8f, 0x0d, + 0xa8, 0x74, 0xfc, 0x7b, 0xe5, 0xe3, 0x7f, 0x0b, 0x56, 0x93, 0x34, 0x9c, 0x79, 0xe9, 0xb9, 0x7b, + 0xca, 0xcf, 0x69, 0x33, 0xf4, 0x41, 0xea, 0x19, 0xf0, 0x57, 0xfc, 0x7c, 0x2f, 0x38, 0xbb, 0xfa, + 0x4b, 0x58, 0x5d, 0x98, 0xc0, 0x0f, 0xe2, 0xbb, 0xdf, 0x56, 0xa1, 0x7d, 0x98, 0x72, 0x23, 0xb2, + 0xaf, 0x43, 0x47, 0xfa, 0x53, 0x3e, 0xf3, 0xf4, 0x49, 0xd7, 0x23, 0x80, 0x06, 0xd1, 0x29, 0x9f, + 0x13, 0x4a, 0x2b, 0xdf, 0x21, 0x94, 0x06, 0x50, 0xd5, 0x76, 0x10, 0x1e, 0x26, 0x7c, 0x2c, 0x24, + 0x71, 0xad, 0x2c, 0x89, 0x6f, 0x40, 0x77, 0xea, 0x49, 0xd7, 0xcb, 0x94, 0x70, 0x7d, 0x11, 0x11, + 0xd3, 0xb5, 0x1c, 0x98, 0x7a, 0x72, 0x27, 0x53, 0x62, 0x57, 0x44, 0xec, 0x5d, 0x00, 0x5f, 0x44, + 0x46, 0xa8, 0x18, 0x23, 0xb0, 0xed, 0x8b, 0x48, 0x4b, 0x12, 0xe4, 0x4a, 0x2e, 0x55, 0x38, 0xf3, + 0xcc, 0x96, 0xba, 0xbe, 0xc8, 0x62, 0x45, 0x9a, 0xb3, 0xea, 0xac, 0xe5, 0x28, 0x47, 0xbc, 0xdc, + 0x45, 0x04, 0xbb, 0x07, 0x7d, 0x5f, 0xcc, 0x12, 0x37, 0xc1, 0x95, 0x25, 0x9b, 0xa4, 0xb5, 0x64, + 0x91, 0x77, 0x91, 0xe2, 0xf0, 0x94, 0x6b, 0x23, 0x69, 0x1b, 0x56, 0xfd, 0x28, 0x93, 0x8a, 0xa7, + 0xee, 0x89, 0xe9, 0xb2, 0x6c, 0xc4, 0xf7, 0x0c, 0x89, 0x31, 0xac, 0x46, 0xd0, 0x0b, 0xa5, 0x2b, + 0xa2, 0xc0, 0xd5, 0xe2, 0xc6, 0xf0, 0x59, 0x27, 0x94, 0x4f, 0xa3, 0xc0, 0x08, 0x3c, 0x4d, 0x13, + 0xf3, 0x97, 0x96, 0xa6, 0x63, 0x69, 0x9e, 0xf0, 0x97, 0x9a, 0x66, 0xf4, 0x5f, 0x56, 0xa0, 0x79, + 0x28, 0xa4, 0x7a, 0x38, 0x8b, 0x2c, 0x8b, 0x57, 0x7e, 0x28, 0x8b, 0xaf, 0x5c, 0xcc, 0xe2, 0x17, + 0x30, 0x59, 0xf5, 0x02, 0x26, 0x43, 0x35, 0x50, 0xa6, 0x23, 0xe6, 0xd0, 0xa6, 0x62, 0xbf, 0x20, + 0x24, 0x06, 0xb9, 0x86, 0xb6, 0x8d, 0x1b, 0x68, 0x99, 0xa4, 0x37, 0xb2, 0x15, 0x4a, 0x23, 0x8f, + 0x34, 0x32, 0x24, 0x5e, 0x33, 0x86, 0x4f, 0x2b, 0x94, 0x86, 0xf7, 0xfe, 0x00, 0xde, 0xce, 0x7b, + 0xba, 0x2f, 0x43, 0x35, 0x15, 0x99, 0x72, 0xc7, 0xe4, 0x43, 0x49, 0x63, 0xd9, 0x5f, 0xb6, 0x23, + 0x7d, 0xad, 0xd1, 0xda, 0xc3, 0x22, 0x3b, 0x6c, 0x9c, 0x45, 0x91, 0xab, 0xf8, 0x99, 0x32, 0x5b, + 0x39, 0xd4, 0x6b, 0x63, 0xd6, 0xed, 0x71, 0x16, 0x45, 0xc7, 0xfc, 0x4c, 0xa1, 0xf0, 0x6f, 0x8d, + 0x4d, 0x63, 0xf4, 0x4f, 0x6a, 0x00, 0xfb, 0xc2, 0x3f, 0x3d, 0xf6, 0xd2, 0x09, 0x57, 0xe8, 0x2f, + 0x58, 0x89, 0x66, 0x24, 0x6e, 0x53, 0x69, 0x39, 0xc6, 0xb6, 0xe1, 0xb2, 0xfd, 0x7e, 0xe4, 0x43, + 0xf4, 0x5d, 0xb4, 0x48, 0x32, 0x07, 0x8a, 0x19, 0xac, 0xf6, 0x95, 0x49, 0x1e, 0xb1, 0x2f, 0x8a, + 0xb5, 0xc5, 0x3e, 0xea, 0x3c, 0xa1, 0xb5, 0xbd, 0xc8, 0xee, 0xec, 0x15, 0xdd, 0x8f, 0xcf, 0x13, + 0x76, 0x0f, 0x2e, 0xa5, 0x7c, 0x9c, 0x72, 0x39, 0x75, 0x95, 0x2c, 0xbf, 0x4c, 0xbb, 0x0d, 0x6b, + 0x06, 0x79, 0x2c, 0xf3, 0x77, 0xdd, 0x83, 0x4b, 0x7a, 0xa5, 0x16, 0xa7, 0xa7, 0xe5, 0xf7, 0x9a, + 0x46, 0x96, 0x67, 0xf7, 0x2e, 0x50, 0x6c, 0x49, 0xcb, 0x64, 0x6b, 0x84, 0x46, 0xb4, 0x18, 0x27, + 0x11, 0x47, 0xfb, 0x6c, 0x77, 0x8a, 0x7e, 0xf0, 0x43, 0x3e, 0x36, 0x8b, 0x5f, 0x00, 0xd8, 0x08, + 0x6a, 0x07, 0x22, 0xe0, 0xb4, 0xd4, 0xfd, 0xed, 0xfe, 0x16, 0x45, 0xa9, 0x70, 0x25, 0x29, 0x9c, + 0x41, 0x38, 0xf6, 0x11, 0xd0, 0x70, 0x9a, 0xfd, 0x96, 0xcf, 0x4a, 0x0b, 0x91, 0xc4, 0x83, 0xf7, + 0xe0, 0x52, 0x31, 0x13, 0xd7, 0x53, 0xae, 0x9a, 0x72, 0x12, 0x87, 0xfa, 0xb8, 0xac, 0xe5, 0x93, + 0xda, 0x51, 0xc7, 0x53, 0x8e, 0xa2, 0x71, 0x13, 0x9a, 0xe2, 0xe4, 0x5b, 0x17, 0x0f, 0x42, 0xe7, + 0xe2, 0x83, 0xd0, 0x10, 0x27, 0xdf, 0x3a, 0x7c, 0xcc, 0x7e, 0x5a, 0x56, 0x25, 0x0b, 0x4b, 0xd3, + 0xa5, 0xa5, 0xd9, 0xc8, 0xf1, 0xa5, 0xd5, 0x19, 0x7d, 0x01, 0x0d, 0xfc, 0x9c, 0xa7, 0x09, 0xdb, + 0x82, 0xa6, 0x22, 0xf6, 0x90, 0x46, 0xf5, 0x6f, 0x14, 0x1a, 0xa0, 0xe0, 0x1d, 0xc7, 0x12, 0x8d, + 0x1c, 0x58, 0xcd, 0xc5, 0xe9, 0xb3, 0x38, 0x7c, 0x9e, 0x71, 0xf6, 0x2b, 0x58, 0x4b, 0x52, 0x6e, + 0xd8, 0xde, 0xcd, 0x4e, 0xd1, 0x3c, 0x31, 0x27, 0x78, 0xc3, 0x70, 0x69, 0xde, 0xe3, 0x14, 0x39, + 0xb4, 0x9f, 0xcc, 0xb5, 0x47, 0xdf, 0xc0, 0x95, 0x9c, 0xe2, 0x88, 0xfb, 0x22, 0x0e, 0xbc, 0xf4, + 0x9c, 0x34, 0xdf, 0xc2, 0xd8, 0xf2, 0x87, 0x8c, 0x7d, 0x44, 0x63, 0xff, 0xf3, 0x0a, 0x74, 0x1e, + 0x67, 0xaf, 0x5e, 0x9d, 0xeb, 0xb3, 0xc4, 0xba, 0x50, 0x79, 0x42, 0x03, 0xac, 0x38, 0x95, 0x27, + 0x68, 0x6a, 0x1d, 0x9e, 0xe2, 0xb9, 0x26, 0x3e, 0x6f, 0x3b, 0xa6, 0x85, 0x9e, 0xd4, 0xe1, 0xe9, + 0xf1, 0x1b, 0x38, 0x5a, 0xa3, 0xd1, 0x05, 0x78, 0x90, 0x85, 0x11, 0x9a, 0x0e, 0x86, 0x79, 0xf3, + 0x36, 0xfa, 0x26, 0x7b, 0x63, 0x3d, 0x95, 0xc7, 0xa9, 0x98, 0xe9, 0xc5, 0x32, 0x22, 0xe3, 0x02, + 0xcc, 0xe8, 0xaf, 0x6b, 0xd0, 0xfa, 0xd2, 0x93, 0xd3, 0xdf, 0x88, 0x30, 0x66, 0xf7, 0xa0, 0xfd, + 0xad, 0x08, 0x63, 0x1d, 0x14, 0xd0, 0xe1, 0xcd, 0x75, 0x3d, 0x89, 0x27, 0x22, 0xe0, 0x5b, 0x48, + 0x83, 0xb3, 0x71, 0x5a, 0xdf, 0x9a, 0x27, 0x23, 0x69, 0xd3, 0x70, 0x32, 0x55, 0x2e, 0x02, 0x8d, + 0x48, 0xec, 0x84, 0xd2, 0x41, 0x18, 0x8d, 0xfa, 0x0e, 0xa0, 0xd2, 0x99, 0xba, 0x22, 0x76, 0x93, + 0x53, 0xe3, 0x70, 0xb4, 0x10, 0xf2, 0x34, 0x3e, 0x3c, 0xc5, 0x23, 0x13, 0x4a, 0xd7, 0x84, 0x1e, + 0xe8, 0x73, 0xe6, 0xfc, 0xb6, 0x0f, 0xa1, 0x8f, 0xaa, 0x5e, 0x9e, 0x86, 0x89, 0x9b, 0xa4, 0xe2, + 0xc4, 0x7e, 0x0b, 0x1a, 0x00, 0x47, 0xa7, 0x61, 0x72, 0x88, 0x30, 0xd2, 0xb0, 0x26, 0xa0, 0x81, + 0xd2, 0x56, 0xab, 0x32, 0x30, 0x20, 0x5c, 0x16, 0x8a, 0x5a, 0x44, 0xda, 0x7c, 0x6d, 0x92, 0xe6, + 0x6c, 0xa6, 0x3c, 0x42, 0x3b, 0x15, 0x51, 0xc8, 0xc3, 0x84, 0x6a, 0x69, 0x94, 0x2f, 0x34, 0xea, + 0x27, 0x00, 0x11, 0x1f, 0x2b, 0x17, 0x99, 0x43, 0x3b, 0x78, 0x0b, 0xd1, 0x01, 0xc4, 0xee, 0x22, + 0x92, 0x7d, 0x0c, 0x1d, 0xbd, 0x0a, 0x9a, 0x16, 0x96, 0x68, 0x81, 0xd0, 0x9a, 0xf8, 0x36, 0x74, + 0x62, 0x11, 0xbb, 0xfc, 0x39, 0x51, 0x9b, 0xe3, 0x36, 0x37, 0x70, 0x2c, 0xe2, 0x47, 0xcf, 0x91, + 0x98, 0xdd, 0x35, 0x73, 0xd0, 0x3e, 0x76, 0xf7, 0x35, 0x3e, 0x36, 0xcd, 0x44, 0x7b, 0x9b, 0xf7, + 0xed, 0x4c, 0x74, 0x8f, 0xde, 0x6b, 0x7a, 0xe8, 0xf9, 0xe8, 0x2e, 0x37, 0xa0, 0x4b, 0xfb, 0x3e, + 0xf3, 0x12, 0x57, 0x79, 0x13, 0x63, 0x12, 0x01, 0xc2, 0x0e, 0xbc, 0xe4, 0xd8, 0x9b, 0x30, 0x07, + 0xde, 0x36, 0xf1, 0x37, 0xa3, 0x3c, 0xdc, 0x13, 0xe4, 0x38, 0xbd, 0x6a, 0xab, 0xd6, 0x47, 0xbf, + 0x38, 0x72, 0x77, 0x79, 0x2e, 0x72, 0x47, 0x9c, 0x4a, 0x0e, 0xc2, 0x3f, 0x5b, 0x81, 0xd6, 0xbe, + 0x10, 0xc9, 0x8f, 0x64, 0xbd, 0xf2, 0x96, 0xae, 0xbc, 0x7e, 0x4b, 0xab, 0xf3, 0x5b, 0xba, 0xb0, + 0xf4, 0xb5, 0xef, 0xbf, 0xf4, 0xf5, 0x1f, 0xbc, 0xf4, 0x8d, 0x1f, 0xb1, 0xf4, 0xcd, 0xc5, 0xa5, + 0x1f, 0x35, 0xa1, 0x7e, 0xc4, 0xd5, 0xd3, 0x64, 0xf4, 0x6f, 0x5a, 0xd0, 0x7e, 0xc8, 0x83, 0x4c, + 0x2f, 0x58, 0xf9, 0xf3, 0x2b, 0xaf, 0xff, 0xfc, 0x95, 0xf9, 0xcf, 0x47, 0xfd, 0x61, 0x39, 0xfa, + 0x82, 0x90, 0x51, 0xcb, 0x32, 0x34, 0xb2, 0x7e, 0xc1, 0xcf, 0x26, 0x66, 0x33, 0xb7, 0x4c, 0x39, + 0x3b, 0xbf, 0x99, 0x37, 0xea, 0x3f, 0x8a, 0x37, 0x16, 0xa4, 0xc2, 0x52, 0x34, 0xe7, 0x3b, 0x57, + 0x6d, 0x51, 0x22, 0xb4, 0x96, 0x24, 0xc2, 0x3e, 0xac, 0x8b, 0xd8, 0x0d, 0xb2, 0x24, 0x0a, 0xd1, + 0x61, 0x70, 0x3d, 0xed, 0xfc, 0xb6, 0x6d, 0x66, 0x21, 0x67, 0xbd, 0xa7, 0xf1, 0x43, 0x4b, 0xa4, + 0x5d, 0x62, 0x67, 0x4d, 0x2c, 0x82, 0x50, 0x4c, 0x05, 0xb8, 0x35, 0xa4, 0x0e, 0xc9, 0x90, 0xd3, + 0x29, 0x92, 0x2e, 0x41, 0x77, 0x45, 0x44, 0x02, 0xfe, 0x0b, 0x58, 0x2d, 0xa8, 0x34, 0x8f, 0x74, + 0x5e, 0xc3, 0x23, 0x3d, 0xdb, 0x51, 0xb3, 0xc9, 0xdf, 0x84, 0x14, 0xf8, 0x04, 0xd6, 0xad, 0xa7, + 0x6f, 0x74, 0x3a, 0xed, 0x60, 0x9f, 0x38, 0x68, 0x60, 0x9c, 0x7b, 0x52, 0xe7, 0xb4, 0x45, 0xbf, + 0x80, 0x8d, 0x12, 0x39, 0x1a, 0xef, 0x65, 0x69, 0x50, 0xe6, 0x95, 0xb5, 0xbc, 0x2f, 0x36, 0xf7, + 0x75, 0xd4, 0xb2, 0x13, 0xf0, 0xc8, 0xbe, 0x68, 0x38, 0xd0, 0xbe, 0x47, 0xc0, 0x23, 0x93, 0x17, + 0x39, 0x80, 0x0f, 0xd1, 0xc4, 0x47, 0xbc, 0xef, 0x25, 0x2a, 0x4b, 0xb9, 0x9b, 0x44, 0x9e, 0xcf, + 0xa7, 0x22, 0x0a, 0x78, 0x5a, 0x4c, 0x6e, 0x8d, 0x26, 0x77, 0x5d, 0x44, 0xc1, 0xae, 0x88, 0x76, + 0x35, 0xe5, 0x61, 0x41, 0x68, 0xe7, 0xba, 0x03, 0xef, 0x2d, 0x0d, 0x87, 0x8a, 0xa3, 0x18, 0x88, + 0xd1, 0x40, 0x6f, 0xcf, 0x0f, 0x84, 0x24, 0x76, 0x88, 0xfb, 0x70, 0x49, 0xef, 0x9d, 0x66, 0xee, + 0x53, 0xce, 0x13, 0x37, 0xf2, 0xa4, 0x1a, 0xae, 0x6b, 0xdd, 0x4a, 0x48, 0x62, 0xe0, 0xaf, 0x38, + 0x4f, 0xf6, 0x3d, 0xfd, 0x56, 0xdd, 0xc5, 0x98, 0xdf, 0xd4, 0x67, 0x6e, 0x6d, 0x37, 0xf4, 0x5b, + 0x89, 0x4a, 0xdb, 0xe0, 0xd8, 0xb9, 0xb4, 0xc8, 0x7f, 0x08, 0xd7, 0xe6, 0x86, 0x98, 0x79, 0xe9, + 0x69, 0x61, 0x8f, 0x0e, 0x2f, 0xd1, 0xba, 0x5d, 0x29, 0xf5, 0x3f, 0x20, 0x02, 0x3d, 0xc2, 0xe8, + 0x7f, 0xd4, 0xa1, 0x4f, 0x7a, 0xf8, 0xf7, 0x62, 0xe3, 0xf7, 0x62, 0xe3, 0x6f, 0x81, 0xd8, 0x18, + 0xfd, 0xfd, 0x0a, 0x34, 0x0f, 0x53, 0x11, 0x64, 0xbe, 0xfa, 0x91, 0x9c, 0x3e, 0xcf, 0x41, 0xd5, + 0xef, 0xe2, 0xa0, 0xda, 0x92, 0xba, 0xfe, 0x17, 0x15, 0x68, 0x9b, 0x29, 0xec, 0x6f, 0xff, 0xc8, + 0x49, 0x14, 0x39, 0x9d, 0xca, 0x85, 0x39, 0x9d, 0xef, 0x9c, 0x05, 0x32, 0xd6, 0x0b, 0x9d, 0xaf, + 0x16, 0x89, 0xb6, 0xa9, 0xea, 0x9a, 0xb1, 0x34, 0xf4, 0x69, 0x82, 0x7b, 0x37, 0x7a, 0x09, 0x6d, + 0x72, 0x78, 0x48, 0x32, 0x5c, 0x86, 0x46, 0x4a, 0x49, 0x0b, 0x33, 0x51, 0xd3, 0x7a, 0xf3, 0x39, + 0x5d, 0xf9, 0x71, 0xa6, 0xdf, 0x7f, 0x58, 0x81, 0x1e, 0x79, 0x9f, 0x8f, 0xb3, 0x58, 0x9f, 0x84, + 0x3c, 0x86, 0x55, 0x99, 0x8f, 0x61, 0xd5, 0x52, 0x74, 0x12, 0xf5, 0x6b, 0xba, 0xfa, 0x35, 0xbb, + 0x22, 0x7a, 0xc8, 0xc7, 0x0e, 0x61, 0x70, 0xa9, 0xbc, 0x74, 0x22, 0x2f, 0x4a, 0x7f, 0x21, 0x1c, + 0xbf, 0x2a, 0xf1, 0x52, 0x6f, 0x26, 0x6d, 0xfa, 0x4b, 0xb7, 0x18, 0x83, 0x1a, 0x9d, 0x37, 0xbd, + 0x2c, 0xf4, 0x6c, 0x02, 0x29, 0x32, 0x8c, 0x27, 0xb9, 0xf0, 0x68, 0x51, 0xd6, 0x73, 0x12, 0x71, + 0xf6, 0x10, 0x98, 0x8e, 0x9a, 0xa6, 0xdc, 0x43, 0x15, 0x44, 0xe3, 0x90, 0x04, 0xe9, 0x6c, 0x5f, + 0xd6, 0xaf, 0xa5, 0xb5, 0x74, 0x08, 0x7d, 0x88, 0x58, 0x67, 0x10, 0x2e, 0x40, 0x2e, 0x58, 0x4c, + 0xad, 0x87, 0x72, 0xef, 0xe3, 0x7b, 0x2f, 0x26, 0x29, 0x27, 0x5a, 0xcc, 0x1d, 0xb8, 0x64, 0x13, + 0x12, 0x28, 0x2e, 0xb6, 0xf1, 0x2c, 0x90, 0x1b, 0x6b, 0xbf, 0xb1, 0x52, 0xfa, 0xc6, 0x0d, 0xa8, + 0x97, 0x2b, 0x18, 0x74, 0x63, 0x74, 0x13, 0x3a, 0xe3, 0x30, 0xe2, 0x26, 0x14, 0x88, 0x8b, 0x66, + 0x82, 0x82, 0x15, 0xca, 0xe1, 0x9b, 0xd6, 0xe8, 0xcf, 0x2b, 0x70, 0x25, 0xf1, 0xd2, 0xe7, 0x19, + 0x57, 0x14, 0x10, 0xa4, 0x04, 0x96, 0x2b, 0xa7, 0x5e, 0x1a, 0xe0, 0xc1, 0xa1, 0x21, 0xf4, 0xe8, + 0x3a, 0xa9, 0xde, 0x46, 0x88, 0x9e, 0xcb, 0x2d, 0x58, 0x2d, 0xf5, 0x50, 0x5e, 0x6a, 0x83, 0x3c, + 0xbd, 0x54, 0xbc, 0xa4, 0x3c, 0xe4, 0x11, 0x02, 0xd1, 0xa1, 0x2c, 0xe8, 0x38, 0x69, 0x1b, 0xca, + 0x4d, 0x5b, 0xaa, 0x47, 0x71, 0x80, 0x27, 0x27, 0xce, 0x66, 0x3a, 0x06, 0xa2, 0xeb, 0x1c, 0x9a, + 0x71, 0x36, 0xa3, 0xb0, 0xc7, 0x06, 0xd4, 0x4f, 0xce, 0x15, 0x59, 0xeb, 0x08, 0xd7, 0x8d, 0xd1, + 0x5f, 0xd6, 0x61, 0x7d, 0xcf, 0xe7, 0x27, 0x3c, 0x9d, 0x3c, 0xf4, 0x94, 0xf7, 0x38, 0x8c, 0xf8, + 0xb1, 0x27, 0x4f, 0x71, 0xc3, 0x69, 0xce, 0x89, 0xa7, 0xa6, 0x66, 0x95, 0x5a, 0x08, 0x38, 0xf4, + 0xd4, 0x14, 0x55, 0x01, 0x21, 0xc7, 0x22, 0x9d, 0x99, 0x90, 0x54, 0xdb, 0xa1, 0x6f, 0x7c, 0x4c, + 0x90, 0xbc, 0xb7, 0x0c, 0x5f, 0x71, 0x53, 0x95, 0x41, 0xbd, 0x29, 0x97, 0xf8, 0x3e, 0x74, 0x53, + 0xee, 0x8b, 0x34, 0x30, 0x51, 0x53, 0x3d, 0xcf, 0x8e, 0x86, 0xe9, 0x78, 0xe9, 0x6d, 0x28, 0x42, + 0xfb, 0xae, 0x4c, 0x38, 0x55, 0x23, 0xe8, 0xd0, 0xd2, 0x6a, 0x8e, 0xc0, 0x9d, 0xdf, 0x0b, 0xd8, + 0xdf, 0x85, 0x41, 0x41, 0x4b, 0x71, 0x66, 0xeb, 0x5e, 0x6c, 0x17, 0x91, 0x93, 0x0b, 0x3e, 0x71, + 0xeb, 0xd0, 0xf6, 0xfa, 0x3b, 0xd4, 0x49, 0xc7, 0xd2, 0x8b, 0xe1, 0x35, 0x94, 0x7d, 0x00, 0x3d, + 0x99, 0x44, 0xa1, 0x32, 0x0c, 0x20, 0x4d, 0xed, 0x46, 0x97, 0x80, 0x3a, 0x1c, 0x2c, 0x2f, 0xda, + 0xc2, 0xd6, 0xf7, 0xda, 0xc2, 0xf6, 0xf2, 0x16, 0xfe, 0x04, 0x06, 0x7e, 0xca, 0x03, 0x1e, 0xab, + 0xd0, 0x8b, 0x5c, 0xe9, 0x8b, 0xc4, 0xaa, 0xbe, 0xd5, 0x02, 0x7e, 0x84, 0x60, 0xf6, 0x53, 0xb8, + 0xe2, 0x8b, 0x58, 0xf1, 0x58, 0xb9, 0x92, 0x3f, 0xcf, 0x78, 0xec, 0x73, 0x37, 0xce, 0x66, 0x27, + 0x3c, 0x35, 0x69, 0xd2, 0x4b, 0x06, 0x7d, 0x64, 0xb0, 0x4f, 0x08, 0xc9, 0xee, 0xc1, 0x86, 0xde, + 0x9e, 0x85, 0x4e, 0x3a, 0x31, 0xc7, 0x68, 0xa7, 0xe6, 0x7b, 0x6c, 0xc1, 0xfa, 0xd4, 0x93, 0x6e, + 0xca, 0x65, 0x18, 0x64, 0x5e, 0x64, 0x4e, 0xa8, 0x49, 0x20, 0xac, 0x4d, 0x3d, 0xe9, 0x18, 0x8c, + 0x89, 0xea, 0xdc, 0x83, 0x8d, 0x05, 0x5a, 0x77, 0xea, 0xc9, 0x29, 0xb9, 0xcf, 0x6d, 0x87, 0xa5, + 0x73, 0xd4, 0x5f, 0x7a, 0x72, 0x7a, 0xf5, 0x01, 0x6c, 0x5c, 0xb4, 0x21, 0xdf, 0x95, 0x5b, 0x68, + 0x97, 0x72, 0x0b, 0xa6, 0x82, 0xe9, 0x7f, 0xae, 0xc0, 0x25, 0xbb, 0xdf, 0x64, 0xf8, 0xe5, 0x4c, + 0x7d, 0x9d, 0x74, 0x24, 0x1a, 0x8b, 0xb9, 0x2f, 0xdd, 0x76, 0x40, 0x83, 0xc8, 0x71, 0xde, 0x84, + 0x81, 0x21, 0x28, 0x98, 0x5f, 0xbf, 0xa5, 0x1f, 0xe4, 0x43, 0xd1, 0x11, 0xa0, 0x0f, 0x1c, 0xf3, + 0x14, 0xd7, 0x28, 0xa0, 0xda, 0x33, 0xea, 0x42, 0xcc, 0x4e, 0x1f, 0x68, 0x71, 0x96, 0xe5, 0xd8, + 0x1d, 0x60, 0xfc, 0x79, 0xe6, 0x45, 0xa1, 0x3a, 0x77, 0xc7, 0x21, 0x8f, 0x02, 0x4a, 0x64, 0xe9, + 0xf2, 0x95, 0x81, 0xc5, 0x3c, 0x46, 0xc4, 0x5e, 0x20, 0x4b, 0x33, 0x31, 0xf9, 0x91, 0xfc, 0x00, + 0x98, 0x99, 0x1c, 0x11, 0x78, 0x2f, 0xb8, 0xf8, 0xac, 0x34, 0x2e, 0x3e, 0x2b, 0x1f, 0xc1, 0xea, + 0xe2, 0x9e, 0xeb, 0x9c, 0x45, 0x5f, 0xce, 0xef, 0xf7, 0x45, 0x4c, 0xd8, 0xba, 0x90, 0x09, 0xcd, + 0xa2, 0xff, 0xef, 0x15, 0xd8, 0x30, 0x8b, 0xbe, 0x2b, 0xa2, 0x6c, 0x86, 0xda, 0x36, 0x09, 0xe3, + 0x09, 0x2a, 0xe4, 0x99, 0xd0, 0x66, 0x49, 0x49, 0xfc, 0xc1, 0x4c, 0xe4, 0xb2, 0x78, 0x13, 0x06, + 0xa1, 0xee, 0x99, 0xaf, 0x8b, 0x2d, 0x22, 0x33, 0x70, 0xb3, 0x2a, 0xc8, 0x85, 0x32, 0xf6, 0x12, + 0x39, 0x15, 0xca, 0x90, 0x92, 0x10, 0xd7, 0x6b, 0xbe, 0x66, 0x51, 0x44, 0x4d, 0xd6, 0xe1, 0x1d, + 0x60, 0x7e, 0x96, 0xa6, 0x78, 0x3e, 0x4a, 0xe4, 0x3a, 0x8f, 0x30, 0x30, 0x98, 0x82, 0xfa, 0x03, + 0x68, 0xce, 0x44, 0x61, 0x11, 0xcc, 0x19, 0x77, 0x4e, 0x63, 0x26, 0x88, 0x43, 0xae, 0xa2, 0xd5, + 0xf2, 0x3c, 0x0b, 0x53, 0x1e, 0x58, 0x3d, 0x68, 0xdb, 0x46, 0x49, 0x4e, 0xc3, 0x20, 0xe0, 0xb1, + 0x89, 0x61, 0xb7, 0x42, 0xf9, 0x25, 0xb5, 0x71, 0x9b, 0x02, 0x3e, 0xf6, 0xb2, 0x48, 0xb9, 0x71, + 0x16, 0xd1, 0xa9, 0x88, 0x4c, 0x95, 0xd0, 0xaa, 0x41, 0x3c, 0xc9, 0x22, 0x3c, 0x11, 0x91, 0xd9, + 0x52, 0xd2, 0x25, 0xc8, 0x82, 0xee, 0x34, 0x8c, 0x15, 0x89, 0x8a, 0x36, 0x6d, 0x29, 0x22, 0x90, + 0x09, 0xbf, 0x0c, 0x63, 0x35, 0xfa, 0xb3, 0x15, 0xb8, 0x6c, 0x16, 0xfe, 0xc8, 0x2c, 0x80, 0xd1, + 0x8f, 0x64, 0xb1, 0xdb, 0xe5, 0x32, 0x29, 0x86, 0xaa, 0x03, 0x16, 0xb4, 0x47, 0x13, 0x2e, 0xb8, + 0x6b, 0xc5, 0x54, 0x0f, 0x59, 0xbe, 0xba, 0x03, 0x6c, 0x89, 0xaf, 0xa4, 0x89, 0x19, 0x0d, 0x16, + 0x18, 0x4b, 0xb2, 0xcf, 0xe0, 0xf2, 0x8c, 0x2b, 0x8f, 0x0e, 0x42, 0x24, 0x7c, 0x8f, 0x7a, 0xd1, + 0x91, 0xd7, 0xcb, 0xbd, 0x61, 0xb1, 0xfb, 0x06, 0x89, 0x87, 0x1e, 0xdf, 0x31, 0xf3, 0xe2, 0x70, + 0xcc, 0xa5, 0x22, 0x3d, 0xaf, 0x7b, 0x68, 0xc3, 0x63, 0x60, 0x31, 0xa8, 0xc9, 0x89, 0x9a, 0x2c, + 0xc6, 0xb1, 0xde, 0xc4, 0x06, 0xd1, 0x34, 0x53, 0x3e, 0x36, 0x7b, 0xd7, 0xc3, 0xbd, 0x8a, 0xc3, + 0x78, 0xa2, 0xcb, 0x20, 0x9b, 0xda, 0xa6, 0xb3, 0xc0, 0x03, 0x11, 0xf0, 0xd1, 0x9f, 0xd6, 0x72, + 0x1e, 0x3d, 0x34, 0xf0, 0x23, 0xe5, 0x29, 0xc9, 0x6e, 0x42, 0x3f, 0x9f, 0xbc, 0xd6, 0x91, 0x7a, + 0xad, 0x7a, 0x16, 0xfa, 0x00, 0x81, 0xc8, 0x7e, 0xf3, 0xb3, 0xd5, 0xb4, 0x2b, 0x3a, 0xeb, 0x57, + 0x9e, 0xae, 0xa6, 0xc7, 0x61, 0x2d, 0xbd, 0x26, 0x35, 0x05, 0x8a, 0x16, 0xaa, 0xc9, 0x3e, 0x29, + 0x16, 0x41, 0xba, 0x92, 0x47, 0xba, 0x80, 0xa5, 0x36, 0x3f, 0xaa, 0x3c, 0x32, 0x08, 0x3c, 0x9a, + 0x05, 0x79, 0x92, 0x66, 0x31, 0x0f, 0x8c, 0x4a, 0x5f, 0xcd, 0xe1, 0x87, 0x04, 0xc6, 0x09, 0xe7, + 0x92, 0xa9, 0x34, 0x74, 0x43, 0x0f, 0x1d, 0x18, 0xc9, 0x54, 0x0c, 0x8d, 0x3c, 0x5a, 0xd0, 0x9b, + 0xb1, 0xb5, 0x80, 0x58, 0xcd, 0xa9, 0xcd, 0xd8, 0x3f, 0x83, 0x61, 0x4e, 0xab, 0xbf, 0xae, 0x78, + 0x41, 0x4b, 0x2b, 0x1f, 0xdb, 0x85, 0x3e, 0x33, 0x7f, 0xc9, 0xa7, 0x70, 0x79, 0xb1, 0xa3, 0x79, + 0x53, 0x9b, 0xba, 0xad, 0xcf, 0x75, 0x2b, 0xbe, 0x24, 0xdf, 0x5f, 0xdf, 0xf3, 0xa7, 0xdc, 0x9d, + 0x86, 0x4a, 0x27, 0xd2, 0xab, 0xce, 0x9a, 0x45, 0xed, 0x22, 0xe6, 0xcb, 0x50, 0xc9, 0x0b, 0xe8, + 0x67, 0xa1, 0x94, 0x46, 0x2b, 0xce, 0xd3, 0x1f, 0x84, 0x52, 0x8e, 0xfe, 0x31, 0x40, 0xd7, 0x5a, + 0x8a, 0x54, 0x72, 0x77, 0xa7, 0x6c, 0x74, 0x77, 0xb6, 0x07, 0xd6, 0x7a, 0x46, 0x92, 0x1d, 0xa5, + 0x52, 0x9b, 0x76, 0xd0, 0xc6, 0xf8, 0x9c, 0xbd, 0xb3, 0x42, 0x06, 0x42, 0x61, 0xef, 0xec, 0xc0, + 0x5a, 0xc9, 0x82, 0x74, 0x95, 0x50, 0x5e, 0x64, 0x8c, 0xf2, 0x52, 0x59, 0x47, 0x89, 0xc4, 0x59, + 0xc5, 0x86, 0xb6, 0x2d, 0x8e, 0x91, 0x1a, 0x8d, 0x7d, 0x5f, 0x44, 0xb6, 0x40, 0x6c, 0xc1, 0xd8, + 0x47, 0x0c, 0x25, 0xac, 0x53, 0x8e, 0xbe, 0xa3, 0x7c, 0x1e, 0x99, 0x13, 0xd4, 0xd6, 0x90, 0xa3, + 0xe7, 0x51, 0x3e, 0x41, 0x32, 0xa6, 0x1b, 0xe4, 0x47, 0xd0, 0x04, 0xc9, 0xa7, 0xfa, 0x04, 0x3a, + 0x22, 0x0d, 0x27, 0x21, 0x65, 0xac, 0xb4, 0x81, 0xb3, 0xf8, 0x12, 0xd0, 0x04, 0xbb, 0xf8, 0xaa, + 0x11, 0x34, 0x8c, 0xfa, 0x5f, 0x4e, 0x62, 0x1b, 0x0c, 0x1a, 0x44, 0x52, 0xa5, 0xa1, 0xaf, 0x70, + 0x3a, 0xfa, 0x44, 0xea, 0x5a, 0xa3, 0x9e, 0x06, 0x1f, 0x3d, 0x8f, 0x28, 0x69, 0x77, 0x0b, 0x56, + 0x7d, 0x52, 0x17, 0xfa, 0x40, 0x45, 0x3c, 0xa6, 0x3d, 0xad, 0x3b, 0x3d, 0x0d, 0xc6, 0xf9, 0xed, + 0xf3, 0xd8, 0xd4, 0x35, 0x79, 0x51, 0x84, 0x1e, 0xa3, 0xf0, 0x02, 0x93, 0xb6, 0xee, 0x5a, 0xe0, + 0xbe, 0xf0, 0x02, 0xf6, 0x73, 0xb8, 0x8a, 0x38, 0x97, 0xcf, 0x12, 0x75, 0x8e, 0xfa, 0x8d, 0xa7, + 0xa1, 0xef, 0x7a, 0xd2, 0x7d, 0xc5, 0x53, 0x61, 0x2a, 0x21, 0x2e, 0x23, 0xc5, 0x23, 0x24, 0x78, + 0xa2, 0xf1, 0x3b, 0xf2, 0x1b, 0x9e, 0x0a, 0xf6, 0x0d, 0x25, 0xee, 0x2e, 0x32, 0xdf, 0xad, 0xab, + 0xff, 0x7e, 0xb1, 0x57, 0xaf, 0xa1, 0xa4, 0x32, 0x11, 0x44, 0x38, 0xd6, 0xe8, 0xa3, 0xfe, 0xec, + 0x2b, 0x60, 0x56, 0xc1, 0x11, 0xe7, 0x2b, 0x4f, 0x9e, 0x4a, 0x8a, 0x02, 0x74, 0xb6, 0xdf, 0x7d, + 0xa3, 0x8d, 0xea, 0x58, 0xcd, 0x88, 0x40, 0x04, 0x48, 0xf6, 0x27, 0xb0, 0x91, 0x0f, 0x66, 0x6c, + 0x19, 0x1a, 0x4e, 0x07, 0x09, 0xae, 0x2f, 0x0f, 0x37, 0x67, 0x02, 0x39, 0x76, 0x26, 0x1a, 0xac, + 0x87, 0xfc, 0x35, 0xac, 0xda, 0x21, 0xf5, 0xaa, 0xcb, 0xe1, 0x80, 0x46, 0x7b, 0x6f, 0x69, 0xb4, + 0x39, 0xdd, 0x9e, 0xeb, 0x67, 0x0d, 0xc5, 0x0f, 0xcd, 0x35, 0xb9, 0xd5, 0x32, 0xc3, 0x35, 0xe2, + 0x91, 0x1b, 0x4b, 0x23, 0x2d, 0x28, 0x2b, 0xc7, 0x4e, 0xc1, 0xc2, 0xd9, 0x7d, 0xb8, 0x64, 0x07, + 0x13, 0x94, 0x67, 0x75, 0x43, 0x41, 0x29, 0x58, 0xa6, 0x4d, 0x2c, 0x83, 0xd4, 0x39, 0xd8, 0x3d, + 0xe1, 0xf0, 0x31, 0xfb, 0x25, 0x5c, 0xb3, 0x5d, 0xb4, 0x16, 0x26, 0x8f, 0x34, 0xff, 0xa8, 0x75, + 0xd2, 0x5d, 0x43, 0x43, 0xa2, 0xf5, 0x32, 0x7a, 0xa0, 0x76, 0xfa, 0x9b, 0x30, 0xa0, 0x6a, 0x4f, + 0xdc, 0x56, 0x91, 0x06, 0x61, 0xec, 0x45, 0xc3, 0x0d, 0xe2, 0x9a, 0x3e, 0xc2, 0x1d, 0xf1, 0xf2, + 0xa9, 0x86, 0xb2, 0x63, 0xb8, 0x6c, 0x5f, 0x94, 0x8b, 0x19, 0x89, 0xaa, 0x84, 0xc2, 0x8e, 0x17, + 0x2d, 0xdc, 0x9c, 0xc2, 0x71, 0xec, 0x16, 0xce, 0xab, 0xa1, 0x87, 0x70, 0x7d, 0x61, 0x6b, 0x67, + 0xde, 0x99, 0x3b, 0xe3, 0x33, 0x91, 0x9e, 0x1b, 0x05, 0x72, 0x99, 0x04, 0xd8, 0xb5, 0xb9, 0x4d, + 0x3c, 0xf0, 0xce, 0x0e, 0x88, 0x46, 0xab, 0x93, 0x5f, 0xc1, 0x3b, 0x0b, 0xa3, 0xe8, 0xe2, 0x49, + 0x1e, 0x7b, 0x27, 0x11, 0x0f, 0x86, 0x57, 0xe8, 0x8b, 0xde, 0x9e, 0x1b, 0xe2, 0x08, 0x29, 0x1e, + 0x69, 0x02, 0x63, 0xd0, 0xf9, 0x00, 0xfa, 0xe6, 0x00, 0x89, 0xc3, 0x8f, 0xa0, 0xa9, 0x4e, 0x22, + 0x2a, 0xc2, 0xa9, 0x5c, 0x58, 0x84, 0xd3, 0x50, 0x27, 0x28, 0x28, 0x4a, 0xfe, 0xb1, 0x56, 0x8b, + 0xa6, 0x85, 0x46, 0x7b, 0x14, 0xce, 0x42, 0x65, 0x54, 0xa0, 0x6e, 0x8c, 0x4e, 0xa0, 0x4d, 0x23, + 0xd0, 0x3b, 0xf2, 0x6a, 0xd9, 0xca, 0x9b, 0xab, 0x65, 0x3f, 0x81, 0xae, 0x71, 0x29, 0x5e, 0x57, + 0x7e, 0xdb, 0xd1, 0x78, 0x7c, 0x96, 0xa3, 0x3b, 0xd0, 0x26, 0x7f, 0x82, 0xde, 0x71, 0x1d, 0x3a, + 0x54, 0xd7, 0xe5, 0x9e, 0x44, 0xc2, 0x3f, 0xb5, 0x1e, 0x00, 0x81, 0x1e, 0x20, 0x64, 0x04, 0xd0, + 0x7a, 0x16, 0x87, 0x22, 0xde, 0x89, 0xa2, 0xd1, 0x5f, 0x35, 0xa0, 0x8d, 0x86, 0x07, 0x05, 0x67, + 0xd0, 0x77, 0x23, 0xee, 0xa0, 0x84, 0xed, 0xcc, 0x4b, 0x4c, 0x3d, 0x70, 0x07, 0x81, 0x48, 0x75, + 0xe0, 0x25, 0x0b, 0xf9, 0xdc, 0x95, 0x85, 0x7c, 0xee, 0xfb, 0xfa, 0x2a, 0x89, 0xae, 0x2c, 0xe3, + 0xb6, 0xc0, 0x94, 0x06, 0x78, 0xa0, 0x41, 0x68, 0x10, 0x11, 0x89, 0x17, 0x91, 0x11, 0x85, 0x2e, + 0x5a, 0x24, 0x4d, 0xea, 0x97, 0x98, 0x73, 0xc7, 0x20, 0x8e, 0xb8, 0x16, 0xfa, 0xa5, 0x88, 0x5c, + 0x7d, 0x31, 0x22, 0x77, 0x1b, 0xc0, 0x17, 0x71, 0x40, 0x76, 0xda, 0x42, 0xca, 0x4d, 0xe7, 0x5d, + 0x0b, 0xec, 0xf7, 0x88, 0xff, 0x7e, 0x04, 0x83, 0x9c, 0x02, 0xcd, 0x30, 0x3f, 0xce, 0x9d, 0x5c, + 0x43, 0xe5, 0xf0, 0xf1, 0x6e, 0xac, 0x16, 0x03, 0xc5, 0xed, 0xa5, 0x40, 0xf1, 0xaf, 0x61, 0x7d, + 0x21, 0xd2, 0x83, 0xe6, 0xa5, 0x29, 0x39, 0xfd, 0x21, 0xb7, 0x1c, 0xde, 0x86, 0x16, 0x55, 0xf0, + 0x04, 0x59, 0x62, 0x14, 0x42, 0x33, 0x94, 0x14, 0xd0, 0x7f, 0x5d, 0x30, 0xba, 0xfb, 0xff, 0x2b, + 0x18, 0xdd, 0xfb, 0x7e, 0xc1, 0xe8, 0xfe, 0xf7, 0x0b, 0x46, 0x2f, 0x04, 0x6f, 0x57, 0x17, 0x73, + 0x3e, 0xaf, 0xcd, 0xb0, 0x0c, 0x5e, 0x9b, 0x61, 0xf9, 0x8e, 0xf4, 0xc8, 0xda, 0x1b, 0xd3, 0x23, + 0xdf, 0x23, 0x3f, 0xc3, 0xbe, 0x2b, 0x3f, 0x73, 0x0b, 0x56, 0x55, 0xea, 0xf9, 0xa7, 0xda, 0xdd, + 0x39, 0xe5, 0xe7, 0xd2, 0xe4, 0x83, 0x7a, 0x04, 0x46, 0x67, 0xe7, 0x2b, 0x7e, 0x2e, 0x47, 0xcf, + 0x00, 0xc8, 0x0f, 0xa4, 0x4f, 0x7b, 0x1d, 0x6f, 0x54, 0x7e, 0x28, 0x6f, 0x8c, 0xfe, 0x4f, 0x05, + 0xe0, 0xc8, 0x9b, 0x25, 0x3a, 0x90, 0xca, 0xfe, 0x18, 0x3a, 0x92, 0x5a, 0xe5, 0x34, 0x7a, 0x49, + 0x5b, 0x16, 0xa4, 0xe6, 0x91, 0xbc, 0x3e, 0x90, 0xf9, 0x33, 0xb1, 0xb5, 0x1e, 0x21, 0x2f, 0x70, + 0xab, 0x5b, 0x02, 0x0a, 0xb0, 0xdd, 0x84, 0xbe, 0x21, 0x48, 0x78, 0xea, 0xf3, 0x58, 0xcb, 0xba, + 0x8a, 0xd3, 0xd3, 0xd0, 0x43, 0x0d, 0x64, 0xf7, 0x73, 0x32, 0xab, 0x97, 0x96, 0x73, 0x41, 0xa6, + 0x8b, 0x51, 0x4c, 0xa3, 0x6d, 0xfb, 0x29, 0x34, 0x91, 0x16, 0xd4, 0xf0, 0x7d, 0x83, 0xb7, 0x58, + 0x07, 0x9a, 0x66, 0xd4, 0x41, 0x85, 0xf5, 0xa0, 0x4d, 0x37, 0x49, 0x08, 0xb7, 0x32, 0xfa, 0xf7, + 0x6b, 0xd0, 0xd9, 0x8b, 0xa5, 0x4a, 0x33, 0xcd, 0xc2, 0xc5, 0x85, 0x89, 0x3a, 0x5d, 0x98, 0x30, + 0xb5, 0x92, 0xfa, 0x33, 0xa8, 0x56, 0xf2, 0x13, 0x68, 0x9a, 0xab, 0x39, 0x26, 0xba, 0x7e, 0xe1, + 0xbd, 0x1e, 0x4b, 0xc3, 0xb6, 0xa0, 0x15, 0x98, 0x3b, 0x43, 0xa6, 0x56, 0xa0, 0x74, 0x91, 0xc7, + 0xde, 0x26, 0x72, 0x72, 0x1a, 0xf6, 0x3e, 0x54, 0xbd, 0xc9, 0xc4, 0xb8, 0xd6, 0xab, 0x05, 0x29, + 0x59, 0x4a, 0x0e, 0xe2, 0xd8, 0x5d, 0x68, 0x93, 0xf8, 0xa4, 0x72, 0x99, 0xc6, 0xe2, 0x98, 0xb6, + 0x16, 0x47, 0x4b, 0x54, 0x0a, 0xcc, 0xdf, 0x85, 0x76, 0x24, 0x44, 0xa2, 0x3b, 0x34, 0x17, 0x3b, + 0xd8, 0x0a, 0x0a, 0xa7, 0x15, 0xd9, 0x5a, 0x8a, 0x5b, 0xd0, 0x40, 0x1b, 0x5c, 0x24, 0xc6, 0x76, + 0x2d, 0xcd, 0x83, 0x2a, 0x09, 0x9c, 0xba, 0xc4, 0x1f, 0xb6, 0x0d, 0xa0, 0xf9, 0x9f, 0x46, 0x6e, + 0x2f, 0x2e, 0x47, 0x9e, 0x34, 0xc4, 0x43, 0x6a, 0xf3, 0x87, 0x0f, 0x60, 0xa0, 0x13, 0x44, 0xa5, + 0x9e, 0x60, 0x6b, 0x03, 0x6d, 0xcf, 0xf9, 0x9c, 0xa3, 0xd3, 0x4f, 0xe7, 0x73, 0x90, 0x1f, 0x43, + 0x33, 0xd1, 0x19, 0x12, 0x92, 0x30, 0x9d, 0xed, 0xb5, 0xa2, 0xab, 0x49, 0x9d, 0x38, 0x96, 0x82, + 0xfd, 0x11, 0xf4, 0x75, 0x0d, 0xdb, 0xd8, 0xa4, 0x0a, 0x28, 0xbc, 0x36, 0x77, 0x25, 0x64, 0x2e, + 0x93, 0xe0, 0xf4, 0xd4, 0x5c, 0x62, 0xe1, 0x17, 0xd0, 0x2b, 0x4a, 0xf4, 0x7d, 0x2f, 0x26, 0xb9, + 0x43, 0x21, 0x7b, 0xdb, 0xbd, 0xec, 0x12, 0x39, 0x5d, 0x5e, 0x76, 0x90, 0x36, 0xa1, 0x61, 0xea, + 0x2a, 0x07, 0xd4, 0xab, 0x74, 0x91, 0x53, 0x57, 0x52, 0x39, 0x06, 0x8f, 0x6b, 0x59, 0x94, 0x8c, + 0x91, 0xf5, 0x36, 0xb7, 0x96, 0x79, 0xbd, 0x98, 0xd3, 0xce, 0x4b, 0xc5, 0xd8, 0xa3, 0xf9, 0x12, + 0x36, 0x5d, 0xaa, 0xb5, 0x4e, 0x5d, 0xdf, 0xbe, 0xa0, 0xab, 0xae, 0xd8, 0x72, 0x56, 0x93, 0x85, + 0x4a, 0xb8, 0x3b, 0xd0, 0x12, 0x69, 0x40, 0x35, 0xb4, 0x94, 0x50, 0xa6, 0xf5, 0xa4, 0xca, 0x3d, + 0x7d, 0x1f, 0x89, 0x84, 0x47, 0x53, 0xe8, 0x06, 0x1a, 0x16, 0x49, 0x2a, 0xc8, 0xd4, 0x24, 0x11, + 0x77, 0x69, 0xd9, 0xb0, 0x30, 0x78, 0x12, 0x70, 0x1f, 0x42, 0xd3, 0x56, 0x8b, 0x5e, 0x5e, 0xa2, + 0xb4, 0x28, 0xf6, 0x29, 0xac, 0xce, 0x0b, 0x34, 0x39, 0xbc, 0xb2, 0x44, 0xdd, 0x9f, 0x93, 0x5f, + 0xa8, 0x8d, 0x8d, 0xb5, 0x34, 0x5c, 0xf2, 0xb0, 0x34, 0x02, 0x9d, 0x30, 0x63, 0x67, 0xbd, 0xbd, + 0xec, 0x84, 0x19, 0x9b, 0x6b, 0x08, 0xcd, 0x50, 0x3e, 0x0e, 0x53, 0xa9, 0x86, 0x57, 0xad, 0x76, + 0xa4, 0x26, 0x5a, 0x69, 0xa1, 0x44, 0x35, 0x31, 0xbc, 0x66, 0x6f, 0xb0, 0x91, 0xd2, 0xb8, 0x0d, + 0x0d, 0x53, 0x49, 0x7b, 0x63, 0xe9, 0x44, 0x9b, 0xea, 0x73, 0xc7, 0x50, 0xb0, 0x9f, 0x40, 0x93, + 0xca, 0x28, 0x45, 0x32, 0x7c, 0x7f, 0x91, 0x03, 0x74, 0x2d, 0xa3, 0xd3, 0x88, 0x74, 0x4d, 0xe3, + 0xc7, 0xd0, 0xb4, 0x46, 0xca, 0x68, 0x91, 0xab, 0x8d, 0xb1, 0xe2, 0x58, 0x0a, 0x76, 0x13, 0xea, + 0x33, 0x94, 0x63, 0xc3, 0x0f, 0x16, 0x4f, 0xa8, 0x16, 0x6f, 0x1a, 0xcb, 0x3e, 0x87, 0x8e, 0x24, + 0xfb, 0x54, 0xb3, 0xee, 0x87, 0xb6, 0x04, 0x71, 0xfe, 0xda, 0x2b, 0x31, 0x2e, 0xc8, 0xc2, 0x90, + 0xfd, 0x7b, 0x70, 0xb5, 0x5c, 0xbf, 0x68, 0x8b, 0x1b, 0x4d, 0x70, 0xf2, 0x26, 0x8d, 0xf2, 0xfe, + 0x05, 0x1c, 0x36, 0x5f, 0x06, 0xe9, 0x5c, 0x49, 0x5e, 0x53, 0x1f, 0xf9, 0x79, 0xae, 0x25, 0xf0, + 0x50, 0x0e, 0x6f, 0x2d, 0x4d, 0x2b, 0xd7, 0x33, 0x56, 0x77, 0x90, 0x7a, 0xfa, 0x02, 0xba, 0xe3, + 0xec, 0xd5, 0xab, 0x73, 0x1b, 0x58, 0xff, 0x88, 0xfa, 0x95, 0xc2, 0x03, 0xa5, 0x92, 0x49, 0xa7, + 0x33, 0x2e, 0xd5, 0x4f, 0x5e, 0x81, 0xa6, 0x1f, 0xbb, 0x5e, 0x10, 0xa4, 0xc3, 0x4d, 0x5d, 0x32, + 0xe9, 0xc7, 0x3b, 0x41, 0x40, 0x77, 0x77, 0x45, 0xc2, 0xe9, 0x52, 0x9d, 0x1b, 0x06, 0xc3, 0x9f, + 0x68, 0x7d, 0x65, 0x41, 0x7b, 0x01, 0x5d, 0xee, 0xb5, 0x3e, 0x75, 0x18, 0x0c, 0x6f, 0x9b, 0xcb, + 0xbd, 0x06, 0xb4, 0x17, 0xa0, 0xbd, 0x8a, 0x0e, 0x88, 0x85, 0x0c, 0x3f, 0xd6, 0xc9, 0x8a, 0x99, + 0x77, 0x76, 0x68, 0x40, 0x78, 0xb6, 0x75, 0xea, 0x8f, 0xa4, 0xdd, 0x9d, 0xc5, 0xb3, 0x9d, 0xa7, + 0x50, 0x9d, 0x76, 0x98, 0x67, 0x53, 0x49, 0x1e, 0x90, 0x04, 0x73, 0xa3, 0xed, 0xe1, 0x27, 0xcb, + 0xf2, 0xc0, 0x64, 0x88, 0x51, 0x1e, 0xd8, 0x64, 0xf1, 0x36, 0x80, 0x16, 0x75, 0xb4, 0xd9, 0x5b, + 0x8b, 0x7d, 0x72, 0x27, 0xc2, 0xd1, 0xb7, 0x05, 0x68, 0xab, 0xb7, 0x01, 0x28, 0x35, 0xa0, 0xfb, + 0xdc, 0x5d, 0xec, 0x93, 0x3b, 0x05, 0x4e, 0xfb, 0x45, 0xee, 0x1f, 0xdc, 0x85, 0x76, 0x86, 0xe6, + 0x3f, 0x1a, 0xe0, 0xc3, 0x7b, 0x8b, 0x67, 0xc0, 0x7a, 0x06, 0x4e, 0x2b, 0x33, 0x4f, 0xf8, 0x12, + 0x52, 0x59, 0x64, 0xbd, 0x0c, 0xef, 0x2f, 0xbe, 0x24, 0x77, 0x1f, 0x1c, 0xd2, 0x6c, 0xda, 0x93, + 0xf8, 0x1c, 0x3a, 0x7a, 0xd1, 0x74, 0xa7, 0xed, 0x45, 0x1e, 0x29, 0xcc, 0x21, 0x47, 0xaf, 0xae, + 0xee, 0x76, 0x13, 0xea, 0x5e, 0x92, 0x44, 0xe7, 0xc3, 0x4f, 0x17, 0x0f, 0xc6, 0x0e, 0x82, 0x1d, + 0x8d, 0x45, 0x56, 0x9a, 0x65, 0x91, 0x0a, 0x6d, 0x81, 0xff, 0x67, 0x8b, 0xac, 0x54, 0xba, 0xff, + 0xe4, 0x74, 0x66, 0xa5, 0xcb, 0x50, 0x77, 0xa0, 0x95, 0x08, 0xa9, 0xdc, 0x60, 0x16, 0x0d, 0x3f, + 0x5f, 0xd2, 0x3e, 0xba, 0xb0, 0xdd, 0x69, 0x26, 0xe6, 0x66, 0xc0, 0xdc, 0xad, 0xbc, 0x9f, 0xce, + 0xdf, 0xca, 0x63, 0xdb, 0xd0, 0x9d, 0x89, 0x78, 0x22, 0x82, 0x13, 0xbd, 0xfa, 0x3f, 0x2b, 0x97, + 0x4d, 0x1f, 0x20, 0x86, 0x56, 0xbe, 0x63, 0x88, 0xb0, 0xa1, 0xfd, 0xce, 0xdf, 0xd4, 0x5a, 0x6b, + 0x03, 0x36, 0xfa, 0x1c, 0xba, 0x3b, 0x74, 0x49, 0x3f, 0x94, 0x24, 0x6b, 0x6f, 0x42, 0x2d, 0x2f, + 0x14, 0xc8, 0x85, 0x38, 0x51, 0xbc, 0xe2, 0x7b, 0xf1, 0x58, 0x38, 0x84, 0x1e, 0xfd, 0xbb, 0x1a, + 0x34, 0x8e, 0x44, 0x96, 0xfa, 0xfc, 0xbb, 0x6f, 0x96, 0xbc, 0x6b, 0x59, 0x2a, 0x2e, 0xca, 0x8d, + 0x35, 0xf7, 0x10, 0x7a, 0xb1, 0x50, 0xb2, 0x5d, 0xd4, 0x20, 0x6c, 0x40, 0x5d, 0xbb, 0x8f, 0x3a, + 0xb4, 0xad, 0x1b, 0x74, 0x9c, 0x32, 0x39, 0xa5, 0x9b, 0xf8, 0x26, 0x59, 0x53, 0x73, 0xc0, 0x82, + 0xf6, 0x02, 0x8a, 0x61, 0x59, 0x02, 0x3a, 0xaf, 0x0d, 0x13, 0xa3, 0x36, 0x40, 0x3a, 0xb5, 0xb6, + 0xbe, 0xa1, 0xf9, 0x9a, 0xfa, 0x86, 0xf7, 0xa0, 0x16, 0xdb, 0x4a, 0xf8, 0x1c, 0x4f, 0x57, 0xa6, + 0x09, 0xce, 0x6e, 0x43, 0x7e, 0x1d, 0xc6, 0x98, 0x2d, 0xaf, 0xbf, 0x2e, 0xb3, 0x0d, 0xed, 0xfc, + 0x6f, 0x1d, 0x8c, 0xa5, 0xb2, 0xb1, 0x55, 0xfc, 0xd1, 0xc3, 0xb1, 0x7d, 0x72, 0x0a, 0xb2, 0x37, + 0x67, 0xe9, 0x3b, 0x3f, 0x2a, 0x4b, 0x6f, 0xdc, 0x38, 0x5f, 0xc4, 0x52, 0x99, 0x28, 0x5d, 0x33, + 0x94, 0xbb, 0xd8, 0x64, 0x7f, 0x00, 0xbd, 0x94, 0xfb, 0x2f, 0xdc, 0x99, 0x9c, 0xe8, 0x57, 0xf4, + 0xca, 0x17, 0xec, 0x66, 0x72, 0xf2, 0x25, 0x55, 0x10, 0x18, 0xaf, 0xaa, 0x83, 0xb4, 0x07, 0x72, + 0x42, 0xa3, 0x7e, 0x0c, 0x6b, 0x33, 0x3e, 0x3b, 0xe1, 0xa9, 0x9c, 0x86, 0x89, 0x95, 0xab, 0x7d, + 0xaa, 0x74, 0x18, 0x14, 0x08, 0x3d, 0x97, 0xd1, 0x3f, 0xaa, 0x40, 0x0b, 0x57, 0x11, 0x79, 0x89, + 0x31, 0xa8, 0xcd, 0xfc, 0x24, 0x33, 0xc6, 0x32, 0x3d, 0x9b, 0xbf, 0x8a, 0xd0, 0x5c, 0x62, 0xfe, + 0x2a, 0x82, 0xf6, 0x50, 0xe7, 0x9e, 0xe8, 0x59, 0x5f, 0xd3, 0x3e, 0xa7, 0xf0, 0xa4, 0xe6, 0x0c, + 0xdb, 0x64, 0x97, 0xa0, 0xe1, 0xc7, 0xe4, 0x31, 0xeb, 0x1c, 0x5e, 0xdd, 0x8f, 0xd1, 0x53, 0xd6, + 0xe0, 0xa2, 0x2c, 0xbb, 0xee, 0xc7, 0x7b, 0xc1, 0xd9, 0xe8, 0x5f, 0x57, 0x60, 0xed, 0x30, 0x15, + 0x3e, 0x97, 0x72, 0x1f, 0x95, 0x3d, 0xe5, 0x4b, 0xf0, 0x8d, 0x14, 0x5e, 0xd6, 0xa9, 0x09, 0x7a, + 0x46, 0x1e, 0xd6, 0xe1, 0x8c, 0xdc, 0x25, 0xa9, 0x3a, 0x6d, 0x82, 0x90, 0x47, 0x92, 0xa3, 0x4b, + 0x79, 0x78, 0x8d, 0xa6, 0xc0, 0xf4, 0x4d, 0xe8, 0x17, 0x19, 0x9e, 0x52, 0xc9, 0x40, 0x71, 0x85, + 0x94, 0x46, 0xb9, 0x0e, 0x1d, 0x53, 0xd8, 0x41, 0xc3, 0xe8, 0x5c, 0x03, 0x68, 0x10, 0x8e, 0x33, + 0x9a, 0xc2, 0xe0, 0x30, 0xe5, 0x89, 0x97, 0x72, 0xaa, 0xe4, 0xa0, 0x35, 0xbc, 0x0c, 0x8d, 0x88, + 0xc7, 0x13, 0x53, 0x3c, 0x50, 0x75, 0x4c, 0x2b, 0xff, 0x1b, 0x8f, 0x95, 0xd2, 0xdf, 0x78, 0xe0, + 0x5a, 0xa6, 0xdc, 0x33, 0xff, 0xf6, 0x41, 0xcf, 0x78, 0xc6, 0xd0, 0x6f, 0xd4, 0xce, 0x51, 0xcb, + 0xd1, 0x8d, 0xd1, 0x7f, 0xaa, 0x42, 0xc7, 0xac, 0x0c, 0xbd, 0x45, 0xef, 0x4a, 0x25, 0xdf, 0x95, + 0x01, 0x54, 0xe5, 0xf3, 0xc8, 0x6c, 0x13, 0x3e, 0xb2, 0x4f, 0xa1, 0x1a, 0x85, 0x33, 0xe3, 0xd0, + 0x5c, 0x9b, 0xd3, 0x32, 0xf3, 0xeb, 0x6b, 0x58, 0x08, 0xa9, 0x51, 0xb4, 0xd1, 0x6d, 0x55, 0x64, + 0x56, 0xb3, 0x26, 0x28, 0xf1, 0xcf, 0xf0, 0x44, 0xe0, 0xa2, 0x7a, 0x3e, 0x55, 0x2e, 0xd8, 0x63, + 0xde, 0x73, 0xda, 0x06, 0xb2, 0x17, 0xb0, 0xcf, 0xa0, 0x95, 0xc7, 0x3e, 0xad, 0x0b, 0xa3, 0xce, + 0xe2, 0xad, 0xdd, 0x27, 0xc7, 0x67, 0xb1, 0x0d, 0x6e, 0x9a, 0x97, 0xe5, 0x94, 0xec, 0x8f, 0xa0, + 0x2b, 0xb9, 0x94, 0xfa, 0x02, 0xe2, 0x58, 0x98, 0xe3, 0x7f, 0xa9, 0xec, 0x9d, 0x10, 0x16, 0xbf, + 0xda, 0x32, 0xbb, 0x2c, 0x40, 0xec, 0x4b, 0xe8, 0xdb, 0xfe, 0x91, 0x98, 0x4c, 0xf2, 0xd8, 0xfc, + 0xb5, 0xa5, 0x11, 0xf6, 0x09, 0x5d, 0x1a, 0xa7, 0x27, 0xcb, 0x08, 0xf6, 0x6b, 0xe8, 0x27, 0x7a, + 0x33, 0x5d, 0x53, 0x1d, 0xa4, 0xc5, 0xc8, 0xd5, 0x39, 0xa3, 0x68, 0x6e, 0xb3, 0x8b, 0x4b, 0x45, + 0x05, 0x5c, 0x2e, 0x5f, 0xad, 0xd5, 0xc9, 0x9a, 0xb9, 0xab, 0xb5, 0xa3, 0xff, 0xbc, 0x02, 0x9d, + 0xd2, 0xa7, 0xd1, 0x3f, 0xb0, 0x48, 0x9e, 0xda, 0xba, 0x1c, 0x7c, 0x46, 0xd8, 0x54, 0x48, 0x5b, + 0x66, 0x42, 0xcf, 0x08, 0x4b, 0x45, 0x9e, 0x6e, 0xa7, 0x67, 0x7c, 0xa1, 0xf1, 0x4d, 0xf5, 0xe5, + 0x67, 0xda, 0xb9, 0x9a, 0xd3, 0x2d, 0x80, 0x7b, 0x01, 0xfd, 0x55, 0x8b, 0xa7, 0xbc, 0x13, 0x4f, + 0xda, 0x02, 0xa7, 0xbc, 0x8d, 0xe7, 0xf7, 0x05, 0x4f, 0x71, 0x2e, 0x36, 0xbd, 0x68, 0x9a, 0xc8, + 0x10, 0x24, 0xf2, 0x5e, 0x89, 0x58, 0xa7, 0x16, 0xbb, 0x4e, 0x0b, 0x01, 0xdf, 0x88, 0x98, 0xba, + 0x99, 0xed, 0x37, 0x29, 0x72, 0xdb, 0x44, 0xc1, 0xf6, 0x3c, 0xe3, 0x68, 0x5d, 0x06, 0x74, 0x45, + 0xa2, 0xed, 0x34, 0xa9, 0xad, 0xb3, 0xf6, 0x64, 0x3d, 0xbf, 0xf4, 0x42, 0x45, 0x7c, 0x26, 0x32, + 0x65, 0x56, 0x68, 0x15, 0x11, 0x5f, 0x7b, 0xa1, 0x3a, 0xd6, 0x60, 0x76, 0xdf, 0x5c, 0x58, 0x2a, + 0xd3, 0xba, 0x68, 0xfa, 0xeb, 0x98, 0x17, 0x5b, 0xa0, 0x3f, 0xe2, 0x6a, 0xf4, 0xdf, 0x2b, 0xb0, + 0xb6, 0xb4, 0xe1, 0x68, 0x2b, 0xe2, 0x66, 0xdb, 0x64, 0x70, 0xd7, 0x69, 0x60, 0x73, 0x2f, 0x20, + 0x84, 0x9a, 0x29, 0x9b, 0x06, 0x46, 0x84, 0x9a, 0x21, 0x37, 0x5f, 0x82, 0x86, 0x3a, 0xa3, 0xc5, + 0xd4, 0x87, 0xb3, 0xae, 0xce, 0x70, 0x15, 0x77, 0xd0, 0xef, 0x9e, 0xb8, 0x11, 0x7f, 0xc1, 0x23, + 0x5a, 0xe6, 0xfe, 0xf6, 0x87, 0x6f, 0xe0, 0xb4, 0xad, 0x7d, 0x31, 0xd9, 0x47, 0x5a, 0xf4, 0xc4, + 0xf5, 0xd3, 0xe8, 0x37, 0xd0, 0xb2, 0x50, 0xd6, 0x86, 0xfa, 0x43, 0x7e, 0x92, 0x4d, 0x06, 0x6f, + 0xb1, 0x16, 0xd4, 0xb0, 0xc7, 0xa0, 0x82, 0x4f, 0x5f, 0x7b, 0x69, 0x3c, 0x58, 0x41, 0xf4, 0xa3, + 0x34, 0x15, 0xe9, 0xa0, 0x8a, 0x8f, 0x87, 0x5e, 0x1c, 0xfa, 0x83, 0x1a, 0x3e, 0x3e, 0xf6, 0x94, + 0x17, 0x0d, 0xea, 0xa3, 0x3f, 0xaf, 0x43, 0xeb, 0xd0, 0xbc, 0x9d, 0x3d, 0x84, 0x5e, 0xfe, 0x9f, + 0x35, 0x17, 0xc7, 0x7a, 0x0e, 0x17, 0x1f, 0x28, 0xd6, 0xd3, 0x4d, 0x4a, 0xad, 0xc5, 0x7f, 0xbe, + 0x59, 0x59, 0xfa, 0xe7, 0x9b, 0x77, 0xa0, 0xfa, 0x3c, 0x3d, 0x9f, 0xaf, 0x43, 0x3c, 0x8c, 0xbc, + 0xd8, 0x41, 0x30, 0xbb, 0x0f, 0x1d, 0x4a, 0xf5, 0x48, 0x32, 0x46, 0x4c, 0x7c, 0xa4, 0xfc, 0x7f, + 0x48, 0x04, 0x77, 0x00, 0x89, 0x8c, 0xc1, 0xb2, 0x05, 0x2d, 0x7f, 0x1a, 0x46, 0x41, 0xca, 0x63, + 0x53, 0xe3, 0xcb, 0x96, 0xa7, 0xec, 0xe4, 0x34, 0xec, 0x8f, 0x61, 0x10, 0x16, 0xf1, 0x9d, 0x22, + 0xb3, 0x37, 0x27, 0x36, 0x4a, 0x11, 0x20, 0x67, 0xb5, 0x44, 0x4e, 0x1a, 0xb2, 0xb8, 0x08, 0xdc, + 0x2c, 0x5f, 0x04, 0xd6, 0xff, 0x6f, 0x42, 0x6a, 0xac, 0x95, 0x7b, 0x87, 0xa8, 0xc5, 0x6e, 0x19, + 0xdb, 0xa3, 0xbd, 0x68, 0x17, 0x5b, 0xcd, 0x69, 0x6c, 0x90, 0x0f, 0xa1, 0x8f, 0x36, 0x8d, 0xab, + 0x4d, 0x21, 0x14, 0x67, 0x60, 0xfe, 0x85, 0x20, 0x93, 0xd3, 0x87, 0x68, 0x0c, 0x21, 0x33, 0xde, + 0x84, 0xbe, 0xfd, 0x16, 0x53, 0x08, 0xd6, 0x31, 0x99, 0x3f, 0x03, 0xd5, 0xa5, 0x60, 0x5b, 0xb0, + 0xee, 0x4f, 0xbd, 0x38, 0xe6, 0x91, 0x7b, 0x92, 0x8d, 0xc7, 0x56, 0x0b, 0x75, 0x29, 0xfc, 0xb8, + 0x66, 0x50, 0x0f, 0x08, 0x43, 0x4a, 0x6d, 0x04, 0xbd, 0x38, 0x8c, 0x74, 0x8c, 0x9d, 0x34, 0x6e, + 0x8f, 0x28, 0x3b, 0x71, 0x18, 0x51, 0x90, 0x1d, 0xf5, 0xee, 0xaf, 0x60, 0x90, 0x65, 0x61, 0x20, + 0x5d, 0x25, 0xec, 0x5f, 0xc3, 0x98, 0x48, 0x6d, 0x29, 0xf6, 0xf1, 0x2c, 0x0b, 0x83, 0x63, 0x61, + 0xfe, 0x1c, 0xa6, 0x47, 0xf4, 0xb6, 0x39, 0xfa, 0x15, 0x74, 0xcb, 0xbc, 0x83, 0xbc, 0x48, 0xce, + 0xe9, 0xe0, 0x2d, 0x06, 0xd0, 0x78, 0x22, 0xd2, 0x99, 0x17, 0x0d, 0x2a, 0xf8, 0xac, 0xaf, 0xc7, + 0x0f, 0x56, 0x58, 0x17, 0x5a, 0xd6, 0x6b, 0x1a, 0x54, 0x4d, 0x8e, 0xe5, 0x17, 0xd0, 0xb2, 0xff, + 0x78, 0x43, 0x7f, 0x35, 0x22, 0x02, 0xae, 0x2d, 0x43, 0x53, 0x70, 0x87, 0x00, 0xb2, 0x0a, 0xed, + 0x1f, 0x53, 0xad, 0x14, 0x7f, 0x4c, 0x35, 0xfa, 0x13, 0xe8, 0x96, 0xa7, 0x68, 0x03, 0x7a, 0x95, + 0x22, 0xa0, 0x77, 0x41, 0x2f, 0x4a, 0x04, 0xa7, 0x62, 0xe6, 0x96, 0x8c, 0x97, 0x16, 0x02, 0xf0, + 0x35, 0xa3, 0x7f, 0x58, 0x81, 0x3a, 0xf9, 0x12, 0xa4, 0xe4, 0xf0, 0xa1, 0x38, 0x41, 0x75, 0xa7, + 0x4d, 0x90, 0xff, 0x87, 0x0b, 0x46, 0x79, 0x82, 0xa7, 0xf6, 0xc6, 0x04, 0xcf, 0xed, 0x3f, 0xab, + 0x40, 0x43, 0xff, 0x19, 0x18, 0x5b, 0x83, 0xde, 0xb3, 0xf8, 0x34, 0x16, 0x2f, 0x63, 0x0d, 0x18, + 0xbc, 0xc5, 0xd6, 0x61, 0xd5, 0xae, 0xbd, 0xf9, 0xd7, 0xb1, 0x41, 0x85, 0x0d, 0xa0, 0x4b, 0xbb, + 0x6b, 0x21, 0x2b, 0xec, 0x1d, 0x18, 0x1a, 0x3d, 0xf5, 0x50, 0xc4, 0xfc, 0x89, 0x50, 0xe1, 0xf8, + 0xdc, 0x62, 0xab, 0x6c, 0x15, 0x3a, 0x47, 0x4a, 0x24, 0x47, 0x3c, 0x0e, 0xc2, 0x78, 0x32, 0xa8, + 0xb1, 0x21, 0x6c, 0xd8, 0x51, 0x75, 0xe4, 0xe0, 0x71, 0x18, 0x87, 0x72, 0x3a, 0xa8, 0xb3, 0x6b, + 0x70, 0xe5, 0x22, 0xcc, 0x8e, 0x7f, 0x3a, 0x68, 0xdc, 0xfe, 0x0c, 0xd8, 0xf2, 0xff, 0x6b, 0xe1, + 0xe8, 0xfb, 0x7c, 0xe2, 0xf9, 0xe7, 0xbb, 0x91, 0x90, 0xc8, 0x14, 0x3d, 0x68, 0x17, 0xbd, 0x2a, + 0xb7, 0x1f, 0x43, 0x43, 0xff, 0x21, 0x5a, 0xe9, 0xfb, 0x34, 0x60, 0xf0, 0x16, 0x76, 0x46, 0x61, + 0x1e, 0xc6, 0x93, 0x27, 0xfc, 0x4c, 0x69, 0x41, 0xb8, 0xef, 0x49, 0x35, 0x58, 0x61, 0x7d, 0x00, + 0xf3, 0x09, 0x8f, 0xe2, 0x60, 0x50, 0x7d, 0xb0, 0xfb, 0x17, 0xbf, 0x7b, 0xaf, 0xf2, 0x97, 0xbf, + 0x7b, 0xaf, 0xf2, 0xdf, 0x7e, 0xf7, 0xde, 0x5b, 0xbf, 0xfd, 0xab, 0xf7, 0x2a, 0xdf, 0xdc, 0x2f, + 0xfd, 0xdd, 0xdb, 0xcc, 0x53, 0x69, 0x78, 0xa6, 0x13, 0xf7, 0xb6, 0x11, 0xf3, 0xbb, 0xc9, 0xe9, + 0xe4, 0x6e, 0x72, 0x72, 0xd7, 0xf2, 0xf9, 0x49, 0x83, 0xfe, 0xc5, 0xed, 0xd3, 0xff, 0x1b, 0x00, + 0x00, 0xff, 0xff, 0xd1, 0x44, 0x7f, 0xad, 0x44, 0x4e, 0x00, 0x00, } func (m *Message) Marshal() (dAtA []byte, err error) { @@ -10943,6 +10952,20 @@ func (m *Instruction) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.MongodbScan != nil { + { + size, err := m.MongodbScan.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPipeline(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3 + i-- + dAtA[i] = 0xba + } if m.SpillMem != 0 { i = encodeVarintPipeline(dAtA, i, uint64(m.SpillMem)) i-- @@ -12215,40 +12238,40 @@ func (m *Pipeline) MarshalToSizedBuffer(dAtA []byte) (int, error) { } } if len(m.NilBatchCnt) > 0 { - dAtA140 := make([]byte, len(m.NilBatchCnt)*10) - var j139 int + dAtA141 := make([]byte, len(m.NilBatchCnt)*10) + var j140 int for _, num1 := range m.NilBatchCnt { num := uint64(num1) for num >= 1<<7 { - dAtA140[j139] = uint8(uint64(num)&0x7f | 0x80) + dAtA141[j140] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j139++ + j140++ } - dAtA140[j139] = uint8(num) - j139++ + dAtA141[j140] = uint8(num) + j140++ } - i -= j139 - copy(dAtA[i:], dAtA140[:j139]) - i = encodeVarintPipeline(dAtA, i, uint64(j139)) + i -= j140 + copy(dAtA[i:], dAtA141[:j140]) + i = encodeVarintPipeline(dAtA, i, uint64(j140)) i-- dAtA[i] = 0x6a } if len(m.ChannelBufferSize) > 0 { - dAtA142 := make([]byte, len(m.ChannelBufferSize)*10) - var j141 int + dAtA143 := make([]byte, len(m.ChannelBufferSize)*10) + var j142 int for _, num1 := range m.ChannelBufferSize { num := uint64(num1) for num >= 1<<7 { - dAtA142[j141] = uint8(uint64(num)&0x7f | 0x80) + dAtA143[j142] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j141++ + j142++ } - dAtA142[j141] = uint8(num) - j141++ + dAtA143[j142] = uint8(num) + j142++ } - i -= j141 - copy(dAtA[i:], dAtA142[:j141]) - i = encodeVarintPipeline(dAtA, i, uint64(j141)) + i -= j142 + copy(dAtA[i:], dAtA143[:j142]) + i = encodeVarintPipeline(dAtA, i, uint64(j142)) i-- dAtA[i] = 0x62 } @@ -12485,40 +12508,40 @@ func (m *Apply) MarshalToSizedBuffer(dAtA []byte) (int, error) { } } if len(m.ColList) > 0 { - dAtA147 := make([]byte, len(m.ColList)*10) - var j146 int + dAtA148 := make([]byte, len(m.ColList)*10) + var j147 int for _, num1 := range m.ColList { num := uint64(num1) for num >= 1<<7 { - dAtA147[j146] = uint8(uint64(num)&0x7f | 0x80) + dAtA148[j147] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j146++ + j147++ } - dAtA147[j146] = uint8(num) - j146++ + dAtA148[j147] = uint8(num) + j147++ } - i -= j146 - copy(dAtA[i:], dAtA147[:j146]) - i = encodeVarintPipeline(dAtA, i, uint64(j146)) + i -= j147 + copy(dAtA[i:], dAtA148[:j147]) + i = encodeVarintPipeline(dAtA, i, uint64(j147)) i-- dAtA[i] = 0x1a } if len(m.RelList) > 0 { - dAtA149 := make([]byte, len(m.RelList)*10) - var j148 int + dAtA150 := make([]byte, len(m.RelList)*10) + var j149 int for _, num1 := range m.RelList { num := uint64(num1) for num >= 1<<7 { - dAtA149[j148] = uint8(uint64(num)&0x7f | 0x80) + dAtA150[j149] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j148++ + j149++ } - dAtA149[j148] = uint8(num) - j148++ + dAtA150[j149] = uint8(num) + j149++ } - i -= j148 - copy(dAtA[i:], dAtA149[:j148]) - i = encodeVarintPipeline(dAtA, i, uint64(j148)) + i -= j149 + copy(dAtA[i:], dAtA150[:j149]) + i = encodeVarintPipeline(dAtA, i, uint64(j149)) i-- dAtA[i] = 0x12 } @@ -14600,6 +14623,10 @@ func (m *Instruction) ProtoSize() (n int) { if m.SpillMem != 0 { n += 2 + sovPipeline(uint64(m.SpillMem)) } + if m.MongodbScan != nil { + l = m.MongodbScan.ProtoSize() + n += 2 + l + sovPipeline(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -29035,6 +29062,42 @@ func (m *Instruction) Unmarshal(dAtA []byte) error { break } } + case 55: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MongodbScan", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPipeline + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPipeline + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPipeline + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.MongodbScan == nil { + m.MongodbScan = &plan.MongoScan{} + } + if err := m.MongodbScan.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipPipeline(dAtA[iNdEx:]) diff --git a/pkg/pb/plan/plan.pb.go b/pkg/pb/plan/plan.pb.go index 4db49b31d71b8..86feea3f88690 100644 --- a/pkg/pb/plan/plan.pb.go +++ b/pkg/pb/plan/plan.pb.go @@ -162,6 +162,7 @@ const ( ExternType_EXTERNAL_TB ExternType = 1 ExternType_RESULT_SCAN ExternType = 2 ExternType_ICEBERG_TB ExternType = 3 + ExternType_MONGODB_TB ExternType = 4 ) var ExternType_name = map[int32]string{ @@ -169,6 +170,7 @@ var ExternType_name = map[int32]string{ 1: "EXTERNAL_TB", 2: "RESULT_SCAN", 3: "ICEBERG_TB", + 4: "MONGODB_TB", } var ExternType_value = map[string]int32{ @@ -176,6 +178,7 @@ var ExternType_value = map[string]int32{ "EXTERNAL_TB": 1, "RESULT_SCAN": 2, "ICEBERG_TB": 3, + "MONGODB_TB": 4, } func (x ExternType) String() string { @@ -186,6 +189,58 @@ func (ExternType) EnumDescriptor() ([]byte, []int) { return fileDescriptor_2d655ab2f7683c23, []int{5} } +type MongoPredicateOp int32 + +const ( + MongoPredicateOp_MONGO_PREDICATE_INVALID MongoPredicateOp = 0 + MongoPredicateOp_MONGO_PREDICATE_AND MongoPredicateOp = 1 + MongoPredicateOp_MONGO_PREDICATE_EQUAL MongoPredicateOp = 2 + MongoPredicateOp_MONGO_PREDICATE_NOT_EQUAL MongoPredicateOp = 3 + MongoPredicateOp_MONGO_PREDICATE_LESS MongoPredicateOp = 4 + MongoPredicateOp_MONGO_PREDICATE_LESS_EQUAL MongoPredicateOp = 5 + MongoPredicateOp_MONGO_PREDICATE_GREATER MongoPredicateOp = 6 + MongoPredicateOp_MONGO_PREDICATE_GREATER_EQUAL MongoPredicateOp = 7 + MongoPredicateOp_MONGO_PREDICATE_IN MongoPredicateOp = 8 + MongoPredicateOp_MONGO_PREDICATE_IS_NULL MongoPredicateOp = 9 + MongoPredicateOp_MONGO_PREDICATE_IS_NOT_NULL MongoPredicateOp = 10 +) + +var MongoPredicateOp_name = map[int32]string{ + 0: "MONGO_PREDICATE_INVALID", + 1: "MONGO_PREDICATE_AND", + 2: "MONGO_PREDICATE_EQUAL", + 3: "MONGO_PREDICATE_NOT_EQUAL", + 4: "MONGO_PREDICATE_LESS", + 5: "MONGO_PREDICATE_LESS_EQUAL", + 6: "MONGO_PREDICATE_GREATER", + 7: "MONGO_PREDICATE_GREATER_EQUAL", + 8: "MONGO_PREDICATE_IN", + 9: "MONGO_PREDICATE_IS_NULL", + 10: "MONGO_PREDICATE_IS_NOT_NULL", +} + +var MongoPredicateOp_value = map[string]int32{ + "MONGO_PREDICATE_INVALID": 0, + "MONGO_PREDICATE_AND": 1, + "MONGO_PREDICATE_EQUAL": 2, + "MONGO_PREDICATE_NOT_EQUAL": 3, + "MONGO_PREDICATE_LESS": 4, + "MONGO_PREDICATE_LESS_EQUAL": 5, + "MONGO_PREDICATE_GREATER": 6, + "MONGO_PREDICATE_GREATER_EQUAL": 7, + "MONGO_PREDICATE_IN": 8, + "MONGO_PREDICATE_IS_NULL": 9, + "MONGO_PREDICATE_IS_NOT_NULL": 10, +} + +func (x MongoPredicateOp) String() string { + return proto.EnumName(MongoPredicateOp_name, int32(x)) +} + +func (MongoPredicateOp) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_2d655ab2f7683c23, []int{6} +} + type TransationCompletionType int32 const ( @@ -211,7 +266,7 @@ func (x TransationCompletionType) String() string { } func (TransationCompletionType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{6} + return fileDescriptor_2d655ab2f7683c23, []int{7} } type TableLockType int32 @@ -245,7 +300,7 @@ func (x TableLockType) String() string { } func (TableLockType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{7} + return fileDescriptor_2d655ab2f7683c23, []int{8} } type AlterPartitionType int32 @@ -276,7 +331,7 @@ func (x AlterPartitionType) String() string { } func (AlterPartitionType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{8} + return fileDescriptor_2d655ab2f7683c23, []int{9} } type SubqueryRef_Type int32 @@ -785,6 +840,31 @@ func (Node_FillType) EnumDescriptor() ([]byte, []int) { return fileDescriptor_2d655ab2f7683c23, []int{60, 3} } +type Node_GapFillMode int32 + +const ( + Node_GAP_FILL_NONE Node_GapFillMode = 0 + Node_GAP_FILL_PARTITION Node_GapFillMode = 1 +) + +var Node_GapFillMode_name = map[int32]string{ + 0: "GAP_FILL_NONE", + 1: "GAP_FILL_PARTITION", +} + +var Node_GapFillMode_value = map[string]int32{ + "GAP_FILL_NONE": 0, + "GAP_FILL_PARTITION": 1, +} + +func (x Node_GapFillMode) String() string { + return proto.EnumName(Node_GapFillMode_name, int32(x)) +} + +func (Node_GapFillMode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_2d655ab2f7683c23, []int{60, 4} +} + type Node_OnDuplicateAction int32 const ( @@ -810,7 +890,7 @@ func (x Node_OnDuplicateAction) String() string { } func (Node_OnDuplicateAction) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{60, 4} + return fileDescriptor_2d655ab2f7683c23, []int{60, 5} } type Node_ApplyType int32 @@ -835,7 +915,7 @@ func (x Node_ApplyType) String() string { } func (Node_ApplyType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{60, 5} + return fileDescriptor_2d655ab2f7683c23, []int{60, 6} } type Query_StatementType int32 @@ -872,7 +952,7 @@ func (x Query_StatementType) String() string { } func (Query_StatementType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{76, 0} + return fileDescriptor_2d655ab2f7683c23, []int{80, 0} } type TransationControl_TclType int32 @@ -900,7 +980,7 @@ func (x TransationControl_TclType) String() string { } func (TransationControl_TclType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{77, 0} + return fileDescriptor_2d655ab2f7683c23, []int{81, 0} } type TransationBegin_TransationMode int32 @@ -928,7 +1008,7 @@ func (x TransationBegin_TransationMode) String() string { } func (TransationBegin_TransationMode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{78, 0} + return fileDescriptor_2d655ab2f7683c23, []int{82, 0} } type DataControl_DclType int32 @@ -977,7 +1057,7 @@ func (x DataControl_DclType) String() string { } func (DataControl_DclType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{83, 0} + return fileDescriptor_2d655ab2f7683c23, []int{87, 0} } type DataDefinition_DdlType int32 @@ -1119,7 +1199,7 @@ func (x DataDefinition_DdlType) String() string { } func (DataDefinition_DdlType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{84, 0} + return fileDescriptor_2d655ab2f7683c23, []int{88, 0} } type AlterTableDrop_Typ int32 @@ -1153,7 +1233,7 @@ func (x AlterTableDrop_Typ) String() string { } func (AlterTableDrop_Typ) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{92, 0} + return fileDescriptor_2d655ab2f7683c23, []int{96, 0} } type AlterTable_AlgorithmType int32 @@ -1184,7 +1264,7 @@ func (x AlterTable_AlgorithmType) String() string { } func (AlterTable_AlgorithmType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{108, 0} + return fileDescriptor_2d655ab2f7683c23, []int{112, 0} } type MetadataScanInfo_MetadataScanInfoType int32 @@ -1245,7 +1325,7 @@ func (x MetadataScanInfo_MetadataScanInfoType) String() string { } func (MetadataScanInfo_MetadataScanInfoType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{131, 0} + return fileDescriptor_2d655ab2f7683c23, []int{135, 0} } type Type struct { @@ -6643,12 +6723,24 @@ type Node struct { DedupColTypes []Type `protobuf:"bytes,68,rep,name=dedup_col_types,json=dedupColTypes,proto3" json:"dedup_col_types"` RollupFilter bool `protobuf:"varint,69,opt,name=rollup_filter,json=rollupFilter,proto3" json:"rollup_filter,omitempty"` // compile time performance setting - SpillMem int64 `protobuf:"varint,70,opt,name=spill_mem,json=spillMem,proto3" json:"spill_mem,omitempty"` - OriginViews []string `protobuf:"bytes,71,rep,name=origin_views,json=originViews,proto3" json:"origin_views,omitempty"` - DirectView string `protobuf:"bytes,72,opt,name=direct_view,json=directView,proto3" json:"direct_view,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + SpillMem int64 `protobuf:"varint,70,opt,name=spill_mem,json=spillMem,proto3" json:"spill_mem,omitempty"` + OriginViews []string `protobuf:"bytes,71,rep,name=origin_views,json=originViews,proto3" json:"origin_views,omitempty"` + DirectView string `protobuf:"bytes,72,opt,name=direct_view,json=directView,proto3" json:"direct_view,omitempty"` + // TIME_WINDOW only: the GROUP BY columns other than the window's own + // timestamp key. The operator restarts its window state whenever these + // change, so each group gets its own windows instead of one global stream. + TimeWindowPartitionBy []*Expr `protobuf:"bytes,73,rep,name=time_window_partition_by,json=timeWindowPartitionBy,proto3" json:"time_window_partition_by,omitempty"` + // FILL only: positions of the partition keys inside this node's input batch + // (the child TIME_WINDOW's projection). fill(prev/next/linear) must not + // carry values across a partition boundary, so the operator compares these + // columns to find where one group ends and the next begins. + TimeWindowPartitionColPos []int32 `protobuf:"varint,74,rep,packed,name=time_window_partition_col_pos,json=timeWindowPartitionColPos,proto3" json:"time_window_partition_col_pos,omitempty"` + // TIME_WINDOW only: explicitly generate missing buckets between each + // partition's observed minimum and maximum timestamp. + GapFillMode Node_GapFillMode `protobuf:"varint,75,opt,name=gap_fill_mode,json=gapFillMode,proto3,enum=plan.Node_GapFillMode" json:"gap_fill_mode,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Node) Reset() { *m = Node{} } @@ -7167,6 +7259,27 @@ func (m *Node) GetDirectView() string { return "" } +func (m *Node) GetTimeWindowPartitionBy() []*Expr { + if m != nil { + return m.TimeWindowPartitionBy + } + return nil +} + +func (m *Node) GetTimeWindowPartitionColPos() []int32 { + if m != nil { + return m.TimeWindowPartitionColPos + } + return nil +} + +func (m *Node) GetGapFillMode() Node_GapFillMode { + if m != nil { + return m.GapFillMode + } + return Node_GAP_FILL_NONE +} + type SnapshotExtraInfo struct { Level string `protobuf:"bytes,1,opt,name=Level,proto3" json:"Level,omitempty"` ObjId uint64 `protobuf:"varint,2,opt,name=ObjId,proto3" json:"ObjId,omitempty"` @@ -7364,6 +7477,7 @@ type ExternScan struct { EscapedBy []byte `protobuf:"bytes,9,opt,name=escaped_by,json=escapedBy,proto3" json:"escaped_by,omitempty"` TbColToDataCol map[string]int32 `protobuf:"bytes,10,rep,name=TbColToDataCol,proto3" json:"TbColToDataCol,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` IcebergScan *IcebergScan `protobuf:"bytes,11,opt,name=iceberg_scan,json=icebergScan,proto3" json:"iceberg_scan,omitempty"` + MongodbScan *MongoScan `protobuf:"bytes,12,opt,name=mongodb_scan,json=mongodbScan,proto3" json:"mongodb_scan,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -7479,6 +7593,13 @@ func (m *ExternScan) GetIcebergScan() *IcebergScan { return nil } +func (m *ExternScan) GetMongodbScan() *MongoScan { + if m != nil { + return m.MongodbScan + } + return nil +} + type IcebergScan struct { MappingId uint64 `protobuf:"varint,1,opt,name=mapping_id,json=mappingId,proto3" json:"mapping_id,omitempty"` CatalogId uint64 `protobuf:"varint,2,opt,name=catalog_id,json=catalogId,proto3" json:"catalog_id,omitempty"` @@ -7598,6 +7719,403 @@ func (m *IcebergScan) GetFilterDigest() string { return "" } +// MongoScan is a credential-free scan description. Authentication and TLS +// material are resolved on the execution CN from connection_id/version. +type MongoScan struct { + MappingId uint64 `protobuf:"varint,1,opt,name=mapping_id,json=mappingId,proto3" json:"mapping_id,omitempty"` + ConnectionId uint64 `protobuf:"varint,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"` + ConnectionVersion uint64 `protobuf:"varint,3,opt,name=connection_version,json=connectionVersion,proto3" json:"connection_version,omitempty"` + Database string `protobuf:"bytes,4,opt,name=database,proto3" json:"database,omitempty"` + Collection string `protobuf:"bytes,5,opt,name=collection,proto3" json:"collection,omitempty"` + Columns []*MongoColumnMapping `protobuf:"bytes,6,rep,name=columns,proto3" json:"columns,omitempty"` + PushedPredicate *MongoPredicate `protobuf:"bytes,7,opt,name=pushed_predicate,json=pushedPredicate,proto3" json:"pushed_predicate,omitempty"` + ProjectedPaths []string `protobuf:"bytes,8,rep,name=projected_paths,json=projectedPaths,proto3" json:"projected_paths,omitempty"` + ResidualFilterDigest string `protobuf:"bytes,9,opt,name=residual_filter_digest,json=residualFilterDigest,proto3" json:"residual_filter_digest,omitempty"` + MaxParallelism int32 `protobuf:"varint,10,opt,name=max_parallelism,json=maxParallelism,proto3" json:"max_parallelism,omitempty"` + Split *MongoSplit `protobuf:"bytes,11,opt,name=split,proto3" json:"split,omitempty"` + MaxScanRows int64 `protobuf:"varint,12,opt,name=max_scan_rows,json=maxScanRows,proto3" json:"max_scan_rows,omitempty"` + MaxScanBytes int64 `protobuf:"varint,13,opt,name=max_scan_bytes,json=maxScanBytes,proto3" json:"max_scan_bytes,omitempty"` + // mapping_version pins the tenant-scoped mapping row that was validated at + // compile time. The execution CN re-reads that exact catalog generation. + MappingVersion uint64 `protobuf:"varint,14,opt,name=mapping_version,json=mappingVersion,proto3" json:"mapping_version,omitempty"` + // table_id is the stable MO relation identity used to locate the mapping + // during compilation. It remains distinct from the catalog mapping_id so a + // cached logical plan can be compiled more than once without identity drift. + TableId uint64 `protobuf:"varint,15,opt,name=table_id,json=tableId,proto3" json:"table_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MongoScan) Reset() { *m = MongoScan{} } +func (m *MongoScan) String() string { return proto.CompactTextString(m) } +func (*MongoScan) ProtoMessage() {} +func (*MongoScan) Descriptor() ([]byte, []int) { + return fileDescriptor_2d655ab2f7683c23, []int{66} +} +func (m *MongoScan) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MongoScan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MongoScan.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MongoScan) XXX_Merge(src proto.Message) { + xxx_messageInfo_MongoScan.Merge(m, src) +} +func (m *MongoScan) XXX_Size() int { + return m.ProtoSize() +} +func (m *MongoScan) XXX_DiscardUnknown() { + xxx_messageInfo_MongoScan.DiscardUnknown(m) +} + +var xxx_messageInfo_MongoScan proto.InternalMessageInfo + +func (m *MongoScan) GetMappingId() uint64 { + if m != nil { + return m.MappingId + } + return 0 +} + +func (m *MongoScan) GetConnectionId() uint64 { + if m != nil { + return m.ConnectionId + } + return 0 +} + +func (m *MongoScan) GetConnectionVersion() uint64 { + if m != nil { + return m.ConnectionVersion + } + return 0 +} + +func (m *MongoScan) GetDatabase() string { + if m != nil { + return m.Database + } + return "" +} + +func (m *MongoScan) GetCollection() string { + if m != nil { + return m.Collection + } + return "" +} + +func (m *MongoScan) GetColumns() []*MongoColumnMapping { + if m != nil { + return m.Columns + } + return nil +} + +func (m *MongoScan) GetPushedPredicate() *MongoPredicate { + if m != nil { + return m.PushedPredicate + } + return nil +} + +func (m *MongoScan) GetProjectedPaths() []string { + if m != nil { + return m.ProjectedPaths + } + return nil +} + +func (m *MongoScan) GetResidualFilterDigest() string { + if m != nil { + return m.ResidualFilterDigest + } + return "" +} + +func (m *MongoScan) GetMaxParallelism() int32 { + if m != nil { + return m.MaxParallelism + } + return 0 +} + +func (m *MongoScan) GetSplit() *MongoSplit { + if m != nil { + return m.Split + } + return nil +} + +func (m *MongoScan) GetMaxScanRows() int64 { + if m != nil { + return m.MaxScanRows + } + return 0 +} + +func (m *MongoScan) GetMaxScanBytes() int64 { + if m != nil { + return m.MaxScanBytes + } + return 0 +} + +func (m *MongoScan) GetMappingVersion() uint64 { + if m != nil { + return m.MappingVersion + } + return 0 +} + +func (m *MongoScan) GetTableId() uint64 { + if m != nil { + return m.TableId + } + return 0 +} + +type MongoColumnMapping struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + MoType Type `protobuf:"bytes,3,opt,name=mo_type,json=moType,proto3" json:"mo_type"` + ConversionMode string `protobuf:"bytes,4,opt,name=conversion_mode,json=conversionMode,proto3" json:"conversion_mode,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MongoColumnMapping) Reset() { *m = MongoColumnMapping{} } +func (m *MongoColumnMapping) String() string { return proto.CompactTextString(m) } +func (*MongoColumnMapping) ProtoMessage() {} +func (*MongoColumnMapping) Descriptor() ([]byte, []int) { + return fileDescriptor_2d655ab2f7683c23, []int{67} +} +func (m *MongoColumnMapping) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MongoColumnMapping) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MongoColumnMapping.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MongoColumnMapping) XXX_Merge(src proto.Message) { + xxx_messageInfo_MongoColumnMapping.Merge(m, src) +} +func (m *MongoColumnMapping) XXX_Size() int { + return m.ProtoSize() +} +func (m *MongoColumnMapping) XXX_DiscardUnknown() { + xxx_messageInfo_MongoColumnMapping.DiscardUnknown(m) +} + +var xxx_messageInfo_MongoColumnMapping proto.InternalMessageInfo + +func (m *MongoColumnMapping) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *MongoColumnMapping) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +func (m *MongoColumnMapping) GetMoType() Type { + if m != nil { + return m.MoType + } + return Type{} +} + +func (m *MongoColumnMapping) GetConversionMode() string { + if m != nil { + return m.ConversionMode + } + return "" +} + +type MongoPredicate struct { + Op MongoPredicateOp `protobuf:"varint,1,opt,name=op,proto3,enum=plan.MongoPredicateOp" json:"op,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + // Canonical BSON value bytes retain Mongo numeric and temporal types while + // keeping the protobuf independent from the Go driver. + ValueBson []byte `protobuf:"bytes,3,opt,name=value_bson,json=valueBson,proto3" json:"value_bson,omitempty"` + ValuesBson [][]byte `protobuf:"bytes,4,rep,name=values_bson,json=valuesBson,proto3" json:"values_bson,omitempty"` + Children []*MongoPredicate `protobuf:"bytes,5,rep,name=children,proto3" json:"children,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MongoPredicate) Reset() { *m = MongoPredicate{} } +func (m *MongoPredicate) String() string { return proto.CompactTextString(m) } +func (*MongoPredicate) ProtoMessage() {} +func (*MongoPredicate) Descriptor() ([]byte, []int) { + return fileDescriptor_2d655ab2f7683c23, []int{68} +} +func (m *MongoPredicate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MongoPredicate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MongoPredicate.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MongoPredicate) XXX_Merge(src proto.Message) { + xxx_messageInfo_MongoPredicate.Merge(m, src) +} +func (m *MongoPredicate) XXX_Size() int { + return m.ProtoSize() +} +func (m *MongoPredicate) XXX_DiscardUnknown() { + xxx_messageInfo_MongoPredicate.DiscardUnknown(m) +} + +var xxx_messageInfo_MongoPredicate proto.InternalMessageInfo + +func (m *MongoPredicate) GetOp() MongoPredicateOp { + if m != nil { + return m.Op + } + return MongoPredicateOp_MONGO_PREDICATE_INVALID +} + +func (m *MongoPredicate) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +func (m *MongoPredicate) GetValueBson() []byte { + if m != nil { + return m.ValueBson + } + return nil +} + +func (m *MongoPredicate) GetValuesBson() [][]byte { + if m != nil { + return m.ValuesBson + } + return nil +} + +func (m *MongoPredicate) GetChildren() []*MongoPredicate { + if m != nil { + return m.Children + } + return nil +} + +type MongoSplit struct { + KeyPath string `protobuf:"bytes,1,opt,name=key_path,json=keyPath,proto3" json:"key_path,omitempty"` + LowerBson []byte `protobuf:"bytes,2,opt,name=lower_bson,json=lowerBson,proto3" json:"lower_bson,omitempty"` + UpperBson []byte `protobuf:"bytes,3,opt,name=upper_bson,json=upperBson,proto3" json:"upper_bson,omitempty"` + LowerInclusive bool `protobuf:"varint,4,opt,name=lower_inclusive,json=lowerInclusive,proto3" json:"lower_inclusive,omitempty"` + UpperInclusive bool `protobuf:"varint,5,opt,name=upper_inclusive,json=upperInclusive,proto3" json:"upper_inclusive,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MongoSplit) Reset() { *m = MongoSplit{} } +func (m *MongoSplit) String() string { return proto.CompactTextString(m) } +func (*MongoSplit) ProtoMessage() {} +func (*MongoSplit) Descriptor() ([]byte, []int) { + return fileDescriptor_2d655ab2f7683c23, []int{69} +} +func (m *MongoSplit) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MongoSplit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MongoSplit.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MongoSplit) XXX_Merge(src proto.Message) { + xxx_messageInfo_MongoSplit.Merge(m, src) +} +func (m *MongoSplit) XXX_Size() int { + return m.ProtoSize() +} +func (m *MongoSplit) XXX_DiscardUnknown() { + xxx_messageInfo_MongoSplit.DiscardUnknown(m) +} + +var xxx_messageInfo_MongoSplit proto.InternalMessageInfo + +func (m *MongoSplit) GetKeyPath() string { + if m != nil { + return m.KeyPath + } + return "" +} + +func (m *MongoSplit) GetLowerBson() []byte { + if m != nil { + return m.LowerBson + } + return nil +} + +func (m *MongoSplit) GetUpperBson() []byte { + if m != nil { + return m.UpperBson + } + return nil +} + +func (m *MongoSplit) GetLowerInclusive() bool { + if m != nil { + return m.LowerInclusive + } + return false +} + +func (m *MongoSplit) GetUpperInclusive() bool { + if m != nil { + return m.UpperInclusive + } + return false +} + type ExternAttr struct { ColName string `protobuf:"bytes,1,opt,name=col_name,json=colName,proto3" json:"col_name,omitempty"` ColIndex int32 `protobuf:"varint,2,opt,name=col_index,json=colIndex,proto3" json:"col_index,omitempty"` @@ -7611,7 +8129,7 @@ func (m *ExternAttr) Reset() { *m = ExternAttr{} } func (m *ExternAttr) String() string { return proto.CompactTextString(m) } func (*ExternAttr) ProtoMessage() {} func (*ExternAttr) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{66} + return fileDescriptor_2d655ab2f7683c23, []int{70} } func (m *ExternAttr) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7686,7 +8204,7 @@ func (m *LockTarget) Reset() { *m = LockTarget{} } func (m *LockTarget) String() string { return proto.CompactTextString(m) } func (*LockTarget) ProtoMessage() {} func (*LockTarget) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{67} + return fileDescriptor_2d655ab2f7683c23, []int{71} } func (m *LockTarget) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7835,7 +8353,7 @@ func (m *PreInsertUkCtx) Reset() { *m = PreInsertUkCtx{} } func (m *PreInsertUkCtx) String() string { return proto.CompactTextString(m) } func (*PreInsertUkCtx) ProtoMessage() {} func (*PreInsertUkCtx) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{68} + return fileDescriptor_2d655ab2f7683c23, []int{72} } func (m *PreInsertUkCtx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7910,7 +8428,7 @@ func (m *PreInsertCtx) Reset() { *m = PreInsertCtx{} } func (m *PreInsertCtx) String() string { return proto.CompactTextString(m) } func (*PreInsertCtx) ProtoMessage() {} func (*PreInsertCtx) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{69} + return fileDescriptor_2d655ab2f7683c23, []int{73} } func (m *PreInsertCtx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8011,7 +8529,7 @@ func (m *RuntimeFilterSpec) Reset() { *m = RuntimeFilterSpec{} } func (m *RuntimeFilterSpec) String() string { return proto.CompactTextString(m) } func (*RuntimeFilterSpec) ProtoMessage() {} func (*RuntimeFilterSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{70} + return fileDescriptor_2d655ab2f7683c23, []int{74} } func (m *RuntimeFilterSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8093,7 +8611,7 @@ func (m *IdList) Reset() { *m = IdList{} } func (m *IdList) String() string { return proto.CompactTextString(m) } func (*IdList) ProtoMessage() {} func (*IdList) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{71} + return fileDescriptor_2d655ab2f7683c23, []int{75} } func (m *IdList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8140,7 +8658,7 @@ func (m *ColPosMap) Reset() { *m = ColPosMap{} } func (m *ColPosMap) String() string { return proto.CompactTextString(m) } func (*ColPosMap) ProtoMessage() {} func (*ColPosMap) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{72} + return fileDescriptor_2d655ab2f7683c23, []int{76} } func (m *ColPosMap) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8194,7 +8712,7 @@ func (m *DeleteCtx) Reset() { *m = DeleteCtx{} } func (m *DeleteCtx) String() string { return proto.CompactTextString(m) } func (*DeleteCtx) ProtoMessage() {} func (*DeleteCtx) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{73} + return fileDescriptor_2d655ab2f7683c23, []int{77} } func (m *DeleteCtx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8293,7 +8811,7 @@ func (m *PostDmlFullTextCtx) Reset() { *m = PostDmlFullTextCtx{} } func (m *PostDmlFullTextCtx) String() string { return proto.CompactTextString(m) } func (*PostDmlFullTextCtx) ProtoMessage() {} func (*PostDmlFullTextCtx) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{74} + return fileDescriptor_2d655ab2f7683c23, []int{78} } func (m *PostDmlFullTextCtx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8368,7 +8886,7 @@ func (m *PostDmlCtx) Reset() { *m = PostDmlCtx{} } func (m *PostDmlCtx) String() string { return proto.CompactTextString(m) } func (*PostDmlCtx) ProtoMessage() {} func (*PostDmlCtx) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{75} + return fileDescriptor_2d655ab2f7683c23, []int{79} } func (m *PostDmlCtx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8485,7 +9003,7 @@ func (m *Query) Reset() { *m = Query{} } func (m *Query) String() string { return proto.CompactTextString(m) } func (*Query) ProtoMessage() {} func (*Query) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{76} + return fileDescriptor_2d655ab2f7683c23, []int{80} } func (m *Query) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8609,7 +9127,7 @@ func (m *TransationControl) Reset() { *m = TransationControl{} } func (m *TransationControl) String() string { return proto.CompactTextString(m) } func (*TransationControl) ProtoMessage() {} func (*TransationControl) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{77} + return fileDescriptor_2d655ab2f7683c23, []int{81} } func (m *TransationControl) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8713,7 +9231,7 @@ func (m *TransationBegin) Reset() { *m = TransationBegin{} } func (m *TransationBegin) String() string { return proto.CompactTextString(m) } func (*TransationBegin) ProtoMessage() {} func (*TransationBegin) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{78} + return fileDescriptor_2d655ab2f7683c23, []int{82} } func (m *TransationBegin) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8760,7 +9278,7 @@ func (m *TransationCommit) Reset() { *m = TransationCommit{} } func (m *TransationCommit) String() string { return proto.CompactTextString(m) } func (*TransationCommit) ProtoMessage() {} func (*TransationCommit) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{79} + return fileDescriptor_2d655ab2f7683c23, []int{83} } func (m *TransationCommit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8807,7 +9325,7 @@ func (m *TransationRollback) Reset() { *m = TransationRollback{} } func (m *TransationRollback) String() string { return proto.CompactTextString(m) } func (*TransationRollback) ProtoMessage() {} func (*TransationRollback) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{80} + return fileDescriptor_2d655ab2f7683c23, []int{84} } func (m *TransationRollback) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8862,7 +9380,7 @@ func (m *Plan) Reset() { *m = Plan{} } func (m *Plan) String() string { return proto.CompactTextString(m) } func (*Plan) ProtoMessage() {} func (*Plan) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{81} + return fileDescriptor_2d655ab2f7683c23, []int{85} } func (m *Plan) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8985,7 +9503,7 @@ func (m *Column) Reset() { *m = Column{} } func (m *Column) String() string { return proto.CompactTextString(m) } func (*Column) ProtoMessage() {} func (*Column) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{82} + return fileDescriptor_2d655ab2f7683c23, []int{86} } func (m *Column) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9041,7 +9559,7 @@ func (m *DataControl) Reset() { *m = DataControl{} } func (m *DataControl) String() string { return proto.CompactTextString(m) } func (*DataControl) ProtoMessage() {} func (*DataControl) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{83} + return fileDescriptor_2d655ab2f7683c23, []int{87} } func (m *DataControl) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9202,7 +9720,7 @@ func (m *DataDefinition) Reset() { *m = DataDefinition{} } func (m *DataDefinition) String() string { return proto.CompactTextString(m) } func (*DataDefinition) ProtoMessage() {} func (*DataDefinition) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{84} + return fileDescriptor_2d655ab2f7683c23, []int{88} } func (m *DataDefinition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9566,7 +10084,7 @@ func (m *SubscriptionOption) Reset() { *m = SubscriptionOption{} } func (m *SubscriptionOption) String() string { return proto.CompactTextString(m) } func (*SubscriptionOption) ProtoMessage() {} func (*SubscriptionOption) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{85} + return fileDescriptor_2d655ab2f7683c23, []int{89} } func (m *SubscriptionOption) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9623,7 +10141,7 @@ func (m *CreateDatabase) Reset() { *m = CreateDatabase{} } func (m *CreateDatabase) String() string { return proto.CompactTextString(m) } func (*CreateDatabase) ProtoMessage() {} func (*CreateDatabase) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{86} + return fileDescriptor_2d655ab2f7683c23, []int{90} } func (m *CreateDatabase) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9692,7 +10210,7 @@ func (m *AlterDatabase) Reset() { *m = AlterDatabase{} } func (m *AlterDatabase) String() string { return proto.CompactTextString(m) } func (*AlterDatabase) ProtoMessage() {} func (*AlterDatabase) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{87} + return fileDescriptor_2d655ab2f7683c23, []int{91} } func (m *AlterDatabase) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9754,7 +10272,7 @@ func (m *DropDatabase) Reset() { *m = DropDatabase{} } func (m *DropDatabase) String() string { return proto.CompactTextString(m) } func (*DropDatabase) ProtoMessage() {} func (*DropDatabase) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{88} + return fileDescriptor_2d655ab2f7683c23, []int{92} } func (m *DropDatabase) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9830,7 +10348,7 @@ func (m *FkColName) Reset() { *m = FkColName{} } func (m *FkColName) String() string { return proto.CompactTextString(m) } func (*FkColName) ProtoMessage() {} func (*FkColName) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{89} + return fileDescriptor_2d655ab2f7683c23, []int{93} } func (m *FkColName) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9899,7 +10417,7 @@ func (m *ForeignKeyInfo) Reset() { *m = ForeignKeyInfo{} } func (m *ForeignKeyInfo) String() string { return proto.CompactTextString(m) } func (*ForeignKeyInfo) ProtoMessage() {} func (*ForeignKeyInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{90} + return fileDescriptor_2d655ab2f7683c23, []int{94} } func (m *ForeignKeyInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9992,7 +10510,7 @@ func (m *CreateTable) Reset() { *m = CreateTable{} } func (m *CreateTable) String() string { return proto.CompactTextString(m) } func (*CreateTable) ProtoMessage() {} func (*CreateTable) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{91} + return fileDescriptor_2d655ab2f7683c23, []int{95} } func (m *CreateTable) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10125,7 +10643,7 @@ func (m *AlterTableDrop) Reset() { *m = AlterTableDrop{} } func (m *AlterTableDrop) String() string { return proto.CompactTextString(m) } func (*AlterTableDrop) ProtoMessage() {} func (*AlterTableDrop) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{92} + return fileDescriptor_2d655ab2f7683c23, []int{96} } func (m *AlterTableDrop) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10190,7 +10708,7 @@ func (m *AlterTableAddFk) Reset() { *m = AlterTableAddFk{} } func (m *AlterTableAddFk) String() string { return proto.CompactTextString(m) } func (*AlterTableAddFk) ProtoMessage() {} func (*AlterTableAddFk) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{93} + return fileDescriptor_2d655ab2f7683c23, []int{97} } func (m *AlterTableAddFk) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10262,7 +10780,7 @@ func (m *AlterTableAddIndex) Reset() { *m = AlterTableAddIndex{} } func (m *AlterTableAddIndex) String() string { return proto.CompactTextString(m) } func (*AlterTableAddIndex) ProtoMessage() {} func (*AlterTableAddIndex) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{94} + return fileDescriptor_2d655ab2f7683c23, []int{98} } func (m *AlterTableAddIndex) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10340,7 +10858,7 @@ func (m *AlterTableDropIndex) Reset() { *m = AlterTableDropIndex{} } func (m *AlterTableDropIndex) String() string { return proto.CompactTextString(m) } func (*AlterTableDropIndex) ProtoMessage() {} func (*AlterTableDropIndex) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{95} + return fileDescriptor_2d655ab2f7683c23, []int{99} } func (m *AlterTableDropIndex) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10411,7 +10929,7 @@ func (m *AlterTableAlterIndex) Reset() { *m = AlterTableAlterIndex{} } func (m *AlterTableAlterIndex) String() string { return proto.CompactTextString(m) } func (*AlterTableAlterIndex) ProtoMessage() {} func (*AlterTableAlterIndex) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{96} + return fileDescriptor_2d655ab2f7683c23, []int{100} } func (m *AlterTableAlterIndex) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10483,7 +11001,7 @@ func (m *AlterTableAlterReIndex) Reset() { *m = AlterTableAlterReIndex{} func (m *AlterTableAlterReIndex) String() string { return proto.CompactTextString(m) } func (*AlterTableAlterReIndex) ProtoMessage() {} func (*AlterTableAlterReIndex) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{97} + return fileDescriptor_2d655ab2f7683c23, []int{101} } func (m *AlterTableAlterReIndex) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10563,7 +11081,7 @@ func (m *AlterTableAlterAutoUpdate) Reset() { *m = AlterTableAlterAutoUp func (m *AlterTableAlterAutoUpdate) String() string { return proto.CompactTextString(m) } func (*AlterTableAlterAutoUpdate) ProtoMessage() {} func (*AlterTableAlterAutoUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{98} + return fileDescriptor_2d655ab2f7683c23, []int{102} } func (m *AlterTableAlterAutoUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10645,7 +11163,7 @@ func (m *AlterTableComment) Reset() { *m = AlterTableComment{} } func (m *AlterTableComment) String() string { return proto.CompactTextString(m) } func (*AlterTableComment) ProtoMessage() {} func (*AlterTableComment) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{99} + return fileDescriptor_2d655ab2f7683c23, []int{103} } func (m *AlterTableComment) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10693,7 +11211,7 @@ func (m *AlterTableName) Reset() { *m = AlterTableName{} } func (m *AlterTableName) String() string { return proto.CompactTextString(m) } func (*AlterTableName) ProtoMessage() {} func (*AlterTableName) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{100} + return fileDescriptor_2d655ab2f7683c23, []int{104} } func (m *AlterTableName) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10750,7 +11268,7 @@ func (m *AlterAddColumn) Reset() { *m = AlterAddColumn{} } func (m *AlterAddColumn) String() string { return proto.CompactTextString(m) } func (*AlterAddColumn) ProtoMessage() {} func (*AlterAddColumn) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{101} + return fileDescriptor_2d655ab2f7683c23, []int{105} } func (m *AlterAddColumn) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10819,7 +11337,7 @@ func (m *AlterDropColumn) Reset() { *m = AlterDropColumn{} } func (m *AlterDropColumn) String() string { return proto.CompactTextString(m) } func (*AlterDropColumn) ProtoMessage() {} func (*AlterDropColumn) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{102} + return fileDescriptor_2d655ab2f7683c23, []int{106} } func (m *AlterDropColumn) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10873,7 +11391,7 @@ func (m *RenameTable) Reset() { *m = RenameTable{} } func (m *RenameTable) String() string { return proto.CompactTextString(m) } func (*RenameTable) ProtoMessage() {} func (*RenameTable) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{103} + return fileDescriptor_2d655ab2f7683c23, []int{107} } func (m *RenameTable) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10922,7 +11440,7 @@ func (m *AlterVarcharLength) Reset() { *m = AlterVarcharLength{} } func (m *AlterVarcharLength) String() string { return proto.CompactTextString(m) } func (*AlterVarcharLength) ProtoMessage() {} func (*AlterVarcharLength) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{104} + return fileDescriptor_2d655ab2f7683c23, []int{108} } func (m *AlterVarcharLength) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10982,7 +11500,7 @@ func (m *AlterReplaceDef) Reset() { *m = AlterReplaceDef{} } func (m *AlterReplaceDef) String() string { return proto.CompactTextString(m) } func (*AlterReplaceDef) ProtoMessage() {} func (*AlterReplaceDef) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{105} + return fileDescriptor_2d655ab2f7683c23, []int{109} } func (m *AlterReplaceDef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11024,7 +11542,7 @@ func (m *AlterRenameColumn) Reset() { *m = AlterRenameColumn{} } func (m *AlterRenameColumn) String() string { return proto.CompactTextString(m) } func (*AlterRenameColumn) ProtoMessage() {} func (*AlterRenameColumn) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{106} + return fileDescriptor_2d655ab2f7683c23, []int{110} } func (m *AlterRenameColumn) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11088,7 +11606,7 @@ func (m *AlterCopyOpt) Reset() { *m = AlterCopyOpt{} } func (m *AlterCopyOpt) String() string { return proto.CompactTextString(m) } func (*AlterCopyOpt) ProtoMessage() {} func (*AlterCopyOpt) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{107} + return fileDescriptor_2d655ab2f7683c23, []int{111} } func (m *AlterCopyOpt) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11173,7 +11691,7 @@ func (m *AlterTable) Reset() { *m = AlterTable{} } func (m *AlterTable) String() string { return proto.CompactTextString(m) } func (*AlterTable) ProtoMessage() {} func (*AlterTable) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{108} + return fileDescriptor_2d655ab2f7683c23, []int{112} } func (m *AlterTable) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11333,7 +11851,7 @@ func (m *AlterTable_Action) Reset() { *m = AlterTable_Action{} } func (m *AlterTable_Action) String() string { return proto.CompactTextString(m) } func (*AlterTable_Action) ProtoMessage() {} func (*AlterTable_Action) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{108, 0} + return fileDescriptor_2d655ab2f7683c23, []int{112, 0} } func (m *AlterTable_Action) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11565,7 +12083,7 @@ func (m *DropTable) Reset() { *m = DropTable{} } func (m *DropTable) String() string { return proto.CompactTextString(m) } func (*DropTable) ProtoMessage() {} func (*DropTable) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{109} + return fileDescriptor_2d655ab2f7683c23, []int{113} } func (m *DropTable) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11692,7 +12210,7 @@ func (m *CreateView) Reset() { *m = CreateView{} } func (m *CreateView) String() string { return proto.CompactTextString(m) } func (*CreateView) ProtoMessage() {} func (*CreateView) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{110} + return fileDescriptor_2d655ab2f7683c23, []int{114} } func (m *CreateView) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11762,7 +12280,7 @@ func (m *AlterView) Reset() { *m = AlterView{} } func (m *AlterView) String() string { return proto.CompactTextString(m) } func (*AlterView) ProtoMessage() {} func (*AlterView) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{111} + return fileDescriptor_2d655ab2f7683c23, []int{115} } func (m *AlterView) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11825,7 +12343,7 @@ func (m *CreateSequence) Reset() { *m = CreateSequence{} } func (m *CreateSequence) String() string { return proto.CompactTextString(m) } func (*CreateSequence) ProtoMessage() {} func (*CreateSequence) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{112} + return fileDescriptor_2d655ab2f7683c23, []int{116} } func (m *CreateSequence) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11889,7 +12407,7 @@ func (m *DropSequence) Reset() { *m = DropSequence{} } func (m *DropSequence) String() string { return proto.CompactTextString(m) } func (*DropSequence) ProtoMessage() {} func (*DropSequence) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{113} + return fileDescriptor_2d655ab2f7683c23, []int{117} } func (m *DropSequence) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11959,7 +12477,7 @@ func (m *AlterSequence) Reset() { *m = AlterSequence{} } func (m *AlterSequence) String() string { return proto.CompactTextString(m) } func (*AlterSequence) ProtoMessage() {} func (*AlterSequence) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{114} + return fileDescriptor_2d655ab2f7683c23, []int{118} } func (m *AlterSequence) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12025,7 +12543,7 @@ func (m *CreateIndex) Reset() { *m = CreateIndex{} } func (m *CreateIndex) String() string { return proto.CompactTextString(m) } func (*CreateIndex) ProtoMessage() {} func (*CreateIndex) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{115} + return fileDescriptor_2d655ab2f7683c23, []int{119} } func (m *CreateIndex) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12107,7 +12625,7 @@ func (m *AlterIndex) Reset() { *m = AlterIndex{} } func (m *AlterIndex) String() string { return proto.CompactTextString(m) } func (*AlterIndex) ProtoMessage() {} func (*AlterIndex) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{116} + return fileDescriptor_2d655ab2f7683c23, []int{120} } func (m *AlterIndex) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12156,7 +12674,7 @@ func (m *DropIndex) Reset() { *m = DropIndex{} } func (m *DropIndex) String() string { return proto.CompactTextString(m) } func (*DropIndex) ProtoMessage() {} func (*DropIndex) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{117} + return fileDescriptor_2d655ab2f7683c23, []int{121} } func (m *DropIndex) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12223,7 +12741,7 @@ func (m *TruncateTable) Reset() { *m = TruncateTable{} } func (m *TruncateTable) String() string { return proto.CompactTextString(m) } func (*TruncateTable) ProtoMessage() {} func (*TruncateTable) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{118} + return fileDescriptor_2d655ab2f7683c23, []int{122} } func (m *TruncateTable) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12314,7 +12832,7 @@ func (m *ClusterTable) Reset() { *m = ClusterTable{} } func (m *ClusterTable) String() string { return proto.CompactTextString(m) } func (*ClusterTable) ProtoMessage() {} func (*ClusterTable) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{119} + return fileDescriptor_2d655ab2f7683c23, []int{123} } func (m *ClusterTable) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12376,7 +12894,7 @@ func (m *ShowVariables) Reset() { *m = ShowVariables{} } func (m *ShowVariables) String() string { return proto.CompactTextString(m) } func (*ShowVariables) ProtoMessage() {} func (*ShowVariables) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{120} + return fileDescriptor_2d655ab2f7683c23, []int{124} } func (m *ShowVariables) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12430,7 +12948,7 @@ func (m *SetVariables) Reset() { *m = SetVariables{} } func (m *SetVariables) String() string { return proto.CompactTextString(m) } func (*SetVariables) ProtoMessage() {} func (*SetVariables) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{121} + return fileDescriptor_2d655ab2f7683c23, []int{125} } func (m *SetVariables) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12481,7 +12999,7 @@ func (m *SetVariablesItem) Reset() { *m = SetVariablesItem{} } func (m *SetVariablesItem) String() string { return proto.CompactTextString(m) } func (*SetVariablesItem) ProtoMessage() {} func (*SetVariablesItem) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{122} + return fileDescriptor_2d655ab2f7683c23, []int{126} } func (m *SetVariablesItem) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12559,7 +13077,7 @@ func (m *Prepare) Reset() { *m = Prepare{} } func (m *Prepare) String() string { return proto.CompactTextString(m) } func (*Prepare) ProtoMessage() {} func (*Prepare) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{123} + return fileDescriptor_2d655ab2f7683c23, []int{127} } func (m *Prepare) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12628,7 +13146,7 @@ func (m *Execute) Reset() { *m = Execute{} } func (m *Execute) String() string { return proto.CompactTextString(m) } func (*Execute) ProtoMessage() {} func (*Execute) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{124} + return fileDescriptor_2d655ab2f7683c23, []int{128} } func (m *Execute) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12682,7 +13200,7 @@ func (m *Deallocate) Reset() { *m = Deallocate{} } func (m *Deallocate) String() string { return proto.CompactTextString(m) } func (*Deallocate) ProtoMessage() {} func (*Deallocate) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{125} + return fileDescriptor_2d655ab2f7683c23, []int{129} } func (m *Deallocate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12729,7 +13247,7 @@ func (m *OtherDCL) Reset() { *m = OtherDCL{} } func (m *OtherDCL) String() string { return proto.CompactTextString(m) } func (*OtherDCL) ProtoMessage() {} func (*OtherDCL) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{126} + return fileDescriptor_2d655ab2f7683c23, []int{130} } func (m *OtherDCL) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12777,7 +13295,7 @@ func (m *TableLockInfo) Reset() { *m = TableLockInfo{} } func (m *TableLockInfo) String() string { return proto.CompactTextString(m) } func (*TableLockInfo) ProtoMessage() {} func (*TableLockInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{127} + return fileDescriptor_2d655ab2f7683c23, []int{131} } func (m *TableLockInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12831,7 +13349,7 @@ func (m *LockTables) Reset() { *m = LockTables{} } func (m *LockTables) String() string { return proto.CompactTextString(m) } func (*LockTables) ProtoMessage() {} func (*LockTables) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{128} + return fileDescriptor_2d655ab2f7683c23, []int{132} } func (m *LockTables) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12877,7 +13395,7 @@ func (m *UnLockTables) Reset() { *m = UnLockTables{} } func (m *UnLockTables) String() string { return proto.CompactTextString(m) } func (*UnLockTables) ProtoMessage() {} func (*UnLockTables) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{129} + return fileDescriptor_2d655ab2f7683c23, []int{133} } func (m *UnLockTables) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12917,7 +13435,7 @@ func (m *MetadataScanInfos) Reset() { *m = MetadataScanInfos{} } func (m *MetadataScanInfos) String() string { return proto.CompactTextString(m) } func (*MetadataScanInfos) ProtoMessage() {} func (*MetadataScanInfos) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{130} + return fileDescriptor_2d655ab2f7683c23, []int{134} } func (m *MetadataScanInfos) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12975,7 +13493,7 @@ func (m *MetadataScanInfo) Reset() { *m = MetadataScanInfo{} } func (m *MetadataScanInfo) String() string { return proto.CompactTextString(m) } func (*MetadataScanInfo) ProtoMessage() {} func (*MetadataScanInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{131} + return fileDescriptor_2d655ab2f7683c23, []int{135} } func (m *MetadataScanInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13112,7 +13630,7 @@ func (m *CreatePitr) Reset() { *m = CreatePitr{} } func (m *CreatePitr) String() string { return proto.CompactTextString(m) } func (*CreatePitr) ProtoMessage() {} func (*CreatePitr) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{132} + return fileDescriptor_2d655ab2f7683c23, []int{136} } func (m *CreatePitr) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13251,7 +13769,7 @@ func (m *DropPitr) Reset() { *m = DropPitr{} } func (m *DropPitr) String() string { return proto.CompactTextString(m) } func (*DropPitr) ProtoMessage() {} func (*DropPitr) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{133} + return fileDescriptor_2d655ab2f7683c23, []int{137} } func (m *DropPitr) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13314,7 +13832,7 @@ func (m *CreateCDC) Reset() { *m = CreateCDC{} } func (m *CreateCDC) String() string { return proto.CompactTextString(m) } func (*CreateCDC) ProtoMessage() {} func (*CreateCDC) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{134} + return fileDescriptor_2d655ab2f7683c23, []int{138} } func (m *CreateCDC) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13427,7 +13945,7 @@ func (m *DropCDC) Reset() { *m = DropCDC{} } func (m *DropCDC) String() string { return proto.CompactTextString(m) } func (*DropCDC) ProtoMessage() {} func (*DropCDC) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{135} + return fileDescriptor_2d655ab2f7683c23, []int{139} } func (m *DropCDC) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13500,7 +14018,7 @@ func (m *CloneTable) Reset() { *m = CloneTable{} } func (m *CloneTable) String() string { return proto.CompactTextString(m) } func (*CloneTable) ProtoMessage() {} func (*CloneTable) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{136} + return fileDescriptor_2d655ab2f7683c23, []int{140} } func (m *CloneTable) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13583,7 +14101,7 @@ func (m *AlterPartitionOption) Reset() { *m = AlterPartitionOption{} } func (m *AlterPartitionOption) String() string { return proto.CompactTextString(m) } func (*AlterPartitionOption) ProtoMessage() {} func (*AlterPartitionOption) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{137} + return fileDescriptor_2d655ab2f7683c23, []int{141} } func (m *AlterPartitionOption) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13637,7 +14155,7 @@ func (m *RankOption) Reset() { *m = RankOption{} } func (m *RankOption) String() string { return proto.CompactTextString(m) } func (*RankOption) ProtoMessage() {} func (*RankOption) Descriptor() ([]byte, []int) { - return fileDescriptor_2d655ab2f7683c23, []int{138} + return fileDescriptor_2d655ab2f7683c23, []int{142} } func (m *RankOption) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13680,6 +14198,7 @@ func init() { proto.RegisterEnum("plan.ShuffleTypeForMultiCN", ShuffleTypeForMultiCN_name, ShuffleTypeForMultiCN_value) proto.RegisterEnum("plan.BoundType", BoundType_name, BoundType_value) proto.RegisterEnum("plan.ExternType", ExternType_name, ExternType_value) + proto.RegisterEnum("plan.MongoPredicateOp", MongoPredicateOp_name, MongoPredicateOp_value) proto.RegisterEnum("plan.TransationCompletionType", TransationCompletionType_name, TransationCompletionType_value) proto.RegisterEnum("plan.TableLockType", TableLockType_name, TableLockType_value) proto.RegisterEnum("plan.AlterPartitionType", AlterPartitionType_name, AlterPartitionType_value) @@ -13693,6 +14212,7 @@ func init() { proto.RegisterEnum("plan.Node_JoinType", Node_JoinType_name, Node_JoinType_value) proto.RegisterEnum("plan.Node_AggMode", Node_AggMode_name, Node_AggMode_value) proto.RegisterEnum("plan.Node_FillType", Node_FillType_name, Node_FillType_value) + proto.RegisterEnum("plan.Node_GapFillMode", Node_GapFillMode_name, Node_GapFillMode_value) proto.RegisterEnum("plan.Node_OnDuplicateAction", Node_OnDuplicateAction_name, Node_OnDuplicateAction_value) proto.RegisterEnum("plan.Node_ApplyType", Node_ApplyType_name, Node_ApplyType_value) proto.RegisterEnum("plan.Query_StatementType", Query_StatementType_name, Query_StatementType_value) @@ -13772,6 +14292,10 @@ func init() { proto.RegisterType((*ExternScan)(nil), "plan.ExternScan") proto.RegisterMapType((map[string]int32)(nil), "plan.ExternScan.TbColToDataColEntry") proto.RegisterType((*IcebergScan)(nil), "plan.IcebergScan") + proto.RegisterType((*MongoScan)(nil), "plan.MongoScan") + proto.RegisterType((*MongoColumnMapping)(nil), "plan.MongoColumnMapping") + proto.RegisterType((*MongoPredicate)(nil), "plan.MongoPredicate") + proto.RegisterType((*MongoSplit)(nil), "plan.MongoSplit") proto.RegisterType((*ExternAttr)(nil), "plan.ExternAttr") proto.RegisterType((*LockTarget)(nil), "plan.LockTarget") proto.RegisterType((*PreInsertUkCtx)(nil), "plan.PreInsertUkCtx") @@ -13855,841 +14379,882 @@ func init() { func init() { proto.RegisterFile("plan.proto", fileDescriptor_2d655ab2f7683c23) } var fileDescriptor_2d655ab2f7683c23 = []byte{ - // 13331 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0xbd, 0x5b, 0x8c, 0x23, 0x47, - 0x96, 0x18, 0x5a, 0x2c, 0xbe, 0x0f, 0x1f, 0x95, 0x15, 0xfd, 0x62, 0xb7, 0x5a, 0xdd, 0xa5, 0xec, - 0x56, 0xab, 0xd5, 0x92, 0x5a, 0x52, 0xb7, 0x9e, 0xb3, 0xb3, 0x3b, 0xc3, 0x22, 0xd9, 0x5d, 0x94, - 0x58, 0x64, 0x4d, 0x92, 0xd5, 0x2d, 0xcd, 0xde, 0x45, 0x22, 0xc9, 0x4c, 0x56, 0xa5, 0x2a, 0x99, - 0x49, 0x65, 0x26, 0xbb, 0xaa, 0x06, 0x58, 0xdc, 0xc1, 0xfd, 0xd8, 0xc7, 0xc5, 0xfd, 0xbb, 0xf0, - 0xfa, 0x6b, 0xe1, 0xb5, 0x01, 0xc3, 0x80, 0x61, 0xc3, 0xb0, 0x31, 0xc0, 0x7a, 0xff, 0xbc, 0xf0, - 0xcf, 0x1a, 0xb6, 0xd7, 0x0b, 0x1b, 0xb6, 0xb1, 0x36, 0xb0, 0xb6, 0xc7, 0xdf, 0x86, 0x0d, 0xd8, - 0x7f, 0xfe, 0xb0, 0x71, 0x4e, 0x44, 0x66, 0x46, 0x92, 0xec, 0x6e, 0x49, 0x33, 0x0b, 0xf8, 0xa7, - 0x8a, 0x71, 0x1e, 0xf1, 0x8e, 0x13, 0xe7, 0x9c, 0x38, 0x11, 0x09, 0x30, 0x77, 0x0c, 0xf7, 0xfe, - 0xdc, 0xf7, 0x42, 0x8f, 0xe5, 0xf0, 0xf7, 0xb5, 0x77, 0x8e, 0xec, 0xf0, 0x78, 0x31, 0xbe, 0x3f, - 0xf1, 0x66, 0xef, 0x1e, 0x79, 0x47, 0xde, 0xbb, 0x84, 0x1c, 0x2f, 0xa6, 0x94, 0xa2, 0x04, 0xfd, - 0xe2, 0x4c, 0xd7, 0xc0, 0xf1, 0x26, 0x27, 0xe2, 0xf7, 0x56, 0x68, 0xcf, 0xac, 0x20, 0x34, 0x66, - 0x73, 0x0e, 0x50, 0xff, 0x30, 0x03, 0xb9, 0xd1, 0xf9, 0xdc, 0x62, 0x75, 0xd8, 0xb4, 0xcd, 0x46, - 0x66, 0x27, 0x73, 0x37, 0xaf, 0x6d, 0xda, 0x26, 0xdb, 0x81, 0x8a, 0xeb, 0x85, 0xfd, 0x85, 0xe3, - 0x18, 0x63, 0xc7, 0x6a, 0x6c, 0xee, 0x64, 0xee, 0x96, 0x34, 0x19, 0xc4, 0x5e, 0x81, 0xb2, 0xb1, - 0x08, 0x3d, 0xdd, 0x76, 0x27, 0x7e, 0x23, 0x4b, 0xf8, 0x12, 0x02, 0xba, 0xee, 0xc4, 0x67, 0x17, - 0x21, 0x7f, 0x6a, 0x9b, 0xe1, 0x71, 0x23, 0x47, 0x39, 0xf2, 0x04, 0x42, 0x83, 0x89, 0xe1, 0x58, - 0x8d, 0x3c, 0x87, 0x52, 0x02, 0xa1, 0x21, 0x15, 0x52, 0xd8, 0xc9, 0xdc, 0x2d, 0x6b, 0x3c, 0xc1, - 0x6e, 0x00, 0x58, 0xee, 0x62, 0xf6, 0xcc, 0x70, 0x16, 0x56, 0xd0, 0x28, 0x12, 0x4a, 0x82, 0xa8, - 0x3f, 0x80, 0xf2, 0x2c, 0x38, 0xda, 0xb3, 0x0c, 0xd3, 0xf2, 0xd9, 0x15, 0x28, 0xce, 0x82, 0x23, - 0x3d, 0x34, 0x8e, 0x44, 0x13, 0x0a, 0xb3, 0xe0, 0x68, 0x64, 0x1c, 0xb1, 0xab, 0x50, 0x22, 0xc4, - 0xf9, 0x9c, 0xb7, 0x21, 0xaf, 0x21, 0x21, 0xb6, 0x58, 0xfd, 0xdd, 0x02, 0x14, 0x7b, 0x76, 0x68, - 0xf9, 0x86, 0xc3, 0x2e, 0x43, 0xc1, 0x0e, 0xdc, 0x85, 0xe3, 0x10, 0x7b, 0x49, 0x13, 0x29, 0x76, - 0x19, 0xf2, 0xf6, 0x27, 0xcf, 0x0c, 0x87, 0xf3, 0xee, 0x6d, 0x68, 0x3c, 0xc9, 0x1a, 0x50, 0xb0, - 0xdf, 0xff, 0x08, 0x11, 0x59, 0x81, 0x10, 0x69, 0xc2, 0x3c, 0x7c, 0x80, 0x98, 0x5c, 0x8c, 0xa1, - 0x34, 0x61, 0x3e, 0xfa, 0x00, 0x31, 0xd8, 0xfa, 0x2c, 0x61, 0x28, 0x8d, 0xa5, 0x2c, 0xa8, 0x14, - 0xec, 0x80, 0x1a, 0x96, 0xb2, 0x88, 0x4a, 0x59, 0xf0, 0x52, 0x8a, 0x02, 0x21, 0xd2, 0x84, 0xe1, - 0xa5, 0x94, 0x62, 0x4c, 0x5c, 0xca, 0x82, 0x97, 0x52, 0xde, 0xc9, 0xdc, 0xcd, 0x11, 0x86, 0x97, - 0x72, 0x11, 0x72, 0x26, 0xc2, 0x61, 0x27, 0x73, 0x37, 0xb3, 0xb7, 0xa1, 0x51, 0x0a, 0xa1, 0x01, - 0x42, 0x2b, 0xd8, 0xc1, 0x08, 0x0d, 0x04, 0x74, 0x8c, 0xd0, 0x2a, 0xf6, 0x06, 0x42, 0xc7, 0x02, - 0x3a, 0x45, 0x68, 0x6d, 0x27, 0x73, 0x77, 0x13, 0xa1, 0x98, 0x62, 0xd7, 0xa0, 0x68, 0x1a, 0xa1, - 0x85, 0x88, 0xba, 0x68, 0x72, 0x04, 0x40, 0x1c, 0xce, 0x38, 0xc4, 0x6d, 0x89, 0x46, 0x47, 0x00, - 0xa6, 0x42, 0x05, 0xc9, 0x22, 0xbc, 0x22, 0xf0, 0x32, 0x90, 0x7d, 0x08, 0x55, 0xd3, 0x9a, 0xd8, - 0x33, 0xc3, 0xe1, 0x6d, 0xda, 0xde, 0xc9, 0xdc, 0xad, 0x3c, 0xd8, 0xba, 0x4f, 0x6b, 0x22, 0xc6, - 0xec, 0x6d, 0x68, 0x29, 0x32, 0xf6, 0x09, 0xd4, 0x44, 0xfa, 0xfd, 0x07, 0xd4, 0xb1, 0x8c, 0xf8, - 0x94, 0x14, 0xdf, 0xfb, 0x0f, 0x3e, 0xd9, 0xdb, 0xd0, 0xd2, 0x84, 0xec, 0x36, 0x54, 0xe3, 0x25, - 0x82, 0x8c, 0x17, 0x44, 0xad, 0x52, 0x50, 0x6c, 0xd6, 0x57, 0x81, 0xe7, 0x22, 0xc1, 0x45, 0xd1, - 0x6f, 0x11, 0x80, 0xed, 0x00, 0x98, 0xd6, 0xd4, 0x58, 0x38, 0x21, 0xa2, 0x2f, 0x89, 0x0e, 0x94, - 0x60, 0xec, 0x06, 0x94, 0x17, 0x73, 0x6c, 0xe5, 0x13, 0xc3, 0x69, 0x5c, 0x16, 0x04, 0x09, 0x08, - 0x73, 0xc7, 0x79, 0x8e, 0xd8, 0x2b, 0x62, 0x74, 0x23, 0x00, 0x0e, 0xef, 0x33, 0x6b, 0x82, 0xa8, - 0x86, 0x28, 0x58, 0xa4, 0x71, 0x15, 0xd9, 0xc1, 0xae, 0xed, 0x36, 0xae, 0xd2, 0x0c, 0xe6, 0x09, - 0x76, 0x1d, 0xb2, 0x81, 0x3f, 0x69, 0x5c, 0xa3, 0xf6, 0x03, 0x6f, 0x7f, 0xe7, 0x6c, 0xee, 0x6b, - 0x08, 0xde, 0x2d, 0x42, 0x9e, 0x56, 0x93, 0x7a, 0x1d, 0x4a, 0x07, 0x86, 0x6f, 0xcc, 0x34, 0x6b, - 0xca, 0x14, 0xc8, 0xce, 0xbd, 0x40, 0xac, 0x23, 0xfc, 0xa9, 0xf6, 0xa0, 0xf0, 0xc4, 0xf0, 0x11, - 0xc7, 0x20, 0xe7, 0x1a, 0x33, 0x8b, 0x90, 0x65, 0x8d, 0x7e, 0xe3, 0xda, 0x09, 0xce, 0x83, 0xd0, - 0x9a, 0x09, 0x21, 0x21, 0x52, 0x08, 0x3f, 0x72, 0xbc, 0xb1, 0x58, 0x23, 0x25, 0x4d, 0xa4, 0xd4, - 0xff, 0x27, 0x03, 0x85, 0x96, 0xe7, 0x60, 0x76, 0x57, 0xa0, 0xe8, 0x5b, 0x8e, 0x9e, 0x14, 0x57, - 0xf0, 0x2d, 0xe7, 0xc0, 0x0b, 0x10, 0x31, 0xf1, 0x38, 0x82, 0xaf, 0xda, 0xc2, 0xc4, 0x23, 0x44, - 0x54, 0x81, 0xac, 0x54, 0x81, 0xab, 0x50, 0x0a, 0xc7, 0x8e, 0x4e, 0xf0, 0x1c, 0xc1, 0x8b, 0xe1, - 0xd8, 0xe9, 0x23, 0xea, 0x0a, 0x14, 0xcd, 0x31, 0xc7, 0xe4, 0x09, 0x53, 0x30, 0xc7, 0x88, 0x50, - 0x3f, 0x85, 0xb2, 0x66, 0x9c, 0x8a, 0x6a, 0x5c, 0x82, 0x02, 0x66, 0x20, 0xe4, 0x5f, 0x4e, 0xcb, - 0x87, 0x63, 0xa7, 0x6b, 0x22, 0x18, 0x2b, 0x61, 0x9b, 0x54, 0x87, 0x9c, 0x96, 0x9f, 0x78, 0x4e, - 0xd7, 0x54, 0x47, 0x00, 0x2d, 0xcf, 0xf7, 0xbf, 0x73, 0x13, 0x2e, 0x42, 0xde, 0xb4, 0xe6, 0xe1, - 0x31, 0x17, 0x1d, 0x1a, 0x4f, 0xa8, 0xf7, 0xa0, 0x84, 0xe3, 0xd2, 0xb3, 0x83, 0x90, 0xdd, 0x80, - 0x9c, 0x63, 0x07, 0x61, 0x23, 0xb3, 0x93, 0x5d, 0x1a, 0x35, 0x82, 0xab, 0x3b, 0x50, 0xda, 0x37, - 0xce, 0x9e, 0xe0, 0xc8, 0x61, 0x6e, 0x34, 0x84, 0x62, 0x48, 0xc4, 0x78, 0x56, 0x01, 0x46, 0x86, - 0x7f, 0x64, 0x85, 0x24, 0xe9, 0xfe, 0x7b, 0x06, 0x2a, 0xc3, 0xc5, 0xf8, 0xeb, 0x85, 0xe5, 0x9f, - 0x63, 0x9d, 0xef, 0x42, 0x36, 0x3c, 0x9f, 0x13, 0x47, 0xfd, 0xc1, 0x65, 0x9e, 0xbd, 0x84, 0xbf, - 0x8f, 0x4c, 0x1a, 0x92, 0x60, 0x23, 0x5c, 0xcf, 0xb4, 0xa2, 0x3e, 0xc8, 0x6b, 0x05, 0x4c, 0x76, - 0x4d, 0xdc, 0x2e, 0xbc, 0xb9, 0x18, 0x85, 0x4d, 0x6f, 0xce, 0x76, 0x20, 0x3f, 0x39, 0xb6, 0x1d, - 0x93, 0x06, 0x20, 0x5d, 0x67, 0x8e, 0xc0, 0x51, 0xf2, 0xbd, 0x53, 0x3d, 0xb0, 0x7f, 0x12, 0x89, - 0xff, 0xa2, 0xef, 0x9d, 0x0e, 0xed, 0x9f, 0x58, 0xea, 0x48, 0xec, 0x41, 0x00, 0x85, 0x61, 0xab, - 0xd9, 0x6b, 0x6a, 0xca, 0x06, 0xfe, 0xee, 0x7c, 0xd1, 0x1d, 0x8e, 0x86, 0x4a, 0x86, 0xd5, 0x01, - 0xfa, 0x83, 0x91, 0x2e, 0xd2, 0x9b, 0xac, 0x00, 0x9b, 0xdd, 0xbe, 0x92, 0x45, 0x1a, 0x84, 0x77, - 0xfb, 0x4a, 0x8e, 0x15, 0x21, 0xdb, 0xec, 0x7f, 0xa9, 0xe4, 0xe9, 0x47, 0xaf, 0xa7, 0x14, 0xd4, - 0x3f, 0xdd, 0x84, 0xf2, 0x60, 0xfc, 0x95, 0x35, 0x09, 0xb1, 0xcd, 0x38, 0x4b, 0x2d, 0xff, 0x99, - 0xe5, 0x53, 0xb3, 0xb3, 0x9a, 0x48, 0x61, 0x43, 0xcc, 0x31, 0x35, 0x2e, 0xab, 0x6d, 0x9a, 0x63, - 0xa2, 0x9b, 0x1c, 0x5b, 0x33, 0x83, 0x1a, 0x87, 0x74, 0x94, 0xc2, 0x55, 0xe1, 0x8d, 0xbf, 0xa2, - 0xe6, 0x65, 0x35, 0xfc, 0xc9, 0x6e, 0x42, 0x85, 0xe7, 0x21, 0xcf, 0x2f, 0xe0, 0xa0, 0xe5, 0xc9, - 0x57, 0x90, 0x27, 0x1f, 0x71, 0x52, 0xae, 0x1c, 0x29, 0xf6, 0x36, 0x0e, 0xea, 0x8b, 0x19, 0xed, - 0x8d, 0xbf, 0xe2, 0xd8, 0x12, 0x9f, 0xd1, 0xde, 0xf8, 0x2b, 0x42, 0xbd, 0x05, 0xdb, 0xc1, 0x62, - 0x1c, 0x4c, 0x7c, 0x7b, 0x1e, 0xda, 0x9e, 0xcb, 0x69, 0xca, 0x44, 0xa3, 0xc8, 0x08, 0x22, 0xbe, - 0x0b, 0xa5, 0xf9, 0x62, 0xac, 0xdb, 0xee, 0xd4, 0x23, 0xb1, 0x5f, 0x79, 0x50, 0xe3, 0x03, 0x73, - 0xb0, 0x18, 0x77, 0xdd, 0xa9, 0xa7, 0x15, 0xe7, 0xfc, 0x07, 0x53, 0xa1, 0xe6, 0x7a, 0xa1, 0x8e, - 0xaa, 0x82, 0x3e, 0xb3, 0x42, 0x83, 0xf6, 0x03, 0xbe, 0xe1, 0xf7, 0xbc, 0xc9, 0xc9, 0xbe, 0x15, - 0x1a, 0xea, 0x1d, 0x28, 0x0a, 0x3e, 0xdc, 0xfb, 0x43, 0xcb, 0x35, 0xdc, 0x50, 0x8f, 0x95, 0x86, - 0x12, 0x07, 0x74, 0x4d, 0xf5, 0x67, 0x19, 0x50, 0x86, 0x52, 0x55, 0x90, 0x79, 0xad, 0xe4, 0x78, - 0x15, 0xc0, 0x98, 0x4c, 0xbc, 0x05, 0xcf, 0x86, 0x4f, 0xb0, 0xb2, 0x80, 0x74, 0x4d, 0xb9, 0xff, - 0xb2, 0xa9, 0xfe, 0x7b, 0x0d, 0xaa, 0x11, 0x9f, 0xb4, 0xe8, 0x2b, 0x02, 0x16, 0xf5, 0x60, 0xb0, - 0x48, 0xad, 0xfc, 0x62, 0xb0, 0xe0, 0xdc, 0x97, 0xa1, 0x40, 0x1a, 0x46, 0x10, 0x8d, 0x0a, 0x4f, - 0xa9, 0xff, 0x36, 0x03, 0xb5, 0xae, 0x6b, 0x5a, 0x67, 0xc3, 0x89, 0xe1, 0x46, 0x9d, 0x62, 0x07, - 0xba, 0x8d, 0x30, 0x3d, 0x98, 0x18, 0xae, 0x50, 0x0e, 0x2a, 0x76, 0x10, 0xd3, 0x61, 0x1b, 0x38, - 0x01, 0x15, 0xb5, 0x49, 0x39, 0x96, 0x09, 0x42, 0x85, 0xdd, 0x81, 0xad, 0xb1, 0xe5, 0x78, 0xee, - 0x91, 0x1e, 0x7a, 0x3a, 0xd7, 0x72, 0x78, 0x5b, 0x6a, 0x1c, 0x3c, 0xf2, 0x46, 0xa4, 0xed, 0x5c, - 0x84, 0xfc, 0xdc, 0xf0, 0xc3, 0xa0, 0x91, 0xdb, 0xc9, 0xe2, 0x32, 0xa6, 0x04, 0x76, 0xb3, 0x1d, - 0xe8, 0x0b, 0xd7, 0xfe, 0x7a, 0xc1, 0x9b, 0x51, 0xd2, 0x4a, 0x76, 0x70, 0x48, 0x69, 0x76, 0x17, - 0x14, 0x5e, 0x32, 0x65, 0x2b, 0xcf, 0xb3, 0x3a, 0xc1, 0x29, 0x63, 0x12, 0x76, 0xff, 0xef, 0x26, - 0x94, 0x1e, 0x2d, 0xdc, 0x09, 0x0e, 0x06, 0xbb, 0x05, 0xb9, 0xe9, 0xc2, 0x9d, 0x50, 0x5b, 0xe2, - 0xad, 0x34, 0x5e, 0x27, 0x1a, 0x21, 0x51, 0x02, 0x19, 0xfe, 0x11, 0x4a, 0xae, 0x15, 0x09, 0x84, - 0x70, 0xf5, 0x1f, 0x66, 0x78, 0x8e, 0x8f, 0x1c, 0xe3, 0x88, 0x95, 0x20, 0xd7, 0x1f, 0xf4, 0x3b, - 0xca, 0x06, 0xab, 0x42, 0xa9, 0xdb, 0x1f, 0x75, 0xb4, 0x7e, 0xb3, 0xa7, 0x64, 0x68, 0x39, 0x8f, - 0x9a, 0xbb, 0xbd, 0x8e, 0xb2, 0x89, 0x98, 0x27, 0x83, 0x5e, 0x73, 0xd4, 0xed, 0x75, 0x94, 0x1c, - 0xc7, 0x68, 0xdd, 0xd6, 0x48, 0x29, 0x31, 0x05, 0xaa, 0x07, 0xda, 0xa0, 0x7d, 0xd8, 0xea, 0xe8, - 0xfd, 0xc3, 0x5e, 0x4f, 0x51, 0xd8, 0x05, 0xd8, 0x8a, 0x21, 0x03, 0x0e, 0xdc, 0x41, 0x96, 0x27, - 0x4d, 0xad, 0xa9, 0x3d, 0x56, 0x7e, 0xc8, 0x4a, 0x90, 0x6d, 0x3e, 0x7e, 0xac, 0xfc, 0x14, 0x25, - 0x43, 0xf9, 0x69, 0xb7, 0xaf, 0x3f, 0x69, 0xf6, 0x0e, 0x3b, 0xca, 0x4f, 0x37, 0xa3, 0xf4, 0x40, - 0x6b, 0x77, 0x34, 0xe5, 0xa7, 0x39, 0xb6, 0x0d, 0xd5, 0x1f, 0x0f, 0xfa, 0x9d, 0xfd, 0xe6, 0xc1, - 0x01, 0x55, 0xe4, 0xa7, 0x25, 0xf5, 0xbf, 0xe4, 0x20, 0x87, 0x2d, 0x61, 0x6a, 0x22, 0x05, 0xe3, - 0x26, 0xa2, 0x18, 0xda, 0xcd, 0xfd, 0xc9, 0x5f, 0xdc, 0xdc, 0xe0, 0xf2, 0xef, 0x35, 0xc8, 0x3a, - 0x76, 0x48, 0xc3, 0x1a, 0xaf, 0x1d, 0xa1, 0x33, 0xee, 0x6d, 0x68, 0x88, 0x63, 0x37, 0x20, 0xc3, - 0x05, 0x61, 0xe5, 0x41, 0x5d, 0x2c, 0x2e, 0xb1, 0x93, 0xee, 0x6d, 0x68, 0x99, 0x39, 0xbb, 0x0e, - 0x99, 0x67, 0x42, 0x2a, 0x56, 0x39, 0x9e, 0xef, 0xa5, 0x88, 0x7d, 0xc6, 0x76, 0x20, 0x3b, 0xf1, - 0xb8, 0x46, 0x18, 0xe3, 0xf9, 0xce, 0x82, 0xf9, 0x4f, 0x3c, 0x87, 0xdd, 0x82, 0xac, 0x6f, 0x9c, - 0xd2, 0xc8, 0xc6, 0xc3, 0x15, 0x6f, 0x5d, 0x48, 0xe4, 0x1b, 0xa7, 0x58, 0x89, 0x29, 0xc9, 0x91, - 0xb8, 0x12, 0xd1, 0x78, 0x63, 0x31, 0x53, 0xb6, 0x03, 0x99, 0x53, 0x92, 0x24, 0xb1, 0x12, 0xf4, - 0xd4, 0x76, 0x4d, 0xef, 0x74, 0x38, 0xb7, 0x26, 0x48, 0x71, 0xca, 0x5e, 0x87, 0x6c, 0xb0, 0x18, - 0x93, 0x24, 0xa9, 0x3c, 0xd8, 0x5e, 0xd9, 0x13, 0xb0, 0xa0, 0x60, 0x31, 0x66, 0x77, 0x20, 0x37, - 0xf1, 0x7c, 0x5f, 0x48, 0x13, 0x25, 0xaa, 0x70, 0xb4, 0x1d, 0xa2, 0x52, 0x88, 0x78, 0x2c, 0x30, - 0x24, 0x19, 0x12, 0x13, 0x25, 0xfb, 0x11, 0x16, 0x18, 0xb2, 0xdb, 0x62, 0x93, 0xab, 0xca, 0xb5, - 0x8e, 0xb6, 0x40, 0xcc, 0x07, 0xb1, 0x38, 0x48, 0x33, 0xe3, 0x8c, 0x34, 0xce, 0x98, 0x28, 0xda, - 0xfb, 0xb0, 0x4e, 0x33, 0xe3, 0x8c, 0xdd, 0x86, 0xec, 0x33, 0x6b, 0x42, 0xca, 0x67, 0x5c, 0x9a, - 0x18, 0xa4, 0x27, 0xd4, 0x3c, 0x44, 0xd3, 0xbc, 0xf7, 0x1c, 0x93, 0xf4, 0xd0, 0x78, 0x2c, 0x1f, - 0x79, 0x8e, 0xf9, 0x84, 0xc6, 0x92, 0x90, 0xb8, 0xe5, 0x1b, 0x8b, 0x33, 0x94, 0x46, 0x0a, 0xdf, - 0x9c, 0x8d, 0xc5, 0x59, 0xd7, 0x44, 0xe1, 0xef, 0x9a, 0xcf, 0x48, 0xfb, 0xcc, 0x68, 0xf8, 0x13, - 0xcd, 0xa3, 0xc0, 0x72, 0xac, 0x49, 0x68, 0x3f, 0xb3, 0xc3, 0x73, 0xd2, 0x2f, 0x33, 0x9a, 0x0c, - 0xda, 0x2d, 0x40, 0xce, 0x3a, 0x9b, 0xfb, 0xea, 0x1e, 0x14, 0x45, 0x29, 0x2b, 0x36, 0xd6, 0x55, - 0x28, 0xd9, 0x81, 0x3e, 0xf1, 0xdc, 0x20, 0x14, 0xba, 0x53, 0xd1, 0x0e, 0x5a, 0x98, 0x44, 0x71, - 0x69, 0x1a, 0x21, 0xdf, 0x84, 0xaa, 0x1a, 0xfd, 0x56, 0x1f, 0x00, 0x24, 0xcd, 0xc2, 0x3a, 0x39, - 0x96, 0x1b, 0xa9, 0x69, 0x8e, 0xe5, 0xc6, 0x3c, 0x9b, 0x12, 0xcf, 0x55, 0x28, 0xc7, 0x9a, 0x31, - 0xab, 0x42, 0xc6, 0x10, 0xdb, 0x5f, 0xc6, 0x50, 0xef, 0xa2, 0xa2, 0x1a, 0xe9, 0xbe, 0x69, 0x1c, - 0xa6, 0xa2, 0x4d, 0x31, 0x33, 0x56, 0xbf, 0x0f, 0x55, 0xcd, 0x0a, 0x16, 0x4e, 0xd8, 0xf2, 0x9c, - 0xb6, 0x35, 0x65, 0x6f, 0x03, 0xc4, 0xe9, 0x40, 0x68, 0x29, 0xc9, 0xdc, 0x6d, 0x5b, 0x53, 0x4d, - 0xc2, 0xab, 0xff, 0x29, 0x47, 0xfa, 0x5e, 0x9b, 0x2b, 0x5a, 0x42, 0xa3, 0xca, 0x48, 0x1a, 0x55, - 0xbc, 0x37, 0x6c, 0xa6, 0xb5, 0xca, 0x63, 0xdb, 0x34, 0x2d, 0x37, 0xd2, 0x1e, 0x79, 0x0a, 0x07, - 0xdb, 0x70, 0x8e, 0x68, 0x41, 0xd5, 0x1f, 0xb0, 0xa8, 0xd0, 0xd9, 0xdc, 0xb7, 0x82, 0x80, 0xeb, - 0x2d, 0x86, 0x73, 0x14, 0xad, 0xed, 0xfc, 0x8b, 0xd6, 0xf6, 0x55, 0x28, 0xe1, 0x96, 0x47, 0x56, - 0x5f, 0x81, 0xf7, 0xbe, 0x30, 0x6f, 0xd9, 0x1b, 0x50, 0x14, 0xfa, 0xba, 0x58, 0x54, 0x62, 0xba, - 0xb4, 0x39, 0x50, 0x8b, 0xb0, 0xac, 0x81, 0x4a, 0xde, 0x6c, 0x66, 0xb9, 0x61, 0xb4, 0x4f, 0x8b, - 0x24, 0x7b, 0x0b, 0xca, 0x9e, 0xab, 0x73, 0xa5, 0x5e, 0xac, 0x2a, 0x31, 0x7d, 0x07, 0xee, 0x21, - 0x41, 0xb5, 0x92, 0x27, 0x7e, 0x61, 0x55, 0x1c, 0xef, 0x54, 0x9f, 0x18, 0xbe, 0x49, 0x2b, 0xab, - 0xa4, 0x15, 0x1d, 0xef, 0xb4, 0x65, 0xf8, 0x26, 0xd7, 0x5b, 0xbe, 0x76, 0x17, 0x33, 0x5a, 0x4d, - 0x35, 0x4d, 0xa4, 0xd8, 0x75, 0x28, 0x4f, 0x9c, 0x45, 0x10, 0x5a, 0xfe, 0xee, 0x39, 0x37, 0xd3, - 0xb4, 0x04, 0x80, 0xf5, 0x9a, 0xfb, 0xf6, 0xcc, 0xf0, 0xcf, 0x69, 0xe9, 0x94, 0xb4, 0x28, 0x49, - 0x1b, 0xcd, 0x89, 0x6d, 0x9e, 0x71, 0x5b, 0x4d, 0xe3, 0x09, 0xa4, 0x3f, 0x26, 0x4b, 0x3a, 0xa0, - 0xf5, 0x51, 0xd2, 0xa2, 0x24, 0x8d, 0x03, 0xfd, 0xa4, 0x15, 0x51, 0xd6, 0x44, 0x2a, 0xa5, 0x74, - 0x6f, 0x3f, 0x57, 0xe9, 0x66, 0xcb, 0x7a, 0x8f, 0xe7, 0xdb, 0x47, 0xb6, 0xd0, 0x5a, 0x2e, 0x70, - 0xbd, 0x87, 0x83, 0x88, 0xe0, 0x63, 0xa8, 0x1d, 0x59, 0xae, 0xe5, 0x1b, 0xa1, 0x65, 0xea, 0x28, - 0x17, 0x2f, 0x52, 0xc7, 0x89, 0x61, 0x7e, 0x1c, 0xa1, 0x50, 0xd6, 0x54, 0x8f, 0xa4, 0x94, 0xfa, - 0x35, 0x14, 0xc5, 0xd8, 0xe0, 0xd6, 0x85, 0xeb, 0x2e, 0x2d, 0xd7, 0xf9, 0xd6, 0x85, 0x70, 0x76, - 0x0b, 0x6a, 0xa2, 0x12, 0x41, 0xe8, 0xdb, 0xee, 0x91, 0x98, 0x75, 0x55, 0x0e, 0x1c, 0x12, 0x0c, - 0x35, 0x0c, 0x9c, 0x17, 0xba, 0x31, 0xb6, 0x1d, 0x5c, 0xdf, 0x59, 0xa1, 0x0d, 0x2d, 0x1c, 0xa7, - 0xc9, 0x41, 0xea, 0x00, 0x4a, 0xd1, 0x48, 0xfe, 0x52, 0xca, 0x54, 0xe7, 0x50, 0x95, 0x5b, 0xf8, - 0xcb, 0x69, 0x08, 0xd7, 0x20, 0x82, 0xd0, 0xf3, 0x2d, 0x33, 0x72, 0xd2, 0xd8, 0xc1, 0x90, 0xd2, - 0xea, 0x6f, 0x65, 0xa0, 0x42, 0x9a, 0xcc, 0x80, 0xf4, 0x34, 0xf6, 0x36, 0xb0, 0x89, 0x6f, 0x19, - 0xa1, 0xa5, 0x5b, 0x67, 0xa1, 0x6f, 0x08, 0x7d, 0x85, 0x2b, 0x3d, 0x0a, 0xc7, 0x74, 0x10, 0xc1, - 0x55, 0x96, 0x9b, 0x50, 0x99, 0x1b, 0x7e, 0x10, 0xe9, 0xbf, 0xbc, 0x74, 0xe0, 0x20, 0xa1, 0x7d, - 0x2a, 0xee, 0x91, 0x6f, 0xcc, 0xf4, 0xd0, 0x3b, 0xb1, 0x5c, 0xae, 0xf9, 0x73, 0x9b, 0xa7, 0x4e, - 0xf0, 0x11, 0x82, 0xc9, 0x00, 0xf8, 0x77, 0x19, 0xa8, 0x1d, 0xf0, 0x09, 0xfa, 0xb9, 0x75, 0xde, - 0xe6, 0x86, 0xe6, 0x24, 0x12, 0x2e, 0x39, 0x8d, 0x7e, 0xb3, 0x1b, 0x50, 0x99, 0x9f, 0x58, 0xe7, - 0x7a, 0xca, 0x28, 0x2b, 0x23, 0xa8, 0x45, 0x62, 0xe4, 0x4d, 0x28, 0x78, 0xd4, 0x10, 0xb1, 0x1d, - 0x8b, 0x5d, 0x4c, 0x6a, 0xa1, 0x26, 0x08, 0x50, 0xb3, 0x8b, 0xb3, 0x92, 0x55, 0x48, 0x91, 0x19, - 0x55, 0xff, 0x22, 0xe4, 0x11, 0x15, 0x34, 0xf2, 0x5c, 0x25, 0xa3, 0x04, 0x7b, 0x0f, 0x6a, 0x13, - 0x6f, 0x36, 0xd7, 0x23, 0x76, 0xb1, 0x31, 0xa7, 0xc5, 0x5f, 0x05, 0x49, 0x0e, 0x78, 0x5e, 0xea, - 0xef, 0x65, 0xa1, 0x44, 0x75, 0x10, 0x12, 0xd0, 0x36, 0xcf, 0x22, 0x09, 0x58, 0xd6, 0xf2, 0xb6, - 0x89, 0x1b, 0xcc, 0x4b, 0xb4, 0xc8, 0x58, 0x3b, 0xcc, 0xca, 0xda, 0xe1, 0x65, 0x28, 0x08, 0xd5, - 0x30, 0xc7, 0x45, 0xe4, 0xe2, 0xf9, 0x8a, 0x61, 0x7e, 0x9d, 0x62, 0x88, 0x43, 0xc8, 0x69, 0xac, - 0x33, 0xdc, 0x8a, 0xb9, 0x14, 0x04, 0x02, 0x75, 0x10, 0x22, 0xcb, 0xb7, 0x62, 0x5a, 0xbe, 0x35, - 0xa0, 0xf8, 0xcc, 0x0e, 0x6c, 0x9c, 0x20, 0x25, 0x2e, 0x31, 0x44, 0x52, 0x1a, 0x86, 0xf2, 0xcb, - 0x86, 0x21, 0x6e, 0xb6, 0xe1, 0x1c, 0x71, 0x0b, 0x25, 0x6a, 0x76, 0xd3, 0x39, 0xf2, 0xd8, 0xfb, - 0x70, 0x29, 0x41, 0x8b, 0xd6, 0x90, 0x27, 0x8f, 0x9c, 0x55, 0x1a, 0x8b, 0x29, 0xa9, 0x45, 0x64, - 0x42, 0xde, 0x83, 0x6d, 0x89, 0x65, 0x8e, 0x9a, 0x58, 0x40, 0xe2, 0xb1, 0xac, 0x6d, 0xc5, 0xe4, - 0xa4, 0xa0, 0x05, 0xea, 0x3f, 0xd9, 0x84, 0xda, 0x23, 0xcf, 0xb7, 0xec, 0x23, 0x37, 0x99, 0x75, - 0x2b, 0x46, 0x4a, 0x34, 0x13, 0x37, 0xa5, 0x99, 0x78, 0x13, 0x2a, 0x53, 0xce, 0xa8, 0x87, 0x63, - 0xee, 0xdf, 0xc8, 0x69, 0x20, 0x40, 0xa3, 0xb1, 0x83, 0xf2, 0x23, 0x22, 0x20, 0xe6, 0x1c, 0x31, - 0x47, 0x4c, 0xb8, 0x2d, 0xb2, 0xef, 0xd1, 0x06, 0x61, 0x5a, 0x8e, 0x15, 0xf2, 0xe1, 0xa9, 0x3f, - 0x78, 0x35, 0x52, 0x4a, 0xa4, 0x3a, 0xdd, 0xd7, 0xac, 0x69, 0x93, 0x34, 0x39, 0xdc, 0x2f, 0xda, - 0x44, 0x2e, 0x78, 0xc5, 0xe6, 0x52, 0xf8, 0x86, 0xbc, 0x5c, 0x56, 0xa9, 0x23, 0x28, 0xc7, 0x60, - 0x54, 0xcb, 0xb5, 0x8e, 0x50, 0xc5, 0x37, 0x58, 0x05, 0x8a, 0xad, 0xe6, 0xb0, 0xd5, 0x6c, 0x77, - 0x94, 0x0c, 0xa2, 0x86, 0x9d, 0x11, 0x57, 0xbf, 0x37, 0xd9, 0x16, 0x54, 0x30, 0xd5, 0xee, 0x3c, - 0x6a, 0x1e, 0xf6, 0x46, 0x4a, 0x96, 0xd5, 0xa0, 0xdc, 0x1f, 0xe8, 0xcd, 0xd6, 0xa8, 0x3b, 0xe8, - 0x2b, 0x39, 0xf5, 0x87, 0x50, 0x6a, 0x1d, 0x5b, 0x93, 0x93, 0xe7, 0xf5, 0x22, 0xf9, 0x07, 0xac, - 0xc9, 0x89, 0x50, 0xa5, 0x97, 0xfc, 0x03, 0xd6, 0xe4, 0x44, 0xed, 0x40, 0xf9, 0xc0, 0xf0, 0x43, - 0x9b, 0xea, 0xf5, 0x09, 0xd4, 0xe2, 0x44, 0xdb, 0x9a, 0x46, 0x4a, 0x06, 0x8b, 0x15, 0xec, 0x18, - 0xa5, 0xa5, 0x09, 0xd5, 0xb7, 0xa1, 0x2a, 0x03, 0xd8, 0x75, 0xc8, 0x9a, 0xd6, 0x74, 0x8d, 0x10, - 0x45, 0xb0, 0xfa, 0x04, 0xaa, 0xad, 0x68, 0xd3, 0x7c, 0x5e, 0xd5, 0x1f, 0x40, 0x9d, 0x56, 0xfc, - 0x64, 0x1c, 0x2d, 0xf9, 0xcd, 0x35, 0x4b, 0xbe, 0x8a, 0x34, 0xad, 0xb1, 0x58, 0xf3, 0x1f, 0x42, - 0xe5, 0xc0, 0xf7, 0xe6, 0x96, 0x1f, 0x52, 0xb6, 0x0a, 0x64, 0x4f, 0xac, 0x73, 0x91, 0x2b, 0xfe, - 0x4c, 0xdc, 0x36, 0x9b, 0xb2, 0xdb, 0xe6, 0x01, 0x94, 0x22, 0xb6, 0x6f, 0xcc, 0xf3, 0x03, 0x14, - 0x9d, 0xc4, 0x63, 0x5b, 0x01, 0x16, 0x76, 0x1f, 0x60, 0x1e, 0x03, 0x44, 0xc7, 0x45, 0x96, 0x89, - 0xc8, 0x5c, 0x93, 0x28, 0xd4, 0x57, 0xa1, 0xf8, 0xc4, 0xb6, 0x4e, 0x45, 0xf3, 0x9f, 0xd9, 0xd6, - 0x69, 0xd4, 0x7c, 0xfc, 0xad, 0xfe, 0x8b, 0x32, 0x94, 0x68, 0x7d, 0xb5, 0x9f, 0xef, 0x29, 0xfb, - 0x36, 0x0a, 0xdc, 0x8e, 0x58, 0x4f, 0xb9, 0x35, 0x6a, 0x23, 0x5f, 0x5d, 0xaf, 0x02, 0x48, 0x6b, - 0x9d, 0x4b, 0xae, 0x72, 0x18, 0x2f, 0x71, 0xd4, 0x7c, 0x68, 0x2f, 0x0a, 0xbe, 0x76, 0x84, 0xc1, - 0x9b, 0x00, 0xd8, 0x7d, 0xae, 0x97, 0x90, 0x89, 0xcb, 0x75, 0xb7, 0x0b, 0x91, 0xfd, 0x31, 0x76, - 0xac, 0xc8, 0x2a, 0x22, 0x65, 0x05, 0x13, 0x24, 0xc7, 0x2c, 0x3f, 0x40, 0x71, 0x45, 0xae, 0x74, - 0x2d, 0x4a, 0xb2, 0x37, 0x20, 0x87, 0x42, 0x5e, 0x58, 0x31, 0x17, 0xa2, 0x1e, 0x94, 0x76, 0x29, - 0x8d, 0x08, 0xd8, 0x5d, 0x28, 0x92, 0x68, 0xb1, 0x50, 0xd2, 0x48, 0xbd, 0x1d, 0x09, 0x7d, 0x2d, - 0x42, 0xb3, 0x37, 0x21, 0x3f, 0x3d, 0xb1, 0xce, 0x83, 0x46, 0x8d, 0xe8, 0x2e, 0xac, 0x59, 0xb3, - 0x1a, 0xa7, 0x60, 0xb7, 0xa1, 0xee, 0x5b, 0x53, 0x9d, 0x7c, 0x67, 0x28, 0x64, 0x82, 0x46, 0x9d, - 0x64, 0x48, 0xd5, 0xb7, 0xa6, 0x2d, 0x04, 0x8e, 0xc6, 0x4e, 0xc0, 0xee, 0x40, 0x81, 0x56, 0x0f, - 0xaa, 0x6d, 0x52, 0xc9, 0xd1, 0x52, 0xd4, 0x04, 0x96, 0xbd, 0x0f, 0x20, 0x94, 0x43, 0x7d, 0x7c, - 0x4e, 0x3e, 0xe7, 0x78, 0x31, 0xc9, 0xf3, 0x5f, 0x56, 0x21, 0xdf, 0x80, 0x3c, 0x4e, 0x92, 0xa0, - 0x71, 0x85, 0x72, 0xde, 0x4e, 0xcf, 0x20, 0xaa, 0x29, 0xe1, 0xd9, 0x5d, 0x28, 0xe1, 0x44, 0xd1, - 0x71, 0x38, 0x1a, 0xb2, 0xb6, 0x2c, 0x66, 0x15, 0xee, 0x0c, 0xd6, 0xe9, 0xf0, 0x6b, 0x87, 0xdd, - 0x83, 0x9c, 0x89, 0x8b, 0xf9, 0x2a, 0xe5, 0x78, 0x59, 0x1a, 0x17, 0x14, 0x56, 0x6d, 0x6b, 0x4a, - 0x0a, 0x3c, 0xd1, 0xb0, 0x3d, 0xa8, 0xe3, 0x34, 0x7a, 0x40, 0x9b, 0x3d, 0x76, 0x5f, 0xe3, 0x1a, - 0x71, 0xbd, 0xb6, 0xc4, 0xd5, 0x17, 0x44, 0xd4, 0xd9, 0x1d, 0x37, 0xf4, 0xcf, 0xb5, 0x9a, 0x2b, - 0xc3, 0xd8, 0x35, 0xb4, 0xb2, 0x7a, 0xde, 0xe4, 0xc4, 0x32, 0x1b, 0xaf, 0x44, 0x1a, 0x10, 0x4f, - 0xb3, 0x4f, 0xa1, 0x46, 0x13, 0x0b, 0x93, 0x58, 0x78, 0xe3, 0x3a, 0x09, 0x53, 0x79, 0xca, 0x44, - 0x28, 0x2d, 0x4d, 0x89, 0x22, 0xde, 0x0e, 0xf4, 0xd0, 0x9a, 0xcd, 0x3d, 0x1f, 0xf5, 0xec, 0x57, - 0x23, 0xdf, 0xd0, 0x28, 0x02, 0xe1, 0x46, 0x1c, 0x9f, 0x90, 0xe9, 0xde, 0x74, 0x1a, 0x58, 0x61, - 0xe3, 0x06, 0xad, 0x9b, 0x7a, 0x74, 0x50, 0x36, 0x20, 0x28, 0x6d, 0x84, 0x81, 0x6e, 0x9e, 0xbb, - 0xc6, 0xcc, 0x9e, 0x34, 0x6e, 0x72, 0x75, 0xde, 0x0e, 0xda, 0x1c, 0x20, 0x6b, 0xd4, 0x3b, 0x29, - 0x8d, 0xfa, 0x02, 0xe4, 0xcd, 0x31, 0x2e, 0xc7, 0xd7, 0x28, 0xdb, 0x9c, 0x39, 0xee, 0x9a, 0xec, - 0x1d, 0x28, 0xcf, 0x23, 0x11, 0xd8, 0x50, 0x65, 0xbf, 0x41, 0x2c, 0x19, 0xb5, 0x84, 0x02, 0x4d, - 0xd9, 0x47, 0x96, 0x11, 0x2e, 0x7c, 0xeb, 0x91, 0x63, 0x1c, 0x35, 0x6e, 0x51, 0x4e, 0x32, 0x08, - 0x6b, 0xe7, 0x78, 0x47, 0xf6, 0xc4, 0xa0, 0x95, 0x7f, 0x9b, 0xeb, 0x5d, 0x02, 0xd2, 0x35, 0x13, - 0x45, 0xd4, 0x10, 0xca, 0xd4, 0xeb, 0xb2, 0x22, 0x6a, 0x90, 0x36, 0x75, 0xed, 0x31, 0x69, 0xe8, - 0xd4, 0x73, 0x1f, 0x2e, 0x09, 0xa8, 0xd4, 0xf2, 0x92, 0x24, 0xd9, 0xde, 0x86, 0x2c, 0xa7, 0x76, - 0xf3, 0x24, 0xc9, 0xaf, 0xfd, 0x10, 0xd8, 0xea, 0x98, 0xbf, 0x4c, 0x5a, 0xe6, 0x85, 0xb4, 0xfc, - 0xde, 0xe6, 0x27, 0x19, 0xf5, 0x09, 0xd4, 0x52, 0xc2, 0x60, 0xad, 0xd4, 0xe7, 0x2a, 0x97, 0x31, - 0x13, 0xd6, 0x34, 0x4f, 0x44, 0xea, 0xb4, 0xed, 0x1e, 0x09, 0x47, 0x1e, 0x57, 0xa7, 0x29, 0xad, - 0xfe, 0x69, 0x16, 0xaa, 0x7b, 0x46, 0x70, 0xbc, 0x6f, 0xcc, 0x87, 0xa1, 0x11, 0x06, 0x38, 0x45, - 0x8e, 0x8d, 0xe0, 0x78, 0x66, 0xcc, 0xb9, 0xf2, 0x9b, 0xe1, 0x5e, 0x02, 0x01, 0x43, 0xcd, 0x17, - 0x27, 0x27, 0x26, 0x07, 0xee, 0xc1, 0xe7, 0xc2, 0x05, 0x10, 0xa7, 0x51, 0x34, 0x05, 0xc7, 0x8b, - 0xe9, 0x34, 0x2e, 0x2a, 0x4a, 0xb2, 0xdb, 0x50, 0x13, 0x3f, 0x49, 0xf3, 0x3d, 0x13, 0xa7, 0xac, - 0x69, 0x20, 0x7b, 0x08, 0x15, 0x01, 0x18, 0x45, 0x82, 0xb4, 0x1e, 0xbb, 0x76, 0x12, 0x84, 0x26, - 0x53, 0xb1, 0x1f, 0xc1, 0x25, 0x29, 0xf9, 0xc8, 0xf3, 0xf7, 0x17, 0x4e, 0x68, 0xb7, 0xfa, 0x42, - 0xcd, 0x78, 0x65, 0x85, 0x3d, 0x21, 0xd1, 0xd6, 0x73, 0xa6, 0x6b, 0xbb, 0x6f, 0xbb, 0x24, 0x97, - 0xb3, 0x5a, 0x1a, 0xb8, 0x44, 0x65, 0x9c, 0x91, 0x38, 0x4e, 0x53, 0x19, 0x67, 0xb8, 0x60, 0x05, - 0x60, 0xdf, 0x0a, 0x8f, 0x3d, 0x93, 0x74, 0xcc, 0x78, 0xc1, 0x0e, 0x65, 0x94, 0x96, 0xa6, 0xc4, - 0xee, 0x44, 0xfb, 0x6d, 0xe2, 0x86, 0xa4, 0x69, 0x66, 0xb5, 0x28, 0x89, 0x5b, 0x95, 0x6f, 0xb8, - 0x47, 0x56, 0xd0, 0xa8, 0xec, 0x64, 0xef, 0x66, 0x34, 0x91, 0x52, 0xff, 0xe6, 0x26, 0xe4, 0xf9, - 0x48, 0xbe, 0x02, 0xe5, 0x31, 0xf9, 0xc6, 0xd1, 0x10, 0x17, 0xfe, 0x6e, 0x02, 0xf4, 0x17, 0x33, - 0xae, 0x21, 0x0a, 0x17, 0x4e, 0x46, 0xa3, 0xdf, 0x98, 0xa5, 0xb7, 0x08, 0xb1, 0xac, 0x2c, 0x41, - 0x45, 0x0a, 0x2b, 0xe1, 0x7b, 0xa7, 0x34, 0x1b, 0x72, 0x84, 0x88, 0x92, 0xe4, 0x52, 0xa7, 0x5d, - 0x0f, 0x99, 0xf2, 0x84, 0x2b, 0x11, 0xa0, 0xe5, 0x86, 0xcb, 0xee, 0xa6, 0xc2, 0x8a, 0xbb, 0x89, - 0xdd, 0x00, 0xd4, 0x3f, 0x27, 0xd6, 0xc0, 0xb5, 0x5a, 0x7d, 0xea, 0xe1, 0x92, 0x26, 0x41, 0x70, - 0x81, 0x98, 0xde, 0x9c, 0x3a, 0x35, 0xaf, 0xe1, 0x4f, 0xf6, 0x51, 0x3c, 0x3b, 0xa9, 0x8d, 0x42, - 0x5b, 0x17, 0xbb, 0x82, 0x3c, 0x8f, 0xb5, 0x14, 0x1d, 0xe6, 0x84, 0xa2, 0x9e, 0x6b, 0xeb, 0xf8, - 0x53, 0xed, 0x00, 0x68, 0xde, 0x69, 0x60, 0x85, 0xe4, 0x57, 0xbd, 0x42, 0x4d, 0x4c, 0x9d, 0x88, - 0x79, 0xa7, 0x07, 0x5e, 0x10, 0x1b, 0xb4, 0x9b, 0xeb, 0x0d, 0x5a, 0xf5, 0x5d, 0x28, 0xa2, 0x1e, - 0x60, 0x84, 0x06, 0xbb, 0x2d, 0x5c, 0x59, 0x5c, 0x7b, 0x11, 0x3e, 0xbd, 0xa4, 0x0c, 0xe1, 0xdc, - 0xea, 0x45, 0xe5, 0x12, 0xcf, 0x6b, 0x92, 0xc9, 0x18, 0xef, 0x41, 0x22, 0x43, 0xa1, 0x59, 0xbc, - 0x02, 0x65, 0xac, 0x1a, 0x1d, 0x13, 0x08, 0xb9, 0x50, 0xf2, 0xbd, 0xd3, 0x16, 0xa6, 0xd5, 0x7f, - 0x9f, 0x81, 0xca, 0xc0, 0x37, 0x71, 0xf3, 0x1b, 0xce, 0xad, 0xc9, 0x4b, 0xed, 0x6f, 0xd4, 0x43, - 0x3c, 0xc7, 0x31, 0x48, 0xcc, 0x0a, 0x93, 0x2d, 0x06, 0xb0, 0xf7, 0x21, 0x37, 0x45, 0x71, 0x9a, - 0x95, 0xb5, 0x73, 0x29, 0xfb, 0xe8, 0x37, 0x0a, 0x58, 0x8d, 0x48, 0xd5, 0x5f, 0x8f, 0xcb, 0x27, - 0xa9, 0x2b, 0x3b, 0xd3, 0x37, 0xe8, 0x58, 0x6b, 0xd8, 0x52, 0x32, 0xac, 0x04, 0xb9, 0x76, 0x67, - 0xd8, 0xe2, 0x3a, 0x39, 0x6a, 0xe7, 0x43, 0xfd, 0x51, 0x57, 0x1b, 0x8e, 0x94, 0x1c, 0x9d, 0x93, - 0x11, 0xa0, 0xd7, 0x1c, 0x8e, 0x94, 0x12, 0x03, 0x28, 0x1c, 0xf6, 0xbb, 0x3f, 0x3a, 0xec, 0x28, - 0x8a, 0xfa, 0xaf, 0x32, 0x00, 0x89, 0xcf, 0x97, 0xbd, 0x05, 0x95, 0x53, 0x4a, 0xe9, 0xd2, 0x61, - 0x80, 0xdc, 0x46, 0xe0, 0x68, 0xd2, 0x91, 0xde, 0x81, 0x6a, 0xbc, 0x5d, 0xa0, 0xfe, 0xb0, 0x7a, - 0x2a, 0x50, 0x89, 0xf1, 0xbb, 0xe7, 0xec, 0x6d, 0x28, 0x79, 0xd8, 0x0e, 0x24, 0xcd, 0xca, 0xca, - 0x83, 0xd4, 0x7c, 0xad, 0xe8, 0xf1, 0x04, 0xea, 0x19, 0x53, 0x3f, 0x32, 0xc1, 0x63, 0xd2, 0x47, - 0x08, 0x6a, 0x39, 0xc6, 0x22, 0xb0, 0x34, 0x8e, 0x8f, 0xa5, 0x74, 0x3e, 0x91, 0xd2, 0xea, 0x8f, - 0xa1, 0x3e, 0x34, 0x66, 0x73, 0x2e, 0xcb, 0xa9, 0x61, 0x0c, 0x72, 0x38, 0x27, 0xc4, 0xd4, 0xa3, - 0xdf, 0xb8, 0xe8, 0x0e, 0x2c, 0x7f, 0x62, 0xb9, 0xd1, 0x1a, 0x8d, 0x92, 0x28, 0x7e, 0x0f, 0x51, - 0x9a, 0x6b, 0xde, 0x69, 0x24, 0xce, 0xa3, 0xb4, 0xfa, 0x77, 0x32, 0x50, 0x91, 0xaa, 0xc1, 0xde, - 0x85, 0x1c, 0x29, 0xa4, 0x19, 0x59, 0x10, 0x4a, 0x04, 0xfc, 0x37, 0x57, 0x61, 0x90, 0x90, 0xdd, - 0x81, 0x7c, 0x10, 0x1a, 0x7e, 0x74, 0x7c, 0xa0, 0x48, 0x1c, 0xbb, 0xde, 0xc2, 0x35, 0x35, 0x8e, - 0x66, 0x2a, 0x64, 0x2d, 0xd7, 0x14, 0x4e, 0x8b, 0x55, 0x2a, 0x44, 0xaa, 0x3b, 0x50, 0x8e, 0xb3, - 0xc7, 0x29, 0xa0, 0x0d, 0x9e, 0x0e, 0x95, 0x0d, 0x56, 0x86, 0xbc, 0xd6, 0xec, 0x3f, 0xee, 0x28, - 0x19, 0xf5, 0x67, 0x19, 0x80, 0x84, 0x8b, 0xdd, 0x4f, 0xd5, 0xf6, 0xda, 0x72, 0xae, 0xf7, 0xe9, - 0xaf, 0x54, 0xd9, 0xeb, 0x50, 0x5e, 0xb8, 0x04, 0xb4, 0x4c, 0xb1, 0x13, 0x25, 0x00, 0xb4, 0xa2, - 0xa2, 0x60, 0x97, 0x25, 0x2b, 0xea, 0x99, 0xe1, 0xa8, 0xdf, 0x83, 0x72, 0x9c, 0x1d, 0x1a, 0x86, - 0x8f, 0x06, 0xbd, 0xde, 0xe0, 0x69, 0xb7, 0xff, 0x58, 0xd9, 0xc0, 0xe4, 0x81, 0xd6, 0x69, 0x75, - 0xda, 0x98, 0xcc, 0xe0, 0x9c, 0x6d, 0x1d, 0x6a, 0x5a, 0xa7, 0x3f, 0xd2, 0xb5, 0xc1, 0x53, 0x65, - 0x53, 0xfd, 0xed, 0x0c, 0xd4, 0x06, 0x8e, 0xd9, 0xf2, 0x9c, 0x96, 0x31, 0x47, 0x8d, 0x83, 0xfd, - 0x00, 0xb6, 0xc7, 0x0b, 0xd4, 0x7a, 0xe7, 0x8e, 0x31, 0xb1, 0x8e, 0x3d, 0xc7, 0xb4, 0xa2, 0x45, - 0x98, 0x3a, 0x20, 0x11, 0xbe, 0x5c, 0x85, 0x88, 0x0f, 0x12, 0x5a, 0xf6, 0x21, 0x54, 0xe7, 0xbe, - 0x37, 0xb6, 0xf4, 0xc0, 0x5b, 0xf8, 0x13, 0x6b, 0xc5, 0x5c, 0x4b, 0x78, 0x2b, 0x44, 0x37, 0x24, - 0x32, 0xf5, 0xef, 0x6d, 0x42, 0xb5, 0x6d, 0x99, 0x8b, 0xf9, 0x67, 0x9e, 0xed, 0xb6, 0xc2, 0x33, - 0xf6, 0x01, 0x54, 0x3d, 0x87, 0xfc, 0x90, 0xba, 0x74, 0x1c, 0xbf, 0x2e, 0x1f, 0xf0, 0xa8, 0x05, - 0x74, 0x78, 0xff, 0x0e, 0x5c, 0xe0, 0x86, 0xb9, 0xf0, 0x53, 0x9d, 0x71, 0x66, 0x5c, 0x33, 0x79, - 0x4d, 0xe1, 0x28, 0xbe, 0x41, 0x13, 0xf9, 0xaf, 0xc0, 0x45, 0x89, 0x1c, 0x05, 0x0b, 0xa7, 0xcf, - 0xae, 0xac, 0xb1, 0xed, 0x98, 0x37, 0x0e, 0x14, 0xf8, 0x0c, 0x2e, 0x46, 0x35, 0x9c, 0xf0, 0xde, - 0xe3, 0xcc, 0x39, 0xd9, 0xbc, 0x48, 0xf5, 0xae, 0xa8, 0xf0, 0xb6, 0x27, 0x03, 0x29, 0xaf, 0xf7, - 0xe1, 0x92, 0x89, 0xad, 0xd7, 0x79, 0xe7, 0x9f, 0x58, 0xd6, 0x5c, 0x77, 0x8c, 0x20, 0x14, 0xe7, - 0x8e, 0x8c, 0x90, 0xbb, 0x88, 0xfb, 0xdc, 0xb2, 0xe6, 0x3d, 0x23, 0x08, 0xd5, 0xbf, 0x96, 0x85, - 0x32, 0xf7, 0x2a, 0x60, 0x77, 0xdd, 0x85, 0xa2, 0x37, 0xfe, 0x4a, 0xf7, 0x63, 0x6b, 0x7b, 0xe5, - 0x6c, 0xb1, 0xe0, 0x8d, 0xbf, 0xd2, 0xac, 0x29, 0x7b, 0x2b, 0xda, 0xea, 0xd0, 0x32, 0xdf, 0x94, - 0x7d, 0xe3, 0x91, 0x5a, 0x2f, 0xb6, 0x3e, 0x34, 0x39, 0x1f, 0x42, 0xc5, 0x76, 0x03, 0xcb, 0x0f, - 0xb9, 0x27, 0xa5, 0xf8, 0xfc, 0x41, 0xe0, 0x64, 0xe4, 0x5c, 0x79, 0x08, 0x15, 0xee, 0x59, 0xe1, - 0x4c, 0xa5, 0xe7, 0x33, 0x71, 0x32, 0x62, 0xfa, 0x14, 0xea, 0x89, 0x98, 0x23, 0xbe, 0xf2, 0x73, - 0xf9, 0x6a, 0x31, 0x25, 0xb1, 0x3e, 0x80, 0xcb, 0xc1, 0x89, 0x3d, 0xd7, 0x45, 0x4d, 0x3d, 0x97, - 0x8e, 0x15, 0xf4, 0xf9, 0x89, 0x70, 0xe7, 0x33, 0xc4, 0x76, 0x09, 0x39, 0x70, 0xfb, 0x0b, 0xc7, - 0x39, 0x38, 0x61, 0x6f, 0xc2, 0xb6, 0x20, 0x9f, 0x9f, 0x44, 0x73, 0x85, 0x8c, 0xcd, 0xbc, 0x56, - 0xe7, 0x88, 0x83, 0x13, 0xa1, 0xc9, 0x7d, 0x0c, 0x0d, 0x7e, 0xdc, 0x2d, 0x1a, 0x65, 0x4c, 0xa7, - 0xd6, 0x24, 0xd4, 0x51, 0x75, 0x10, 0xbe, 0xff, 0x4b, 0x84, 0xe7, 0xee, 0xa1, 0x26, 0x61, 0x51, - 0xf2, 0xa9, 0x7f, 0x3f, 0x03, 0x65, 0x5e, 0x2c, 0x8e, 0xd0, 0x6b, 0x90, 0x7d, 0xc1, 0xe8, 0x20, - 0x8e, 0xdd, 0x83, 0x6d, 0xc3, 0x34, 0x45, 0x01, 0x96, 0xc9, 0x8b, 0xe0, 0xe2, 0x60, 0xcb, 0x30, - 0xcd, 0xa6, 0x80, 0x93, 0x58, 0xbd, 0x0b, 0x8a, 0x1d, 0xe8, 0x91, 0x5d, 0x99, 0x1c, 0x6e, 0x97, - 0xb4, 0xba, 0x1d, 0x08, 0xb3, 0x92, 0xbb, 0x8a, 0x53, 0x03, 0x9e, 0x7b, 0xf1, 0x80, 0xab, 0x0c, - 0x40, 0xb3, 0x68, 0xed, 0xb7, 0xc2, 0xb3, 0xcf, 0x72, 0xa5, 0x8c, 0x02, 0xea, 0x3f, 0xad, 0x40, - 0xa5, 0xe9, 0x1a, 0xce, 0xf9, 0x4f, 0x2c, 0x3a, 0x99, 0x27, 0xc7, 0xe1, 0x7c, 0x21, 0xba, 0x80, - 0x1f, 0x5b, 0x95, 0x09, 0x42, 0x35, 0xbb, 0x09, 0x15, 0x6f, 0x11, 0xc6, 0x78, 0x7e, 0x90, 0x05, - 0x1c, 0x44, 0x04, 0x31, 0x7f, 0xec, 0x94, 0x8e, 0xf8, 0x49, 0x2b, 0x4f, 0xf8, 0x63, 0x4d, 0x2d, - 0xe6, 0x27, 0x82, 0x5b, 0x50, 0x0b, 0xed, 0x99, 0x45, 0x67, 0x77, 0x8b, 0x99, 0x65, 0xf2, 0x90, - 0x3e, 0x1e, 0x25, 0xd6, 0x12, 0x30, 0xcc, 0x65, 0x66, 0xcd, 0x3c, 0xff, 0x9c, 0xe7, 0x52, 0xe0, - 0xb9, 0x70, 0x10, 0xe5, 0xf2, 0x36, 0xb0, 0x53, 0xc3, 0x0e, 0xf5, 0x74, 0x56, 0x5c, 0x3b, 0x56, - 0x10, 0x33, 0x92, 0xb3, 0xbb, 0x0c, 0x05, 0xd3, 0x0e, 0x4e, 0xba, 0x03, 0xa1, 0x19, 0x8b, 0x14, - 0xb6, 0x25, 0x98, 0x18, 0xb8, 0x31, 0x87, 0x16, 0xd7, 0xe2, 0xb2, 0x5a, 0x19, 0x21, 0xbb, 0x08, - 0x40, 0xc1, 0xee, 0x5a, 0xe1, 0xa9, 0xe7, 0x23, 0x27, 0x57, 0x7c, 0x13, 0x00, 0x6e, 0x80, 0x48, - 0x8a, 0x05, 0xd1, 0xdc, 0xcb, 0x6a, 0x71, 0x1a, 0x55, 0x4a, 0x3e, 0x0f, 0x09, 0x5b, 0xe5, 0xd5, - 0x4f, 0x20, 0xec, 0x36, 0xd4, 0xa9, 0xfa, 0xa4, 0x18, 0x63, 0x1b, 0xe8, 0xac, 0x29, 0xab, 0x55, - 0x11, 0x4a, 0x76, 0x32, 0x52, 0x7d, 0x0a, 0x57, 0x53, 0xed, 0xd3, 0x0d, 0xdf, 0x37, 0xce, 0xf5, - 0x99, 0xf1, 0x95, 0xe7, 0x93, 0x4f, 0x23, 0xab, 0x5d, 0x96, 0xbb, 0xad, 0x89, 0xe8, 0x7d, 0xc4, - 0x3e, 0x97, 0xd5, 0x76, 0x3d, 0x9f, 0x1c, 0x1e, 0x6b, 0x59, 0x11, 0x4b, 0xd6, 0x39, 0x0d, 0x30, - 0x69, 0xe9, 0x01, 0x8f, 0x2e, 0xd4, 0x2a, 0x04, 0xdb, 0x25, 0x10, 0xea, 0xa9, 0xc1, 0x43, 0x2e, - 0x2f, 0xb7, 0x45, 0xa8, 0xcf, 0x43, 0x92, 0x84, 0x1c, 0x71, 0x6c, 0x19, 0x26, 0x9d, 0x5f, 0x11, - 0x62, 0xcf, 0x32, 0xe8, 0x74, 0x38, 0x78, 0xa8, 0xcf, 0x17, 0x21, 0x0f, 0x0b, 0xd4, 0xf2, 0xc1, - 0xc3, 0x83, 0x45, 0x28, 0xc0, 0x47, 0x56, 0x48, 0xc7, 0x55, 0x04, 0x7e, 0x6c, 0x85, 0xa8, 0x6c, - 0x06, 0x0f, 0x23, 0x07, 0xef, 0x25, 0xd1, 0xb7, 0x0f, 0x85, 0x07, 0x57, 0x85, 0x5a, 0x8c, 0xd4, - 0x67, 0x0b, 0x1e, 0x07, 0x98, 0xd5, 0x2a, 0x11, 0xc1, 0xfe, 0xc2, 0xc1, 0x81, 0x9d, 0x18, 0x93, - 0x63, 0x4b, 0xf7, 0xb1, 0x2a, 0x57, 0xf8, 0xd0, 0x11, 0x44, 0xc3, 0xda, 0xbc, 0x02, 0x3c, 0xa1, - 0x1f, 0xdb, 0x21, 0x39, 0x5e, 0xb2, 0x5a, 0x89, 0x00, 0x7b, 0x76, 0x88, 0xeb, 0x98, 0x23, 0xc5, - 0x0c, 0xa4, 0x2c, 0xae, 0x12, 0xd1, 0x16, 0x21, 0xf6, 0x09, 0x4e, 0x19, 0xdd, 0x05, 0x25, 0x45, - 0x8b, 0xf9, 0x5d, 0x23, 0xd2, 0xba, 0x44, 0x8a, 0xb9, 0xde, 0x01, 0xce, 0xac, 0xe3, 0xd4, 0xe3, - 0x79, 0xbe, 0xc2, 0xad, 0x34, 0x02, 0xb7, 0xed, 0xe0, 0x84, 0x72, 0xbc, 0x0d, 0x75, 0x89, 0x0e, - 0xf3, 0xbb, 0xce, 0x67, 0x46, 0x4c, 0x96, 0xaa, 0xa3, 0x6f, 0xcd, 0xbc, 0x50, 0x34, 0xf3, 0x55, - 0xa9, 0x8e, 0x1a, 0xc1, 0xd3, 0x75, 0x14, 0xb4, 0x98, 0xe7, 0x0d, 0xa9, 0x8e, 0x9c, 0x14, 0x73, - 0x7d, 0x0d, 0xaa, 0xa7, 0xbe, 0x1d, 0x86, 0x96, 0xcb, 0x17, 0xff, 0x4d, 0xde, 0xb1, 0x02, 0x46, - 0xab, 0xff, 0x35, 0xa8, 0xf2, 0x9e, 0x17, 0xf2, 0x6d, 0x87, 0x93, 0x08, 0x58, 0x24, 0x20, 0x44, - 0x6f, 0xcc, 0x6c, 0x97, 0xbc, 0x2b, 0x59, 0xad, 0xcc, 0x21, 0x68, 0xac, 0x4a, 0x68, 0xe3, 0x8c, - 0x7c, 0x2c, 0x09, 0xda, 0x38, 0xa3, 0x25, 0x39, 0xb7, 0x1d, 0x87, 0x2f, 0xfc, 0x5b, 0x62, 0x49, - 0x22, 0x84, 0xd6, 0x7d, 0x8c, 0xa6, 0xd2, 0x6f, 0x4b, 0x68, 0x2a, 0x1b, 0x27, 0x0e, 0xa1, 0xb1, - 0xe8, 0xd7, 0xc5, 0xc4, 0x41, 0x00, 0x96, 0x9c, 0x20, 0x8d, 0xb3, 0xc6, 0x1d, 0x19, 0x69, 0x9c, - 0x09, 0xb9, 0x85, 0xb9, 0x12, 0xef, 0x1b, 0xb1, 0xdc, 0x42, 0x10, 0x72, 0xcb, 0x04, 0xc6, 0x59, - 0xe3, 0x6e, 0x9a, 0xc0, 0x38, 0x23, 0x0b, 0xc9, 0x32, 0x4c, 0x5e, 0xf1, 0x37, 0x79, 0xf6, 0x08, - 0xa0, 0x7a, 0xef, 0x40, 0x35, 0x78, 0xa8, 0x27, 0xf8, 0x7b, 0x9c, 0x3d, 0x78, 0xa8, 0x45, 0x14, - 0xb7, 0xa1, 0x1e, 0x4f, 0x0d, 0x4e, 0xf3, 0x16, 0x1f, 0x78, 0x53, 0x4c, 0x0d, 0x3a, 0xee, 0xfb, - 0x69, 0x06, 0xae, 0x0d, 0xc8, 0x39, 0x44, 0xe2, 0x7f, 0xdf, 0x0a, 0x02, 0xe3, 0xc8, 0x7a, 0xe4, - 0xf9, 0x8f, 0x16, 0x3f, 0xf9, 0xc9, 0x39, 0xbb, 0x0b, 0x5b, 0x07, 0x86, 0x6f, 0xb9, 0x61, 0x7c, - 0x50, 0x25, 0x3c, 0x33, 0xcb, 0x60, 0xf6, 0x09, 0x28, 0x1c, 0xc4, 0x43, 0xa2, 0x5a, 0xd1, 0x39, - 0xcd, 0xb2, 0x5f, 0x79, 0x85, 0x0a, 0x8d, 0xbd, 0x72, 0xdb, 0x0e, 0x42, 0x0d, 0x2d, 0x7d, 0xf6, - 0x29, 0x28, 0x8e, 0x77, 0x8a, 0x16, 0x0b, 0xaa, 0xb1, 0xba, 0xa4, 0x38, 0x8b, 0x5d, 0x32, 0xd1, - 0x96, 0xeb, 0x44, 0x98, 0xa8, 0xbb, 0x9f, 0x82, 0xb2, 0x98, 0xcf, 0xd3, 0xac, 0x9b, 0xcf, 0x61, - 0x25, 0xc2, 0x84, 0xf5, 0x2d, 0xa8, 0x48, 0xa5, 0xae, 0x51, 0xae, 0x21, 0x29, 0x0b, 0x89, 0xa5, - 0x72, 0xd6, 0x84, 0x59, 0x42, 0x92, 0xbb, 0xfa, 0xff, 0x6d, 0x82, 0x42, 0xce, 0x31, 0x8d, 0x0e, - 0xeb, 0xe9, 0xbc, 0x2b, 0x65, 0x96, 0x65, 0x5e, 0x6a, 0x96, 0xed, 0x40, 0xde, 0xb1, 0x67, 0x71, - 0xec, 0x53, 0xea, 0xc0, 0x86, 0x10, 0x38, 0xd6, 0x9e, 0x6f, 0x1f, 0x91, 0x01, 0x29, 0x47, 0xe9, - 0x91, 0xdf, 0x0f, 0xed, 0x31, 0x1a, 0xa2, 0xfb, 0x00, 0xa6, 0x1d, 0x84, 0x3a, 0xb9, 0x54, 0x44, - 0xb5, 0x45, 0xcf, 0xc4, 0xfd, 0xaf, 0x95, 0xcd, 0x78, 0x28, 0xee, 0x82, 0x22, 0x29, 0x61, 0x6e, - 0xec, 0x0d, 0xc9, 0x6b, 0x89, 0x72, 0xd6, 0x72, 0x5b, 0x6e, 0xb8, 0x42, 0x89, 0xea, 0x53, 0x61, - 0x85, 0xb2, 0x6b, 0x9e, 0xa9, 0x7f, 0xf6, 0x1a, 0xe4, 0xfa, 0x9e, 0x69, 0xb1, 0xf7, 0xa0, 0x4c, - 0xe1, 0xac, 0xd2, 0x00, 0x0b, 0x25, 0x19, 0xd1, 0xf4, 0x87, 0x46, 0xaa, 0xe4, 0x8a, 0x5f, 0xcf, - 0x0f, 0x80, 0x7d, 0x8d, 0x8c, 0x3b, 0x3a, 0x92, 0xc5, 0x26, 0x55, 0x84, 0x03, 0x8a, 0xfc, 0x25, - 0x1c, 0x83, 0x7b, 0x2b, 0xb9, 0xef, 0x7d, 0xcb, 0x25, 0x8d, 0x3c, 0xaf, 0xc5, 0x69, 0x32, 0xa9, - 0x7d, 0x0f, 0x55, 0x2f, 0xbe, 0x03, 0xe5, 0xd7, 0x98, 0xd4, 0x1c, 0x4f, 0x5b, 0xd2, 0x7b, 0x50, - 0xfe, 0xca, 0xb3, 0x5d, 0x5e, 0xf1, 0xc2, 0x4a, 0xc5, 0xd1, 0x62, 0xe1, 0x15, 0xff, 0x4a, 0xfc, - 0x62, 0xb7, 0xa0, 0xe8, 0xb9, 0x3c, 0xef, 0xe2, 0x4a, 0xde, 0x05, 0xcf, 0xed, 0xf1, 0xe8, 0xaa, - 0x9a, 0x1d, 0xe8, 0xbe, 0x7d, 0x74, 0x1c, 0xea, 0xc8, 0x29, 0x8e, 0x72, 0x2b, 0x76, 0xa0, 0x21, - 0x0c, 0xb3, 0xc5, 0x89, 0x37, 0xb5, 0x1d, 0xd4, 0xf0, 0x28, 0xb3, 0xf2, 0x4a, 0x66, 0xc0, 0xd1, - 0x94, 0xe1, 0xeb, 0x50, 0x3a, 0xf2, 0x3d, 0x34, 0x22, 0xce, 0x1b, 0xb0, 0x42, 0x59, 0x24, 0xdc, - 0xee, 0x39, 0xaa, 0x4f, 0xf4, 0xd3, 0x76, 0x8f, 0x74, 0xf2, 0x92, 0x54, 0x76, 0xb2, 0x77, 0x4b, - 0x5a, 0x35, 0x02, 0x92, 0xff, 0xe3, 0x75, 0x28, 0x19, 0x47, 0x47, 0xba, 0x08, 0x12, 0x5b, 0xc9, - 0xcb, 0x38, 0x3a, 0xa2, 0x22, 0xef, 0x43, 0xed, 0xd4, 0x76, 0xf5, 0x60, 0x6e, 0x4d, 0x38, 0x6d, - 0x6d, 0xb5, 0x2b, 0x4f, 0x6d, 0x17, 0x67, 0x37, 0xd1, 0xcb, 0xcb, 0xa0, 0xfe, 0xcd, 0x97, 0xc1, - 0xd6, 0xf3, 0x96, 0x81, 0x0a, 0x05, 0xe1, 0xda, 0x57, 0x56, 0x48, 0x04, 0x86, 0xbd, 0x0f, 0x15, - 0xdf, 0x70, 0x4f, 0x74, 0x71, 0x2e, 0xfe, 0xa5, 0x6c, 0xe9, 0x6b, 0x86, 0x7b, 0x22, 0x8e, 0xc5, - 0xc1, 0x8f, 0x7f, 0xa7, 0x55, 0xe6, 0xed, 0x97, 0xd8, 0x48, 0x92, 0xe9, 0xc5, 0x5e, 0x6c, 0x7a, - 0x7d, 0x48, 0x36, 0x8e, 0xe5, 0x86, 0x7a, 0xc4, 0x70, 0x61, 0x3d, 0x43, 0x95, 0x93, 0x0d, 0x38, - 0x1b, 0x36, 0x80, 0x3c, 0x6d, 0x3a, 0xb9, 0xe5, 0x2e, 0xa6, 0x1a, 0x10, 0xbb, 0xe0, 0x34, 0xf0, - 0x13, 0x77, 0x5c, 0x13, 0xb6, 0x92, 0xc8, 0x59, 0x1e, 0x82, 0x7c, 0x49, 0x76, 0xf5, 0xa7, 0x42, - 0x6d, 0x23, 0xab, 0xca, 0x4e, 0xc5, 0xdf, 0xde, 0x82, 0x1a, 0x0f, 0x44, 0xe1, 0xfd, 0x16, 0x90, - 0x92, 0x54, 0xd6, 0xaa, 0x04, 0xe4, 0xfd, 0x14, 0x90, 0x80, 0x11, 0xa6, 0x5e, 0x78, 0x46, 0x5a, - 0x52, 0x22, 0x60, 0xb8, 0x6d, 0x17, 0x9e, 0x69, 0x65, 0x33, 0xfa, 0x89, 0x9b, 0xff, 0xd8, 0x76, - 0x4d, 0x9c, 0x7a, 0xa1, 0x71, 0x14, 0x34, 0x1a, 0xb4, 0x32, 0x2b, 0x02, 0x36, 0x32, 0x8e, 0x02, - 0x34, 0xfc, 0x0d, 0x6e, 0x6c, 0xf0, 0x7a, 0x5f, 0x95, 0x3d, 0x53, 0x92, 0x19, 0xa2, 0x55, 0x0c, - 0xc9, 0x26, 0xf9, 0x18, 0x58, 0x74, 0xf2, 0x28, 0xd9, 0xf1, 0xd7, 0x56, 0x66, 0xe3, 0x96, 0x38, - 0x7a, 0x8c, 0xad, 0xf8, 0x9b, 0x50, 0xe1, 0x9e, 0x0a, 0x3d, 0x08, 0xad, 0x79, 0xe3, 0x15, 0xaa, - 0x10, 0x70, 0xd0, 0x30, 0xb4, 0xe6, 0xec, 0x63, 0xa8, 0xa5, 0xad, 0xac, 0xeb, 0x6b, 0x0e, 0xf0, - 0x68, 0x5a, 0x68, 0xd5, 0x89, 0x6c, 0x77, 0xdd, 0xe2, 0x51, 0xdd, 0xa4, 0x21, 0x11, 0x23, 0x3f, - 0xa4, 0xaa, 0xba, 0x5e, 0xd8, 0x8a, 0x60, 0xd8, 0x81, 0x91, 0x81, 0x1d, 0x9e, 0x91, 0x52, 0x15, - 0x77, 0x60, 0x6c, 0x3a, 0xa2, 0x71, 0x14, 0x59, 0x91, 0x6d, 0xe0, 0x81, 0x17, 0xb4, 0xc9, 0x5b, - 0x3e, 0x0f, 0xb2, 0x20, 0x1d, 0x2a, 0x3e, 0xd3, 0x5b, 0xde, 0x7b, 0x34, 0x1e, 0x90, 0x22, 0xef, - 0x46, 0x9f, 0x40, 0x7d, 0xee, 0x5b, 0xba, 0x54, 0xb2, 0x2a, 0x37, 0xea, 0xc0, 0xb7, 0x92, 0xc2, - 0xab, 0x73, 0x29, 0xc5, 0x7e, 0x00, 0xdb, 0x12, 0xe7, 0xe2, 0x84, 0x98, 0x6f, 0x11, 0xf3, 0xc5, - 0x25, 0xe6, 0xc3, 0x13, 0x64, 0xaf, 0xcf, 0x53, 0x69, 0x76, 0x11, 0xf2, 0xdd, 0xa0, 0xe3, 0x9a, - 0xa4, 0x5b, 0x95, 0x34, 0x9e, 0x60, 0x0f, 0xa1, 0xca, 0x0d, 0x19, 0x8a, 0x53, 0x0d, 0x1a, 0x77, - 0x64, 0xd7, 0x33, 0x59, 0x33, 0x84, 0xd0, 0x2a, 0x4e, 0xfc, 0x3b, 0x60, 0x1f, 0xc1, 0x36, 0x3f, - 0x17, 0x90, 0x45, 0xe4, 0x1b, 0xab, 0x43, 0x4e, 0x44, 0x8f, 0x12, 0x39, 0xa9, 0xc1, 0x55, 0x7f, - 0xe1, 0x92, 0x71, 0x23, 0x38, 0xb9, 0xc7, 0x8a, 0xf8, 0xef, 0x12, 0xff, 0x15, 0xb1, 0xba, 0x38, - 0x19, 0xe7, 0x25, 0xd9, 0x74, 0xd9, 0x97, 0x41, 0x07, 0xc8, 0xf7, 0x9c, 0x3c, 0xb9, 0x27, 0x87, - 0xf2, 0x7c, 0xf3, 0xdb, 0xe4, 0x49, 0x5e, 0x1e, 0xca, 0x93, 0x41, 0x6e, 0xb1, 0xb0, 0x4d, 0xd2, - 0xf4, 0xaa, 0x1a, 0xfd, 0x66, 0xaf, 0x43, 0xdd, 0xb7, 0x26, 0x0b, 0x3f, 0xb0, 0x9f, 0x59, 0x7a, - 0x60, 0xbb, 0x27, 0xa4, 0xe3, 0x95, 0xb4, 0x5a, 0x0c, 0x1d, 0xda, 0xee, 0x09, 0x8a, 0x0c, 0xeb, - 0x2c, 0xb4, 0x7c, 0x97, 0x87, 0xce, 0xbf, 0x2d, 0x8b, 0x8c, 0x0e, 0x21, 0x70, 0x9d, 0x6b, 0x60, - 0xc5, 0xbf, 0x97, 0x46, 0x36, 0xe0, 0x23, 0x7b, 0xff, 0x1b, 0x8d, 0xec, 0x90, 0x46, 0xf6, 0x0e, - 0x94, 0x6c, 0x37, 0xb4, 0xfc, 0x67, 0x86, 0xd3, 0x78, 0x77, 0x45, 0x1a, 0xc7, 0x38, 0x76, 0x1b, - 0x8a, 0x81, 0x63, 0xe3, 0x7a, 0x6f, 0xbc, 0xb7, 0x42, 0x16, 0xa1, 0xd8, 0x5d, 0x28, 0xc7, 0xb7, - 0xbe, 0x1a, 0xef, 0xaf, 0xd0, 0x25, 0x48, 0x76, 0x03, 0x72, 0xa7, 0x38, 0xa1, 0x1e, 0xac, 0x1e, - 0x15, 0x20, 0x1c, 0xb7, 0xef, 0x29, 0xea, 0xec, 0xb4, 0x7d, 0x3f, 0x5c, 0xd9, 0xbe, 0x1f, 0xd9, - 0x8e, 0xc3, 0xb7, 0xef, 0xa9, 0xf8, 0x85, 0x9b, 0x1f, 0x71, 0x60, 0x4b, 0x3e, 0x58, 0xdd, 0xfc, - 0x10, 0xf7, 0x84, 0xee, 0xc7, 0x55, 0x02, 0xf2, 0x7f, 0x73, 0x37, 0xfe, 0x87, 0x72, 0x5f, 0xa5, - 0x1d, 0xe3, 0x1a, 0x04, 0x71, 0x1a, 0x0d, 0x10, 0xe1, 0xfd, 0x47, 0xa5, 0xe9, 0x23, 0x7e, 0xf1, - 0x82, 0x43, 0xba, 0xe6, 0x19, 0x7b, 0x0f, 0x6a, 0x51, 0xb8, 0x10, 0x16, 0x17, 0x34, 0x3e, 0x5e, - 0xa9, 0x41, 0x9a, 0x80, 0xb5, 0xa1, 0x3a, 0x45, 0xdd, 0x7d, 0xc6, 0x55, 0xf9, 0xc6, 0x27, 0x54, - 0x91, 0x9d, 0x68, 0x63, 0x7d, 0x9e, 0xaa, 0xaf, 0xa5, 0xb8, 0xd8, 0x7d, 0x60, 0xf6, 0x94, 0x8f, - 0xe7, 0x23, 0xdf, 0x9b, 0x71, 0x75, 0xbd, 0xf1, 0x29, 0xf7, 0xa0, 0xad, 0x62, 0xe8, 0x30, 0xd0, - 0x72, 0x4d, 0x7d, 0x16, 0x08, 0x35, 0xe1, 0x7b, 0x54, 0x4f, 0x21, 0xbc, 0xe2, 0xdb, 0xa1, 0x91, - 0xb3, 0x17, 0x69, 0xf7, 0x03, 0xae, 0x35, 0x7c, 0x0a, 0x38, 0x5d, 0x9f, 0x25, 0xac, 0xbf, 0xf2, - 0x42, 0x56, 0xa4, 0x8d, 0x58, 0x3f, 0x81, 0x3a, 0x77, 0x94, 0x92, 0x46, 0x86, 0x53, 0xf4, 0xfb, - 0xb2, 0xe4, 0x92, 0x5d, 0xc8, 0x5a, 0xd5, 0x94, 0x1d, 0xca, 0x1f, 0xc3, 0x56, 0xe4, 0xeb, 0x0d, - 0x85, 0x5b, 0xf8, 0x57, 0xe5, 0x62, 0x63, 0x5f, 0xaa, 0x56, 0x5b, 0x44, 0x3f, 0xa9, 0xc8, 0x87, - 0x50, 0xa3, 0x5d, 0x34, 0x70, 0x8d, 0x79, 0x70, 0xec, 0x85, 0x8d, 0x5f, 0x93, 0x15, 0x82, 0xa1, - 0x80, 0x6a, 0x55, 0x24, 0x8a, 0x52, 0x28, 0xfc, 0x93, 0x75, 0x3a, 0x09, 0xad, 0xc6, 0x0f, 0xb8, - 0xf0, 0x8f, 0x81, 0xad, 0xd0, 0x62, 0x0f, 0x01, 0x8c, 0xf9, 0xdc, 0x39, 0xe7, 0x53, 0xf3, 0x87, - 0x34, 0x35, 0x2f, 0x4a, 0x53, 0xb3, 0x89, 0x48, 0x9a, 0x9b, 0x65, 0x23, 0xfa, 0xc9, 0x1e, 0x40, - 0x75, 0xee, 0x05, 0xa1, 0x6e, 0xce, 0x1c, 0x6a, 0x7f, 0x53, 0x5e, 0xdb, 0x07, 0x5e, 0x10, 0xb6, - 0x67, 0x0e, 0xb6, 0x02, 0xe6, 0xf1, 0x6f, 0xd6, 0x83, 0x0b, 0x9e, 0xab, 0x9b, 0x8b, 0xb9, 0x63, - 0x4f, 0xb0, 0x07, 0x0c, 0x3a, 0x7a, 0x6f, 0xec, 0x52, 0x89, 0xd7, 0xa5, 0x12, 0x07, 0x6e, 0x3b, - 0x22, 0x12, 0xb1, 0x6b, 0xdb, 0xde, 0x32, 0x88, 0xec, 0x4c, 0x1a, 0x83, 0x38, 0x80, 0xb3, 0xc5, - 0x55, 0x03, 0x82, 0x46, 0x11, 0x9c, 0x9f, 0xc0, 0x56, 0x42, 0x85, 0x0d, 0x0c, 0x1a, 0x6d, 0x79, - 0x26, 0x4b, 0x11, 0xe1, 0xb5, 0x88, 0x11, 0x61, 0x01, 0xf5, 0x9d, 0xe7, 0x38, 0x8b, 0xb9, 0x10, - 0xa5, 0x8d, 0x8e, 0xe8, 0x3b, 0x02, 0x72, 0x29, 0x29, 0x99, 0xe2, 0xd6, 0xac, 0xf1, 0x48, 0x36, - 0xc5, 0xad, 0x19, 0xaa, 0x19, 0x22, 0x3a, 0xf7, 0x99, 0x6d, 0x9d, 0x06, 0x8d, 0xc7, 0x14, 0xb9, - 0x29, 0xe2, 0x9f, 0x9f, 0x20, 0x08, 0xf7, 0x7d, 0xd3, 0xf6, 0xd1, 0x04, 0xa0, 0xa0, 0xab, 0x3d, - 0x1e, 0x40, 0xcb, 0x41, 0x48, 0xa1, 0xfe, 0x2c, 0x0f, 0xa5, 0xc8, 0x26, 0x61, 0x15, 0x28, 0x1e, - 0xf6, 0x3f, 0xef, 0x0f, 0x9e, 0xf6, 0xf9, 0xed, 0xb8, 0xe6, 0x70, 0xd8, 0xd1, 0x46, 0x8a, 0xc9, - 0xea, 0x00, 0x74, 0xff, 0x45, 0x1f, 0xb6, 0x9a, 0x7d, 0x7e, 0x5b, 0x8e, 0x6e, 0xdd, 0xf0, 0xf4, - 0x26, 0xdb, 0x86, 0xda, 0xa3, 0xc3, 0x3e, 0x05, 0xea, 0x71, 0x50, 0x16, 0x41, 0x9d, 0x2f, 0xf8, - 0xd1, 0x22, 0x07, 0xe5, 0x10, 0xb4, 0xdf, 0x1c, 0x75, 0xb4, 0x6e, 0x04, 0xca, 0x53, 0xcc, 0xdf, - 0xe0, 0x50, 0x6b, 0x89, 0x9c, 0x0a, 0xec, 0x12, 0x6c, 0xc7, 0x6c, 0x51, 0x96, 0x4a, 0x11, 0x6b, - 0x76, 0xa0, 0x0d, 0x3e, 0xeb, 0xb4, 0x46, 0x0a, 0xd0, 0x39, 0xe5, 0xe3, 0xc7, 0x4a, 0x85, 0x55, - 0xa1, 0xd4, 0xee, 0x0e, 0x47, 0xdd, 0x7e, 0x6b, 0xa4, 0x54, 0xb1, 0xc2, 0x8f, 0xba, 0xbd, 0x51, - 0x47, 0x53, 0x6a, 0xac, 0x04, 0xb9, 0xcf, 0x06, 0xdd, 0xbe, 0x52, 0xa7, 0x7b, 0x40, 0xcd, 0xfd, - 0x83, 0x5e, 0x47, 0xd9, 0x42, 0xe8, 0x70, 0xa0, 0x8d, 0x14, 0x05, 0xa1, 0x4f, 0xbb, 0xfd, 0xf6, - 0xe0, 0xa9, 0xb2, 0xcd, 0xca, 0x90, 0x3f, 0xec, 0x63, 0x31, 0x8c, 0xd5, 0xa0, 0x4c, 0x3f, 0xf5, - 0x66, 0xaf, 0xa7, 0x5c, 0x90, 0x0e, 0x37, 0x2f, 0x22, 0x8a, 0x8e, 0x4a, 0x87, 0x58, 0x87, 0x4b, - 0xd8, 0x96, 0x38, 0x49, 0xd4, 0x97, 0x31, 0x9f, 0xfd, 0x6e, 0xff, 0x70, 0xa8, 0x5c, 0x41, 0x62, - 0xfa, 0x49, 0x98, 0x06, 0xe6, 0xd3, 0xed, 0x53, 0x57, 0xde, 0xc0, 0xdf, 0xed, 0x4e, 0xaf, 0x33, - 0xea, 0x28, 0x37, 0xb1, 0x55, 0xbd, 0x41, 0xeb, 0x73, 0x7d, 0x70, 0xa0, 0xbc, 0x86, 0x7d, 0x7a, - 0xa0, 0x75, 0x74, 0x41, 0x78, 0x8b, 0x29, 0x50, 0x7d, 0x74, 0xf8, 0xe3, 0x1f, 0x7f, 0xa9, 0x8b, - 0x46, 0xbd, 0x8e, 0x65, 0x26, 0x14, 0xfa, 0xe1, 0xe7, 0xca, 0x9d, 0x25, 0xd0, 0xf0, 0x73, 0xe5, - 0x0d, 0xec, 0x94, 0xa8, 0x97, 0x95, 0xbb, 0x48, 0xa0, 0x75, 0x5a, 0x87, 0xda, 0xb0, 0xfb, 0xa4, - 0xa3, 0xb7, 0x46, 0x1d, 0xe5, 0x4d, 0xea, 0x85, 0x6e, 0xff, 0x73, 0xe5, 0x1e, 0x56, 0x13, 0x7f, - 0xf1, 0xbe, 0x7f, 0x8b, 0x31, 0xa8, 0x27, 0xb4, 0x04, 0x7b, 0x1b, 0x49, 0x76, 0xb5, 0x41, 0xb3, - 0xdd, 0x6a, 0x0e, 0x47, 0xca, 0x3b, 0xd8, 0xc6, 0xe1, 0x41, 0xaf, 0x3b, 0x52, 0xee, 0x63, 0x43, - 0x1e, 0x37, 0x47, 0x7b, 0x1d, 0x4d, 0x79, 0x17, 0x87, 0x71, 0xd4, 0xdd, 0xef, 0xe8, 0xa2, 0x4f, - 0x1f, 0x60, 0x19, 0x8f, 0xba, 0xbd, 0x9e, 0xf2, 0x90, 0x0e, 0xe7, 0x9a, 0xda, 0xa8, 0x4b, 0x03, - 0xf9, 0x01, 0x66, 0xd0, 0x3c, 0x38, 0xe8, 0x7d, 0xa9, 0x7c, 0x88, 0x0d, 0xdc, 0x3f, 0xec, 0x8d, - 0xba, 0xfa, 0xe1, 0x41, 0xbb, 0x39, 0xea, 0x28, 0x1f, 0xd1, 0x28, 0x0f, 0x86, 0xa3, 0xf6, 0x7e, - 0x4f, 0xf9, 0x98, 0xf2, 0xa4, 0x39, 0xd6, 0xea, 0x0d, 0xfa, 0x1d, 0xe5, 0x13, 0x35, 0x57, 0xda, - 0x51, 0x76, 0xd4, 0x5c, 0x49, 0x55, 0x54, 0xf5, 0x37, 0xa1, 0x14, 0x19, 0xa4, 0x98, 0x65, 0xb7, - 0xdf, 0xef, 0x68, 0xca, 0x06, 0x16, 0xdb, 0xeb, 0x3c, 0x1a, 0x29, 0x19, 0x3a, 0xb5, 0xec, 0x3e, - 0xde, 0x1b, 0x29, 0x9b, 0xf8, 0x73, 0x70, 0x88, 0x3d, 0x98, 0xa5, 0xa6, 0x77, 0xf6, 0xbb, 0x4a, - 0x0e, 0x7f, 0x35, 0xfb, 0xa3, 0xae, 0x92, 0xa7, 0x09, 0xd2, 0xed, 0x3f, 0xee, 0x75, 0x94, 0x02, - 0x42, 0xf7, 0x9b, 0xda, 0xe7, 0x4a, 0x91, 0x67, 0xda, 0xee, 0x7c, 0xa1, 0x94, 0x58, 0x01, 0x36, - 0x7b, 0x0f, 0x94, 0x32, 0x82, 0xda, 0x9d, 0xf6, 0xe1, 0x81, 0x02, 0xea, 0x5d, 0x28, 0x36, 0x8f, - 0x8e, 0xf6, 0xd1, 0xde, 0xc7, 0x96, 0x1e, 0xf6, 0x7a, 0x7c, 0xc1, 0xec, 0x0e, 0x46, 0xa3, 0xc1, - 0xbe, 0x92, 0xc1, 0x29, 0x3a, 0x1a, 0x1c, 0x28, 0x9b, 0x6a, 0x17, 0x4a, 0xd1, 0xd6, 0x2b, 0x5d, - 0x62, 0x2b, 0x41, 0xee, 0x40, 0xeb, 0x3c, 0xe1, 0x47, 0xed, 0xfd, 0xce, 0x17, 0x58, 0x4d, 0xfc, - 0x85, 0x19, 0x65, 0xb1, 0x20, 0x7e, 0xdb, 0x8c, 0x6e, 0xb1, 0xf5, 0xba, 0xfd, 0x4e, 0x53, 0x53, - 0xf2, 0xea, 0x87, 0xb0, 0xbd, 0x22, 0xb8, 0xa8, 0xf8, 0x66, 0x57, 0x14, 0xdf, 0x7d, 0xdc, 0x1f, - 0x68, 0x1d, 0x7e, 0x2d, 0x4e, 0x74, 0xea, 0xa6, 0xfa, 0x16, 0x94, 0x63, 0x09, 0x8b, 0x93, 0xac, - 0xa5, 0x0d, 0x86, 0x43, 0x3e, 0x06, 0x1b, 0x98, 0xa6, 0xbe, 0xe1, 0xe9, 0xcc, 0x67, 0xb9, 0xd2, - 0x4d, 0x65, 0xe7, 0xb3, 0x5c, 0xe9, 0xb6, 0xf2, 0xba, 0x3a, 0x84, 0xed, 0x48, 0xd0, 0x53, 0x48, - 0x3e, 0x59, 0x20, 0x17, 0x21, 0xdf, 0xb3, 0x9e, 0x59, 0x4e, 0x14, 0x5b, 0x4e, 0x09, 0x84, 0x0e, - 0xc6, 0x5f, 0x75, 0xe3, 0x5b, 0xcc, 0x94, 0x40, 0xcd, 0xae, 0x2f, 0x5d, 0xa4, 0xa6, 0x7b, 0x82, - 0x7f, 0x25, 0x03, 0xa5, 0x78, 0xfb, 0xb8, 0x0d, 0x9b, 0xa3, 0xa1, 0x38, 0x2b, 0xba, 0x78, 0x3f, - 0x79, 0x37, 0x62, 0x14, 0xfd, 0xd2, 0x36, 0x47, 0x43, 0xf6, 0x36, 0x14, 0xf8, 0xbd, 0x4f, 0xe1, - 0x27, 0xba, 0x98, 0xde, 0x92, 0x46, 0x84, 0xd3, 0x04, 0x0d, 0xfb, 0x10, 0xca, 0x71, 0x6d, 0x85, - 0xe3, 0xe4, 0x4a, 0x9a, 0x21, 0x46, 0x6b, 0x09, 0xa5, 0xda, 0x83, 0x7a, 0x3a, 0x43, 0x76, 0x03, - 0x80, 0x67, 0x29, 0x79, 0x07, 0x25, 0x08, 0xbb, 0x06, 0xd1, 0x75, 0xd4, 0x36, 0x55, 0xac, 0x16, - 0x5f, 0x4f, 0x6d, 0xab, 0xff, 0x32, 0x0b, 0x90, 0x28, 0xa0, 0xd8, 0x11, 0xb1, 0x3b, 0x28, 0x2f, - 0x0e, 0xc3, 0x5f, 0x81, 0xb2, 0xe3, 0x19, 0xa6, 0xfc, 0x6c, 0x44, 0x09, 0x01, 0x34, 0x4c, 0xf2, - 0xd5, 0xac, 0x32, 0x8f, 0x44, 0x61, 0x97, 0xa1, 0x30, 0xf5, 0xfc, 0x99, 0x11, 0x8a, 0x8b, 0x04, - 0x22, 0x85, 0xfb, 0x88, 0x7d, 0xe4, 0x7a, 0xbe, 0x85, 0x6a, 0xb8, 0x4b, 0x77, 0x09, 0x70, 0x0c, - 0xaa, 0x02, 0xd8, 0x43, 0x18, 0xee, 0x03, 0x96, 0x3b, 0x71, 0xbc, 0xc0, 0x32, 0xf5, 0x31, 0x0f, - 0xee, 0xa9, 0x6a, 0x10, 0x81, 0x76, 0xcf, 0x79, 0x6b, 0xfd, 0x99, 0xed, 0x1a, 0xa1, 0x38, 0x1f, - 0xa2, 0xd6, 0x46, 0x10, 0xac, 0xee, 0x57, 0x81, 0x27, 0xbc, 0x43, 0xfc, 0x1e, 0x52, 0x09, 0x01, - 0x54, 0xdd, 0x57, 0x01, 0xac, 0x60, 0x62, 0xcc, 0x79, 0xe6, 0x65, 0xca, 0xbc, 0x2c, 0x20, 0xbb, - 0xe7, 0xac, 0x07, 0xf5, 0xd1, 0x18, 0xf7, 0x3d, 0x0f, 0xad, 0xf6, 0x96, 0xe7, 0x08, 0xbf, 0xcd, - 0xed, 0x65, 0x4d, 0xfd, 0x7e, 0x9a, 0x8c, 0x87, 0x5a, 0x2e, 0xf1, 0xa2, 0xe5, 0x6c, 0x4f, 0xac, - 0xb1, 0xe5, 0x1f, 0x71, 0xad, 0xbf, 0x92, 0xba, 0x01, 0xc0, 0x31, 0xa4, 0xf6, 0x57, 0xec, 0x24, - 0x71, 0xad, 0x09, 0x17, 0xd6, 0x64, 0xfe, 0xad, 0x62, 0xfa, 0xfe, 0xd9, 0x26, 0x54, 0xa4, 0xfc, - 0xc9, 0x41, 0x6f, 0xcc, 0xc9, 0xc1, 0x14, 0x07, 0x2b, 0x97, 0x05, 0x84, 0xdf, 0xb7, 0x98, 0x18, - 0xa1, 0xe1, 0x78, 0x47, 0xd2, 0x4d, 0x12, 0x01, 0xe9, 0x9a, 0x74, 0x66, 0x66, 0xcc, 0xac, 0x60, - 0x6e, 0x4c, 0xa2, 0x15, 0x92, 0x00, 0x92, 0xf7, 0x4a, 0x72, 0xf2, 0x7b, 0x25, 0x0a, 0x3f, 0x5c, - 0xe5, 0xd1, 0x29, 0x74, 0x96, 0x8a, 0x76, 0xbd, 0x98, 0xb6, 0x58, 0x8a, 0x38, 0xff, 0x8b, 0x40, - 0x5d, 0x93, 0xdd, 0x81, 0xe4, 0x3d, 0x16, 0xdd, 0x08, 0x74, 0x6f, 0x1a, 0x85, 0xc6, 0xc5, 0xe0, - 0x66, 0x30, 0x98, 0xc6, 0x4e, 0xf9, 0x99, 0x67, 0xc6, 0xe3, 0x8b, 0x00, 0x92, 0x71, 0xf7, 0xe1, - 0x82, 0xf0, 0x14, 0x5a, 0xa6, 0x3e, 0xb5, 0x2d, 0xc7, 0xd4, 0x6d, 0x93, 0x1f, 0x5d, 0xe7, 0xb5, - 0xed, 0x18, 0xf5, 0x08, 0x31, 0x5d, 0x93, 0x54, 0x1b, 0x61, 0x1e, 0x9a, 0xf6, 0x91, 0x15, 0x84, - 0x22, 0x90, 0xab, 0xca, 0x81, 0x6d, 0x82, 0xa9, 0x4e, 0xb4, 0x44, 0x9a, 0x61, 0x48, 0x77, 0xbd, - 0x62, 0x3d, 0x2b, 0x13, 0x5d, 0x03, 0xe1, 0x2a, 0xd6, 0x2b, 0x14, 0x04, 0x25, 0x22, 0x74, 0xc5, - 0x4a, 0x89, 0x23, 0x6f, 0xef, 0xc0, 0x16, 0x22, 0x45, 0xa5, 0x88, 0x84, 0xdf, 0xff, 0xa9, 0x4d, - 0x3c, 0x87, 0x57, 0x08, 0x81, 0xea, 0x5f, 0xcd, 0x03, 0x24, 0x16, 0x36, 0x5d, 0x2d, 0x23, 0xd7, - 0x57, 0x3c, 0x72, 0x45, 0x4a, 0x77, 0x4d, 0xf6, 0x00, 0x2e, 0x8b, 0x8b, 0x6c, 0x71, 0x74, 0x85, - 0xed, 0xea, 0x63, 0x23, 0x8a, 0xe6, 0x62, 0x02, 0xcb, 0xcf, 0xcd, 0xbb, 0xee, 0xae, 0x81, 0xfa, - 0xfa, 0x96, 0xcc, 0x13, 0x9e, 0xcf, 0xd3, 0xae, 0x76, 0x59, 0x0b, 0x4c, 0xd8, 0x47, 0xe7, 0x73, - 0xf6, 0x1e, 0x5c, 0xf2, 0xad, 0xa9, 0x6f, 0x05, 0xc7, 0x7a, 0x18, 0xc8, 0x85, 0xf1, 0x70, 0xcb, - 0x6d, 0x81, 0x1c, 0x05, 0x71, 0x59, 0xef, 0xc1, 0x25, 0xd1, 0xb9, 0x4b, 0xd5, 0xe3, 0x2e, 0xec, - 0x6d, 0x8e, 0x94, 0x6b, 0x47, 0xb1, 0xb5, 0xe4, 0x76, 0x88, 0x5e, 0xc0, 0x29, 0x69, 0x65, 0xee, - 0x62, 0x10, 0xf7, 0xc2, 0xc9, 0x77, 0x40, 0x0b, 0xb7, 0xa4, 0xf1, 0x04, 0x53, 0x21, 0x87, 0x63, - 0x4f, 0x43, 0x57, 0x7f, 0x50, 0xbf, 0x4f, 0x2f, 0xfc, 0xd0, 0x3d, 0x7d, 0xcf, 0xb4, 0x34, 0xc2, - 0xb1, 0x77, 0x70, 0x5e, 0x24, 0xcd, 0x8e, 0x1e, 0xa9, 0xe0, 0x01, 0x06, 0x4a, 0xd2, 0x50, 0x8d, - 0x3f, 0x57, 0xf1, 0x16, 0x30, 0xa9, 0xe6, 0x11, 0x75, 0x95, 0xa8, 0xb7, 0xe2, 0x6a, 0x0b, 0xe2, - 0x37, 0x80, 0xaa, 0xc8, 0xcf, 0xaf, 0x6a, 0xab, 0x86, 0x36, 0x22, 0xe9, 0x28, 0xeb, 0x3d, 0xb8, - 0x94, 0xb4, 0x4e, 0x37, 0x42, 0x3d, 0x3c, 0xb6, 0x74, 0xcb, 0x35, 0xe9, 0xf6, 0x61, 0x49, 0xdb, - 0x8e, 0x1b, 0xda, 0x0c, 0x47, 0xc7, 0x16, 0x9a, 0xca, 0x92, 0x2b, 0x73, 0xeb, 0xc5, 0xae, 0xcc, - 0x8f, 0xa0, 0x91, 0x0a, 0xd7, 0x90, 0xbb, 0x9b, 0xdf, 0xde, 0xbd, 0x28, 0x07, 0x69, 0xc4, 0x3d, - 0x7e, 0x0f, 0xb6, 0x8f, 0x8d, 0x40, 0x4f, 0xf1, 0x92, 0x87, 0xb5, 0xa4, 0x6d, 0x1d, 0x1b, 0xc1, - 0x81, 0xc4, 0xa3, 0xfe, 0x7e, 0x06, 0xea, 0x69, 0x9f, 0x03, 0xbf, 0x12, 0xe5, 0x2c, 0x66, 0x2e, - 0x8f, 0x34, 0xcc, 0x6b, 0x51, 0x12, 0xd7, 0x02, 0x8f, 0xe4, 0x58, 0xcc, 0xdc, 0x68, 0x2d, 0xcc, - 0x4f, 0x5a, 0x94, 0x66, 0x6f, 0x42, 0x71, 0x7e, 0xc2, 0x25, 0xf4, 0xf3, 0x66, 0x5f, 0x61, 0xce, - 0x23, 0xcb, 0xdf, 0x84, 0xe2, 0x42, 0x90, 0xe6, 0x9e, 0x47, 0xba, 0x20, 0x52, 0xf5, 0x9f, 0x6f, - 0x42, 0x55, 0x76, 0x95, 0x7d, 0x93, 0x10, 0x8f, 0x6f, 0x15, 0x7d, 0xb3, 0x43, 0x41, 0xa2, 0x3a, - 0x85, 0xb1, 0x63, 0x3f, 0xf1, 0xf8, 0x0e, 0x38, 0x36, 0x82, 0xe6, 0x22, 0xf4, 0x50, 0xe4, 0xa3, - 0x28, 0xf5, 0x9c, 0x28, 0xbc, 0x9d, 0xaf, 0x0c, 0x94, 0x09, 0x22, 0xb2, 0xfd, 0x3d, 0x71, 0x7b, - 0x86, 0xee, 0xcb, 0x51, 0x3c, 0x65, 0x7e, 0x65, 0xbe, 0x54, 0xa3, 0xeb, 0x72, 0x14, 0x3f, 0xfa, - 0x00, 0xb6, 0x92, 0xbb, 0x0a, 0x9c, 0xa5, 0xb0, 0xc2, 0x52, 0x8b, 0x2f, 0x2a, 0x88, 0xbb, 0xfc, - 0x35, 0x3b, 0xd0, 0x3d, 0xc7, 0x8c, 0x2e, 0x45, 0x15, 0xa3, 0x83, 0x8c, 0x81, 0x63, 0x8a, 0x4b, - 0x9a, 0x9c, 0xc6, 0xb5, 0x4e, 0x23, 0x9a, 0xf8, 0xb0, 0xa3, 0x6f, 0x9d, 0x8a, 0xcb, 0x51, 0x7f, - 0x9e, 0x81, 0xed, 0x15, 0xef, 0x18, 0x8a, 0xf6, 0xe4, 0x65, 0x29, 0xfc, 0x89, 0xd6, 0xdd, 0xcc, - 0x08, 0x27, 0xc7, 0xfa, 0xdc, 0xb7, 0xa6, 0xf6, 0x59, 0xf4, 0x3c, 0x16, 0xc1, 0x0e, 0x08, 0x84, - 0xd2, 0x9f, 0x1f, 0xd8, 0xf1, 0xf3, 0x03, 0x2e, 0xf8, 0xf8, 0x21, 0x5d, 0x8f, 0x0e, 0x0e, 0xa2, - 0xf8, 0xd2, 0xdc, 0x73, 0xe2, 0x4b, 0xaf, 0x41, 0xd9, 0xf5, 0x28, 0x96, 0x68, 0x7e, 0x22, 0x82, - 0xb0, 0x8a, 0xae, 0x17, 0x0e, 0xdc, 0x83, 0x13, 0xf6, 0x00, 0x2e, 0x2d, 0x02, 0x3a, 0xb0, 0x1f, - 0x5b, 0x7e, 0x70, 0x6c, 0xc7, 0x76, 0x2a, 0x17, 0x20, 0x17, 0x16, 0x81, 0xb5, 0x1f, 0xe3, 0x78, - 0x4b, 0xd4, 0xeb, 0x50, 0xe8, 0xc6, 0x5e, 0xbd, 0x38, 0xa0, 0x2d, 0x2b, 0xde, 0x94, 0xf1, 0xa0, - 0xdc, 0xa2, 0xf7, 0x69, 0xf6, 0x8d, 0x39, 0xbb, 0x07, 0xd9, 0x99, 0x31, 0x17, 0xa7, 0x84, 0x8d, - 0xf8, 0x28, 0x95, 0x63, 0xef, 0xef, 0x1b, 0x73, 0xbe, 0xfb, 0x23, 0xd1, 0xb5, 0x8f, 0xa0, 0x14, - 0x01, 0xbe, 0xd5, 0x8e, 0xfd, 0x6f, 0x36, 0xa1, 0xdc, 0x96, 0xbd, 0xf2, 0x13, 0xc3, 0xd5, 0x43, - 0x7f, 0xe1, 0xa2, 0x02, 0x1d, 0xbd, 0xb4, 0x31, 0x31, 0xdc, 0x91, 0x00, 0x45, 0x53, 0x7b, 0xf3, - 0x05, 0x53, 0xfb, 0x3a, 0x80, 0x4f, 0x4e, 0x2d, 0xf2, 0x6b, 0x65, 0xe3, 0x00, 0xdf, 0xae, 0xd9, - 0x35, 0xcf, 0xd6, 0xc7, 0x36, 0xe5, 0xbe, 0x79, 0x6c, 0x53, 0x7e, 0x6d, 0x6c, 0xd3, 0x9d, 0x64, - 0x7b, 0xc1, 0x29, 0x8e, 0x05, 0x97, 0xf9, 0x26, 0x37, 0x8f, 0xef, 0x0a, 0x61, 0xe9, 0xdf, 0x83, - 0x7a, 0xd4, 0x3a, 0x91, 0x1f, 0xa4, 0xae, 0x27, 0x09, 0x1c, 0x77, 0xe3, 0xd7, 0x42, 0x39, 0x99, - 0x5e, 0xb2, 0x95, 0x97, 0xc4, 0x4f, 0xfd, 0xf5, 0x0c, 0x30, 0xe1, 0x84, 0x79, 0xb4, 0x70, 0x9c, - 0x91, 0x75, 0x46, 0x92, 0xe1, 0x1e, 0x6c, 0x8b, 0x53, 0x06, 0xe9, 0x5a, 0xa8, 0x38, 0x57, 0xe7, - 0x88, 0xe4, 0x5c, 0x7d, 0xdd, 0x0d, 0xd2, 0xcd, 0xb5, 0x37, 0x48, 0xd7, 0xdf, 0x4c, 0xbd, 0x09, - 0x15, 0xf9, 0xfe, 0x25, 0xd7, 0x93, 0xc0, 0x48, 0xae, 0x5e, 0xfe, 0xf9, 0x26, 0x40, 0xe2, 0x28, - 0xfa, 0x65, 0x07, 0xa6, 0xad, 0x19, 0x92, 0xec, 0xba, 0x21, 0xb9, 0x0b, 0x8a, 0x4c, 0x27, 0x5d, - 0x04, 0xae, 0x27, 0x84, 0x91, 0x9a, 0x63, 0x07, 0xf2, 0x65, 0x4d, 0xba, 0xf7, 0x21, 0x62, 0x79, - 0x38, 0x92, 0x7b, 0xad, 0xc5, 0x02, 0x2c, 0xd9, 0x01, 0x97, 0xc9, 0xec, 0x53, 0xb8, 0x1a, 0x73, - 0xea, 0xa7, 0x76, 0x78, 0xec, 0x2d, 0x42, 0xb1, 0x58, 0x03, 0x21, 0xa5, 0x2e, 0x47, 0x39, 0x3d, - 0xe5, 0x68, 0xbe, 0x5e, 0x03, 0xb4, 0x96, 0xa6, 0x0b, 0xc7, 0xd1, 0x43, 0xeb, 0x2c, 0x14, 0x8f, - 0x77, 0x34, 0x52, 0x3e, 0x36, 0x69, 0x78, 0xb5, 0xd2, 0x54, 0x24, 0xd4, 0xff, 0x99, 0x85, 0xfc, - 0x8f, 0x16, 0x96, 0x7f, 0xce, 0x3e, 0x82, 0x72, 0x10, 0xce, 0x42, 0xf9, 0xb8, 0xfb, 0x2a, 0xcf, - 0x80, 0xf0, 0x74, 0x5a, 0x6d, 0xcd, 0x2c, 0x37, 0xe4, 0xce, 0x67, 0xa4, 0xa5, 0x0d, 0xe8, 0x22, - 0xe4, 0x83, 0xd0, 0x9a, 0x07, 0x22, 0x68, 0x95, 0x27, 0xd8, 0x0e, 0xe4, 0x5d, 0xcf, 0xb4, 0x82, - 0x74, 0x68, 0x6a, 0x1f, 0x35, 0x0e, 0x8e, 0x60, 0x2a, 0x14, 0xe2, 0x11, 0x5f, 0x39, 0x72, 0xe6, - 0x18, 0xba, 0xf0, 0x62, 0x19, 0xa6, 0xed, 0x1e, 0x45, 0x17, 0xab, 0xe3, 0x34, 0x6e, 0xad, 0x64, - 0x65, 0x19, 0x47, 0xd1, 0x83, 0x0c, 0x22, 0xc9, 0x76, 0xa0, 0x82, 0x3f, 0x9f, 0xfa, 0x76, 0x68, - 0x0d, 0x1f, 0x46, 0xd2, 0x5d, 0x02, 0xa1, 0x8d, 0x64, 0x5a, 0xa1, 0x35, 0x09, 0x87, 0x5f, 0x8b, - 0x80, 0xcf, 0xb2, 0x26, 0x41, 0xd8, 0xf7, 0x80, 0x8d, 0x8d, 0xc9, 0xc9, 0x91, 0x4f, 0x61, 0x1a, - 0x5f, 0x2f, 0x2c, 0xdf, 0xb6, 0xa2, 0x00, 0xcf, 0x8a, 0xd4, 0x29, 0xda, 0x76, 0x42, 0xf6, 0x23, - 0x4e, 0x85, 0xd6, 0xdd, 0xcc, 0x38, 0x6b, 0x7b, 0x73, 0x11, 0x3f, 0x27, 0x52, 0xec, 0x21, 0x5c, - 0xc6, 0xcd, 0x31, 0xba, 0xe9, 0x8b, 0x73, 0x48, 0xb8, 0x35, 0xf9, 0xeb, 0x49, 0x17, 0x8e, 0x8d, - 0x20, 0xb9, 0xdc, 0xc7, 0x9d, 0x02, 0xea, 0x6f, 0x40, 0x2d, 0xd5, 0xef, 0x2b, 0x8e, 0xbd, 0x61, - 0xa7, 0xd7, 0x69, 0x8d, 0xb8, 0xa3, 0x40, 0x38, 0x9c, 0x36, 0x25, 0xcf, 0x54, 0x4e, 0x72, 0x20, - 0xe4, 0xc9, 0xaf, 0xd5, 0xd1, 0x1e, 0x77, 0x94, 0x82, 0x9a, 0x2b, 0x65, 0x95, 0xac, 0xfa, 0x37, - 0x36, 0x61, 0x7b, 0xe4, 0x1b, 0x6e, 0x60, 0x70, 0x1d, 0xc6, 0x0d, 0x7d, 0xcf, 0x61, 0xdf, 0x83, - 0x52, 0x38, 0x71, 0xe4, 0x89, 0x70, 0x33, 0x12, 0x3b, 0x4b, 0xa4, 0xf7, 0x47, 0x13, 0x7e, 0x16, - 0x51, 0x0c, 0xf9, 0x0f, 0xf6, 0x0e, 0xe4, 0xc7, 0xd6, 0x91, 0xed, 0x0a, 0xc9, 0x7b, 0x69, 0x99, - 0x71, 0x17, 0x91, 0x7b, 0x1b, 0x1a, 0xa7, 0x62, 0xef, 0x41, 0x61, 0xe2, 0xcd, 0xa2, 0x2d, 0x2f, - 0xb9, 0xe6, 0x27, 0x15, 0x84, 0xd8, 0xbd, 0x0d, 0x4d, 0xd0, 0xb1, 0x8f, 0xa0, 0xe4, 0x7b, 0x8e, - 0x83, 0xfd, 0x2e, 0x36, 0xc3, 0xc6, 0x32, 0x8f, 0x26, 0xf0, 0x7b, 0x1b, 0x5a, 0x4c, 0xab, 0xde, - 0x87, 0xa2, 0xa8, 0x2c, 0x76, 0xc3, 0x6e, 0xe7, 0x71, 0x57, 0xf4, 0x60, 0x6b, 0xb0, 0xbf, 0xdf, - 0x1d, 0xf1, 0x3b, 0xcc, 0xda, 0xa0, 0xd7, 0xdb, 0x6d, 0xb6, 0x3e, 0x57, 0x36, 0x77, 0x4b, 0x50, - 0xe0, 0xc3, 0xa3, 0xfe, 0x56, 0x06, 0xb6, 0x96, 0x1a, 0xc0, 0x3e, 0x81, 0x1c, 0xd9, 0x57, 0xbc, - 0x7b, 0x6e, 0xaf, 0x6d, 0xa5, 0x94, 0xe6, 0x9a, 0x36, 0x72, 0xa8, 0x9f, 0x42, 0x3d, 0x0d, 0x97, - 0x9c, 0x49, 0x35, 0x28, 0x6b, 0x9d, 0x66, 0x5b, 0x1f, 0xf4, 0x7b, 0x5f, 0x72, 0xdf, 0x2c, 0x25, - 0x9f, 0x6a, 0x5d, 0xf2, 0xff, 0xfc, 0x3a, 0x28, 0xcb, 0x1d, 0xc3, 0x1e, 0xa3, 0xd5, 0x34, 0x9b, - 0x3b, 0x16, 0x29, 0xa7, 0xd2, 0x90, 0xdd, 0x58, 0xd3, 0x93, 0x82, 0x8c, 0xc7, 0x17, 0x4d, 0x52, - 0x69, 0xf5, 0x37, 0x80, 0xad, 0xf6, 0xe0, 0x2f, 0x2f, 0xfb, 0xff, 0x91, 0x81, 0xdc, 0x81, 0x63, - 0xb8, 0xec, 0x16, 0xe4, 0xe9, 0x99, 0x20, 0x21, 0xbf, 0xe5, 0xd5, 0x84, 0xd3, 0x82, 0x70, 0xec, - 0x2d, 0xc8, 0x86, 0x93, 0xe8, 0xea, 0xf4, 0x95, 0xe7, 0x4c, 0xbe, 0xbd, 0x0d, 0x0d, 0xa9, 0xd8, - 0x5d, 0xc8, 0x9a, 0x66, 0x74, 0xdd, 0x40, 0xb8, 0x94, 0xda, 0x46, 0x68, 0xb4, 0xad, 0xa9, 0xed, - 0xda, 0xe2, 0x59, 0x23, 0x24, 0x61, 0xaf, 0x43, 0xd6, 0x9c, 0x38, 0xe9, 0xbb, 0x23, 0xdc, 0x89, - 0x10, 0x67, 0x68, 0x4e, 0x1c, 0xd4, 0xfd, 0x42, 0xff, 0x5c, 0xf7, 0x17, 0x2e, 0x05, 0xaa, 0x06, - 0xc2, 0x1e, 0xab, 0xa0, 0x16, 0xb3, 0xa0, 0x68, 0xd7, 0x40, 0xdc, 0xc1, 0x9c, 0xfb, 0xd6, 0xdc, - 0xf0, 0x63, 0x4b, 0xcc, 0x0e, 0x0e, 0x38, 0x60, 0xb7, 0x00, 0xf4, 0xfa, 0xaa, 0xfa, 0x36, 0xbd, - 0x61, 0x83, 0x2a, 0xbd, 0x1a, 0xfd, 0x5a, 0xf3, 0x50, 0x9f, 0xc0, 0xa8, 0x7f, 0x91, 0x85, 0x8a, - 0x54, 0x1f, 0xf6, 0x01, 0x94, 0xcc, 0xf4, 0x42, 0xbc, 0xba, 0x52, 0xe9, 0xfb, 0xed, 0x68, 0x09, - 0x9a, 0x62, 0x7a, 0xd3, 0x41, 0x57, 0xa8, 0x3f, 0x33, 0x7c, 0x9b, 0xbf, 0x5c, 0xb6, 0x29, 0x9f, - 0x38, 0x0d, 0xad, 0xf0, 0x49, 0x84, 0xd9, 0xdb, 0xd0, 0xaa, 0x81, 0x94, 0x26, 0xbb, 0x43, 0x34, - 0x29, 0x9b, 0x7a, 0x01, 0x8e, 0x03, 0xf7, 0x36, 0xb4, 0x08, 0x8f, 0xa4, 0xd6, 0x99, 0x35, 0x59, - 0x84, 0x91, 0xdd, 0x51, 0x8b, 0x1a, 0x44, 0x40, 0x7a, 0x86, 0x92, 0xff, 0x64, 0x0f, 0x50, 0xda, - 0x1a, 0x8e, 0xe3, 0x91, 0xb2, 0x96, 0x97, 0xcf, 0x7f, 0xda, 0x31, 0x9c, 0x3f, 0x7b, 0x19, 0xa5, - 0xd8, 0x1d, 0xc8, 0x7b, 0xe1, 0xb1, 0x15, 0x69, 0xf3, 0xd1, 0x6b, 0x38, 0x08, 0x6a, 0xb7, 0x7a, - 0x38, 0x53, 0x08, 0xad, 0xfe, 0x41, 0x06, 0x8a, 0xa2, 0x07, 0xd8, 0x36, 0xd4, 0x86, 0x9d, 0x91, - 0xfe, 0xa4, 0xa9, 0x75, 0x9b, 0xbb, 0xbd, 0x8e, 0xb8, 0xf2, 0xf2, 0x58, 0x6b, 0xf6, 0x85, 0x80, - 0xd4, 0x3a, 0x4f, 0x06, 0x9f, 0x77, 0xb8, 0x87, 0xb6, 0xdd, 0xe9, 0x7f, 0xa9, 0x64, 0xf9, 0x71, - 0x44, 0xe7, 0xa0, 0xa9, 0xa1, 0xac, 0xac, 0x40, 0xb1, 0xf3, 0x45, 0xa7, 0x75, 0x48, 0xc2, 0xb2, - 0x0e, 0xd0, 0xee, 0x34, 0x7b, 0xbd, 0x41, 0x0b, 0x85, 0x67, 0x81, 0x31, 0xa8, 0xb7, 0xb4, 0x4e, - 0x73, 0xd4, 0xd1, 0x9b, 0xad, 0xd6, 0xe0, 0xb0, 0x3f, 0x52, 0x8a, 0x58, 0x62, 0xb3, 0x37, 0xea, - 0x68, 0x31, 0x88, 0x5e, 0x28, 0x6b, 0x6b, 0x83, 0x83, 0x18, 0x52, 0xde, 0x2d, 0xa3, 0x0d, 0x48, - 0x63, 0xa5, 0xfe, 0xd1, 0x36, 0xd4, 0xd3, 0x53, 0x93, 0x7d, 0x0c, 0x25, 0xd3, 0x4c, 0x8d, 0xf1, - 0xf5, 0x75, 0x53, 0xf8, 0x7e, 0xdb, 0x8c, 0x86, 0x99, 0xff, 0x60, 0xaf, 0x45, 0x0b, 0x69, 0x73, - 0x65, 0x21, 0x45, 0xcb, 0xe8, 0x07, 0xb0, 0x25, 0x9e, 0x68, 0x31, 0x8d, 0xd0, 0x18, 0x1b, 0x81, - 0x95, 0x5e, 0x25, 0x2d, 0x42, 0xb6, 0x05, 0x6e, 0x6f, 0x43, 0xab, 0x4f, 0x52, 0x10, 0xf6, 0x7d, - 0xa8, 0x1b, 0xdc, 0xfb, 0x13, 0xf1, 0xe7, 0x64, 0x35, 0xb4, 0x49, 0x4e, 0xa0, 0x84, 0xbd, 0x66, - 0xc8, 0x00, 0x9c, 0x88, 0xa6, 0xef, 0xcd, 0x13, 0xe6, 0x7c, 0xea, 0xe8, 0xd3, 0xf7, 0xe6, 0x12, - 0x6f, 0xd5, 0x94, 0xd2, 0xec, 0x23, 0xa8, 0x8a, 0x9a, 0x27, 0xae, 0x8e, 0x78, 0xc9, 0xf2, 0x6a, - 0x93, 0x5a, 0xb9, 0xb7, 0xa1, 0x55, 0x26, 0x49, 0x92, 0x3d, 0x44, 0x5d, 0x32, 0x51, 0xc2, 0x8b, - 0xf2, 0x5c, 0xa3, 0xda, 0x46, 0x5c, 0x60, 0xc4, 0x29, 0xf6, 0x1e, 0x00, 0xd5, 0x93, 0xf3, 0x94, - 0x52, 0x41, 0x41, 0xbe, 0x37, 0x8f, 0x58, 0xca, 0x66, 0x94, 0x90, 0xaa, 0xc7, 0x1d, 0x55, 0xe5, - 0xd5, 0xea, 0x91, 0xb3, 0x2a, 0xa9, 0x1e, 0xf7, 0x71, 0xc5, 0xd5, 0xe3, 0x6c, 0xb0, 0x52, 0xbd, - 0x88, 0x8b, 0x57, 0x8f, 0x33, 0x45, 0xd5, 0xe3, 0x3c, 0x95, 0xe5, 0xea, 0x45, 0x2c, 0x54, 0x3d, - 0xce, 0xf1, 0xfd, 0x15, 0xeb, 0xa1, 0xfa, 0x5c, 0xeb, 0x01, 0x87, 0x2d, 0x6d, 0x3f, 0x7c, 0x1f, - 0xea, 0xc1, 0xb1, 0x77, 0x2a, 0x09, 0x90, 0x9a, 0xcc, 0x3d, 0x3c, 0xf6, 0x4e, 0x65, 0x09, 0x52, - 0x0b, 0x64, 0x00, 0xd6, 0x96, 0x37, 0x91, 0x8e, 0x29, 0xeb, 0x72, 0x6d, 0xa9, 0x85, 0x4f, 0x6c, - 0xeb, 0x14, 0x6b, 0x6b, 0x44, 0x09, 0xec, 0x94, 0xc4, 0xed, 0x13, 0x08, 0x47, 0x4e, 0x2a, 0x94, - 0x46, 0x94, 0x04, 0xb1, 0x03, 0x28, 0xc0, 0xb9, 0xb5, 0x70, 0x65, 0x36, 0x45, 0x9e, 0x5b, 0x87, - 0x6e, 0x8a, 0xb1, 0xca, 0x49, 0x05, 0x6b, 0xb2, 0x2a, 0x02, 0xeb, 0xeb, 0x85, 0xe5, 0x4e, 0x2c, - 0x11, 0x32, 0x97, 0x5a, 0x15, 0x43, 0x81, 0x4b, 0x56, 0x45, 0x04, 0x89, 0xe7, 0x75, 0xcc, 0xce, - 0x96, 0xe7, 0xb5, 0xc4, 0x4c, 0xf3, 0x3a, 0x66, 0x8d, 0x17, 0x54, 0xcc, 0x7b, 0x61, 0x65, 0x41, - 0x49, 0xcc, 0x7c, 0x41, 0xc5, 0xdc, 0x0f, 0x41, 0xcc, 0x26, 0xde, 0xb9, 0xa9, 0xc0, 0x3a, 0x5e, - 0x6b, 0xd1, 0xbb, 0x30, 0x89, 0x53, 0x38, 0x57, 0x7d, 0x0b, 0xad, 0x15, 0x31, 0x15, 0x2e, 0xc9, - 0x73, 0x55, 0x23, 0x4c, 0xbc, 0x94, 0xfc, 0x24, 0x29, 0x15, 0x36, 0xb7, 0x43, 0xbf, 0x61, 0xae, - 0x16, 0x76, 0x60, 0x87, 0x7e, 0x52, 0x18, 0xa6, 0xd8, 0x3b, 0x40, 0xd3, 0x90, 0xb3, 0x58, 0xb2, - 0xe8, 0xc6, 0x6e, 0x11, 0x0c, 0x25, 0x53, 0xfc, 0xc6, 0xc9, 0x22, 0xca, 0x98, 0x98, 0x93, 0xc6, - 0x54, 0x9e, 0x2c, 0xbc, 0x88, 0x56, 0xbb, 0x85, 0x93, 0x85, 0x13, 0xb5, 0xcc, 0x09, 0xbb, 0x07, - 0xc4, 0x4d, 0xf4, 0x47, 0xa9, 0xd7, 0xd6, 0x7c, 0x6f, 0xce, 0xa9, 0x8b, 0x48, 0x80, 0xb4, 0xd8, - 0x02, 0xc7, 0x73, 0xa3, 0x86, 0x1f, 0xa7, 0x5a, 0x80, 0x88, 0x58, 0x18, 0x4c, 0xe2, 0x94, 0xfa, - 0x3b, 0x05, 0x28, 0x0a, 0x59, 0xcb, 0x2e, 0xc0, 0x96, 0x10, 0xf9, 0xed, 0xe6, 0xa8, 0xb9, 0xdb, - 0x1c, 0xa2, 0x92, 0xc6, 0xa0, 0xce, 0x65, 0x7e, 0x0c, 0xcb, 0xe0, 0x3e, 0x40, 0x42, 0x3f, 0x06, - 0x6d, 0xe2, 0x3e, 0x20, 0x78, 0xf9, 0xab, 0x96, 0x59, 0xb6, 0x05, 0x15, 0xce, 0xc8, 0x01, 0x74, - 0x03, 0x97, 0xb8, 0x78, 0x3a, 0x2f, 0xb1, 0xf0, 0x03, 0xcb, 0x42, 0xc2, 0xc2, 0x01, 0xc5, 0x98, - 0x25, 0x3a, 0xd1, 0x64, 0x50, 0x1f, 0x69, 0x87, 0xfd, 0x56, 0x52, 0x4e, 0x99, 0x6e, 0x4d, 0xf2, - 0x6c, 0x9e, 0x74, 0x3b, 0x4f, 0x15, 0x40, 0x26, 0x9e, 0x0b, 0xa5, 0x2b, 0xa8, 0x66, 0x52, 0x26, - 0x94, 0xac, 0xb2, 0x2b, 0x70, 0x61, 0xb8, 0x37, 0x78, 0xaa, 0x73, 0xa6, 0xb8, 0x09, 0x35, 0x76, - 0x11, 0x14, 0x09, 0xc1, 0xb3, 0xaf, 0x63, 0x91, 0x04, 0x8d, 0x08, 0x87, 0xca, 0x16, 0x1d, 0xfe, - 0x23, 0x6c, 0xc4, 0xf7, 0x5d, 0x05, 0x9b, 0xc2, 0x59, 0x07, 0xbd, 0xc3, 0xfd, 0xfe, 0x50, 0xd9, - 0xc6, 0x4a, 0x10, 0x84, 0xd7, 0x9c, 0xc5, 0xd9, 0x24, 0xbb, 0xf5, 0x05, 0xda, 0xc0, 0x11, 0xf6, - 0xb4, 0xa9, 0xf5, 0xbb, 0xfd, 0xc7, 0x43, 0xe5, 0x62, 0x9c, 0x73, 0x47, 0xd3, 0x06, 0xda, 0x50, - 0xb9, 0x14, 0x03, 0x86, 0xa3, 0xe6, 0xe8, 0x70, 0xa8, 0x5c, 0x8e, 0x6b, 0x79, 0xa0, 0x0d, 0x5a, - 0x9d, 0xe1, 0xb0, 0xd7, 0x1d, 0x8e, 0x94, 0x2b, 0xec, 0x12, 0x6c, 0x27, 0x35, 0x8a, 0x88, 0x1b, - 0x52, 0x45, 0xb5, 0xc7, 0x9d, 0x91, 0x72, 0x35, 0xae, 0x46, 0x6b, 0xd0, 0xeb, 0x35, 0xe9, 0x64, - 0xfb, 0x1a, 0x12, 0xd1, 0x61, 0xbe, 0x68, 0xcd, 0x2b, 0x58, 0xaf, 0xc3, 0xbe, 0x0c, 0xba, 0x2e, - 0x4d, 0x8d, 0x61, 0xe7, 0x47, 0x87, 0x9d, 0x7e, 0xab, 0xa3, 0xbc, 0x9a, 0x4c, 0x8d, 0x18, 0x76, - 0x23, 0x9e, 0x1a, 0x31, 0xe8, 0x66, 0x5c, 0x66, 0x04, 0x1a, 0x2a, 0x3b, 0x98, 0x9f, 0xa8, 0x47, - 0xbf, 0xdf, 0x69, 0x8d, 0xb0, 0xad, 0xaf, 0xc5, 0xbd, 0x78, 0x78, 0xf0, 0x58, 0x6b, 0xb6, 0x3b, - 0x8a, 0x8a, 0x10, 0xad, 0xd3, 0x6f, 0xee, 0x47, 0xa3, 0x7d, 0x4b, 0x1a, 0xed, 0x83, 0xee, 0x48, - 0x53, 0x6e, 0xc7, 0xa3, 0x4b, 0xc9, 0xd7, 0xd9, 0x2b, 0x70, 0x45, 0x9e, 0x87, 0xfa, 0xd3, 0xee, - 0x68, 0x4f, 0x1c, 0xc4, 0xdf, 0xe1, 0x87, 0xc8, 0x84, 0x6c, 0xb5, 0x5b, 0x3c, 0xe2, 0x80, 0x78, - 0x31, 0x75, 0x77, 0xb7, 0x4a, 0x8f, 0x93, 0x0b, 0x05, 0x44, 0xfd, 0x0c, 0x98, 0xfc, 0x4e, 0xaf, - 0x88, 0x3c, 0x66, 0x90, 0x9b, 0xfa, 0xde, 0x2c, 0x7a, 0x0d, 0x03, 0x7f, 0xa3, 0xfd, 0x3d, 0x5f, - 0x8c, 0xe9, 0x70, 0x3b, 0xb9, 0xed, 0x2e, 0x83, 0xd4, 0xbf, 0x9b, 0x81, 0x7a, 0x5a, 0xf9, 0x20, - 0x87, 0xeb, 0x54, 0x77, 0xbd, 0x90, 0x3f, 0x2f, 0x16, 0xc4, 0xcf, 0xe7, 0x4e, 0xfb, 0x5e, 0x48, - 0xef, 0x8b, 0x91, 0x3b, 0x20, 0xd6, 0x25, 0x78, 0xae, 0x71, 0x9a, 0x75, 0xe1, 0x42, 0xea, 0xa9, - 0xe3, 0xd4, 0xe3, 0x6e, 0x8d, 0xf8, 0x89, 0xd2, 0xa5, 0xfa, 0x6b, 0x2c, 0x58, 0x6d, 0x93, 0x78, - 0xb3, 0x20, 0x97, 0xbc, 0x59, 0xb0, 0x07, 0xb5, 0x94, 0xae, 0x43, 0x5e, 0x9c, 0x69, 0xba, 0xa6, - 0x25, 0x7b, 0xfa, 0xf2, 0x6a, 0xaa, 0x7f, 0x3b, 0x03, 0x55, 0x59, 0xf3, 0xf9, 0xce, 0x39, 0x51, - 0x40, 0x90, 0xf8, 0xad, 0xdb, 0x66, 0xf4, 0xac, 0x58, 0x04, 0xea, 0xd2, 0x47, 0x19, 0xb8, 0xef, - 0xfa, 0xd1, 0xc9, 0x30, 0x6e, 0x8e, 0x0c, 0x62, 0x37, 0x00, 0xe8, 0xc9, 0x9f, 0x47, 0x9f, 0x23, - 0x81, 0x78, 0x93, 0x3a, 0x81, 0xa8, 0x37, 0xa1, 0xfc, 0xe8, 0x24, 0x8a, 0x8f, 0x92, 0x1f, 0xd9, - 0x2b, 0xf3, 0x27, 0x12, 0xd4, 0x3f, 0xcc, 0x40, 0x3d, 0xf1, 0x59, 0x50, 0x58, 0x01, 0x7f, 0x22, - 0x9b, 0x4f, 0x87, 0x4d, 0x73, 0x9c, 0x9c, 0x7f, 0x6e, 0xca, 0xe7, 0x9f, 0xb7, 0x44, 0x66, 0x59, - 0x59, 0xe4, 0xc7, 0x65, 0x89, 0x07, 0x18, 0x1e, 0x42, 0x15, 0xff, 0x6b, 0xd6, 0xd4, 0xf2, 0x7d, - 0xcb, 0x4c, 0xdf, 0x07, 0x49, 0x88, 0x53, 0x44, 0x64, 0xe3, 0x89, 0x93, 0xd5, 0xe7, 0xbc, 0x99, - 0x44, 0x6f, 0x79, 0xfd, 0xb7, 0x2c, 0x54, 0x24, 0x3d, 0xf2, 0x1b, 0x4d, 0xbf, 0xeb, 0x50, 0x4e, - 0x5e, 0xf0, 0x11, 0xb7, 0xde, 0x63, 0x40, 0x6a, 0xac, 0xb2, 0x4b, 0x63, 0xd5, 0x80, 0xa2, 0xcf, - 0x6f, 0xa9, 0x0a, 0x17, 0x72, 0x94, 0x4c, 0x3b, 0x6b, 0xf3, 0x2f, 0x39, 0x5f, 0x79, 0x1f, 0xaa, - 0x92, 0xa7, 0x35, 0x68, 0x14, 0xe4, 0x67, 0x9c, 0x62, 0xfa, 0x4a, 0xe2, 0x75, 0x0d, 0xd8, 0x25, - 0x28, 0x4c, 0x4f, 0x74, 0x73, 0xcc, 0xef, 0x42, 0x97, 0xb5, 0xfc, 0xf4, 0xa4, 0x3d, 0xa6, 0xd3, - 0xa7, 0x69, 0xac, 0x3a, 0x71, 0xff, 0x57, 0x69, 0x1a, 0x29, 0x48, 0x77, 0xa1, 0x38, 0x3d, 0x91, - 0xef, 0x34, 0xaf, 0x74, 0x79, 0x61, 0x7a, 0x42, 0x37, 0x99, 0xdf, 0x85, 0x8b, 0x62, 0xff, 0x36, - 0x02, 0x9d, 0x3f, 0x30, 0x42, 0x2f, 0x3b, 0xf1, 0x27, 0xf7, 0xb6, 0x39, 0xae, 0x19, 0x0c, 0x09, - 0x83, 0x33, 0x4e, 0x85, 0xaa, 0x34, 0x01, 0xf9, 0x13, 0x58, 0x65, 0x2d, 0x05, 0x63, 0x9f, 0x40, - 0x75, 0x7a, 0xc2, 0x07, 0x74, 0xe4, 0xed, 0x5b, 0xe2, 0x8a, 0xc6, 0xc5, 0xe5, 0xa1, 0xa4, 0xb8, - 0x8f, 0x14, 0x25, 0xbb, 0x0c, 0x05, 0xcd, 0x38, 0x1d, 0xfe, 0xa8, 0x47, 0x4a, 0x64, 0x59, 0x13, - 0xa9, 0xcf, 0x72, 0xa5, 0xba, 0xb2, 0xa5, 0xfe, 0xe3, 0x0c, 0xd4, 0x13, 0x1b, 0x00, 0x17, 0x21, - 0xbb, 0x27, 0xbf, 0x6d, 0xdf, 0x58, 0x36, 0x13, 0x90, 0xe4, 0xfe, 0xe8, 0x7c, 0xce, 0x5f, 0x80, - 0x5d, 0xf7, 0x6c, 0xd9, 0x3a, 0xd7, 0x77, 0x76, 0xed, 0xab, 0xda, 0x8f, 0x21, 0x3b, 0x3a, 0x9f, - 0x73, 0x7f, 0x13, 0x6e, 0x89, 0xdc, 0x36, 0xe5, 0x9b, 0x21, 0x05, 0x19, 0x7d, 0xde, 0xf9, 0x92, - 0xbf, 0xd2, 0x71, 0xa0, 0x75, 0xf7, 0x9b, 0xda, 0x97, 0x3a, 0x02, 0x48, 0x69, 0x78, 0x34, 0xd0, - 0x3a, 0xdd, 0xc7, 0x7d, 0x02, 0xe4, 0xc8, 0x1b, 0x95, 0x54, 0xb1, 0x69, 0x9a, 0x8f, 0x4e, 0xe4, - 0x17, 0x9f, 0x32, 0xa9, 0x17, 0x9f, 0xe2, 0xc7, 0xd1, 0xe4, 0x97, 0x22, 0xc3, 0xd8, 0x1f, 0xcf, - 0xe2, 0x55, 0x18, 0x2f, 0x69, 0xf6, 0x06, 0xe4, 0xa6, 0x27, 0xd6, 0x79, 0xda, 0xd0, 0x4b, 0x2f, - 0x20, 0x22, 0x50, 0x7f, 0x9e, 0x01, 0x96, 0xaa, 0x08, 0xb7, 0x3d, 0xbe, 0x6b, 0x5d, 0x3e, 0x86, - 0x86, 0x08, 0x81, 0xe4, 0x54, 0x92, 0xaf, 0x5d, 0x74, 0xe9, 0x25, 0x2f, 0x09, 0x0d, 0x4e, 0x5e, - 0x56, 0x63, 0xef, 0x02, 0x7f, 0x04, 0x92, 0xc2, 0x84, 0x72, 0xcf, 0xb1, 0x13, 0xb5, 0x84, 0x26, - 0x79, 0xf5, 0x51, 0x7e, 0xcd, 0x92, 0xbb, 0xe9, 0xb7, 0x92, 0x51, 0xa3, 0x35, 0xaf, 0xfe, 0x5e, - 0x06, 0x2e, 0xa4, 0x27, 0xc4, 0x2f, 0xd6, 0xca, 0xf4, 0xd3, 0x9d, 0xd9, 0xe5, 0xa7, 0x3b, 0xd7, - 0xcd, 0xa7, 0xdc, 0xda, 0xf9, 0xf4, 0xdb, 0x19, 0xb8, 0x28, 0xf5, 0x7e, 0x62, 0x2d, 0xfe, 0x25, - 0xd5, 0x4c, 0x7a, 0xc1, 0x33, 0x97, 0x7a, 0xc1, 0x53, 0xfd, 0xe3, 0x0c, 0x5c, 0x5e, 0xaa, 0x89, - 0x66, 0xfd, 0xa5, 0xd6, 0x25, 0xfd, 0xd2, 0x27, 0x1d, 0x15, 0x44, 0x2f, 0x59, 0x64, 0xee, 0x66, - 0xa5, 0x97, 0x3e, 0xe9, 0xfc, 0x88, 0x0e, 0x31, 0x5f, 0x15, 0x0f, 0x1e, 0xe9, 0xc1, 0xb9, 0x3b, - 0x11, 0x83, 0x5d, 0x26, 0xc8, 0xf0, 0xdc, 0x9d, 0xa8, 0x7f, 0x94, 0x81, 0xab, 0x4b, 0x6d, 0x68, - 0x2e, 0x42, 0x4f, 0x9c, 0x05, 0xff, 0x25, 0x35, 0xe3, 0x26, 0x54, 0xe8, 0xa4, 0x5c, 0x1c, 0x30, - 0xf3, 0x6e, 0x05, 0x23, 0x29, 0x57, 0x81, 0xac, 0x69, 0x9c, 0x8b, 0xd7, 0x02, 0xf0, 0x27, 0x2e, - 0xd8, 0x63, 0x6f, 0xe1, 0x8b, 0xe8, 0x20, 0xfa, 0xad, 0x7e, 0x00, 0xdb, 0x49, 0xd5, 0x5b, 0xe2, - 0xc1, 0xd5, 0x9b, 0x50, 0x71, 0xad, 0x53, 0x3d, 0x7a, 0x8e, 0x55, 0xc4, 0xbc, 0xb9, 0xd6, 0xa9, - 0x20, 0x50, 0x1f, 0xc9, 0xb2, 0x30, 0xfe, 0x8c, 0x84, 0x63, 0xa6, 0xe2, 0x76, 0x3c, 0xc7, 0x8c, - 0x50, 0x98, 0x9b, 0xd4, 0xca, 0xa2, 0x6b, 0x9d, 0xd2, 0x3c, 0x3c, 0x15, 0xf9, 0x34, 0x4d, 0x53, - 0xc4, 0x2e, 0xac, 0x7b, 0x1f, 0xed, 0x2a, 0x94, 0xe6, 0x7e, 0xaa, 0x9b, 0x8a, 0x73, 0x9f, 0x17, - 0x7b, 0x5b, 0x44, 0xd4, 0x3d, 0x2f, 0xce, 0x81, 0xc7, 0xd8, 0x89, 0xcf, 0xcc, 0xe4, 0x92, 0xcf, - 0xcc, 0x7c, 0x28, 0xc4, 0x20, 0xd9, 0x7d, 0xbc, 0x64, 0x05, 0xb2, 0xb6, 0x79, 0x46, 0x05, 0xd7, - 0x34, 0xfc, 0x49, 0x9a, 0x9c, 0xf5, 0xb5, 0x08, 0xea, 0xc3, 0x9f, 0xea, 0x2e, 0x54, 0xb4, 0x94, - 0x91, 0x5b, 0x95, 0xfc, 0x45, 0x41, 0xfa, 0x09, 0xa9, 0xa4, 0x83, 0xb4, 0x4a, 0xe2, 0x2e, 0x0a, - 0xd4, 0x40, 0x08, 0xbe, 0x27, 0x86, 0x3f, 0x39, 0x36, 0xfc, 0x9e, 0xe5, 0x1e, 0x85, 0xc7, 0xd8, - 0xe5, 0xdc, 0x8d, 0x2b, 0x77, 0x21, 0x70, 0x50, 0x34, 0x1d, 0xb0, 0x17, 0x1d, 0x22, 0x8f, 0x3e, - 0x60, 0xe1, 0x5a, 0xa7, 0x82, 0xff, 0x55, 0x00, 0xec, 0x7f, 0x81, 0xe6, 0x47, 0x90, 0x65, 0xcf, - 0x31, 0x39, 0x5a, 0xdd, 0x16, 0xed, 0x15, 0xaf, 0x5d, 0xb4, 0xad, 0xa9, 0xea, 0x88, 0x91, 0xe7, - 0x0d, 0x12, 0x9d, 0xf0, 0x9d, 0x86, 0x91, 0xbd, 0x06, 0xd5, 0xc8, 0x23, 0x41, 0xaf, 0x96, 0xf1, - 0xe2, 0x2b, 0x11, 0xac, 0xbf, 0x98, 0xa9, 0xbf, 0x9f, 0x85, 0x6a, 0x93, 0x47, 0xf6, 0xcc, 0xcf, - 0x07, 0xf3, 0x90, 0xfd, 0x06, 0x5c, 0xa2, 0x67, 0x4c, 0xf8, 0x43, 0xc2, 0x14, 0x50, 0x43, 0x71, - 0xf1, 0xa2, 0x13, 0xef, 0x49, 0x9d, 0x28, 0x58, 0xee, 0x0f, 0x4f, 0xec, 0x39, 0xbf, 0x8e, 0xd1, - 0x35, 0xcf, 0xe8, 0xee, 0x03, 0x8f, 0x0d, 0xa0, 0x17, 0x4f, 0xd2, 0x08, 0x7a, 0xf4, 0x00, 0xb3, - 0x9f, 0x9f, 0x88, 0x6c, 0x45, 0xd8, 0x04, 0x02, 0x0f, 0x4e, 0x38, 0xcd, 0x3d, 0xd8, 0xe6, 0x37, - 0xb0, 0x56, 0x37, 0xe0, 0x2d, 0x8e, 0x48, 0xe6, 0xf7, 0x10, 0xb6, 0xc5, 0xab, 0x2b, 0xf4, 0xbc, - 0xa6, 0x3e, 0xf1, 0xe6, 0xe7, 0xe2, 0xe8, 0xf1, 0x8d, 0xe7, 0x54, 0xb5, 0xcb, 0x49, 0x11, 0xc4, - 0xeb, 0xb9, 0x15, 0xa4, 0xa1, 0xd7, 0x3a, 0x70, 0xe5, 0x39, 0x6d, 0x7a, 0x59, 0x78, 0x43, 0x49, - 0x0a, 0x6f, 0xb8, 0xb6, 0x0b, 0x17, 0xd7, 0x95, 0xf7, 0x6d, 0xf2, 0x50, 0x7f, 0x56, 0x03, 0x48, - 0x66, 0x6c, 0x4a, 0x1d, 0xcd, 0x2c, 0xa9, 0xa3, 0xdf, 0x2a, 0xa8, 0xe7, 0x03, 0xa8, 0x63, 0x57, - 0xe9, 0x09, 0x47, 0x76, 0x2d, 0x47, 0x15, 0xa9, 0x46, 0xc9, 0x25, 0xd3, 0xd5, 0x90, 0x88, 0xdc, - 0xda, 0x90, 0x88, 0xf7, 0xa1, 0xc8, 0x0f, 0xda, 0x02, 0x71, 0xaf, 0xf9, 0xca, 0xf2, 0xea, 0xbb, - 0x2f, 0xae, 0x76, 0x44, 0x74, 0xac, 0x03, 0x75, 0x14, 0xfd, 0xbe, 0x1d, 0x1e, 0xcf, 0xe4, 0x5b, - 0xce, 0x37, 0x56, 0x39, 0x23, 0x32, 0xfe, 0x28, 0xa7, 0x21, 0x27, 0x25, 0xed, 0x35, 0x9c, 0x09, - 0xef, 0x2f, 0x69, 0xaf, 0x45, 0x59, 0x7b, 0x1d, 0xcd, 0xb8, 0xcf, 0x17, 0xb5, 0xd7, 0x77, 0xe0, - 0x82, 0xb8, 0x6e, 0x86, 0x0c, 0xd8, 0x9d, 0x44, 0xcf, 0x83, 0x2c, 0x15, 0xf1, 0xd8, 0xc9, 0x8c, - 0x6c, 0x3b, 0x24, 0xff, 0x02, 0x2e, 0x4e, 0x8e, 0x0d, 0xf7, 0xc8, 0xd2, 0xc3, 0xb1, 0xa3, 0xd3, - 0xd7, 0x0b, 0xf4, 0x99, 0x31, 0x17, 0x4a, 0xf5, 0x1b, 0x2b, 0x95, 0x6d, 0x11, 0xf1, 0x68, 0xec, - 0x50, 0x00, 0x5a, 0x1c, 0x38, 0xb3, 0x3d, 0x59, 0x86, 0x2f, 0x9d, 0x5f, 0xc3, 0xca, 0xf9, 0xf5, - 0xb2, 0x9a, 0x5d, 0x59, 0xa3, 0x66, 0x27, 0xca, 0x72, 0x55, 0x56, 0x96, 0xd9, 0xdb, 0x50, 0x14, - 0xb7, 0x65, 0x85, 0xdf, 0x97, 0xad, 0xae, 0x0e, 0x2d, 0x22, 0xc1, 0x92, 0xa2, 0x68, 0x0a, 0x7a, - 0x50, 0xa1, 0xce, 0x4b, 0x92, 0x61, 0x6c, 0x57, 0x38, 0x3d, 0xe3, 0x60, 0x39, 0xe1, 0xe3, 0xbd, - 0x26, 0x65, 0x1c, 0xe3, 0x84, 0x5d, 0xbe, 0xc4, 0x71, 0xed, 0x1f, 0x15, 0xa0, 0x20, 0x02, 0xe5, - 0xef, 0x41, 0xce, 0xf4, 0xbd, 0x79, 0x1c, 0x6d, 0xbe, 0x46, 0x6b, 0xa7, 0x0f, 0xd6, 0xa1, 0x82, - 0x7f, 0x1f, 0x0a, 0x86, 0x69, 0xea, 0xd3, 0x93, 0xf4, 0x79, 0xf4, 0x92, 0x02, 0xbd, 0xb7, 0xa1, - 0xe5, 0x0d, 0xd2, 0xa4, 0x3f, 0x86, 0x32, 0xd2, 0x27, 0xe1, 0xa7, 0x95, 0x55, 0xb3, 0x20, 0x52, - 0x75, 0xf7, 0x36, 0xb4, 0x92, 0x11, 0xa9, 0xbd, 0xbf, 0x9a, 0xf6, 0xec, 0xe7, 0x56, 0x1a, 0xb8, - 0xa4, 0xa7, 0x2d, 0xf9, 0xf8, 0x7f, 0x0d, 0xb8, 0xab, 0x37, 0xde, 0xb1, 0xf3, 0xf2, 0xd1, 0xe7, - 0xca, 0xfe, 0xbe, 0xb7, 0xa1, 0xf1, 0x7d, 0x2b, 0xda, 0xef, 0x3f, 0x8c, 0xbc, 0xee, 0xf1, 0x87, - 0x7d, 0xd6, 0xf4, 0x0c, 0x8a, 0xc1, 0xd8, 0xf5, 0x4e, 0x32, 0x11, 0xd9, 0x4c, 0x33, 0x8a, 0x42, - 0x2c, 0xae, 0xb0, 0xc5, 0xbb, 0x3a, 0xb1, 0xc5, 0x5b, 0xfc, 0x27, 0x50, 0xe1, 0x4e, 0x58, 0xce, - 0x57, 0x5a, 0xe9, 0xda, 0x64, 0x53, 0xa6, 0x63, 0xbd, 0x64, 0x8b, 0x6e, 0x45, 0xed, 0xf4, 0x2d, - 0xf9, 0xe4, 0xe4, 0xfa, 0xda, 0x8e, 0xd2, 0xe2, 0x43, 0x14, 0xde, 0x58, 0x8d, 0xf3, 0xb0, 0x1e, - 0x5c, 0x14, 0x47, 0x0c, 0x7c, 0x03, 0x8e, 0xf6, 0x4c, 0x58, 0x19, 0xaf, 0xd4, 0x0e, 0xbd, 0xb7, - 0xa1, 0x31, 0x63, 0x75, 0xdf, 0x6e, 0xc1, 0x76, 0x54, 0x25, 0xda, 0x59, 0xa5, 0xb0, 0x29, 0xb9, - 0x49, 0xc9, 0xbe, 0xbb, 0xb7, 0xa1, 0x6d, 0x19, 0x69, 0x10, 0xeb, 0xc2, 0x85, 0x28, 0x13, 0x72, - 0xb5, 0x8b, 0x9e, 0xa9, 0xae, 0x8c, 0xa2, 0xbc, 0x57, 0xef, 0x6d, 0x68, 0xdb, 0xc6, 0xca, 0x06, - 0xbe, 0x1f, 0xd5, 0x47, 0x56, 0x0e, 0xf9, 0x4a, 0xbc, 0xb9, 0xb6, 0x9b, 0x12, 0x4d, 0x35, 0xae, - 0x59, 0x02, 0x4a, 0xe2, 0x18, 0xae, 0x69, 0x70, 0x79, 0xbd, 0x84, 0x91, 0xb7, 0x99, 0x1c, 0xdf, - 0x66, 0x54, 0x79, 0x9b, 0x59, 0x7e, 0x20, 0x45, 0xda, 0x74, 0x7e, 0x08, 0xb5, 0x94, 0x88, 0x65, - 0x15, 0x28, 0x46, 0xcf, 0xbe, 0xd3, 0xe5, 0x98, 0xd6, 0xe0, 0xe0, 0x4b, 0x25, 0x83, 0xe0, 0x6e, - 0x7f, 0x38, 0x6a, 0xf6, 0x47, 0xca, 0x26, 0x4f, 0x1c, 0xf4, 0x9a, 0xad, 0x8e, 0x92, 0x55, 0xff, - 0x38, 0x0b, 0xe5, 0xf8, 0x94, 0xed, 0xbb, 0x7b, 0xc3, 0x62, 0x37, 0x53, 0x56, 0x76, 0x33, 0x2d, - 0x99, 0x7a, 0xfc, 0x0b, 0x0d, 0xfc, 0xa3, 0x59, 0x5b, 0x69, 0x83, 0x2a, 0x58, 0xbd, 0x37, 0x9f, - 0xff, 0x86, 0xf7, 0xe6, 0xe5, 0x08, 0xf4, 0x42, 0x3a, 0x02, 0x7d, 0xe9, 0xe9, 0xff, 0x22, 0x3d, - 0xca, 0x2d, 0x3f, 0xfd, 0x4f, 0x9f, 0x12, 0x7d, 0x62, 0x5b, 0xa7, 0x22, 0x64, 0x5b, 0xa4, 0xd2, - 0x3b, 0x34, 0xbc, 0x64, 0x87, 0xfe, 0x26, 0xd2, 0xfe, 0x01, 0x5c, 0x9c, 0x9e, 0xc4, 0x4f, 0x81, - 0x27, 0xce, 0x95, 0x2a, 0x55, 0x69, 0x2d, 0x8e, 0xbd, 0x11, 0x7f, 0xfb, 0xac, 0x26, 0xbb, 0x81, - 0xe2, 0xd1, 0x8a, 0x3f, 0x86, 0xf6, 0xff, 0x67, 0x00, 0x92, 0xf3, 0xa7, 0x5f, 0xd8, 0x95, 0x2b, - 0x79, 0xcb, 0xb2, 0x2f, 0xf0, 0x96, 0xbd, 0xec, 0x69, 0xb8, 0xaf, 0xa1, 0x1c, 0x9f, 0x38, 0x7e, - 0xf7, 0x89, 0xf5, 0xad, 0x8a, 0xfc, 0xcd, 0xc8, 0xad, 0x1d, 0x1f, 0xd9, 0xfd, 0xa2, 0x7d, 0x91, - 0x2a, 0x3e, 0xfb, 0x92, 0xe2, 0xcf, 0xb8, 0x6f, 0x39, 0x2e, 0xfc, 0x97, 0xbc, 0x9a, 0xe4, 0x89, - 0x9e, 0x4b, 0x4d, 0x74, 0x75, 0x21, 0x1c, 0xe4, 0xbf, 0x78, 0xd1, 0xdf, 0xaa, 0xc1, 0xff, 0x35, - 0x13, 0x79, 0x71, 0xe3, 0xd7, 0xdb, 0x9f, 0xab, 0xf4, 0xae, 0x77, 0x44, 0x7f, 0x9b, 0xe2, 0x5e, - 0xe8, 0xa3, 0xca, 0xbd, 0xc8, 0x47, 0xf5, 0x06, 0xe4, 0xf9, 0x76, 0x97, 0x7f, 0x9e, 0x7f, 0x8a, - 0xe3, 0x5f, 0xfa, 0x8d, 0x15, 0x55, 0x15, 0x4a, 0x3e, 0x6f, 0xef, 0xc5, 0x28, 0xdf, 0xe8, 0xfb, - 0x30, 0x74, 0x43, 0xe6, 0xff, 0xe2, 0x12, 0xf5, 0xbb, 0x76, 0xc9, 0x8b, 0xdd, 0x16, 0xea, 0xff, - 0xca, 0x40, 0x2d, 0x15, 0x41, 0xf0, 0x1d, 0x8a, 0x58, 0x2b, 0x97, 0xb3, 0xff, 0x07, 0xc9, 0xe5, - 0x54, 0x08, 0x6f, 0x29, 0x1d, 0xc2, 0x8b, 0xe2, 0xae, 0x9a, 0x32, 0x61, 0xd6, 0x19, 0x3b, 0x99, - 0xb5, 0xc6, 0xce, 0x8d, 0xf8, 0x23, 0x96, 0xdd, 0x36, 0x8f, 0x98, 0xad, 0x69, 0x12, 0x84, 0x7d, - 0x0a, 0x57, 0x85, 0x13, 0x81, 0xf7, 0x8f, 0x37, 0xd5, 0xe3, 0x4f, 0x5c, 0x0a, 0xa3, 0xfc, 0x32, - 0x27, 0xe0, 0x5f, 0xc8, 0x99, 0x36, 0x23, 0xac, 0xda, 0x85, 0x5a, 0x2a, 0x34, 0x43, 0xfa, 0xa4, - 0x6e, 0x46, 0xfe, 0xa4, 0x2e, 0xdb, 0x81, 0xfc, 0xe9, 0xb1, 0xe5, 0x5b, 0x6b, 0x5e, 0x66, 0xe6, - 0x08, 0xf5, 0xfb, 0x50, 0x95, 0xc3, 0xc4, 0xd8, 0xdb, 0x90, 0xb7, 0x43, 0x6b, 0x16, 0xb9, 0x47, - 0x2e, 0xaf, 0x46, 0x92, 0x75, 0x43, 0x6b, 0xa6, 0x71, 0x22, 0xf5, 0x0f, 0x32, 0xa0, 0x2c, 0xe3, - 0xa4, 0xef, 0xfe, 0x66, 0x9e, 0xf3, 0xdd, 0xdf, 0xcd, 0x54, 0x25, 0xd7, 0x7d, 0xba, 0x77, 0x27, - 0x52, 0x4a, 0xd6, 0x7c, 0x36, 0x96, 0x10, 0xec, 0x0e, 0x94, 0x7c, 0x8b, 0x3e, 0xaa, 0x6a, 0xae, - 0xb9, 0x39, 0x12, 0xe3, 0xd4, 0xdf, 0xcd, 0x40, 0x51, 0xc4, 0xb4, 0xad, 0xf5, 0x57, 0xbd, 0x09, - 0x45, 0xfe, 0x81, 0xd5, 0xe8, 0x85, 0xb8, 0x95, 0x30, 0xf3, 0x08, 0xcf, 0x6e, 0xf0, 0x48, 0xbf, - 0xb4, 0xff, 0xea, 0xc0, 0x31, 0x5c, 0x8d, 0xe0, 0xe2, 0xc3, 0x57, 0xc6, 0x4c, 0x3c, 0x29, 0xc0, - 0x9f, 0xf6, 0x02, 0x02, 0xd1, 0xeb, 0x01, 0xea, 0xaf, 0x42, 0x51, 0xc4, 0xcc, 0xad, 0xad, 0xca, - 0xcb, 0x3e, 0xae, 0xb9, 0x03, 0x90, 0x04, 0xd1, 0xad, 0xcb, 0x41, 0xbd, 0x07, 0xa5, 0x28, 0x6e, - 0x0e, 0xe7, 0x5f, 0x52, 0xb4, 0xb8, 0x92, 0x24, 0x57, 0xc6, 0x11, 0x5f, 0x3b, 0xe8, 0x79, 0x93, - 0x13, 0x72, 0x96, 0xbf, 0x0b, 0x74, 0x3f, 0x6b, 0xb4, 0xf2, 0x06, 0x5a, 0xfa, 0x73, 0x17, 0x31, - 0x11, 0xbb, 0x07, 0xb1, 0xbc, 0x7c, 0x99, 0x6b, 0x41, 0x6d, 0x46, 0x37, 0xf9, 0x68, 0x96, 0x3d, - 0x14, 0xde, 0xd4, 0x1e, 0xbd, 0xc1, 0x99, 0x91, 0x5f, 0x25, 0x4e, 0xd5, 0x49, 0x93, 0xc8, 0xd4, - 0x3a, 0x54, 0xe5, 0x60, 0x1f, 0xb5, 0x09, 0xdb, 0xfb, 0x56, 0x68, 0xa0, 0xfc, 0x89, 0x5e, 0x86, - 0xe2, 0xf3, 0x17, 0x7f, 0xa4, 0xe7, 0xef, 0x32, 0x9d, 0xc6, 0x89, 0xd4, 0x3f, 0xce, 0x81, 0xb2, - 0x8c, 0x7b, 0xd1, 0xad, 0xc6, 0x9b, 0x50, 0xf1, 0x68, 0x5e, 0xa4, 0x3e, 0x6d, 0xc6, 0x41, 0xd2, - 0x7d, 0x80, 0xd4, 0xf7, 0x6d, 0x4a, 0x76, 0xb0, 0xc7, 0xbf, 0x70, 0x73, 0x85, 0x5f, 0x61, 0x73, - 0xbc, 0x09, 0x4d, 0xeb, 0x2a, 0xdd, 0x58, 0xeb, 0x79, 0x13, 0xba, 0x2c, 0x29, 0xbc, 0x13, 0x3c, - 0x02, 0xb5, 0xaa, 0x95, 0x84, 0x4b, 0x82, 0xce, 0xef, 0xc4, 0x2d, 0x81, 0x30, 0x10, 0x77, 0x80, - 0x4b, 0x1c, 0x30, 0x0a, 0xa2, 0x37, 0xf5, 0x27, 0xe2, 0x3b, 0x5c, 0x59, 0x7a, 0x53, 0xbf, 0xe5, - 0xd2, 0x5d, 0x49, 0x7a, 0x69, 0x78, 0x22, 0xbe, 0x40, 0x28, 0xbe, 0x6a, 0x80, 0xa8, 0x5b, 0xfc, - 0x4b, 0x65, 0xbe, 0x15, 0x04, 0xfc, 0x29, 0xc6, 0xb2, 0x78, 0x83, 0x53, 0x00, 0xe3, 0x97, 0x6e, - 0xc5, 0x47, 0xe4, 0x90, 0x04, 0xc4, 0x83, 0x90, 0xfc, 0x13, 0x72, 0x48, 0x70, 0x15, 0x4a, 0x3f, - 0xf1, 0x5c, 0x8b, 0xbc, 0x1c, 0x15, 0xaa, 0x55, 0x11, 0xd3, 0xfb, 0xc6, 0x1c, 0x37, 0x02, 0x87, - 0xae, 0x9b, 0xf3, 0x5b, 0x82, 0x3c, 0xa1, 0xfe, 0xeb, 0x0c, 0x5c, 0x5c, 0xee, 0x6b, 0x9a, 0x46, - 0x55, 0x28, 0xb5, 0x06, 0x3d, 0xbd, 0xdf, 0xdc, 0xef, 0x28, 0x1b, 0x6c, 0x0b, 0x2a, 0x83, 0xdd, - 0xcf, 0x3a, 0xad, 0x11, 0x07, 0x64, 0xe8, 0x0d, 0x87, 0xa1, 0xbe, 0xd7, 0x6d, 0xb7, 0x3b, 0x7d, - 0x6e, 0x51, 0x0c, 0x76, 0x3f, 0xd3, 0x7b, 0x83, 0x16, 0xff, 0xd8, 0x54, 0x14, 0xf1, 0x30, 0x54, - 0x72, 0x14, 0x0f, 0x41, 0xc1, 0xf0, 0x98, 0xcc, 0xf3, 0x28, 0xef, 0xa7, 0x43, 0xbd, 0xd5, 0x1f, - 0x29, 0x05, 0x4c, 0xf5, 0x0f, 0x7b, 0x3d, 0x4a, 0x51, 0x38, 0x67, 0x6b, 0xb0, 0x7f, 0xa0, 0x75, - 0x86, 0x43, 0x7d, 0xd8, 0xfd, 0x71, 0x47, 0x29, 0x51, 0xc9, 0x5a, 0xf7, 0x71, 0xb7, 0xcf, 0x01, - 0x65, 0x56, 0x84, 0xec, 0x7e, 0xb7, 0xcf, 0xdf, 0xae, 0xd8, 0x6f, 0x7e, 0xa1, 0x54, 0xf0, 0xc7, - 0xf0, 0x70, 0x5f, 0xa9, 0xb2, 0x32, 0xe4, 0x7b, 0x9d, 0x27, 0x9d, 0x9e, 0x52, 0x53, 0xff, 0x43, - 0x36, 0xd2, 0x88, 0x29, 0xce, 0xe9, 0x9b, 0x68, 0x81, 0xeb, 0xce, 0x17, 0xe3, 0x4e, 0xcb, 0x4a, - 0x9d, 0xf6, 0x4d, 0xbe, 0x68, 0x7c, 0x0b, 0x6a, 0x71, 0x70, 0x80, 0xf4, 0x0e, 0x7e, 0x35, 0x02, - 0xae, 0x39, 0xbe, 0x28, 0xac, 0x39, 0xbe, 0x98, 0xdb, 0x21, 0x5a, 0xd9, 0x28, 0x73, 0xf9, 0x4c, - 0x2a, 0x23, 0x84, 0x7f, 0x4b, 0xfc, 0x15, 0xa0, 0x84, 0xbe, 0x70, 0xed, 0xe8, 0x7b, 0x96, 0x25, - 0x04, 0x1c, 0xba, 0x76, 0xb8, 0x1c, 0x9c, 0x50, 0x5e, 0x09, 0x4e, 0x90, 0x37, 0x67, 0x48, 0x6f, - 0xce, 0xe9, 0x0f, 0x3d, 0xf3, 0x0f, 0x59, 0x4a, 0x1f, 0x7a, 0x7e, 0x1b, 0xd8, 0x64, 0xe1, 0xd3, - 0xab, 0x74, 0x12, 0x59, 0x95, 0xc8, 0x14, 0x81, 0x89, 0x77, 0x45, 0xf6, 0x06, 0x6c, 0x2d, 0x51, - 0x93, 0x2d, 0x5d, 0xd6, 0xea, 0x69, 0x52, 0x76, 0x1f, 0x2e, 0x88, 0xb9, 0x9d, 0xea, 0x5b, 0x71, - 0xf5, 0x94, 0xa3, 0x9a, 0x49, 0x0f, 0xab, 0xbf, 0x02, 0xa5, 0x28, 0xa4, 0xed, 0xc5, 0xca, 0xee, - 0x9a, 0x71, 0x55, 0xff, 0xc1, 0x26, 0x94, 0xe3, 0x00, 0xb7, 0x6f, 0x34, 0x3b, 0xe8, 0x83, 0x1f, - 0xc1, 0x89, 0x2c, 0x62, 0x4a, 0x08, 0x88, 0x46, 0x4a, 0xdc, 0xd6, 0x5a, 0xf8, 0x76, 0xa4, 0xb1, - 0x71, 0xc8, 0xa1, 0x6f, 0xd3, 0xd3, 0x33, 0xb6, 0x2b, 0x5d, 0x12, 0x2d, 0x6b, 0x25, 0x04, 0xd0, - 0x42, 0xbb, 0x0a, 0xf4, 0x9b, 0x38, 0xa3, 0x6f, 0x5f, 0xdb, 0xee, 0x09, 0xf2, 0x3d, 0xe7, 0xdb, - 0xd7, 0xf4, 0xb9, 0x12, 0x1e, 0x5d, 0xc3, 0x63, 0x0a, 0xa2, 0x0f, 0xf4, 0xbd, 0x02, 0xe5, 0x45, - 0xfc, 0x85, 0x47, 0x31, 0x23, 0x16, 0xd1, 0xf7, 0x1d, 0xd3, 0xa3, 0x5a, 0x5e, 0x1e, 0xd5, 0xe5, - 0x39, 0x0d, 0x2b, 0x73, 0x5a, 0x0d, 0xa1, 0x28, 0x82, 0xfc, 0x5e, 0xdc, 0xe1, 0x2f, 0xec, 0x2a, - 0x05, 0xb2, 0x86, 0x13, 0xdd, 0x4c, 0xc5, 0x9f, 0x4b, 0x15, 0xcb, 0x2d, 0x55, 0x4c, 0xfd, 0x5b, - 0x9b, 0x00, 0x49, 0xb0, 0x20, 0x7b, 0x67, 0x29, 0x30, 0x39, 0xb3, 0xb2, 0xed, 0x2f, 0xc5, 0x23, - 0x2f, 0xbd, 0xc5, 0xb4, 0xf9, 0x0d, 0xde, 0x62, 0x7a, 0x00, 0xb5, 0xc0, 0x9f, 0xbc, 0xd4, 0xe1, - 0x5e, 0x09, 0xfc, 0x49, 0xec, 0x6f, 0x7f, 0x17, 0x30, 0x49, 0xef, 0x34, 0x26, 0x86, 0xea, 0x8a, - 0xd6, 0x52, 0x0e, 0xfc, 0xc9, 0x60, 0xfc, 0x55, 0x9b, 0x5f, 0x91, 0x33, 0x83, 0x50, 0x5f, 0x27, - 0x25, 0xb6, 0xcc, 0x20, 0x6c, 0xcb, 0x82, 0xe2, 0x36, 0xd4, 0x91, 0x76, 0x45, 0x58, 0x54, 0xcd, - 0x20, 0x39, 0x60, 0x51, 0x7f, 0x27, 0x3a, 0x92, 0x5e, 0xf2, 0xe5, 0xb2, 0x8f, 0x84, 0x21, 0x2e, - 0x29, 0x11, 0x8d, 0x75, 0xae, 0x5f, 0xfe, 0x72, 0x54, 0x4c, 0xba, 0xfa, 0x5d, 0xbf, 0xcd, 0x6f, - 0xfa, 0x5d, 0xbf, 0x1d, 0x80, 0xe4, 0xa5, 0x4c, 0x5c, 0x81, 0xf1, 0x65, 0x9d, 0x32, 0xbf, 0x86, - 0x73, 0xef, 0x35, 0xa8, 0xca, 0x1f, 0x02, 0xa6, 0x4b, 0x38, 0x9e, 0x6b, 0xf1, 0x6f, 0xa7, 0xf4, - 0x7e, 0xf2, 0x81, 0x92, 0xb9, 0xa7, 0x42, 0x45, 0xfa, 0x72, 0x11, 0x52, 0xec, 0x19, 0xc1, 0xb1, - 0xf8, 0x8e, 0x86, 0xe1, 0x1e, 0x59, 0x4a, 0xe6, 0xde, 0x1d, 0x54, 0xba, 0xe5, 0xef, 0x06, 0x01, - 0x14, 0xfa, 0x9e, 0x3f, 0x33, 0x1c, 0x41, 0x67, 0x2d, 0x02, 0xa4, 0x7b, 0x17, 0x2e, 0xad, 0xfd, - 0x0a, 0x12, 0x5d, 0xe1, 0xb2, 0x67, 0x73, 0xc7, 0xe2, 0x97, 0x91, 0xf6, 0xce, 0xc7, 0xbe, 0x6d, - 0x2a, 0x99, 0x7b, 0x9f, 0x2c, 0x7d, 0x25, 0xe3, 0xb0, 0xbf, 0x3b, 0x38, 0xec, 0xb7, 0x3b, 0x6d, - 0x7e, 0x4d, 0xa8, 0xdb, 0x6f, 0xf5, 0x0e, 0x87, 0xdd, 0x27, 0x62, 0x2f, 0xec, 0x7c, 0x11, 0x25, - 0x37, 0xef, 0xed, 0x45, 0xaf, 0x31, 0x44, 0xb5, 0xee, 0x0d, 0x9a, 0x6d, 0xbe, 0x87, 0xc6, 0xef, - 0x31, 0x8d, 0x76, 0xf9, 0xd7, 0x35, 0xb4, 0xce, 0xf0, 0xb0, 0x37, 0x8a, 0xde, 0x7e, 0xaa, 0x03, - 0x74, 0x5b, 0x9d, 0xdd, 0x8e, 0xf6, 0x18, 0x09, 0xb2, 0xf7, 0x7e, 0x08, 0x8d, 0xe7, 0xdd, 0xef, - 0xc1, 0xb6, 0xb5, 0xf6, 0x9a, 0x74, 0x87, 0x0a, 0xf7, 0xd0, 0x81, 0xce, 0x53, 0xe4, 0xe9, 0xd3, - 0x3a, 0xbd, 0x0e, 0x05, 0xc1, 0xde, 0xfb, 0x69, 0x46, 0xd2, 0x27, 0xa3, 0x3b, 0x1a, 0x31, 0x40, - 0x74, 0xb8, 0x0c, 0xd2, 0x2c, 0xc3, 0x54, 0x32, 0xec, 0x32, 0xb0, 0x14, 0xa8, 0xe7, 0x4d, 0x0c, - 0x47, 0xd9, 0xa4, 0x70, 0xd7, 0x08, 0x4e, 0x77, 0xf9, 0x94, 0x2c, 0x7b, 0x15, 0xae, 0xc6, 0xb0, - 0x9e, 0x77, 0x7a, 0xe0, 0xdb, 0x9e, 0x6f, 0x87, 0xe7, 0x1c, 0x9d, 0xbb, 0xf7, 0x7f, 0x8b, 0xc3, - 0xda, 0xd4, 0x2c, 0xc3, 0x02, 0x9a, 0xa6, 0x99, 0xc0, 0x48, 0xb0, 0x29, 0x1b, 0xec, 0x0a, 0x5c, - 0x20, 0xa9, 0xbe, 0x84, 0xc8, 0xb0, 0x57, 0xe0, 0x4a, 0x64, 0xf4, 0x2e, 0x23, 0x37, 0x11, 0xa9, - 0x59, 0x14, 0x2a, 0xb9, 0x82, 0xcc, 0xee, 0xfe, 0xe0, 0x4f, 0x7e, 0x7e, 0x23, 0xf3, 0x67, 0x3f, - 0xbf, 0x91, 0xf9, 0x8f, 0x3f, 0xbf, 0xb1, 0xf1, 0x07, 0xff, 0xf9, 0x46, 0xe6, 0xc7, 0xef, 0x1c, - 0xd9, 0xe1, 0xf1, 0x62, 0x7c, 0x7f, 0xe2, 0xcd, 0xde, 0x9d, 0x19, 0xa1, 0x6f, 0x9f, 0xf1, 0xed, - 0x25, 0x4a, 0xb8, 0xd6, 0xbb, 0xf3, 0x93, 0xa3, 0x77, 0xe7, 0xe3, 0x77, 0x71, 0xa2, 0x8f, 0x0b, - 0x73, 0xdf, 0x0b, 0xbd, 0x87, 0xff, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xf7, 0x55, 0x1d, 0xeb, 0xdc, - 0x89, 0x00, 0x00, + // 13998 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0xbd, 0x5b, 0x8c, 0x1c, 0xc7, + 0x96, 0x20, 0xd6, 0xd5, 0xf5, 0x3e, 0xf5, 0xe8, 0xec, 0x60, 0x93, 0x2c, 0x3e, 0x44, 0x36, 0x93, + 0x14, 0x45, 0x51, 0x12, 0x25, 0x91, 0x7a, 0x50, 0x9a, 0x3b, 0xa3, 0x5b, 0x5d, 0x55, 0x64, 0x97, + 0x54, 0x5d, 0xd5, 0x37, 0xab, 0x9a, 0x94, 0xee, 0x78, 0x90, 0xc8, 0xae, 0xcc, 0xea, 0x4e, 0x75, + 0x56, 0x66, 0x29, 0x33, 0x8b, 0xdd, 0x7d, 0x81, 0x81, 0x2f, 0xfc, 0x31, 0x0f, 0xc3, 0x1f, 0x06, + 0x0c, 0x8f, 0xbf, 0x06, 0x1e, 0x1b, 0x30, 0x0c, 0x18, 0x36, 0x0c, 0x1b, 0x17, 0x18, 0xcf, 0x8f, + 0xe1, 0x81, 0x7f, 0xc6, 0xb0, 0x67, 0xbc, 0xd8, 0xc5, 0xee, 0x62, 0x76, 0x81, 0xd9, 0xdd, 0xbb, + 0xdf, 0x83, 0x5d, 0x60, 0xf7, 0x6f, 0x3f, 0x76, 0x71, 0x4e, 0x44, 0x66, 0x46, 0x56, 0x15, 0x45, + 0x49, 0xf7, 0x0e, 0xb0, 0x3f, 0xdd, 0x15, 0xe7, 0x11, 0xef, 0x38, 0x71, 0xce, 0x89, 0x13, 0x91, + 0x00, 0x33, 0xc7, 0x70, 0x1f, 0xcc, 0x7c, 0x2f, 0xf4, 0x58, 0x0e, 0x7f, 0x5f, 0x7d, 0xe7, 0xc8, + 0x0e, 0x8f, 0xe7, 0x87, 0x0f, 0xc6, 0xde, 0xf4, 0xdd, 0x23, 0xef, 0xc8, 0x7b, 0x97, 0x90, 0x87, + 0xf3, 0x09, 0xa5, 0x28, 0x41, 0xbf, 0x38, 0xd3, 0x55, 0x70, 0xbc, 0xf1, 0x89, 0xf8, 0xbd, 0x11, + 0xda, 0x53, 0x2b, 0x08, 0x8d, 0xe9, 0x8c, 0x03, 0xd4, 0x3f, 0xcd, 0x40, 0x6e, 0x74, 0x3e, 0xb3, + 0x58, 0x1d, 0xd6, 0x6d, 0xb3, 0x91, 0xd9, 0xce, 0xdc, 0xcb, 0x6b, 0xeb, 0xb6, 0xc9, 0xb6, 0xa1, + 0xe2, 0x7a, 0x61, 0x7f, 0xee, 0x38, 0xc6, 0xa1, 0x63, 0x35, 0xd6, 0xb7, 0x33, 0xf7, 0x4a, 0x9a, + 0x0c, 0x62, 0xd7, 0xa0, 0x6c, 0xcc, 0x43, 0x4f, 0xb7, 0xdd, 0xb1, 0xdf, 0xc8, 0x12, 0xbe, 0x84, + 0x80, 0xae, 0x3b, 0xf6, 0xd9, 0x16, 0xe4, 0x4f, 0x6d, 0x33, 0x3c, 0x6e, 0xe4, 0x28, 0x47, 0x9e, + 0x40, 0x68, 0x30, 0x36, 0x1c, 0xab, 0x91, 0xe7, 0x50, 0x4a, 0x20, 0x34, 0xa4, 0x42, 0x0a, 0xdb, + 0x99, 0x7b, 0x65, 0x8d, 0x27, 0xd8, 0x0d, 0x00, 0xcb, 0x9d, 0x4f, 0x5f, 0x18, 0xce, 0xdc, 0x0a, + 0x1a, 0x45, 0x42, 0x49, 0x10, 0xf5, 0x33, 0x28, 0x4f, 0x83, 0xa3, 0x5d, 0xcb, 0x30, 0x2d, 0x9f, + 0x5d, 0x86, 0xe2, 0x34, 0x38, 0xd2, 0x43, 0xe3, 0x48, 0x34, 0xa1, 0x30, 0x0d, 0x8e, 0x46, 0xc6, + 0x11, 0xbb, 0x02, 0x25, 0x42, 0x9c, 0xcf, 0x78, 0x1b, 0xf2, 0x1a, 0x12, 0x62, 0x8b, 0xd5, 0x3f, + 0x2c, 0x40, 0xb1, 0x67, 0x87, 0x96, 0x6f, 0x38, 0xec, 0x12, 0x14, 0xec, 0xc0, 0x9d, 0x3b, 0x0e, + 0xb1, 0x97, 0x34, 0x91, 0x62, 0x97, 0x20, 0x6f, 0x3f, 0x7e, 0x61, 0x38, 0x9c, 0x77, 0x77, 0x4d, + 0xe3, 0x49, 0xd6, 0x80, 0x82, 0xfd, 0xfe, 0x47, 0x88, 0xc8, 0x0a, 0x84, 0x48, 0x13, 0xe6, 0xd1, + 0x43, 0xc4, 0xe4, 0x62, 0x0c, 0xa5, 0x09, 0xf3, 0xd1, 0x07, 0x88, 0xc1, 0xd6, 0x67, 0x09, 0x43, + 0x69, 0x2c, 0x65, 0x4e, 0xa5, 0x60, 0x07, 0xd4, 0xb0, 0x94, 0x79, 0x54, 0xca, 0x9c, 0x97, 0x52, + 0x14, 0x08, 0x91, 0x26, 0x0c, 0x2f, 0xa5, 0x14, 0x63, 0xe2, 0x52, 0xe6, 0xbc, 0x94, 0xf2, 0x76, + 0xe6, 0x5e, 0x8e, 0x30, 0xbc, 0x94, 0x2d, 0xc8, 0x99, 0x08, 0x87, 0xed, 0xcc, 0xbd, 0xcc, 0xee, + 0x9a, 0x46, 0x29, 0x84, 0x06, 0x08, 0xad, 0x60, 0x07, 0x23, 0x34, 0x10, 0xd0, 0x43, 0x84, 0x56, + 0xb1, 0x37, 0x10, 0x7a, 0x28, 0xa0, 0x13, 0x84, 0xd6, 0xb6, 0x33, 0xf7, 0xd6, 0x11, 0x8a, 0x29, + 0x76, 0x15, 0x8a, 0xa6, 0x11, 0x5a, 0x88, 0xa8, 0x8b, 0x26, 0x47, 0x00, 0xc4, 0xe1, 0x8c, 0x43, + 0xdc, 0x86, 0x68, 0x74, 0x04, 0x60, 0x2a, 0x54, 0x90, 0x2c, 0xc2, 0x2b, 0x02, 0x2f, 0x03, 0xd9, + 0x87, 0x50, 0x35, 0xad, 0xb1, 0x3d, 0x35, 0x1c, 0xde, 0xa6, 0xcd, 0xed, 0xcc, 0xbd, 0xca, 0xc3, + 0x8d, 0x07, 0xb4, 0x26, 0x62, 0xcc, 0xee, 0x9a, 0x96, 0x22, 0x63, 0x8f, 0xa1, 0x26, 0xd2, 0xef, + 0x3f, 0xa4, 0x8e, 0x65, 0xc4, 0xa7, 0xa4, 0xf8, 0xde, 0x7f, 0xf8, 0x78, 0x77, 0x4d, 0x4b, 0x13, + 0xb2, 0x3b, 0x50, 0x8d, 0x97, 0x08, 0x32, 0x5e, 0x10, 0xb5, 0x4a, 0x41, 0xb1, 0x59, 0x5f, 0x07, + 0x9e, 0x8b, 0x04, 0x5b, 0xa2, 0xdf, 0x22, 0x00, 0xdb, 0x06, 0x30, 0xad, 0x89, 0x31, 0x77, 0x42, + 0x44, 0x5f, 0x14, 0x1d, 0x28, 0xc1, 0xd8, 0x0d, 0x28, 0xcf, 0x67, 0xd8, 0xca, 0x67, 0x86, 0xd3, + 0xb8, 0x24, 0x08, 0x12, 0x10, 0xe6, 0x8e, 0xf3, 0x1c, 0xb1, 0x97, 0xc5, 0xe8, 0x46, 0x00, 0x1c, + 0xde, 0x17, 0xd6, 0x18, 0x51, 0x0d, 0x51, 0xb0, 0x48, 0xe3, 0x2a, 0xb2, 0x83, 0x1d, 0xdb, 0x6d, + 0x5c, 0xa1, 0x19, 0xcc, 0x13, 0xec, 0x3a, 0x64, 0x03, 0x7f, 0xdc, 0xb8, 0x4a, 0xed, 0x07, 0xde, + 0xfe, 0xce, 0xd9, 0xcc, 0xd7, 0x10, 0xbc, 0x53, 0x84, 0x3c, 0xad, 0x26, 0xf5, 0x3a, 0x94, 0xf6, + 0x0d, 0xdf, 0x98, 0x6a, 0xd6, 0x84, 0x29, 0x90, 0x9d, 0x79, 0x81, 0x58, 0x47, 0xf8, 0x53, 0xed, + 0x41, 0xe1, 0x99, 0xe1, 0x23, 0x8e, 0x41, 0xce, 0x35, 0xa6, 0x16, 0x21, 0xcb, 0x1a, 0xfd, 0xc6, + 0xb5, 0x13, 0x9c, 0x07, 0xa1, 0x35, 0x15, 0x42, 0x42, 0xa4, 0x10, 0x7e, 0xe4, 0x78, 0x87, 0x62, + 0x8d, 0x94, 0x34, 0x91, 0x52, 0xff, 0xb3, 0x0c, 0x14, 0x5a, 0x9e, 0x83, 0xd9, 0x5d, 0x86, 0xa2, + 0x6f, 0x39, 0x7a, 0x52, 0x5c, 0xc1, 0xb7, 0x9c, 0x7d, 0x2f, 0x40, 0xc4, 0xd8, 0xe3, 0x08, 0xbe, + 0x6a, 0x0b, 0x63, 0x8f, 0x10, 0x51, 0x05, 0xb2, 0x52, 0x05, 0xae, 0x40, 0x29, 0x3c, 0x74, 0x74, + 0x82, 0xe7, 0x08, 0x5e, 0x0c, 0x0f, 0x9d, 0x3e, 0xa2, 0x2e, 0x43, 0xd1, 0x3c, 0xe4, 0x98, 0x3c, + 0x61, 0x0a, 0xe6, 0x21, 0x22, 0xd4, 0x4f, 0xa0, 0xac, 0x19, 0xa7, 0xa2, 0x1a, 0x17, 0xa1, 0x80, + 0x19, 0x08, 0xf9, 0x97, 0xd3, 0xf2, 0xe1, 0xa1, 0xd3, 0x35, 0x11, 0x8c, 0x95, 0xb0, 0x4d, 0xaa, + 0x43, 0x4e, 0xcb, 0x8f, 0x3d, 0xa7, 0x6b, 0xaa, 0x23, 0x80, 0x96, 0xe7, 0xfb, 0x3f, 0xb8, 0x09, + 0x5b, 0x90, 0x37, 0xad, 0x59, 0x78, 0xcc, 0x45, 0x87, 0xc6, 0x13, 0xea, 0x7d, 0x28, 0xe1, 0xb8, + 0xf4, 0xec, 0x20, 0x64, 0x37, 0x20, 0xe7, 0xd8, 0x41, 0xd8, 0xc8, 0x6c, 0x67, 0x17, 0x46, 0x8d, + 0xe0, 0xea, 0x36, 0x94, 0xf6, 0x8c, 0xb3, 0x67, 0x38, 0x72, 0x98, 0x1b, 0x0d, 0xa1, 0x18, 0x12, + 0x31, 0x9e, 0x55, 0x80, 0x91, 0xe1, 0x1f, 0x59, 0x21, 0x49, 0xba, 0x7f, 0x93, 0x81, 0xca, 0x70, + 0x7e, 0xf8, 0xcd, 0xdc, 0xf2, 0xcf, 0xb1, 0xce, 0xf7, 0x20, 0x1b, 0x9e, 0xcf, 0x88, 0xa3, 0xfe, + 0xf0, 0x12, 0xcf, 0x5e, 0xc2, 0x3f, 0x40, 0x26, 0x0d, 0x49, 0xb0, 0x11, 0xae, 0x67, 0x5a, 0x51, + 0x1f, 0xe4, 0xb5, 0x02, 0x26, 0xbb, 0x26, 0x6e, 0x17, 0xde, 0x4c, 0x8c, 0xc2, 0xba, 0x37, 0x63, + 0xdb, 0x90, 0x1f, 0x1f, 0xdb, 0x8e, 0x49, 0x03, 0x90, 0xae, 0x33, 0x47, 0xe0, 0x28, 0xf9, 0xde, + 0xa9, 0x1e, 0xd8, 0x3f, 0x8b, 0xc4, 0x7f, 0xd1, 0xf7, 0x4e, 0x87, 0xf6, 0xcf, 0x2c, 0x75, 0x24, + 0xf6, 0x20, 0x80, 0xc2, 0xb0, 0xd5, 0xec, 0x35, 0x35, 0x65, 0x0d, 0x7f, 0x77, 0xbe, 0xec, 0x0e, + 0x47, 0x43, 0x25, 0xc3, 0xea, 0x00, 0xfd, 0xc1, 0x48, 0x17, 0xe9, 0x75, 0x56, 0x80, 0xf5, 0x6e, + 0x5f, 0xc9, 0x22, 0x0d, 0xc2, 0xbb, 0x7d, 0x25, 0xc7, 0x8a, 0x90, 0x6d, 0xf6, 0xbf, 0x52, 0xf2, + 0xf4, 0xa3, 0xd7, 0x53, 0x0a, 0xea, 0x5f, 0xad, 0x43, 0x79, 0x70, 0xf8, 0xb5, 0x35, 0x0e, 0xb1, + 0xcd, 0x38, 0x4b, 0x2d, 0xff, 0x85, 0xe5, 0x53, 0xb3, 0xb3, 0x9a, 0x48, 0x61, 0x43, 0xcc, 0x43, + 0x6a, 0x5c, 0x56, 0x5b, 0x37, 0x0f, 0x89, 0x6e, 0x7c, 0x6c, 0x4d, 0x0d, 0x6a, 0x1c, 0xd2, 0x51, + 0x0a, 0x57, 0x85, 0x77, 0xf8, 0x35, 0x35, 0x2f, 0xab, 0xe1, 0x4f, 0x76, 0x13, 0x2a, 0x3c, 0x0f, + 0x79, 0x7e, 0x01, 0x07, 0x2d, 0x4e, 0xbe, 0x82, 0x3c, 0xf9, 0x88, 0x93, 0x72, 0xe5, 0x48, 0xb1, + 0xb7, 0x71, 0x50, 0x5f, 0xcc, 0x68, 0xef, 0xf0, 0x6b, 0x8e, 0x2d, 0xf1, 0x19, 0xed, 0x1d, 0x7e, + 0x4d, 0xa8, 0xb7, 0x60, 0x33, 0x98, 0x1f, 0x06, 0x63, 0xdf, 0x9e, 0x85, 0xb6, 0xe7, 0x72, 0x9a, + 0x32, 0xd1, 0x28, 0x32, 0x82, 0x88, 0xef, 0x41, 0x69, 0x36, 0x3f, 0xd4, 0x6d, 0x77, 0xe2, 0x91, + 0xd8, 0xaf, 0x3c, 0xac, 0xf1, 0x81, 0xd9, 0x9f, 0x1f, 0x76, 0xdd, 0x89, 0xa7, 0x15, 0x67, 0xfc, + 0x07, 0x53, 0xa1, 0xe6, 0x7a, 0xa1, 0x8e, 0xaa, 0x82, 0x3e, 0xb5, 0x42, 0x83, 0xf6, 0x03, 0xbe, + 0xe1, 0xf7, 0xbc, 0xf1, 0xc9, 0x9e, 0x15, 0x1a, 0xea, 0x5d, 0x28, 0x0a, 0x3e, 0xdc, 0xfb, 0x43, + 0xcb, 0x35, 0xdc, 0x50, 0x8f, 0x95, 0x86, 0x12, 0x07, 0x74, 0x4d, 0xf5, 0x17, 0x19, 0x50, 0x86, + 0x52, 0x55, 0x90, 0x79, 0xa5, 0xe4, 0x78, 0x0d, 0xc0, 0x18, 0x8f, 0xbd, 0x39, 0xcf, 0x86, 0x4f, + 0xb0, 0xb2, 0x80, 0x74, 0x4d, 0xb9, 0xff, 0xb2, 0xa9, 0xfe, 0xbb, 0x05, 0xd5, 0x88, 0x4f, 0x5a, + 0xf4, 0x15, 0x01, 0x8b, 0x7a, 0x30, 0x98, 0xa7, 0x56, 0x7e, 0x31, 0x98, 0x73, 0xee, 0x4b, 0x50, + 0x20, 0x0d, 0x23, 0x88, 0x46, 0x85, 0xa7, 0xd4, 0x7f, 0x9c, 0x81, 0x5a, 0xd7, 0x35, 0xad, 0xb3, + 0xe1, 0xd8, 0x70, 0xa3, 0x4e, 0xb1, 0x03, 0xdd, 0x46, 0x98, 0x1e, 0x8c, 0x0d, 0x57, 0x28, 0x07, + 0x15, 0x3b, 0x88, 0xe9, 0xb0, 0x0d, 0x9c, 0x80, 0x8a, 0x5a, 0xa7, 0x1c, 0xcb, 0x04, 0xa1, 0xc2, + 0xee, 0xc2, 0xc6, 0xa1, 0xe5, 0x78, 0xee, 0x91, 0x1e, 0x7a, 0x3a, 0xd7, 0x72, 0x78, 0x5b, 0x6a, + 0x1c, 0x3c, 0xf2, 0x46, 0xa4, 0xed, 0x6c, 0x41, 0x7e, 0x66, 0xf8, 0x61, 0xd0, 0xc8, 0x6d, 0x67, + 0x71, 0x19, 0x53, 0x02, 0xbb, 0xd9, 0x0e, 0xf4, 0xb9, 0x6b, 0x7f, 0x33, 0xe7, 0xcd, 0x28, 0x69, + 0x25, 0x3b, 0x38, 0xa0, 0x34, 0xbb, 0x07, 0x0a, 0x2f, 0x99, 0xb2, 0x95, 0xe7, 0x59, 0x9d, 0xe0, + 0x94, 0x31, 0x09, 0xbb, 0xff, 0x7c, 0x1d, 0x4a, 0x4f, 0xe6, 0xee, 0x18, 0x07, 0x83, 0xdd, 0x86, + 0xdc, 0x64, 0xee, 0x8e, 0xa9, 0x2d, 0xf1, 0x56, 0x1a, 0xaf, 0x13, 0x8d, 0x90, 0x28, 0x81, 0x0c, + 0xff, 0x08, 0x25, 0xd7, 0x92, 0x04, 0x42, 0xb8, 0xfa, 0x7f, 0x64, 0x78, 0x8e, 0x4f, 0x1c, 0xe3, + 0x88, 0x95, 0x20, 0xd7, 0x1f, 0xf4, 0x3b, 0xca, 0x1a, 0xab, 0x42, 0xa9, 0xdb, 0x1f, 0x75, 0xb4, + 0x7e, 0xb3, 0xa7, 0x64, 0x68, 0x39, 0x8f, 0x9a, 0x3b, 0xbd, 0x8e, 0xb2, 0x8e, 0x98, 0x67, 0x83, + 0x5e, 0x73, 0xd4, 0xed, 0x75, 0x94, 0x1c, 0xc7, 0x68, 0xdd, 0xd6, 0x48, 0x29, 0x31, 0x05, 0xaa, + 0xfb, 0xda, 0xa0, 0x7d, 0xd0, 0xea, 0xe8, 0xfd, 0x83, 0x5e, 0x4f, 0x51, 0xd8, 0x05, 0xd8, 0x88, + 0x21, 0x03, 0x0e, 0xdc, 0x46, 0x96, 0x67, 0x4d, 0xad, 0xa9, 0x3d, 0x55, 0x7e, 0xcc, 0x4a, 0x90, + 0x6d, 0x3e, 0x7d, 0xaa, 0xfc, 0x1c, 0x25, 0x43, 0xf9, 0x79, 0xb7, 0xaf, 0x3f, 0x6b, 0xf6, 0x0e, + 0x3a, 0xca, 0xcf, 0xd7, 0xa3, 0xf4, 0x40, 0x6b, 0x77, 0x34, 0xe5, 0xe7, 0x39, 0xb6, 0x09, 0xd5, + 0x9f, 0x0e, 0xfa, 0x9d, 0xbd, 0xe6, 0xfe, 0x3e, 0x55, 0xe4, 0xe7, 0x25, 0xf5, 0x6f, 0x73, 0x90, + 0xc3, 0x96, 0x30, 0x35, 0x91, 0x82, 0x71, 0x13, 0x51, 0x0c, 0xed, 0xe4, 0xfe, 0xe2, 0x6f, 0x6e, + 0xae, 0x71, 0xf9, 0x77, 0x0b, 0xb2, 0x8e, 0x1d, 0xd2, 0xb0, 0xc6, 0x6b, 0x47, 0xe8, 0x8c, 0xbb, + 0x6b, 0x1a, 0xe2, 0xd8, 0x0d, 0xc8, 0x70, 0x41, 0x58, 0x79, 0x58, 0x17, 0x8b, 0x4b, 0xec, 0xa4, + 0xbb, 0x6b, 0x5a, 0x66, 0xc6, 0xae, 0x43, 0xe6, 0x85, 0x90, 0x8a, 0x55, 0x8e, 0xe7, 0x7b, 0x29, + 0x62, 0x5f, 0xb0, 0x6d, 0xc8, 0x8e, 0x3d, 0xae, 0x11, 0xc6, 0x78, 0xbe, 0xb3, 0x60, 0xfe, 0x63, + 0xcf, 0x61, 0xb7, 0x21, 0xeb, 0x1b, 0xa7, 0x34, 0xb2, 0xf1, 0x70, 0xc5, 0x5b, 0x17, 0x12, 0xf9, + 0xc6, 0x29, 0x56, 0x62, 0x42, 0x72, 0x24, 0xae, 0x44, 0x34, 0xde, 0x58, 0xcc, 0x84, 0x6d, 0x43, + 0xe6, 0x94, 0x24, 0x49, 0xac, 0x04, 0x3d, 0xb7, 0x5d, 0xd3, 0x3b, 0x1d, 0xce, 0xac, 0x31, 0x52, + 0x9c, 0xb2, 0xd7, 0x21, 0x1b, 0xcc, 0x0f, 0x49, 0x92, 0x54, 0x1e, 0x6e, 0x2e, 0xed, 0x09, 0x58, + 0x50, 0x30, 0x3f, 0x64, 0x77, 0x21, 0x37, 0xf6, 0x7c, 0x5f, 0x48, 0x13, 0x25, 0xaa, 0x70, 0xb4, + 0x1d, 0xa2, 0x52, 0x88, 0x78, 0x2c, 0x30, 0x24, 0x19, 0x12, 0x13, 0x25, 0xfb, 0x11, 0x16, 0x18, + 0xb2, 0x3b, 0x62, 0x93, 0xab, 0xca, 0xb5, 0x8e, 0xb6, 0x40, 0xcc, 0x07, 0xb1, 0x38, 0x48, 0x53, + 0xe3, 0x8c, 0x34, 0xce, 0x98, 0x28, 0xda, 0xfb, 0xb0, 0x4e, 0x53, 0xe3, 0x8c, 0xdd, 0x81, 0xec, + 0x0b, 0x6b, 0x4c, 0xca, 0x67, 0x5c, 0x9a, 0x18, 0xa4, 0x67, 0xd4, 0x3c, 0x44, 0xd3, 0xbc, 0xf7, + 0x1c, 0x93, 0xf4, 0xd0, 0x78, 0x2c, 0x9f, 0x78, 0x8e, 0xf9, 0x8c, 0xc6, 0x92, 0x90, 0xb8, 0xe5, + 0x1b, 0xf3, 0x33, 0x94, 0x46, 0x0a, 0xdf, 0x9c, 0x8d, 0xf9, 0x59, 0xd7, 0x44, 0xe1, 0xef, 0x9a, + 0x2f, 0x48, 0xfb, 0xcc, 0x68, 0xf8, 0x13, 0xcd, 0xa3, 0xc0, 0x72, 0xac, 0x71, 0x68, 0xbf, 0xb0, + 0xc3, 0x73, 0xd2, 0x2f, 0x33, 0x9a, 0x0c, 0xda, 0x29, 0x40, 0xce, 0x3a, 0x9b, 0xf9, 0xea, 0x2e, + 0x14, 0x45, 0x29, 0x4b, 0x36, 0xd6, 0x15, 0x28, 0xd9, 0x81, 0x3e, 0xf6, 0xdc, 0x20, 0x14, 0xba, + 0x53, 0xd1, 0x0e, 0x5a, 0x98, 0x44, 0x71, 0x69, 0x1a, 0x21, 0xdf, 0x84, 0xaa, 0x1a, 0xfd, 0x56, + 0x1f, 0x02, 0x24, 0xcd, 0xc2, 0x3a, 0x39, 0x96, 0x1b, 0xa9, 0x69, 0x8e, 0xe5, 0xc6, 0x3c, 0xeb, + 0x12, 0xcf, 0x15, 0x28, 0xc7, 0x9a, 0x31, 0xab, 0x42, 0xc6, 0x10, 0xdb, 0x5f, 0xc6, 0x50, 0xef, + 0xa1, 0xa2, 0x1a, 0xe9, 0xbe, 0x69, 0x1c, 0xa6, 0xa2, 0x4d, 0x31, 0x73, 0xa8, 0xfe, 0x08, 0xaa, + 0x9a, 0x15, 0xcc, 0x9d, 0xb0, 0xe5, 0x39, 0x6d, 0x6b, 0xc2, 0xde, 0x06, 0x88, 0xd3, 0x81, 0xd0, + 0x52, 0x92, 0xb9, 0xdb, 0xb6, 0x26, 0x9a, 0x84, 0x57, 0xff, 0x45, 0x8e, 0xf4, 0xbd, 0x36, 0x57, + 0xb4, 0x84, 0x46, 0x95, 0x91, 0x34, 0xaa, 0x78, 0x6f, 0x58, 0x4f, 0x6b, 0x95, 0xc7, 0xb6, 0x69, + 0x5a, 0x6e, 0xa4, 0x3d, 0xf2, 0x14, 0x0e, 0xb6, 0xe1, 0x1c, 0xd1, 0x82, 0xaa, 0x3f, 0x64, 0x51, + 0xa1, 0xd3, 0x99, 0x6f, 0x05, 0x01, 0xd7, 0x5b, 0x0c, 0xe7, 0x28, 0x5a, 0xdb, 0xf9, 0x6f, 0x5b, + 0xdb, 0x57, 0xa0, 0x84, 0x5b, 0x1e, 0x59, 0x7d, 0x05, 0xde, 0xfb, 0xc2, 0xbc, 0x65, 0x6f, 0x40, + 0x51, 0xe8, 0xeb, 0x62, 0x51, 0x89, 0xe9, 0xd2, 0xe6, 0x40, 0x2d, 0xc2, 0xb2, 0x06, 0x2a, 0x79, + 0xd3, 0xa9, 0xe5, 0x86, 0xd1, 0x3e, 0x2d, 0x92, 0xec, 0x2d, 0x28, 0x7b, 0xae, 0xce, 0x95, 0x7a, + 0xb1, 0xaa, 0xc4, 0xf4, 0x1d, 0xb8, 0x07, 0x04, 0xd5, 0x4a, 0x9e, 0xf8, 0x85, 0x55, 0x71, 0xbc, + 0x53, 0x7d, 0x6c, 0xf8, 0x26, 0xad, 0xac, 0x92, 0x56, 0x74, 0xbc, 0xd3, 0x96, 0xe1, 0x9b, 0x5c, + 0x6f, 0xf9, 0xc6, 0x9d, 0x4f, 0x69, 0x35, 0xd5, 0x34, 0x91, 0x62, 0xd7, 0xa1, 0x3c, 0x76, 0xe6, + 0x41, 0x68, 0xf9, 0x3b, 0xe7, 0xdc, 0x4c, 0xd3, 0x12, 0x00, 0xd6, 0x6b, 0xe6, 0xdb, 0x53, 0xc3, + 0x3f, 0xa7, 0xa5, 0x53, 0xd2, 0xa2, 0x24, 0x6d, 0x34, 0x27, 0xb6, 0x79, 0xc6, 0x6d, 0x35, 0x8d, + 0x27, 0x90, 0xfe, 0x98, 0x2c, 0xe9, 0x80, 0xd6, 0x47, 0x49, 0x8b, 0x92, 0x34, 0x0e, 0xf4, 0x93, + 0x56, 0x44, 0x59, 0x13, 0xa9, 0x94, 0xd2, 0xbd, 0xf9, 0x52, 0xa5, 0x9b, 0x2d, 0xea, 0x3d, 0x9e, + 0x6f, 0x1f, 0xd9, 0x42, 0x6b, 0xb9, 0xc0, 0xf5, 0x1e, 0x0e, 0x22, 0x82, 0x8f, 0xa1, 0x76, 0x64, + 0xb9, 0x96, 0x6f, 0x84, 0x96, 0xa9, 0xa3, 0x5c, 0xdc, 0xa2, 0x8e, 0x13, 0xc3, 0xfc, 0x34, 0x42, + 0xa1, 0xac, 0xa9, 0x1e, 0x49, 0x29, 0xf5, 0x1b, 0x28, 0x8a, 0xb1, 0xc1, 0xad, 0x0b, 0xd7, 0x5d, + 0x5a, 0xae, 0xf3, 0xad, 0x0b, 0xe1, 0xec, 0x36, 0xd4, 0x44, 0x25, 0x82, 0xd0, 0xb7, 0xdd, 0x23, + 0x31, 0xeb, 0xaa, 0x1c, 0x38, 0x24, 0x18, 0x6a, 0x18, 0x38, 0x2f, 0x74, 0xe3, 0xd0, 0x76, 0x70, + 0x7d, 0x67, 0x85, 0x36, 0x34, 0x77, 0x9c, 0x26, 0x07, 0xa9, 0x03, 0x28, 0x45, 0x23, 0xf9, 0x6b, + 0x29, 0x53, 0x9d, 0x41, 0x55, 0x6e, 0xe1, 0xaf, 0xa7, 0x21, 0x5c, 0x83, 0x08, 0x42, 0xcf, 0xb7, + 0xcc, 0xc8, 0x49, 0x63, 0x07, 0x43, 0x4a, 0xab, 0xbf, 0x97, 0x81, 0x0a, 0x69, 0x32, 0x03, 0xd2, + 0xd3, 0xd8, 0xdb, 0xc0, 0xc6, 0xbe, 0x65, 0x84, 0x96, 0x6e, 0x9d, 0x85, 0xbe, 0x21, 0xf4, 0x15, + 0xae, 0xf4, 0x28, 0x1c, 0xd3, 0x41, 0x04, 0x57, 0x59, 0x6e, 0x42, 0x65, 0x66, 0xf8, 0x41, 0xa4, + 0xff, 0xf2, 0xd2, 0x81, 0x83, 0x84, 0xf6, 0xa9, 0xb8, 0x47, 0xbe, 0x31, 0xd5, 0x43, 0xef, 0xc4, + 0x72, 0xb9, 0xe6, 0xcf, 0x6d, 0x9e, 0x3a, 0xc1, 0x47, 0x08, 0x26, 0x03, 0xe0, 0x9f, 0x64, 0xa0, + 0xb6, 0xcf, 0x27, 0xe8, 0x17, 0xd6, 0x79, 0x9b, 0x1b, 0x9a, 0xe3, 0x48, 0xb8, 0xe4, 0x34, 0xfa, + 0xcd, 0x6e, 0x40, 0x65, 0x76, 0x62, 0x9d, 0xeb, 0x29, 0xa3, 0xac, 0x8c, 0xa0, 0x16, 0x89, 0x91, + 0x37, 0xa1, 0xe0, 0x51, 0x43, 0xc4, 0x76, 0x2c, 0x76, 0x31, 0xa9, 0x85, 0x9a, 0x20, 0x40, 0xcd, + 0x2e, 0xce, 0x4a, 0x56, 0x21, 0x45, 0x66, 0x54, 0xfd, 0x2d, 0xc8, 0x23, 0x2a, 0x68, 0xe4, 0xb9, + 0x4a, 0x46, 0x09, 0xf6, 0x1e, 0xd4, 0xc6, 0xde, 0x74, 0xa6, 0x47, 0xec, 0x62, 0x63, 0x4e, 0x8b, + 0xbf, 0x0a, 0x92, 0xec, 0xf3, 0xbc, 0xd4, 0x3f, 0xca, 0x42, 0x89, 0xea, 0x20, 0x24, 0xa0, 0x6d, + 0x9e, 0x45, 0x12, 0xb0, 0xac, 0xe5, 0x6d, 0x13, 0x37, 0x98, 0x57, 0x68, 0x91, 0xb1, 0x76, 0x98, + 0x95, 0xb5, 0xc3, 0x4b, 0x50, 0x10, 0xaa, 0x61, 0x8e, 0x8b, 0xc8, 0xf9, 0xcb, 0x15, 0xc3, 0xfc, + 0x2a, 0xc5, 0x10, 0x87, 0x90, 0xd3, 0x58, 0x67, 0xb8, 0x15, 0x73, 0x29, 0x08, 0x04, 0xea, 0x20, + 0x44, 0x96, 0x6f, 0xc5, 0xb4, 0x7c, 0x6b, 0x40, 0xf1, 0x85, 0x1d, 0xd8, 0x38, 0x41, 0x4a, 0x5c, + 0x62, 0x88, 0xa4, 0x34, 0x0c, 0xe5, 0x57, 0x0d, 0x43, 0xdc, 0x6c, 0xc3, 0x39, 0xe2, 0x16, 0x4a, + 0xd4, 0xec, 0xa6, 0x73, 0xe4, 0xb1, 0xf7, 0xe1, 0x62, 0x82, 0x16, 0xad, 0x21, 0x4f, 0x1e, 0x39, + 0xab, 0x34, 0x16, 0x53, 0x52, 0x8b, 0xc8, 0x84, 0xbc, 0x0f, 0x9b, 0x12, 0xcb, 0x0c, 0x35, 0xb1, + 0x80, 0xc4, 0x63, 0x59, 0xdb, 0x88, 0xc9, 0x49, 0x41, 0x0b, 0xd4, 0xff, 0x67, 0x1d, 0x6a, 0x4f, + 0x3c, 0xdf, 0xb2, 0x8f, 0xdc, 0x64, 0xd6, 0x2d, 0x19, 0x29, 0xd1, 0x4c, 0x5c, 0x97, 0x66, 0xe2, + 0x4d, 0xa8, 0x4c, 0x38, 0xa3, 0x1e, 0x1e, 0x72, 0xff, 0x46, 0x4e, 0x03, 0x01, 0x1a, 0x1d, 0x3a, + 0x28, 0x3f, 0x22, 0x02, 0x62, 0xce, 0x11, 0x73, 0xc4, 0x84, 0xdb, 0x22, 0xfb, 0x94, 0x36, 0x08, + 0xd3, 0x72, 0xac, 0x90, 0x0f, 0x4f, 0xfd, 0xe1, 0x6b, 0x91, 0x52, 0x22, 0xd5, 0xe9, 0x81, 0x66, + 0x4d, 0x9a, 0xa4, 0xc9, 0xe1, 0x7e, 0xd1, 0x26, 0x72, 0xc1, 0x2b, 0x36, 0x97, 0xc2, 0x77, 0xe4, + 0xe5, 0xb2, 0x4a, 0x1d, 0x41, 0x39, 0x06, 0xa3, 0x5a, 0xae, 0x75, 0x84, 0x2a, 0xbe, 0xc6, 0x2a, + 0x50, 0x6c, 0x35, 0x87, 0xad, 0x66, 0xbb, 0xa3, 0x64, 0x10, 0x35, 0xec, 0x8c, 0xb8, 0xfa, 0xbd, + 0xce, 0x36, 0xa0, 0x82, 0xa9, 0x76, 0xe7, 0x49, 0xf3, 0xa0, 0x37, 0x52, 0xb2, 0xac, 0x06, 0xe5, + 0xfe, 0x40, 0x6f, 0xb6, 0x46, 0xdd, 0x41, 0x5f, 0xc9, 0xa9, 0x3f, 0x86, 0x52, 0xeb, 0xd8, 0x1a, + 0x9f, 0xbc, 0xac, 0x17, 0xc9, 0x3f, 0x60, 0x8d, 0x4f, 0x84, 0x2a, 0xbd, 0xe0, 0x1f, 0xb0, 0xc6, + 0x27, 0x6a, 0x07, 0xca, 0xfb, 0x86, 0x1f, 0xda, 0x54, 0xaf, 0xc7, 0x50, 0x8b, 0x13, 0x6d, 0x6b, + 0x12, 0x29, 0x19, 0x2c, 0x56, 0xb0, 0x63, 0x94, 0x96, 0x26, 0x54, 0xdf, 0x86, 0xaa, 0x0c, 0x60, + 0xd7, 0x21, 0x6b, 0x5a, 0x93, 0x15, 0x42, 0x14, 0xc1, 0xea, 0x33, 0xa8, 0xb6, 0xa2, 0x4d, 0xf3, + 0x65, 0x55, 0x7f, 0x08, 0x75, 0x5a, 0xf1, 0xe3, 0xc3, 0x68, 0xc9, 0xaf, 0xaf, 0x58, 0xf2, 0x55, + 0xa4, 0x69, 0x1d, 0x8a, 0x35, 0xff, 0x21, 0x54, 0xf6, 0x7d, 0x6f, 0x66, 0xf9, 0x21, 0x65, 0xab, + 0x40, 0xf6, 0xc4, 0x3a, 0x17, 0xb9, 0xe2, 0xcf, 0xc4, 0x6d, 0xb3, 0x2e, 0xbb, 0x6d, 0x1e, 0x42, + 0x29, 0x62, 0xfb, 0xce, 0x3c, 0x9f, 0xa1, 0xe8, 0x24, 0x1e, 0xdb, 0x0a, 0xb0, 0xb0, 0x07, 0x00, + 0xb3, 0x18, 0x20, 0x3a, 0x2e, 0xb2, 0x4c, 0x44, 0xe6, 0x9a, 0x44, 0xa1, 0xbe, 0x06, 0xc5, 0x67, + 0xb6, 0x75, 0x2a, 0x9a, 0xff, 0xc2, 0xb6, 0x4e, 0xa3, 0xe6, 0xe3, 0x6f, 0xf5, 0xff, 0x2f, 0x43, + 0x89, 0xd6, 0x57, 0xfb, 0xe5, 0x9e, 0xb2, 0xef, 0xa3, 0xc0, 0x6d, 0x8b, 0xf5, 0x94, 0x5b, 0xa1, + 0x36, 0xf2, 0xd5, 0xf5, 0x1a, 0x80, 0xb4, 0xd6, 0xb9, 0xe4, 0x2a, 0x87, 0xf1, 0x12, 0x47, 0xcd, + 0x87, 0xf6, 0xa2, 0xe0, 0x1b, 0x47, 0x18, 0xbc, 0x09, 0x80, 0x3d, 0xe0, 0x7a, 0x09, 0x99, 0xb8, + 0x5c, 0x77, 0xbb, 0x10, 0xd9, 0x1f, 0x87, 0x8e, 0x15, 0x59, 0x45, 0xa4, 0xac, 0x60, 0x82, 0xe4, + 0x98, 0xe5, 0x07, 0x28, 0xae, 0xc8, 0x95, 0xae, 0x45, 0x49, 0xf6, 0x06, 0xe4, 0x50, 0xc8, 0x0b, + 0x2b, 0xe6, 0x42, 0xd4, 0x83, 0xd2, 0x2e, 0xa5, 0x11, 0x01, 0xbb, 0x07, 0x45, 0x12, 0x2d, 0x16, + 0x4a, 0x1a, 0xa9, 0xb7, 0x23, 0xa1, 0xaf, 0x45, 0x68, 0xf6, 0x26, 0xe4, 0x27, 0x27, 0xd6, 0x79, + 0xd0, 0xa8, 0x11, 0xdd, 0x85, 0x15, 0x6b, 0x56, 0xe3, 0x14, 0xec, 0x0e, 0xd4, 0x7d, 0x6b, 0xa2, + 0x93, 0xef, 0x0c, 0x85, 0x4c, 0xd0, 0xa8, 0x93, 0x0c, 0xa9, 0xfa, 0xd6, 0xa4, 0x85, 0xc0, 0xd1, + 0xa1, 0x13, 0xb0, 0xbb, 0x50, 0xa0, 0xd5, 0x83, 0x6a, 0x9b, 0x54, 0x72, 0xb4, 0x14, 0x35, 0x81, + 0x65, 0xef, 0x03, 0x08, 0xe5, 0x50, 0x3f, 0x3c, 0x27, 0x9f, 0x73, 0xbc, 0x98, 0xe4, 0xf9, 0x2f, + 0xab, 0x90, 0x6f, 0x40, 0x1e, 0x27, 0x49, 0xd0, 0xb8, 0x4c, 0x39, 0x6f, 0xa6, 0x67, 0x10, 0xd5, + 0x94, 0xf0, 0xec, 0x1e, 0x94, 0x70, 0xa2, 0xe8, 0x38, 0x1c, 0x0d, 0x59, 0x5b, 0x16, 0xb3, 0x0a, + 0x77, 0x06, 0xeb, 0x74, 0xf8, 0x8d, 0xc3, 0xee, 0x43, 0xce, 0xc4, 0xc5, 0x7c, 0x85, 0x72, 0xbc, + 0x24, 0x8d, 0x0b, 0x0a, 0xab, 0xb6, 0x35, 0x21, 0x05, 0x9e, 0x68, 0xd8, 0x2e, 0xd4, 0x71, 0x1a, + 0x3d, 0xa4, 0xcd, 0x1e, 0xbb, 0xaf, 0x71, 0x95, 0xb8, 0x6e, 0x2d, 0x70, 0xf5, 0x05, 0x11, 0x75, + 0x76, 0xc7, 0x0d, 0xfd, 0x73, 0xad, 0xe6, 0xca, 0x30, 0x76, 0x15, 0xad, 0xac, 0x9e, 0x37, 0x3e, + 0xb1, 0xcc, 0xc6, 0xb5, 0x48, 0x03, 0xe2, 0x69, 0xf6, 0x09, 0xd4, 0x68, 0x62, 0x61, 0x12, 0x0b, + 0x6f, 0x5c, 0x27, 0x61, 0x2a, 0x4f, 0x99, 0x08, 0xa5, 0xa5, 0x29, 0x51, 0xc4, 0xdb, 0x81, 0x1e, + 0x5a, 0xd3, 0x99, 0xe7, 0xa3, 0x9e, 0xfd, 0x5a, 0xe4, 0x1b, 0x1a, 0x45, 0x20, 0xdc, 0x88, 0xe3, + 0x13, 0x32, 0xdd, 0x9b, 0x4c, 0x02, 0x2b, 0x6c, 0xdc, 0xa0, 0x75, 0x53, 0x8f, 0x0e, 0xca, 0x06, + 0x04, 0xa5, 0x8d, 0x30, 0xd0, 0xcd, 0x73, 0xd7, 0x98, 0xda, 0xe3, 0xc6, 0x4d, 0xae, 0xce, 0xdb, + 0x41, 0x9b, 0x03, 0x64, 0x8d, 0x7a, 0x3b, 0xa5, 0x51, 0x5f, 0x80, 0xbc, 0x79, 0x88, 0xcb, 0xf1, + 0x16, 0x65, 0x9b, 0x33, 0x0f, 0xbb, 0x26, 0x7b, 0x07, 0xca, 0xb3, 0x48, 0x04, 0x36, 0x54, 0xd9, + 0x6f, 0x10, 0x4b, 0x46, 0x2d, 0xa1, 0x40, 0x53, 0xf6, 0x89, 0x65, 0x84, 0x73, 0xdf, 0x7a, 0xe2, + 0x18, 0x47, 0x8d, 0xdb, 0x94, 0x93, 0x0c, 0xc2, 0xda, 0x39, 0xde, 0x91, 0x3d, 0x36, 0x68, 0xe5, + 0xdf, 0xe1, 0x7a, 0x97, 0x80, 0x74, 0xcd, 0x44, 0x11, 0x35, 0x84, 0x32, 0xf5, 0xba, 0xac, 0x88, + 0x1a, 0xa4, 0x4d, 0x5d, 0x7d, 0x4a, 0x1a, 0x3a, 0xf5, 0xdc, 0x87, 0x0b, 0x02, 0x2a, 0xb5, 0xbc, + 0x24, 0x49, 0xb6, 0xbb, 0x26, 0xcb, 0xa9, 0x9d, 0x3c, 0x49, 0xf2, 0xab, 0x3f, 0x06, 0xb6, 0x3c, + 0xe6, 0xaf, 0x92, 0x96, 0x79, 0x21, 0x2d, 0x3f, 0x5d, 0x7f, 0x9c, 0x51, 0x9f, 0x41, 0x2d, 0x25, + 0x0c, 0x56, 0x4a, 0x7d, 0xae, 0x72, 0x19, 0x53, 0x61, 0x4d, 0xf3, 0x44, 0xa4, 0x4e, 0xdb, 0xee, + 0x91, 0x70, 0xe4, 0x71, 0x75, 0x9a, 0xd2, 0xea, 0x5f, 0x65, 0xa1, 0xba, 0x6b, 0x04, 0xc7, 0x7b, + 0xc6, 0x6c, 0x18, 0x1a, 0x61, 0x80, 0x53, 0xe4, 0xd8, 0x08, 0x8e, 0xa7, 0xc6, 0x8c, 0x2b, 0xbf, + 0x19, 0xee, 0x25, 0x10, 0x30, 0xd4, 0x7c, 0x71, 0x72, 0x62, 0x72, 0xe0, 0xee, 0x7f, 0x21, 0x5c, + 0x00, 0x71, 0x1a, 0x45, 0x53, 0x70, 0x3c, 0x9f, 0x4c, 0xe2, 0xa2, 0xa2, 0x24, 0xbb, 0x03, 0x35, + 0xf1, 0x93, 0x34, 0xdf, 0x33, 0x71, 0xca, 0x9a, 0x06, 0xb2, 0x47, 0x50, 0x11, 0x80, 0x51, 0x24, + 0x48, 0xeb, 0xb1, 0x6b, 0x27, 0x41, 0x68, 0x32, 0x15, 0xfb, 0x09, 0x5c, 0x94, 0x92, 0x4f, 0x3c, + 0x7f, 0x6f, 0xee, 0x84, 0x76, 0xab, 0x2f, 0xd4, 0x8c, 0x6b, 0x4b, 0xec, 0x09, 0x89, 0xb6, 0x9a, + 0x33, 0x5d, 0xdb, 0x3d, 0xdb, 0x25, 0xb9, 0x9c, 0xd5, 0xd2, 0xc0, 0x05, 0x2a, 0xe3, 0x8c, 0xc4, + 0x71, 0x9a, 0xca, 0x38, 0xc3, 0x05, 0x2b, 0x00, 0x7b, 0x56, 0x78, 0xec, 0x99, 0xa4, 0x63, 0xc6, + 0x0b, 0x76, 0x28, 0xa3, 0xb4, 0x34, 0x25, 0x76, 0x27, 0xda, 0x6f, 0x63, 0x37, 0x24, 0x4d, 0x33, + 0xab, 0x45, 0x49, 0xdc, 0xaa, 0x7c, 0xc3, 0x3d, 0xb2, 0x82, 0x46, 0x65, 0x3b, 0x7b, 0x2f, 0xa3, + 0x89, 0x94, 0xfa, 0x3f, 0xac, 0x43, 0x9e, 0x8f, 0xe4, 0x35, 0x28, 0x1f, 0x92, 0x6f, 0x1c, 0x0d, + 0x71, 0xe1, 0xef, 0x26, 0x40, 0x7f, 0x3e, 0xe5, 0x1a, 0xa2, 0x70, 0xe1, 0x64, 0x34, 0xfa, 0x8d, + 0x59, 0x7a, 0xf3, 0x10, 0xcb, 0xca, 0x12, 0x54, 0xa4, 0xb0, 0x12, 0xbe, 0x77, 0x4a, 0xb3, 0x21, + 0x47, 0x88, 0x28, 0x49, 0x2e, 0x75, 0xda, 0xf5, 0x90, 0x29, 0x4f, 0xb8, 0x12, 0x01, 0x5a, 0x6e, + 0xb8, 0xe8, 0x6e, 0x2a, 0x2c, 0xb9, 0x9b, 0xd8, 0x0d, 0x40, 0xfd, 0x73, 0x6c, 0x0d, 0x5c, 0xab, + 0xd5, 0xa7, 0x1e, 0x2e, 0x69, 0x12, 0x04, 0x17, 0x88, 0xe9, 0xcd, 0xa8, 0x53, 0xf3, 0x1a, 0xfe, + 0x64, 0x1f, 0xc5, 0xb3, 0x93, 0xda, 0x28, 0xb4, 0x75, 0xb1, 0x2b, 0xc8, 0xf3, 0x58, 0x4b, 0xd1, + 0x61, 0x4e, 0x28, 0xea, 0xb9, 0xb6, 0x8e, 0x3f, 0xd5, 0x0e, 0x80, 0xe6, 0x9d, 0x06, 0x56, 0x48, + 0x7e, 0xd5, 0xcb, 0xd4, 0xc4, 0xd4, 0x89, 0x98, 0x77, 0xba, 0xef, 0x05, 0xb1, 0x41, 0xbb, 0xbe, + 0xda, 0xa0, 0x55, 0xdf, 0x85, 0x22, 0xea, 0x01, 0x46, 0x68, 0xb0, 0x3b, 0xc2, 0x95, 0xc5, 0xb5, + 0x17, 0xe1, 0xd3, 0x4b, 0xca, 0x10, 0xce, 0xad, 0x5e, 0x54, 0x2e, 0xf1, 0xdc, 0x92, 0x4c, 0xc6, + 0x78, 0x0f, 0x12, 0x19, 0x0a, 0xcd, 0xe2, 0x1a, 0x94, 0xb1, 0x6a, 0x74, 0x4c, 0x20, 0xe4, 0x42, + 0xc9, 0xf7, 0x4e, 0x5b, 0x98, 0x56, 0xff, 0x69, 0x06, 0x2a, 0x03, 0xdf, 0xc4, 0xcd, 0x6f, 0x38, + 0xb3, 0xc6, 0xaf, 0xb4, 0xbf, 0x51, 0x0f, 0xf1, 0x1c, 0xc7, 0x20, 0x31, 0x2b, 0x4c, 0xb6, 0x18, + 0xc0, 0xde, 0x87, 0xdc, 0x04, 0xc5, 0x69, 0x56, 0xd6, 0xce, 0xa5, 0xec, 0xa3, 0xdf, 0x28, 0x60, + 0x35, 0x22, 0x55, 0x7f, 0x3b, 0x2e, 0x9f, 0xa4, 0xae, 0xec, 0x4c, 0x5f, 0xa3, 0x63, 0xad, 0x61, + 0x4b, 0xc9, 0xb0, 0x12, 0xe4, 0xda, 0x9d, 0x61, 0x8b, 0xeb, 0xe4, 0xa8, 0x9d, 0x0f, 0xf5, 0x27, + 0x5d, 0x6d, 0x38, 0x52, 0x72, 0x74, 0x4e, 0x46, 0x80, 0x5e, 0x73, 0x38, 0x52, 0x4a, 0x0c, 0xa0, + 0x70, 0xd0, 0xef, 0xfe, 0xe4, 0xa0, 0xa3, 0x28, 0xea, 0x3f, 0xc8, 0x00, 0x24, 0x3e, 0x5f, 0xf6, + 0x16, 0x54, 0x4e, 0x29, 0xa5, 0x4b, 0x87, 0x01, 0x72, 0x1b, 0x81, 0xa3, 0x49, 0x47, 0x7a, 0x07, + 0xaa, 0xf1, 0x76, 0x81, 0xfa, 0xc3, 0xf2, 0xa9, 0x40, 0x25, 0xc6, 0xef, 0x9c, 0xb3, 0xb7, 0xa1, + 0xe4, 0x61, 0x3b, 0x90, 0x34, 0x2b, 0x2b, 0x0f, 0x52, 0xf3, 0xb5, 0xa2, 0xc7, 0x13, 0xa8, 0x67, + 0x4c, 0xfc, 0xc8, 0x04, 0x8f, 0x49, 0x9f, 0x20, 0xa8, 0xe5, 0x18, 0xf3, 0xc0, 0xd2, 0x38, 0x3e, + 0x96, 0xd2, 0xf9, 0x44, 0x4a, 0xab, 0x3f, 0x85, 0xfa, 0xd0, 0x98, 0xce, 0xb8, 0x2c, 0xa7, 0x86, + 0x31, 0xc8, 0xe1, 0x9c, 0x10, 0x53, 0x8f, 0x7e, 0xe3, 0xa2, 0xdb, 0xb7, 0xfc, 0xb1, 0xe5, 0x46, + 0x6b, 0x34, 0x4a, 0xa2, 0xf8, 0x3d, 0x40, 0x69, 0xae, 0x79, 0xa7, 0x91, 0x38, 0x8f, 0xd2, 0xea, + 0xff, 0x9c, 0x81, 0x8a, 0x54, 0x0d, 0xf6, 0x2e, 0xe4, 0x48, 0x21, 0xcd, 0xc8, 0x82, 0x50, 0x22, + 0xe0, 0xbf, 0xb9, 0x0a, 0x83, 0x84, 0xec, 0x2e, 0xe4, 0x83, 0xd0, 0xf0, 0xa3, 0xe3, 0x03, 0x45, + 0xe2, 0xd8, 0xf1, 0xe6, 0xae, 0xa9, 0x71, 0x34, 0x53, 0x21, 0x6b, 0xb9, 0xa6, 0x70, 0x5a, 0x2c, + 0x53, 0x21, 0x52, 0xdd, 0x86, 0x72, 0x9c, 0x3d, 0x4e, 0x01, 0x6d, 0xf0, 0x7c, 0xa8, 0xac, 0xb1, + 0x32, 0xe4, 0xb5, 0x66, 0xff, 0x69, 0x47, 0xc9, 0xa8, 0xbf, 0xc8, 0x00, 0x24, 0x5c, 0xec, 0x41, + 0xaa, 0xb6, 0x57, 0x17, 0x73, 0x7d, 0x40, 0x7f, 0xa5, 0xca, 0x5e, 0x87, 0xf2, 0xdc, 0x25, 0xa0, + 0x65, 0x8a, 0x9d, 0x28, 0x01, 0xa0, 0x15, 0x15, 0x05, 0xbb, 0x2c, 0x58, 0x51, 0x2f, 0x0c, 0x47, + 0xfd, 0x14, 0xca, 0x71, 0x76, 0x68, 0x18, 0x3e, 0x19, 0xf4, 0x7a, 0x83, 0xe7, 0xdd, 0xfe, 0x53, + 0x65, 0x0d, 0x93, 0xfb, 0x5a, 0xa7, 0xd5, 0x69, 0x63, 0x32, 0x83, 0x73, 0xb6, 0x75, 0xa0, 0x69, + 0x9d, 0xfe, 0x48, 0xd7, 0x06, 0xcf, 0x95, 0x75, 0xf5, 0xf7, 0x33, 0x50, 0x1b, 0x38, 0x66, 0xcb, + 0x73, 0x5a, 0xc6, 0x0c, 0x35, 0x0e, 0xf6, 0x19, 0x6c, 0x1e, 0xce, 0x51, 0xeb, 0x9d, 0x39, 0xc6, + 0xd8, 0x3a, 0xf6, 0x1c, 0xd3, 0x8a, 0x16, 0x61, 0xea, 0x80, 0x44, 0xf8, 0x72, 0x15, 0x22, 0xde, + 0x4f, 0x68, 0xd9, 0x87, 0x50, 0x9d, 0xf9, 0xde, 0xa1, 0xa5, 0x07, 0xde, 0xdc, 0x1f, 0x5b, 0x4b, + 0xe6, 0x5a, 0xc2, 0x5b, 0x21, 0xba, 0x21, 0x91, 0xa9, 0xff, 0xeb, 0x3a, 0x54, 0xdb, 0x96, 0x39, + 0x9f, 0x7d, 0xee, 0xd9, 0x6e, 0x2b, 0x3c, 0x63, 0x1f, 0x40, 0xd5, 0x73, 0xc8, 0x0f, 0xa9, 0x4b, + 0xc7, 0xf1, 0xab, 0xf2, 0x01, 0x8f, 0x5a, 0x40, 0x87, 0xf7, 0xef, 0xc0, 0x05, 0x6e, 0x98, 0x0b, + 0x3f, 0xd5, 0x19, 0x67, 0xc6, 0x35, 0x93, 0xd7, 0x14, 0x8e, 0xe2, 0x1b, 0x34, 0x91, 0xff, 0x06, + 0x6c, 0x49, 0xe4, 0x28, 0x58, 0x38, 0x7d, 0x76, 0x69, 0x8d, 0x6d, 0xc6, 0xbc, 0x71, 0xa0, 0xc0, + 0xe7, 0xb0, 0x15, 0xd5, 0x70, 0xcc, 0x7b, 0x8f, 0x33, 0xe7, 0x64, 0xf3, 0x22, 0xd5, 0xbb, 0xa2, + 0xc2, 0x9b, 0x9e, 0x0c, 0xa4, 0xbc, 0xde, 0x87, 0x8b, 0x26, 0xb6, 0x5e, 0xe7, 0x9d, 0x7f, 0x62, + 0x59, 0x33, 0xdd, 0x31, 0x82, 0x50, 0x9c, 0x3b, 0x32, 0x42, 0xee, 0x20, 0xee, 0x0b, 0xcb, 0x9a, + 0xf5, 0x8c, 0x20, 0x54, 0xff, 0xdb, 0x2c, 0x94, 0xb9, 0x57, 0x01, 0xbb, 0xeb, 0x1e, 0x14, 0xbd, + 0xc3, 0xaf, 0x75, 0x3f, 0xb6, 0xb6, 0x97, 0xce, 0x16, 0x0b, 0xde, 0xe1, 0xd7, 0x9a, 0x35, 0x61, + 0x6f, 0x45, 0x5b, 0x1d, 0x5a, 0xe6, 0xeb, 0xb2, 0x6f, 0x3c, 0x52, 0xeb, 0xc5, 0xd6, 0x87, 0x26, + 0xe7, 0x23, 0xa8, 0xd8, 0x6e, 0x60, 0xf9, 0x21, 0xf7, 0xa4, 0x14, 0x5f, 0x3e, 0x08, 0x9c, 0x8c, + 0x9c, 0x2b, 0x8f, 0xa0, 0xc2, 0x3d, 0x2b, 0x9c, 0xa9, 0xf4, 0x72, 0x26, 0x4e, 0x46, 0x4c, 0x9f, + 0x40, 0x3d, 0x11, 0x73, 0xc4, 0x57, 0x7e, 0x29, 0x5f, 0x2d, 0xa6, 0x24, 0xd6, 0x87, 0x70, 0x29, + 0x38, 0xb1, 0x67, 0xba, 0xa8, 0xa9, 0xe7, 0xd2, 0xb1, 0x82, 0x3e, 0x3b, 0x11, 0xee, 0x7c, 0x86, + 0xd8, 0x2e, 0x21, 0x07, 0x6e, 0x7f, 0xee, 0x38, 0xfb, 0x27, 0xec, 0x4d, 0xd8, 0x14, 0xe4, 0xb3, + 0x93, 0x68, 0xae, 0x90, 0xb1, 0x99, 0xd7, 0xea, 0x1c, 0xb1, 0x7f, 0x22, 0x34, 0xb9, 0x8f, 0xa1, + 0xc1, 0x8f, 0xbb, 0x45, 0xa3, 0x8c, 0xc9, 0xc4, 0x1a, 0x87, 0x3a, 0xaa, 0x0e, 0xc2, 0xf7, 0x7f, + 0x91, 0xf0, 0xdc, 0x3d, 0xd4, 0x24, 0x2c, 0x4a, 0x3e, 0xf5, 0x7f, 0xcb, 0x40, 0x99, 0x17, 0x8b, + 0x23, 0x74, 0x0b, 0xb2, 0xdf, 0x32, 0x3a, 0x88, 0x63, 0xf7, 0x61, 0xd3, 0x30, 0x4d, 0x51, 0x80, + 0x65, 0xf2, 0x22, 0xb8, 0x38, 0xd8, 0x30, 0x4c, 0xb3, 0x29, 0xe0, 0x24, 0x56, 0xef, 0x81, 0x62, + 0x07, 0x7a, 0x64, 0x57, 0x26, 0x87, 0xdb, 0x25, 0xad, 0x6e, 0x07, 0xc2, 0xac, 0xe4, 0xae, 0xe2, + 0xd4, 0x80, 0xe7, 0xbe, 0x7d, 0xc0, 0x55, 0x06, 0xa0, 0x59, 0xb4, 0xf6, 0x5b, 0xe1, 0xd9, 0xe7, + 0xb9, 0x52, 0x46, 0x01, 0xf5, 0xff, 0xad, 0x40, 0xa5, 0xe9, 0x1a, 0xce, 0xf9, 0xcf, 0x2c, 0x3a, + 0x99, 0x27, 0xc7, 0xe1, 0x6c, 0x2e, 0xba, 0x80, 0x1f, 0x5b, 0x95, 0x09, 0x42, 0x35, 0xbb, 0x09, + 0x15, 0x6f, 0x1e, 0xc6, 0x78, 0x7e, 0x90, 0x05, 0x1c, 0x44, 0x04, 0x31, 0x7f, 0xec, 0x94, 0x8e, + 0xf8, 0x49, 0x2b, 0x4f, 0xf8, 0x63, 0x4d, 0x2d, 0xe6, 0x27, 0x82, 0xdb, 0x50, 0x0b, 0xed, 0xa9, + 0x45, 0x67, 0x77, 0xf3, 0xa9, 0x65, 0xf2, 0x90, 0x3e, 0x1e, 0x25, 0xd6, 0x12, 0x30, 0xcc, 0x65, + 0x6a, 0x4d, 0x3d, 0xff, 0x9c, 0xe7, 0x52, 0xe0, 0xb9, 0x70, 0x10, 0xe5, 0xf2, 0x36, 0xb0, 0x53, + 0xc3, 0x0e, 0xf5, 0x74, 0x56, 0x5c, 0x3b, 0x56, 0x10, 0x33, 0x92, 0xb3, 0xbb, 0x04, 0x05, 0xd3, + 0x0e, 0x4e, 0xba, 0x03, 0xa1, 0x19, 0x8b, 0x14, 0xb6, 0x25, 0x18, 0x1b, 0xb8, 0x31, 0x87, 0x16, + 0xd7, 0xe2, 0xb2, 0x5a, 0x19, 0x21, 0x3b, 0x08, 0x40, 0xc1, 0xee, 0x5a, 0xe1, 0xa9, 0xe7, 0x23, + 0x27, 0x57, 0x7c, 0x13, 0x00, 0x6e, 0x80, 0x48, 0x8a, 0x05, 0xd1, 0xdc, 0xcb, 0x6a, 0x71, 0x1a, + 0x55, 0x4a, 0x3e, 0x0f, 0x09, 0x5b, 0xe5, 0xd5, 0x4f, 0x20, 0xec, 0x0e, 0xd4, 0xa9, 0xfa, 0xa4, + 0x18, 0x63, 0x1b, 0xe8, 0xac, 0x29, 0xab, 0x55, 0x11, 0x4a, 0x76, 0x32, 0x52, 0x7d, 0x02, 0x57, + 0x52, 0xed, 0xd3, 0x0d, 0xdf, 0x37, 0xce, 0xf5, 0xa9, 0xf1, 0xb5, 0xe7, 0x93, 0x4f, 0x23, 0xab, + 0x5d, 0x92, 0xbb, 0xad, 0x89, 0xe8, 0x3d, 0xc4, 0xbe, 0x94, 0xd5, 0x76, 0x3d, 0x9f, 0x1c, 0x1e, + 0x2b, 0x59, 0x11, 0x4b, 0xd6, 0x39, 0x0d, 0x30, 0x69, 0xe9, 0x01, 0x8f, 0x2e, 0xd4, 0x2a, 0x04, + 0xdb, 0x21, 0x10, 0xea, 0xa9, 0xc1, 0x23, 0x2e, 0x2f, 0x37, 0x45, 0xa8, 0xcf, 0x23, 0x92, 0x84, + 0x1c, 0x71, 0x6c, 0x19, 0x26, 0x9d, 0x5f, 0x11, 0x62, 0xd7, 0x32, 0xe8, 0x74, 0x38, 0x78, 0xa4, + 0xcf, 0xe6, 0x21, 0x0f, 0x0b, 0xd4, 0xf2, 0xc1, 0xa3, 0xfd, 0x79, 0x28, 0xc0, 0x47, 0x56, 0x48, + 0xc7, 0x55, 0x04, 0x7e, 0x6a, 0x85, 0xa8, 0x6c, 0x06, 0x8f, 0x22, 0x07, 0xef, 0x45, 0xd1, 0xb7, + 0x8f, 0x84, 0x07, 0x57, 0x85, 0x5a, 0x8c, 0xd4, 0xa7, 0x73, 0x1e, 0x07, 0x98, 0xd5, 0x2a, 0x11, + 0xc1, 0xde, 0xdc, 0xc1, 0x81, 0x1d, 0x1b, 0xe3, 0x63, 0x4b, 0xf7, 0xb1, 0x2a, 0x97, 0xf9, 0xd0, + 0x11, 0x44, 0xc3, 0xda, 0x5c, 0x03, 0x9e, 0xd0, 0x8f, 0xed, 0x90, 0x1c, 0x2f, 0x59, 0xad, 0x44, + 0x80, 0x5d, 0x3b, 0xc4, 0x75, 0xcc, 0x91, 0x62, 0x06, 0x52, 0x16, 0x57, 0x88, 0x68, 0x83, 0x10, + 0x7b, 0x04, 0xa7, 0x8c, 0xee, 0x81, 0x92, 0xa2, 0xc5, 0xfc, 0xae, 0x12, 0x69, 0x5d, 0x22, 0xc5, + 0x5c, 0xef, 0x02, 0x67, 0xd6, 0x71, 0xea, 0xf1, 0x3c, 0xaf, 0x71, 0x2b, 0x8d, 0xc0, 0x6d, 0x3b, + 0x38, 0xa1, 0x1c, 0xef, 0x40, 0x5d, 0xa2, 0xc3, 0xfc, 0xae, 0xf3, 0x99, 0x11, 0x93, 0xa5, 0xea, + 0xe8, 0x5b, 0x53, 0x2f, 0x14, 0xcd, 0x7c, 0x4d, 0xaa, 0xa3, 0x46, 0xf0, 0x74, 0x1d, 0x05, 0x2d, + 0xe6, 0x79, 0x43, 0xaa, 0x23, 0x27, 0xc5, 0x5c, 0x6f, 0x41, 0xf5, 0xd4, 0xb7, 0xc3, 0xd0, 0x72, + 0xf9, 0xe2, 0xbf, 0xc9, 0x3b, 0x56, 0xc0, 0x68, 0xf5, 0xdf, 0x82, 0x2a, 0xef, 0x79, 0x21, 0xdf, + 0xb6, 0x39, 0x89, 0x80, 0x45, 0x02, 0x42, 0xf4, 0xc6, 0xd4, 0x76, 0xc9, 0xbb, 0x92, 0xd5, 0xca, + 0x1c, 0x82, 0xc6, 0xaa, 0x84, 0x36, 0xce, 0xc8, 0xc7, 0x92, 0xa0, 0x8d, 0x33, 0x5a, 0x92, 0x33, + 0xdb, 0x71, 0xf8, 0xc2, 0xbf, 0x2d, 0x96, 0x24, 0x42, 0x68, 0xdd, 0xc7, 0x68, 0x2a, 0xfd, 0x8e, + 0x84, 0xa6, 0xb2, 0x71, 0xe2, 0x10, 0x1a, 0x8b, 0x7e, 0x5d, 0x4c, 0x1c, 0x04, 0x60, 0xc9, 0x09, + 0xd2, 0x38, 0x6b, 0xdc, 0x95, 0x91, 0xc6, 0x99, 0x90, 0x5b, 0x98, 0x2b, 0xf1, 0xbe, 0x11, 0xcb, + 0x2d, 0x04, 0x21, 0xb7, 0x4c, 0x60, 0x9c, 0x35, 0xee, 0xa5, 0x09, 0x8c, 0x33, 0xb2, 0x90, 0x2c, + 0xc3, 0xe4, 0x15, 0x7f, 0x93, 0x67, 0x8f, 0x00, 0xaa, 0xf7, 0x36, 0x54, 0x83, 0x47, 0x7a, 0x82, + 0xbf, 0xcf, 0xd9, 0x83, 0x47, 0x5a, 0x44, 0x71, 0x07, 0xea, 0xf1, 0xd4, 0xe0, 0x34, 0x6f, 0xf1, + 0x81, 0x37, 0xc5, 0xd4, 0xa0, 0xe3, 0xbe, 0x9f, 0x67, 0xe0, 0xea, 0x80, 0x9c, 0x43, 0x24, 0xfe, + 0xf7, 0xac, 0x20, 0x30, 0x8e, 0xac, 0x27, 0x9e, 0xff, 0x64, 0xfe, 0xb3, 0x9f, 0x9d, 0xb3, 0x7b, + 0xb0, 0xb1, 0x6f, 0xf8, 0x96, 0x1b, 0xc6, 0x07, 0x55, 0xc2, 0x33, 0xb3, 0x08, 0x66, 0x8f, 0x41, + 0xe1, 0x20, 0x1e, 0x12, 0xd5, 0x8a, 0xce, 0x69, 0x16, 0xfd, 0xca, 0x4b, 0x54, 0x68, 0xec, 0x95, + 0xdb, 0x76, 0x10, 0x6a, 0x68, 0xe9, 0xb3, 0x4f, 0x40, 0x71, 0xbc, 0x53, 0xb4, 0x58, 0x50, 0x8d, + 0xd5, 0x25, 0xc5, 0x59, 0xec, 0x92, 0x89, 0xb6, 0x5c, 0x27, 0xc2, 0x44, 0xdd, 0xfd, 0x04, 0x94, + 0xf9, 0x6c, 0x96, 0x66, 0x5d, 0x7f, 0x09, 0x2b, 0x11, 0x26, 0xac, 0x6f, 0x41, 0x45, 0x2a, 0x75, + 0x85, 0x72, 0x0d, 0x49, 0x59, 0x48, 0x2c, 0x95, 0xb3, 0x22, 0xcc, 0x12, 0x92, 0xdc, 0xd5, 0xff, + 0x62, 0x1d, 0x14, 0x72, 0x8e, 0x69, 0x74, 0x58, 0x4f, 0xe7, 0x5d, 0x29, 0xb3, 0x2c, 0xf3, 0x4a, + 0xb3, 0x6c, 0x1b, 0xf2, 0x8e, 0x3d, 0x8d, 0x63, 0x9f, 0x52, 0x07, 0x36, 0x84, 0xc0, 0xb1, 0xf6, + 0x7c, 0xfb, 0x88, 0x0c, 0x48, 0x39, 0x4a, 0x8f, 0xfc, 0x7e, 0x68, 0x8f, 0xd1, 0x10, 0x3d, 0x00, + 0x30, 0xed, 0x20, 0xd4, 0xc9, 0xa5, 0x22, 0xaa, 0x2d, 0x7a, 0x26, 0xee, 0x7f, 0xad, 0x6c, 0xc6, + 0x43, 0x71, 0x0f, 0x14, 0x49, 0x09, 0x73, 0x63, 0x6f, 0x48, 0x5e, 0x4b, 0x94, 0xb3, 0x96, 0xdb, + 0x72, 0xc3, 0x25, 0x4a, 0x54, 0x9f, 0x0a, 0x4b, 0x94, 0x5d, 0xf3, 0x4c, 0xfd, 0xcb, 0xdb, 0x90, + 0xeb, 0x7b, 0xa6, 0xc5, 0xde, 0x83, 0x32, 0x85, 0xb3, 0x4a, 0x03, 0x2c, 0x94, 0x64, 0x44, 0xd3, + 0x1f, 0x1a, 0xa9, 0x92, 0x2b, 0x7e, 0xbd, 0x3c, 0x00, 0xf6, 0x16, 0x19, 0x77, 0x74, 0x24, 0x8b, + 0x4d, 0xaa, 0x08, 0x07, 0x14, 0xf9, 0x4b, 0x38, 0x06, 0xf7, 0x56, 0x72, 0xdf, 0xfb, 0x96, 0x4b, + 0x1a, 0x79, 0x5e, 0x8b, 0xd3, 0x64, 0x52, 0xfb, 0x1e, 0xaa, 0x5e, 0x7c, 0x07, 0xca, 0xaf, 0x30, + 0xa9, 0x39, 0x9e, 0xb6, 0xa4, 0xf7, 0xa0, 0xfc, 0xb5, 0x67, 0xbb, 0xbc, 0xe2, 0x85, 0xa5, 0x8a, + 0xa3, 0xc5, 0xc2, 0x2b, 0xfe, 0xb5, 0xf8, 0xc5, 0x6e, 0x43, 0xd1, 0x73, 0x79, 0xde, 0xc5, 0xa5, + 0xbc, 0x0b, 0x9e, 0xdb, 0xe3, 0xd1, 0x55, 0x35, 0x3b, 0xd0, 0x7d, 0xfb, 0xe8, 0x38, 0xd4, 0x91, + 0x53, 0x1c, 0xe5, 0x56, 0xec, 0x40, 0x43, 0x18, 0x66, 0x8b, 0x13, 0x6f, 0x62, 0x3b, 0xa8, 0xe1, + 0x51, 0x66, 0xe5, 0xa5, 0xcc, 0x80, 0xa3, 0x29, 0xc3, 0xd7, 0xa1, 0x74, 0xe4, 0x7b, 0x68, 0x44, + 0x9c, 0x37, 0x60, 0x89, 0xb2, 0x48, 0xb8, 0x9d, 0x73, 0x54, 0x9f, 0xe8, 0xa7, 0xed, 0x1e, 0xe9, + 0xe4, 0x25, 0xa9, 0x6c, 0x67, 0xef, 0x95, 0xb4, 0x6a, 0x04, 0x24, 0xff, 0xc7, 0xeb, 0x50, 0x32, + 0x8e, 0x8e, 0x74, 0x11, 0x24, 0xb6, 0x94, 0x97, 0x71, 0x74, 0x44, 0x45, 0x3e, 0x80, 0xda, 0xa9, + 0xed, 0xea, 0xc1, 0xcc, 0x1a, 0x73, 0xda, 0xda, 0x72, 0x57, 0x9e, 0xda, 0x2e, 0xce, 0x6e, 0xa2, + 0x97, 0x97, 0x41, 0xfd, 0xbb, 0x2f, 0x83, 0x8d, 0x97, 0x2d, 0x03, 0x15, 0x0a, 0xc2, 0xb5, 0xaf, + 0x2c, 0x91, 0x08, 0x0c, 0x7b, 0x1f, 0x2a, 0xbe, 0xe1, 0x9e, 0xe8, 0xe2, 0x5c, 0xfc, 0x2b, 0xd9, + 0xd2, 0xd7, 0x0c, 0xf7, 0x44, 0x1c, 0x8b, 0x83, 0x1f, 0xff, 0x4e, 0xab, 0xcc, 0x9b, 0xaf, 0xb0, + 0x91, 0x24, 0xd3, 0x8b, 0x7d, 0xbb, 0xe9, 0xf5, 0x21, 0xd9, 0x38, 0x96, 0x1b, 0xea, 0x11, 0xc3, + 0x85, 0xd5, 0x0c, 0x55, 0x4e, 0x36, 0xe0, 0x6c, 0xd8, 0x00, 0xf2, 0xb4, 0xe9, 0xe4, 0x96, 0xdb, + 0x4a, 0x35, 0x20, 0x76, 0xc1, 0x69, 0xe0, 0x27, 0xee, 0xb8, 0x26, 0x6c, 0x24, 0x91, 0xb3, 0x3c, + 0x04, 0xf9, 0xa2, 0xec, 0xea, 0x4f, 0x85, 0xda, 0x46, 0x56, 0x95, 0x9d, 0x8a, 0xbf, 0xbd, 0x0d, + 0x35, 0x1e, 0x88, 0xc2, 0xfb, 0x2d, 0x20, 0x25, 0xa9, 0xac, 0x55, 0x09, 0xc8, 0xfb, 0x29, 0x20, + 0x01, 0x23, 0x4c, 0xbd, 0xf0, 0x8c, 0xb4, 0xa4, 0x44, 0xc0, 0x70, 0xdb, 0x2e, 0x3c, 0xd3, 0xca, + 0x66, 0xf4, 0x13, 0x37, 0xff, 0x43, 0xdb, 0x35, 0x71, 0xea, 0x85, 0xc6, 0x51, 0xd0, 0x68, 0xd0, + 0xca, 0xac, 0x08, 0xd8, 0xc8, 0x38, 0x0a, 0xd0, 0xf0, 0x37, 0xb8, 0xb1, 0xc1, 0xeb, 0x7d, 0x45, + 0xf6, 0x4c, 0x49, 0x66, 0x88, 0x56, 0x31, 0x24, 0x9b, 0xe4, 0x63, 0x60, 0xd1, 0xc9, 0xa3, 0x64, + 0xc7, 0x5f, 0x5d, 0x9a, 0x8d, 0x1b, 0xe2, 0xe8, 0x31, 0xb6, 0xe2, 0x6f, 0x42, 0x85, 0x7b, 0x2a, + 0xf4, 0x20, 0xb4, 0x66, 0x8d, 0x6b, 0x54, 0x21, 0xe0, 0xa0, 0x61, 0x68, 0xcd, 0xd8, 0xc7, 0x50, + 0x4b, 0x5b, 0x59, 0xd7, 0x57, 0x1c, 0xe0, 0xd1, 0xb4, 0xd0, 0xaa, 0x63, 0xd9, 0xee, 0xba, 0xcd, + 0xa3, 0xba, 0x49, 0x43, 0x22, 0x46, 0x7e, 0x48, 0x55, 0x75, 0xbd, 0xb0, 0x15, 0xc1, 0xb0, 0x03, + 0x23, 0x03, 0x3b, 0x3c, 0x23, 0xa5, 0x2a, 0xee, 0xc0, 0xd8, 0x74, 0x44, 0xe3, 0x28, 0xb2, 0x22, + 0xdb, 0xc0, 0x03, 0x2f, 0x68, 0x93, 0xb7, 0x7c, 0x1e, 0x64, 0x41, 0x3a, 0x54, 0x7c, 0xa6, 0xb7, + 0xb8, 0xf7, 0x68, 0x3c, 0x20, 0x45, 0xde, 0x8d, 0x1e, 0x43, 0x7d, 0xe6, 0x5b, 0xba, 0x54, 0xb2, + 0x2a, 0x37, 0x6a, 0xdf, 0xb7, 0x92, 0xc2, 0xab, 0x33, 0x29, 0xc5, 0x3e, 0x83, 0x4d, 0x89, 0x73, + 0x7e, 0x42, 0xcc, 0xb7, 0x89, 0x79, 0x6b, 0x81, 0xf9, 0xe0, 0x04, 0xd9, 0xeb, 0xb3, 0x54, 0x9a, + 0x6d, 0x41, 0xbe, 0x1b, 0x74, 0x5c, 0x93, 0x74, 0xab, 0x92, 0xc6, 0x13, 0xec, 0x11, 0x54, 0xb9, + 0x21, 0x43, 0x71, 0xaa, 0x41, 0xe3, 0xae, 0xec, 0x7a, 0x26, 0x6b, 0x86, 0x10, 0x5a, 0xc5, 0x89, + 0x7f, 0x07, 0xec, 0x23, 0xd8, 0xe4, 0xe7, 0x02, 0xb2, 0x88, 0x7c, 0x63, 0x79, 0xc8, 0x89, 0xe8, + 0x49, 0x22, 0x27, 0x35, 0xb8, 0xe2, 0xcf, 0x5d, 0x32, 0x6e, 0x04, 0x27, 0xf7, 0x58, 0x11, 0xff, + 0x3d, 0xe2, 0xbf, 0x2c, 0x56, 0x17, 0x27, 0xe3, 0xbc, 0x24, 0x9b, 0x2e, 0xf9, 0x32, 0x68, 0x1f, + 0xf9, 0x5e, 0x92, 0x27, 0xf7, 0xe4, 0x50, 0x9e, 0x6f, 0x7e, 0x9f, 0x3c, 0xc9, 0xcb, 0x43, 0x79, + 0x32, 0xc8, 0xcd, 0xe7, 0xb6, 0x49, 0x9a, 0x5e, 0x55, 0xa3, 0xdf, 0xec, 0x75, 0xa8, 0xfb, 0xd6, + 0x78, 0xee, 0x07, 0xf6, 0x0b, 0x4b, 0x0f, 0x6c, 0xf7, 0x84, 0x74, 0xbc, 0x92, 0x56, 0x8b, 0xa1, + 0x43, 0xdb, 0x3d, 0x41, 0x91, 0x61, 0x9d, 0x85, 0x96, 0xef, 0xf2, 0xd0, 0xf9, 0xb7, 0x65, 0x91, + 0xd1, 0x21, 0x04, 0xae, 0x73, 0x0d, 0xac, 0xf8, 0xf7, 0xc2, 0xc8, 0x06, 0x7c, 0x64, 0x1f, 0x7c, + 0xa7, 0x91, 0x1d, 0xd2, 0xc8, 0xde, 0x85, 0x92, 0xed, 0x86, 0x96, 0xff, 0xc2, 0x70, 0x1a, 0xef, + 0x2e, 0x49, 0xe3, 0x18, 0xc7, 0xee, 0x40, 0x31, 0x70, 0x6c, 0x5c, 0xef, 0x8d, 0xf7, 0x96, 0xc8, + 0x22, 0x14, 0xbb, 0x07, 0xe5, 0xf8, 0xd6, 0x57, 0xe3, 0xfd, 0x25, 0xba, 0x04, 0xc9, 0x6e, 0x40, + 0xee, 0x14, 0x27, 0xd4, 0xc3, 0xe5, 0xa3, 0x02, 0x84, 0xe3, 0xf6, 0x3d, 0x41, 0x9d, 0x9d, 0xb6, + 0xef, 0x47, 0x4b, 0xdb, 0xf7, 0x13, 0xdb, 0x71, 0xf8, 0xf6, 0x3d, 0x11, 0xbf, 0x70, 0xf3, 0x23, + 0x0e, 0x6c, 0xc9, 0x07, 0xcb, 0x9b, 0x1f, 0xe2, 0x9e, 0xd1, 0xfd, 0xb8, 0x4a, 0x40, 0xfe, 0x6f, + 0xee, 0xc6, 0xff, 0x50, 0xee, 0xab, 0xb4, 0x63, 0x5c, 0x83, 0x20, 0x4e, 0xa3, 0x01, 0x22, 0xbc, + 0xff, 0xa8, 0x34, 0x7d, 0xc4, 0x2f, 0x5e, 0x70, 0x48, 0xd7, 0x3c, 0x63, 0xef, 0x41, 0x2d, 0x0a, + 0x17, 0xc2, 0xe2, 0x82, 0xc6, 0xc7, 0x4b, 0x35, 0x48, 0x13, 0xb0, 0x36, 0x54, 0x27, 0xa8, 0xbb, + 0x4f, 0xb9, 0x2a, 0xdf, 0x78, 0x4c, 0x15, 0xd9, 0x8e, 0x36, 0xd6, 0x97, 0xa9, 0xfa, 0x5a, 0x8a, + 0x8b, 0x3d, 0x00, 0x66, 0x4f, 0xf8, 0x78, 0x3e, 0xf1, 0xbd, 0x29, 0x57, 0xd7, 0x1b, 0x9f, 0x70, + 0x0f, 0xda, 0x32, 0x86, 0x0e, 0x03, 0x2d, 0xd7, 0xd4, 0xa7, 0x81, 0x50, 0x13, 0x3e, 0xa5, 0x7a, + 0x0a, 0xe1, 0x15, 0xdf, 0x0e, 0x8d, 0x9c, 0xbd, 0x48, 0xbb, 0x17, 0x70, 0xad, 0xe1, 0x13, 0xc0, + 0xe9, 0xfa, 0x22, 0x61, 0xfd, 0x8d, 0x6f, 0x65, 0x45, 0xda, 0x88, 0xf5, 0x31, 0xd4, 0xb9, 0xa3, + 0x94, 0x34, 0x32, 0x9c, 0xa2, 0x3f, 0x92, 0x25, 0x97, 0xec, 0x42, 0xd6, 0xaa, 0xa6, 0xec, 0x50, + 0xfe, 0x18, 0x36, 0x22, 0x5f, 0x6f, 0x28, 0xdc, 0xc2, 0xbf, 0x29, 0x17, 0x1b, 0xfb, 0x52, 0xb5, + 0xda, 0x3c, 0xfa, 0x49, 0x45, 0x3e, 0x82, 0x1a, 0xed, 0xa2, 0x81, 0x6b, 0xcc, 0x82, 0x63, 0x2f, + 0x6c, 0xfc, 0x96, 0xac, 0x10, 0x0c, 0x05, 0x54, 0xab, 0x22, 0x51, 0x94, 0x42, 0xe1, 0x9f, 0xac, + 0xd3, 0x71, 0x68, 0x35, 0x3e, 0xe3, 0xc2, 0x3f, 0x06, 0xb6, 0x42, 0x8b, 0x3d, 0x02, 0x30, 0x66, + 0x33, 0xe7, 0x9c, 0x4f, 0xcd, 0x1f, 0xd3, 0xd4, 0xdc, 0x92, 0xa6, 0x66, 0x13, 0x91, 0x34, 0x37, + 0xcb, 0x46, 0xf4, 0x93, 0x3d, 0x84, 0xea, 0xcc, 0x0b, 0x42, 0xdd, 0x9c, 0x3a, 0xd4, 0xfe, 0xa6, + 0xbc, 0xb6, 0xf7, 0xbd, 0x20, 0x6c, 0x4f, 0x1d, 0x6c, 0x05, 0xcc, 0xe2, 0xdf, 0xac, 0x07, 0x17, + 0x3c, 0x57, 0x37, 0xe7, 0x33, 0xc7, 0x1e, 0x63, 0x0f, 0x18, 0x74, 0xf4, 0xde, 0xd8, 0xa1, 0x12, + 0xaf, 0x4b, 0x25, 0x0e, 0xdc, 0x76, 0x44, 0x24, 0x62, 0xd7, 0x36, 0xbd, 0x45, 0x10, 0xd9, 0x99, + 0x34, 0x06, 0x71, 0x00, 0x67, 0x8b, 0xab, 0x06, 0x04, 0x8d, 0x22, 0x38, 0x1f, 0xc3, 0x46, 0x42, + 0x85, 0x0d, 0x0c, 0x1a, 0x6d, 0x79, 0x26, 0x4b, 0x11, 0xe1, 0xb5, 0x88, 0x11, 0x61, 0x01, 0xf5, + 0x9d, 0xe7, 0x38, 0xf3, 0x99, 0x10, 0xa5, 0x8d, 0x8e, 0xe8, 0x3b, 0x02, 0x72, 0x29, 0x29, 0x99, + 0xe2, 0xd6, 0xb4, 0xf1, 0x44, 0x36, 0xc5, 0xad, 0x29, 0xaa, 0x19, 0x22, 0x3a, 0xf7, 0x85, 0x6d, + 0x9d, 0x06, 0x8d, 0xa7, 0x14, 0xb9, 0x29, 0xe2, 0x9f, 0x9f, 0x21, 0x08, 0xf7, 0x7d, 0xd3, 0xf6, + 0xd1, 0x04, 0xa0, 0xa0, 0xab, 0x5d, 0x1e, 0x40, 0xcb, 0x41, 0x48, 0xc1, 0x5a, 0xd0, 0x20, 0x71, + 0x2e, 0xd6, 0x6a, 0xea, 0x0c, 0xae, 0xbb, 0xb4, 0x24, 0x2f, 0x22, 0x2d, 0x3f, 0xe2, 0xdb, 0x97, + 0x4e, 0xe3, 0x7e, 0x0c, 0xaf, 0xad, 0xce, 0x24, 0xba, 0x9d, 0xf8, 0x39, 0xe9, 0x1b, 0x57, 0x56, + 0x70, 0xb7, 0xf8, 0x85, 0xc5, 0x4f, 0xa1, 0x76, 0x64, 0x50, 0x4f, 0x38, 0xfa, 0xd4, 0x33, 0xad, + 0xc6, 0x17, 0xf2, 0xc5, 0x41, 0x1a, 0xb4, 0xa7, 0x06, 0x76, 0x8a, 0xb3, 0xe7, 0x99, 0x96, 0x56, + 0x39, 0x4a, 0x12, 0xea, 0x2f, 0xf2, 0x50, 0x8a, 0xcc, 0x2a, 0x56, 0x81, 0xe2, 0x41, 0xff, 0x8b, + 0xfe, 0xe0, 0x79, 0x9f, 0x5f, 0xf0, 0x6b, 0x0e, 0x87, 0x1d, 0x6d, 0xa4, 0x98, 0xac, 0x0e, 0x40, + 0x57, 0x78, 0xf4, 0x61, 0xab, 0xd9, 0xe7, 0x17, 0xfe, 0xe8, 0xe2, 0x10, 0x4f, 0xaf, 0xb3, 0x4d, + 0xa8, 0x3d, 0x39, 0xe8, 0x53, 0xac, 0x21, 0x07, 0x65, 0x11, 0xd4, 0xf9, 0x92, 0x9f, 0x8e, 0x72, + 0x50, 0x0e, 0x41, 0x7b, 0xcd, 0x51, 0x47, 0xeb, 0x46, 0xa0, 0x3c, 0x85, 0x2d, 0x0e, 0x0e, 0xb4, + 0x96, 0xc8, 0xa9, 0xc0, 0x2e, 0xc2, 0x66, 0xcc, 0x16, 0x65, 0xa9, 0x14, 0xb1, 0x66, 0xfb, 0xda, + 0xe0, 0xf3, 0x4e, 0x6b, 0xa4, 0x00, 0x1d, 0xb5, 0x3e, 0x7d, 0xaa, 0x54, 0x58, 0x15, 0x4a, 0xed, + 0xee, 0x70, 0xd4, 0xed, 0xb7, 0x46, 0x4a, 0x15, 0x2b, 0xfc, 0xa4, 0xdb, 0x1b, 0x75, 0x34, 0xa5, + 0xc6, 0x4a, 0x90, 0xfb, 0x7c, 0xd0, 0xed, 0x2b, 0x75, 0xba, 0xca, 0xd4, 0xdc, 0xdb, 0xef, 0x75, + 0x94, 0x0d, 0x84, 0x0e, 0x07, 0xda, 0x48, 0x51, 0x10, 0xfa, 0xbc, 0xdb, 0x6f, 0x0f, 0x9e, 0x2b, + 0x9b, 0xac, 0x0c, 0xf9, 0x83, 0x3e, 0x16, 0xc3, 0x58, 0x0d, 0xca, 0xf4, 0x53, 0x6f, 0xf6, 0x7a, + 0xca, 0x05, 0xe9, 0x7c, 0x76, 0x0b, 0x51, 0x74, 0xda, 0x3b, 0xc4, 0x3a, 0x5c, 0xc4, 0xb6, 0xc4, + 0x49, 0xa2, 0xbe, 0x84, 0xf9, 0xec, 0x75, 0xfb, 0x07, 0x43, 0xe5, 0x32, 0x12, 0xd3, 0x4f, 0xc2, + 0x34, 0x30, 0x9f, 0x6e, 0x9f, 0xba, 0xf2, 0x06, 0xfe, 0x6e, 0x77, 0x7a, 0x9d, 0x51, 0x47, 0xb9, + 0x89, 0xad, 0xea, 0x0d, 0x5a, 0x5f, 0xe8, 0x83, 0x7d, 0xe5, 0x16, 0xf6, 0xe9, 0xbe, 0xd6, 0xd1, + 0x05, 0xe1, 0x6d, 0xa6, 0x40, 0xf5, 0xc9, 0xc1, 0x4f, 0x7f, 0xfa, 0x95, 0x2e, 0x1a, 0xf5, 0x3a, + 0x96, 0x99, 0x50, 0xe8, 0x07, 0x5f, 0x28, 0x77, 0x17, 0x40, 0xc3, 0x2f, 0x94, 0x37, 0xb0, 0x53, + 0xa2, 0x5e, 0x56, 0xee, 0x21, 0x81, 0xd6, 0x69, 0x1d, 0x68, 0xc3, 0xee, 0xb3, 0x8e, 0xde, 0x1a, + 0x75, 0x94, 0x37, 0xa9, 0x17, 0xba, 0xfd, 0x2f, 0x94, 0xfb, 0x58, 0x4d, 0xfc, 0xc5, 0xfb, 0xfe, + 0x2d, 0xc6, 0xa0, 0x9e, 0xd0, 0x12, 0xec, 0x6d, 0x24, 0xd9, 0xd1, 0x06, 0xcd, 0x76, 0xab, 0x39, + 0x1c, 0x29, 0xef, 0x60, 0x1b, 0x87, 0xfb, 0xbd, 0xee, 0x48, 0x79, 0x80, 0x0d, 0x79, 0xda, 0x1c, + 0xed, 0x76, 0x34, 0xe5, 0x5d, 0x1c, 0xc6, 0x51, 0x77, 0xaf, 0xa3, 0x8b, 0x3e, 0x7d, 0x88, 0x65, + 0x3c, 0xe9, 0xf6, 0x7a, 0xca, 0x23, 0x3a, 0x5f, 0x6c, 0x6a, 0xa3, 0x2e, 0x0d, 0xe4, 0x07, 0x98, + 0x41, 0x73, 0x7f, 0xbf, 0xf7, 0x95, 0xf2, 0x21, 0x36, 0x70, 0xef, 0xa0, 0x37, 0xea, 0xea, 0x07, + 0xfb, 0xed, 0xe6, 0xa8, 0xa3, 0x7c, 0x44, 0xa3, 0x3c, 0x18, 0x8e, 0xda, 0x7b, 0x3d, 0xe5, 0x63, + 0xca, 0x93, 0xe6, 0x58, 0xab, 0x37, 0xe8, 0x77, 0x94, 0xc7, 0x6a, 0xae, 0xb4, 0xad, 0x6c, 0xab, + 0xb9, 0x92, 0xaa, 0xa8, 0xea, 0xef, 0x42, 0x29, 0xb2, 0xa9, 0x31, 0xcb, 0x6e, 0xbf, 0xdf, 0xd1, + 0x94, 0x35, 0x2c, 0xb6, 0xd7, 0x79, 0x32, 0x52, 0x32, 0x74, 0xf0, 0xda, 0x7d, 0xba, 0x3b, 0x52, + 0xd6, 0xf1, 0xe7, 0xe0, 0x00, 0x7b, 0x30, 0x4b, 0x4d, 0xef, 0xec, 0x75, 0x95, 0x1c, 0xfe, 0x6a, + 0xf6, 0x47, 0x5d, 0x25, 0x4f, 0x13, 0xa4, 0xdb, 0x7f, 0xda, 0xeb, 0x28, 0x05, 0x84, 0xee, 0x35, + 0xb5, 0x2f, 0x94, 0x22, 0xcf, 0xb4, 0xdd, 0xf9, 0x52, 0x29, 0xb1, 0x02, 0xac, 0xf7, 0x1e, 0x2a, + 0x65, 0x04, 0xb5, 0x3b, 0xed, 0x83, 0x7d, 0x05, 0xd4, 0x7b, 0x50, 0x6c, 0x1e, 0x1d, 0xe1, 0x02, + 0xa2, 0x96, 0x1e, 0xf4, 0x7a, 0x7c, 0xc1, 0xec, 0x0c, 0x46, 0xa3, 0xc1, 0x9e, 0x92, 0xc1, 0x29, + 0x3a, 0x1a, 0xec, 0x2b, 0xeb, 0x6a, 0x17, 0x4a, 0x91, 0xf6, 0x20, 0xdd, 0xc3, 0x2b, 0x41, 0x6e, + 0x5f, 0xeb, 0x3c, 0xe3, 0xd1, 0x02, 0xfd, 0xce, 0x97, 0x58, 0x4d, 0xfc, 0x85, 0x19, 0x65, 0xb1, + 0x20, 0x7e, 0x61, 0x8e, 0x2e, 0xe2, 0xf5, 0xba, 0xfd, 0x4e, 0x53, 0x53, 0xf2, 0xea, 0x63, 0xa8, + 0x48, 0xcb, 0x18, 0x47, 0xf6, 0x69, 0x73, 0x1f, 0x67, 0x47, 0x4f, 0x17, 0xd9, 0x5e, 0x02, 0x16, + 0x83, 0x92, 0x4e, 0xcf, 0xa8, 0x1f, 0xc2, 0xe6, 0x92, 0xd4, 0xa6, 0x8a, 0x37, 0xbb, 0xa2, 0xe2, + 0xdd, 0xa7, 0xfd, 0x81, 0xd6, 0xe1, 0x77, 0x02, 0xc5, 0x70, 0xac, 0xab, 0x6f, 0x41, 0x39, 0xde, + 0x5e, 0x70, 0x7a, 0xb6, 0xb4, 0xc1, 0x70, 0xc8, 0x47, 0x6f, 0x0d, 0xd3, 0xd4, 0xab, 0x3c, 0x9d, + 0xf9, 0x3c, 0x57, 0xba, 0xa9, 0x6c, 0x7f, 0x9e, 0x2b, 0xdd, 0x51, 0x5e, 0x57, 0x87, 0xb0, 0x19, + 0xed, 0x72, 0x74, 0x1f, 0x81, 0xcc, 0xaf, 0x2d, 0xc8, 0xf7, 0xac, 0x17, 0x96, 0x13, 0x05, 0xd6, + 0x53, 0x02, 0xa1, 0x83, 0xc3, 0xaf, 0xbb, 0xf1, 0x15, 0x6e, 0x4a, 0xa0, 0x5a, 0xdb, 0x97, 0x6e, + 0x91, 0xd3, 0x25, 0xc9, 0xff, 0x3a, 0x03, 0xa5, 0x78, 0xef, 0xbc, 0x03, 0xeb, 0xa3, 0xa1, 0x38, + 0x28, 0xdb, 0x7a, 0x90, 0x3c, 0x9a, 0x31, 0x8a, 0x7e, 0x69, 0xeb, 0xa3, 0x21, 0x7b, 0x1b, 0x0a, + 0xfc, 0xd2, 0xab, 0x70, 0x92, 0x6d, 0xa5, 0xf7, 0xe3, 0x11, 0xe1, 0x34, 0x41, 0xc3, 0x3e, 0x84, + 0x72, 0x5c, 0x5b, 0xe1, 0x35, 0xba, 0x9c, 0x66, 0x88, 0xd1, 0x5a, 0x42, 0xa9, 0xf6, 0xa0, 0x9e, + 0xce, 0x90, 0xdd, 0x00, 0xe0, 0x59, 0x4a, 0xae, 0x51, 0x09, 0xc2, 0xae, 0x42, 0x74, 0x17, 0xb7, + 0x4d, 0x15, 0xab, 0xc5, 0x77, 0x73, 0xdb, 0xea, 0xef, 0xe5, 0x00, 0x12, 0xed, 0x1b, 0x3b, 0x22, + 0xf6, 0x85, 0xe5, 0x45, 0x24, 0xc0, 0x35, 0x28, 0x3b, 0x9e, 0x61, 0xca, 0x6f, 0x66, 0x94, 0x10, + 0x40, 0xc3, 0x24, 0xdf, 0x4b, 0x2b, 0xf3, 0x30, 0x1c, 0x76, 0x09, 0x0a, 0x13, 0xcf, 0x9f, 0x1a, + 0xa1, 0xb8, 0x45, 0x21, 0x52, 0xb8, 0x89, 0xda, 0x47, 0xae, 0xe7, 0x5b, 0x68, 0x83, 0xb8, 0x74, + 0x91, 0x02, 0xc7, 0xa0, 0x2a, 0x80, 0x3d, 0x84, 0xe1, 0x26, 0x68, 0xb9, 0x63, 0xc7, 0x0b, 0x2c, + 0x13, 0xb7, 0xb5, 0x02, 0x19, 0x1a, 0x10, 0x81, 0x76, 0xce, 0x79, 0x6b, 0xfd, 0xa9, 0xed, 0x1a, + 0xa1, 0x38, 0x1c, 0xa3, 0xd6, 0x46, 0x10, 0xac, 0xee, 0xd7, 0x81, 0x27, 0x5c, 0x63, 0xfc, 0x12, + 0x56, 0x09, 0x01, 0x54, 0xdd, 0xd7, 0x00, 0xac, 0x60, 0x6c, 0xcc, 0x78, 0xe6, 0x65, 0xca, 0xbc, + 0x2c, 0x20, 0x3b, 0xe7, 0xac, 0x07, 0xf5, 0xd1, 0x21, 0x6e, 0xfa, 0x5e, 0xdb, 0x08, 0x8d, 0x96, + 0xe7, 0x08, 0xa7, 0xd5, 0x9d, 0x45, 0x33, 0xe5, 0x41, 0x9a, 0x8c, 0xc7, 0x99, 0x2e, 0xf0, 0xb2, + 0x0f, 0xa0, 0x6a, 0x8f, 0xad, 0x43, 0xcb, 0x3f, 0xe2, 0x26, 0x4f, 0x25, 0x75, 0xfd, 0x81, 0x63, + 0xc8, 0xe6, 0xa9, 0xd8, 0x49, 0x02, 0x95, 0xa9, 0xa9, 0xe7, 0x1e, 0x79, 0xe6, 0x21, 0xe7, 0xaa, + 0xca, 0x06, 0xf8, 0x1e, 0x62, 0x38, 0x8f, 0x20, 0xc2, 0xc4, 0xd5, 0x26, 0x5c, 0x58, 0x51, 0xa1, + 0xef, 0x15, 0x04, 0xf9, 0xff, 0xad, 0x43, 0x45, 0xaa, 0x13, 0x9d, 0x68, 0x18, 0x33, 0xf2, 0xc8, + 0xc5, 0xd1, 0xdd, 0x65, 0x01, 0xe1, 0x17, 0x54, 0xc6, 0x46, 0x68, 0x38, 0xde, 0x91, 0x74, 0xf5, + 0x46, 0x40, 0xba, 0x26, 0x1d, 0x32, 0x1a, 0x53, 0x2b, 0x98, 0x19, 0xe3, 0x68, 0x55, 0x25, 0x80, + 0xe4, 0x81, 0x97, 0x9c, 0xfc, 0xc0, 0x8b, 0xc2, 0x4f, 0xa3, 0x79, 0x38, 0x0f, 0x1d, 0x3e, 0xdf, + 0x84, 0x4a, 0xa4, 0xe1, 0x62, 0x29, 0xe2, 0xc0, 0x34, 0x02, 0x75, 0x4d, 0x76, 0x17, 0x92, 0x07, + 0x6c, 0x74, 0x23, 0xd0, 0xbd, 0x49, 0x14, 0x4b, 0x18, 0x83, 0x9b, 0xc1, 0x60, 0x12, 0x9f, 0x62, + 0x90, 0xb6, 0x22, 0xe6, 0x04, 0x02, 0x48, 0xb0, 0x3d, 0x80, 0x0b, 0xc2, 0xb5, 0x6a, 0x99, 0xfa, + 0xc4, 0xb6, 0x1c, 0x53, 0xb7, 0x4d, 0x7e, 0xd6, 0x9f, 0xd7, 0x36, 0x63, 0xd4, 0x13, 0xc4, 0x74, + 0x4d, 0xd2, 0x05, 0x85, 0x3d, 0x6d, 0xda, 0x47, 0x56, 0x10, 0x8a, 0xc8, 0xb7, 0x2a, 0x07, 0xb6, + 0x09, 0xa6, 0xfe, 0x6d, 0x0e, 0xca, 0xf1, 0x60, 0xbd, 0xaa, 0x33, 0x6f, 0x43, 0x6d, 0xec, 0xb9, + 0xae, 0x45, 0x82, 0x32, 0xe9, 0xcf, 0x6a, 0x02, 0xa4, 0x28, 0x5e, 0x26, 0x11, 0x45, 0x31, 0xea, + 0xfc, 0xaa, 0xc9, 0x66, 0x82, 0x79, 0x26, 0xa2, 0xd5, 0xaf, 0x42, 0x09, 0x17, 0xe3, 0xa1, 0x11, + 0x44, 0xdd, 0x1c, 0xa7, 0x71, 0x09, 0x8d, 0x3d, 0xc7, 0xe1, 0x0c, 0xd1, 0x43, 0x05, 0x09, 0x84, + 0x3d, 0xa4, 0xa7, 0x2a, 0xe6, 0x53, 0x37, 0x68, 0x14, 0x68, 0xfe, 0x37, 0xa4, 0xd9, 0xd7, 0x22, + 0xcc, 0x1e, 0xaf, 0xbc, 0x16, 0x11, 0xb2, 0xcf, 0x40, 0x99, 0xcd, 0x83, 0x63, 0xcb, 0xd4, 0x67, + 0xbe, 0x65, 0x92, 0xe0, 0x17, 0xf1, 0xf6, 0x5b, 0x12, 0xf3, 0x7e, 0x84, 0xd3, 0x36, 0x38, 0x75, + 0x0c, 0x60, 0x6f, 0xc0, 0x46, 0x32, 0x0c, 0x33, 0x23, 0x3c, 0xe6, 0x61, 0x1a, 0x65, 0x34, 0xea, + 0x05, 0x78, 0x1f, 0xa1, 0xec, 0x03, 0xb8, 0xe4, 0x5b, 0x81, 0x6d, 0xce, 0x0d, 0x47, 0x4f, 0x0f, + 0x04, 0x7f, 0xf6, 0x60, 0x2b, 0xc2, 0x3e, 0x91, 0x06, 0x04, 0xb3, 0x9f, 0x1a, 0x67, 0xe4, 0x9c, + 0x72, 0x1c, 0xcb, 0xb1, 0x83, 0x29, 0x8d, 0x5b, 0x5e, 0xab, 0x4f, 0x8d, 0xb3, 0xfd, 0x04, 0x4a, + 0x51, 0x5a, 0x33, 0xc7, 0x5e, 0xb8, 0xad, 0xcc, 0xc7, 0x12, 0xe1, 0x1a, 0x47, 0x33, 0x15, 0x6a, + 0x98, 0x21, 0xd9, 0x61, 0x71, 0xe0, 0x45, 0x56, 0xab, 0x4c, 0x0d, 0x72, 0x58, 0xd2, 0xc9, 0xdd, + 0x1d, 0xa8, 0xc7, 0x34, 0xfc, 0x38, 0x5e, 0x9c, 0x88, 0x0b, 0x22, 0x7e, 0x22, 0x4f, 0x55, 0xe3, + 0xb3, 0x23, 0x1a, 0xd6, 0x3a, 0x8f, 0x0a, 0x17, 0xe0, 0x68, 0x4c, 0xaf, 0x00, 0x77, 0xf1, 0xe2, + 0x14, 0xd9, 0x20, 0x8a, 0x22, 0xa5, 0xbb, 0xa6, 0xfa, 0x5f, 0x66, 0x80, 0x2d, 0x0f, 0xcf, 0xcb, + 0x2e, 0x30, 0x61, 0xf7, 0x46, 0x97, 0x33, 0xf0, 0x37, 0x7b, 0x13, 0x8a, 0x53, 0x8f, 0x8b, 0xcc, + 0xec, 0x4b, 0xee, 0xc8, 0x16, 0xa6, 0x1e, 0x89, 0xd0, 0x37, 0x60, 0x63, 0xec, 0xb9, 0xa2, 0xa2, + 0x7c, 0x45, 0xf1, 0xf9, 0x55, 0x4f, 0xc0, 0xa4, 0xea, 0xff, 0x9f, 0x19, 0xa8, 0xa7, 0x07, 0x9d, + 0xdd, 0xa5, 0x57, 0x42, 0x52, 0xef, 0x8c, 0xa4, 0x29, 0x06, 0x33, 0x7a, 0x3d, 0x64, 0x55, 0x15, + 0x5f, 0x03, 0x20, 0x69, 0xa5, 0x1f, 0x06, 0x62, 0xde, 0x57, 0xb5, 0x32, 0x41, 0x76, 0x02, 0x8f, + 0x4e, 0x32, 0xf9, 0x43, 0x50, 0x1c, 0x9f, 0xdb, 0xce, 0xe2, 0xbe, 0xc1, 0x41, 0x44, 0xf0, 0x9e, + 0x74, 0xfa, 0xc2, 0x4f, 0x57, 0x56, 0x4f, 0xcc, 0x98, 0x4a, 0xfd, 0xd3, 0x0c, 0x40, 0x32, 0xee, + 0xd8, 0xfb, 0x27, 0xd6, 0x39, 0x4d, 0x4d, 0xd1, 0x9f, 0xc5, 0x13, 0xeb, 0x7c, 0x5f, 0xd4, 0x4d, + 0x9c, 0xdc, 0x05, 0x22, 0xf6, 0xb3, 0xaa, 0x95, 0xf9, 0x61, 0x5d, 0xc0, 0xaf, 0xb5, 0x89, 0xb3, + 0x3a, 0xa9, 0xea, 0xfc, 0x78, 0x2e, 0xa0, 0x8b, 0x25, 0x1b, 0x9c, 0xdb, 0x76, 0xc7, 0xce, 0x1c, + 0x2d, 0x71, 0x71, 0x81, 0x8f, 0x9f, 0x2d, 0x76, 0x23, 0x28, 0x12, 0xf2, 0x7c, 0x12, 0x42, 0x1e, + 0x8c, 0xc5, 0x4f, 0x12, 0x63, 0x42, 0xd5, 0x89, 0x36, 0xf5, 0x66, 0x18, 0xd2, 0xd5, 0xdc, 0xd8, + 0x2c, 0xce, 0x44, 0xb7, 0xf6, 0xb8, 0x45, 0x7c, 0x8d, 0x62, 0x56, 0xc5, 0x85, 0x0a, 0xb1, 0xb7, + 0xc7, 0x17, 0x25, 0xee, 0xe2, 0x48, 0x3b, 0x91, 0x48, 0x24, 0x12, 0x7e, 0x5d, 0xb3, 0x36, 0xf6, + 0x1c, 0x2e, 0x0e, 0x11, 0xa8, 0xfe, 0x37, 0x79, 0x80, 0xc4, 0x21, 0x9a, 0x9a, 0xa5, 0x99, 0xd4, + 0x2c, 0x65, 0x0f, 0xe1, 0x92, 0xb8, 0x77, 0x1c, 0x07, 0xc3, 0xd9, 0xae, 0x7e, 0x68, 0x44, 0xc1, + 0xb7, 0x4c, 0x60, 0x79, 0x98, 0x53, 0xd7, 0xdd, 0x31, 0x42, 0x34, 0xda, 0x65, 0x9e, 0xf0, 0x7c, + 0xf6, 0xd2, 0x29, 0x5a, 0x4b, 0xd8, 0x47, 0xe7, 0x33, 0xf6, 0x1e, 0x5c, 0xf4, 0xad, 0x89, 0x6f, + 0x05, 0xc7, 0x7a, 0x18, 0xc8, 0x85, 0xf1, 0xe8, 0xf8, 0x4d, 0x81, 0x1c, 0x05, 0x71, 0x59, 0xef, + 0xc1, 0x45, 0x21, 0x51, 0x16, 0xaa, 0xc7, 0x4f, 0x1c, 0x37, 0x39, 0x52, 0xae, 0x1d, 0x8d, 0x3c, + 0x79, 0x89, 0xa3, 0x07, 0xcb, 0x4a, 0x38, 0xf2, 0xd8, 0x19, 0xe2, 0x19, 0x0f, 0x72, 0xf5, 0x92, + 0x68, 0x2a, 0x69, 0x3c, 0xc1, 0x54, 0xc8, 0xe1, 0x0a, 0x21, 0x01, 0x54, 0x7f, 0x58, 0x7f, 0x40, + 0x0f, 0xb2, 0xd1, 0xb3, 0x2a, 0x68, 0x2f, 0x13, 0x8e, 0xbd, 0x83, 0xbb, 0x52, 0xd2, 0xec, 0xe8, + 0x4d, 0x21, 0x1e, 0x0f, 0xa6, 0x24, 0x0d, 0xd5, 0xf8, 0xeb, 0x42, 0x6f, 0x01, 0x93, 0x6a, 0x1e, + 0x51, 0x57, 0x89, 0x7a, 0x23, 0xae, 0xb6, 0x20, 0x7e, 0x03, 0xa8, 0x8a, 0x5c, 0x6c, 0xd5, 0x96, + 0xfd, 0xa2, 0x88, 0x24, 0xf9, 0xf5, 0x1e, 0x5c, 0x4c, 0x5a, 0xa7, 0x1b, 0xa1, 0x1e, 0x1e, 0x5b, + 0xba, 0xe5, 0x9a, 0x24, 0x9f, 0x4a, 0xda, 0x66, 0xdc, 0xd0, 0x66, 0x38, 0x3a, 0xb6, 0x3a, 0xae, + 0x29, 0x9f, 0x3c, 0x6d, 0x7c, 0xfb, 0xc9, 0xd3, 0x47, 0xd0, 0x48, 0xfb, 0x1e, 0xa4, 0xee, 0xe6, + 0x8f, 0x2d, 0x6c, 0xc9, 0x31, 0x75, 0x71, 0x8f, 0xdf, 0x87, 0xcd, 0x63, 0x23, 0x48, 0xfb, 0x2d, + 0xe8, 0x40, 0xac, 0xa4, 0x6d, 0x1c, 0x1b, 0x81, 0xec, 0xac, 0x50, 0xff, 0x38, 0x03, 0xf5, 0xb4, + 0x8b, 0x98, 0xdf, 0x60, 0xe5, 0x7b, 0x5b, 0x86, 0x76, 0xf8, 0x78, 0x07, 0xbb, 0x06, 0x65, 0x1e, + 0x78, 0x37, 0x9f, 0xba, 0xd1, 0x5a, 0x98, 0x9d, 0x70, 0x79, 0x8a, 0x02, 0x72, 0x76, 0xf2, 0x0a, + 0x01, 0x39, 0xe3, 0x17, 0x81, 0xde, 0x84, 0xe2, 0x5c, 0x90, 0xe6, 0x5e, 0x46, 0x3a, 0x27, 0x52, + 0xf5, 0x2f, 0xd7, 0xa1, 0x2a, 0x9f, 0x6c, 0x7c, 0x97, 0x88, 0xbc, 0xef, 0x15, 0x2c, 0xb9, 0x4d, + 0x31, 0xfd, 0x3a, 0xdd, 0x3a, 0xc2, 0x7e, 0xe2, 0xe1, 0x78, 0x70, 0x6c, 0x04, 0xcd, 0x79, 0x88, + 0x7b, 0x05, 0x29, 0x72, 0x9e, 0x13, 0xdd, 0x46, 0xe2, 0x2b, 0x03, 0x65, 0x82, 0xb8, 0x88, 0xf4, + 0x9e, 0xb8, 0xec, 0x48, 0xd7, 0x9b, 0x29, 0xfc, 0x3d, 0xbf, 0x34, 0x5f, 0xaa, 0xd1, 0xed, 0x66, + 0x0a, 0xf7, 0x7f, 0x08, 0x1b, 0xc9, 0xd5, 0x32, 0xce, 0x52, 0x58, 0x62, 0xa9, 0xc5, 0xf7, 0xca, + 0xc4, 0xd3, 0x2b, 0x35, 0x3b, 0xd0, 0x3d, 0xc7, 0x8c, 0xee, 0xb0, 0x16, 0xa3, 0x73, 0xe7, 0x81, + 0x63, 0x8a, 0x3b, 0xf5, 0x9c, 0xc6, 0xb5, 0x4e, 0x23, 0x9a, 0xf8, 0x6c, 0xba, 0x6f, 0x9d, 0x8a, + 0xbb, 0xac, 0x7f, 0x9d, 0x81, 0xcd, 0xa5, 0xc3, 0x0c, 0x54, 0x2c, 0x93, 0x87, 0x00, 0xf1, 0x27, + 0xbb, 0x05, 0xd5, 0xa9, 0x11, 0x8e, 0x8f, 0x51, 0x57, 0x99, 0xd8, 0x67, 0xd1, 0x6b, 0x86, 0x04, + 0xdb, 0x27, 0x10, 0xee, 0x27, 0x5c, 0xd6, 0xf2, 0xe3, 0x5e, 0x2e, 0xf8, 0xb8, 0x18, 0xef, 0xd1, + 0x39, 0x6f, 0x74, 0x1d, 0x20, 0xf7, 0x92, 0xeb, 0x00, 0x57, 0xa1, 0xec, 0x7a, 0x14, 0xfa, 0x39, + 0x3b, 0x11, 0x62, 0xba, 0xe8, 0x7a, 0xe1, 0xc0, 0xdd, 0x3f, 0x61, 0x0f, 0xe1, 0xe2, 0x3c, 0xa0, + 0xf8, 0xaa, 0x43, 0xcb, 0x0f, 0x8e, 0xed, 0xd8, 0xad, 0xc8, 0x05, 0xc8, 0x85, 0x79, 0x60, 0xed, + 0xc5, 0x38, 0xde, 0x12, 0xf5, 0x3a, 0x14, 0xba, 0xf1, 0x21, 0x4c, 0x1c, 0x7f, 0x9c, 0x15, 0x4f, + 0x80, 0x79, 0x50, 0xe6, 0xde, 0xb9, 0x3d, 0x63, 0xc6, 0xee, 0x43, 0x76, 0x6a, 0xcc, 0x44, 0x50, + 0x47, 0x23, 0x8e, 0x7c, 0xe1, 0xd8, 0x07, 0x7b, 0xc6, 0x8c, 0xdb, 0x2b, 0x48, 0x74, 0xf5, 0x23, + 0x28, 0x45, 0x80, 0xef, 0x65, 0x2f, 0xfc, 0xa3, 0x75, 0x28, 0xb7, 0xe5, 0x43, 0x54, 0xd4, 0x71, + 0x42, 0x7f, 0xee, 0x92, 0xe6, 0x27, 0x1e, 0x46, 0x1a, 0x1b, 0xee, 0x48, 0x80, 0xa2, 0xa9, 0xbd, + 0xfe, 0x2d, 0x53, 0xfb, 0x3a, 0x80, 0x4f, 0x67, 0x10, 0x74, 0x0c, 0x91, 0x8d, 0xef, 0x63, 0x74, + 0xcd, 0xae, 0x79, 0xb6, 0x3a, 0x14, 0x35, 0xf7, 0xdd, 0x43, 0x51, 0xf3, 0x2b, 0x43, 0x51, 0xef, + 0x26, 0xdb, 0x0b, 0x4e, 0x71, 0x2c, 0xb8, 0xcc, 0x37, 0xb9, 0x59, 0x7c, 0xb5, 0x13, 0x4b, 0xff, + 0x14, 0xea, 0x51, 0xeb, 0x44, 0x7e, 0x90, 0xba, 0x4d, 0x2a, 0x70, 0xfc, 0xd4, 0xb5, 0x16, 0xca, + 0xc9, 0xf4, 0x92, 0xad, 0xbc, 0x22, 0xdc, 0xf5, 0xbf, 0xcb, 0x00, 0x13, 0x3e, 0xf3, 0x27, 0x73, + 0xc7, 0x19, 0x59, 0x67, 0x24, 0x19, 0xee, 0xc3, 0xa6, 0x38, 0x14, 0x96, 0x6e, 0xf1, 0x8b, 0x30, + 0x28, 0x8e, 0x48, 0xc2, 0xa0, 0x56, 0x5d, 0xf8, 0x5f, 0x5f, 0x79, 0xe1, 0x7f, 0xf5, 0x43, 0x02, + 0x37, 0xa1, 0x22, 0x5f, 0x97, 0xe7, 0xea, 0x1d, 0x18, 0xc9, 0x4d, 0xf9, 0xbf, 0x5e, 0x07, 0x48, + 0xfc, 0xfa, 0xbf, 0xee, 0x38, 0xe2, 0x15, 0x43, 0x92, 0x5d, 0x35, 0x24, 0xf7, 0x40, 0x91, 0xe9, + 0xa4, 0x77, 0x1b, 0xea, 0x09, 0x61, 0xa4, 0xe6, 0xd8, 0x81, 0x7c, 0xb7, 0x9e, 0xae, 0xe9, 0x89, + 0xd0, 0x4b, 0x8e, 0xe4, 0x87, 0x8c, 0x62, 0x01, 0x96, 0xec, 0x80, 0xcb, 0x64, 0xf6, 0x09, 0x5c, + 0x89, 0x39, 0xf5, 0x53, 0x3b, 0x3c, 0xf6, 0xe6, 0xa1, 0x58, 0xac, 0x81, 0x90, 0x52, 0x97, 0xa2, + 0x9c, 0x9e, 0x73, 0x34, 0x5f, 0xaf, 0x01, 0xfb, 0x10, 0xca, 0x93, 0xb9, 0xe3, 0xe8, 0xa1, 0x75, + 0x16, 0x8a, 0xb7, 0x96, 0x1a, 0xa9, 0x23, 0x11, 0x69, 0x78, 0xb5, 0xd2, 0x44, 0x24, 0xd4, 0x7f, + 0x97, 0x85, 0xfc, 0x4f, 0xe6, 0x96, 0x7f, 0xce, 0x3e, 0x82, 0x72, 0x10, 0x4e, 0x43, 0x39, 0x3a, + 0xe9, 0x0a, 0xcf, 0x80, 0xf0, 0x14, 0x5c, 0x64, 0x4d, 0x2d, 0x37, 0xe4, 0x67, 0x85, 0x48, 0x4b, + 0x1b, 0xd0, 0x16, 0xe4, 0x83, 0xd0, 0x9a, 0x05, 0xe2, 0x8e, 0x01, 0x4f, 0xb0, 0x6d, 0xc8, 0xbb, + 0x9e, 0x69, 0x05, 0xe9, 0x9b, 0x04, 0x7d, 0xd4, 0x38, 0x38, 0x82, 0xa9, 0x50, 0x88, 0x47, 0x7c, + 0x29, 0x42, 0x88, 0x63, 0xe8, 0x7e, 0xa2, 0x65, 0x98, 0xb6, 0x7b, 0x14, 0xbd, 0x83, 0x11, 0xa7, + 0x71, 0x6b, 0x25, 0xbf, 0x90, 0x71, 0x14, 0xbd, 0x9f, 0x23, 0x92, 0x6c, 0x1b, 0x2a, 0xf8, 0xf3, + 0xb9, 0x6f, 0x87, 0xd6, 0xf0, 0x51, 0x24, 0xdd, 0x25, 0x10, 0x9a, 0xa4, 0xa6, 0x15, 0x5a, 0xe3, + 0x70, 0xf8, 0x8d, 0x13, 0x19, 0x7e, 0x12, 0x84, 0x7d, 0x0a, 0xec, 0xd0, 0x18, 0x9f, 0x1c, 0xf9, + 0x14, 0x55, 0xf7, 0xcd, 0xdc, 0xf2, 0x6d, 0x2b, 0x8a, 0xc7, 0xaf, 0x48, 0x9d, 0xa2, 0x6d, 0x26, + 0x64, 0x3f, 0xe1, 0x54, 0xec, 0x12, 0x14, 0xa6, 0xc6, 0x59, 0xdb, 0x9b, 0x89, 0x70, 0x67, 0x91, + 0x62, 0x8f, 0xe0, 0x12, 0x6e, 0x8e, 0xd1, 0xc3, 0x0c, 0x38, 0x87, 0xc4, 0x29, 0x14, 0x7f, 0xec, + 0xee, 0xc2, 0xb1, 0x11, 0x24, 0x77, 0xb1, 0xb9, 0x1b, 0x53, 0xfd, 0x1d, 0xa8, 0xa5, 0xfa, 0x7d, + 0xe9, 0x10, 0x63, 0xd8, 0xe9, 0x75, 0x5a, 0x23, 0xee, 0xda, 0x14, 0xce, 0xf5, 0x75, 0xc9, 0x0b, + 0x9f, 0x93, 0x5c, 0x9e, 0x79, 0xf2, 0xe1, 0x77, 0xb4, 0xa7, 0x1d, 0xa5, 0xa0, 0xe6, 0x4a, 0x59, + 0x25, 0xab, 0xfe, 0xf7, 0xeb, 0xb0, 0x39, 0xf2, 0x0d, 0x37, 0x30, 0xb8, 0x0e, 0xe3, 0x86, 0xbe, + 0xe7, 0xb0, 0x4f, 0xa1, 0x14, 0x8e, 0x1d, 0x79, 0x22, 0xdc, 0x8c, 0xc4, 0xce, 0x02, 0xe9, 0x83, + 0xd1, 0x98, 0x1f, 0x1d, 0x17, 0x43, 0xfe, 0x83, 0xbd, 0x03, 0xf9, 0x43, 0xeb, 0xc8, 0x76, 0x85, + 0xe4, 0xbd, 0xb8, 0xc8, 0xb8, 0x83, 0xc8, 0xdd, 0x35, 0x8d, 0x53, 0xb1, 0xf7, 0xa0, 0x30, 0xf6, + 0xa6, 0xd1, 0x96, 0x97, 0xdc, 0xca, 0x96, 0x0a, 0x42, 0xec, 0xee, 0x9a, 0x26, 0xe8, 0xd8, 0x47, + 0x50, 0xf2, 0x3d, 0xc7, 0xc1, 0x7e, 0x17, 0x9b, 0x61, 0x63, 0x91, 0x47, 0x13, 0xf8, 0xdd, 0x35, + 0x2d, 0xa6, 0x55, 0x1f, 0x40, 0x51, 0x54, 0x16, 0xbb, 0x61, 0xa7, 0xf3, 0xb4, 0x2b, 0x7a, 0xb0, + 0x35, 0xd8, 0xdb, 0xeb, 0x8e, 0xf8, 0x93, 0x13, 0xda, 0xa0, 0xd7, 0xdb, 0x69, 0xb6, 0xbe, 0x50, + 0xd6, 0x77, 0x4a, 0x50, 0xe0, 0xc3, 0xa3, 0xfe, 0x5e, 0x06, 0x36, 0x16, 0x1a, 0xc0, 0x1e, 0x43, + 0x8e, 0x6c, 0x51, 0xde, 0x3d, 0x77, 0x56, 0xb6, 0x52, 0x4a, 0x73, 0x4d, 0x1b, 0x39, 0xd4, 0x4f, + 0xa0, 0x9e, 0x86, 0x4b, 0x8e, 0xf3, 0x1a, 0x94, 0xb5, 0x4e, 0xb3, 0xad, 0x0f, 0xfa, 0xbd, 0xaf, + 0xf8, 0x39, 0x14, 0x25, 0x9f, 0x6b, 0x5d, 0xf2, 0x58, 0xff, 0x36, 0x28, 0x8b, 0x1d, 0xc3, 0x9e, + 0xa2, 0xd5, 0x34, 0x9d, 0x39, 0x16, 0x29, 0xa7, 0xd2, 0x90, 0xdd, 0x58, 0xd1, 0x93, 0x82, 0x8c, + 0x87, 0x83, 0x8e, 0x53, 0x69, 0xf5, 0x77, 0x80, 0x2d, 0xf7, 0xe0, 0xaf, 0x2f, 0xfb, 0x7f, 0x9b, + 0x81, 0xdc, 0xbe, 0x63, 0xb8, 0xec, 0x36, 0xe4, 0xe9, 0x55, 0x37, 0x21, 0xbf, 0xe5, 0xd5, 0x84, + 0xd3, 0x82, 0x70, 0xec, 0x2d, 0xc8, 0x86, 0xe3, 0xe8, 0xa5, 0x8b, 0xcb, 0x2f, 0x99, 0x7c, 0xbb, + 0x6b, 0x1a, 0x52, 0xb1, 0x7b, 0x90, 0x35, 0xcd, 0xe8, 0x76, 0x98, 0xb0, 0xb2, 0xdb, 0x46, 0x68, + 0xb4, 0xad, 0x89, 0xed, 0xda, 0xe2, 0x15, 0x3a, 0x24, 0x61, 0xaf, 0x43, 0xd6, 0x1c, 0x3b, 0xe9, + 0xab, 0x7e, 0xdc, 0x85, 0x19, 0x67, 0x68, 0x8e, 0x1d, 0xd4, 0xfd, 0x42, 0xff, 0x5c, 0xf7, 0xe7, + 0x2e, 0xdd, 0x2b, 0x08, 0x84, 0x3d, 0x56, 0x41, 0x2d, 0x66, 0x4e, 0x97, 0x13, 0x02, 0x71, 0x65, + 0x7e, 0xe6, 0x5b, 0x33, 0xc3, 0x8f, 0x2d, 0x31, 0x3b, 0xd8, 0xe7, 0x80, 0x9d, 0x02, 0xd0, 0x63, + 0xd9, 0xea, 0xdb, 0xf4, 0xe4, 0x18, 0xaa, 0xf4, 0x6a, 0xf4, 0x6b, 0xc5, 0xbb, 0xaa, 0x02, 0xa3, + 0xfe, 0x4d, 0x16, 0x2a, 0x52, 0x7d, 0xd8, 0x07, 0x50, 0x32, 0xd3, 0x0b, 0xf1, 0xca, 0x52, 0xa5, + 0x1f, 0xb4, 0xa3, 0x25, 0x68, 0x8a, 0xe9, 0x4d, 0x71, 0x09, 0xa1, 0xfe, 0xc2, 0xf0, 0x6d, 0xfe, + 0xd0, 0xe4, 0xba, 0x1c, 0x20, 0x30, 0xb4, 0xc2, 0x67, 0x11, 0x66, 0x77, 0x4d, 0xab, 0x06, 0x52, + 0x9a, 0xec, 0x0e, 0xd1, 0xa4, 0x6c, 0xea, 0xc1, 0x4e, 0x0e, 0xdc, 0x5d, 0xd3, 0x22, 0x3c, 0x92, + 0x5a, 0x67, 0xd6, 0x78, 0x1e, 0x46, 0x76, 0x47, 0x2d, 0x6a, 0x10, 0x01, 0xe9, 0xd5, 0x60, 0xfe, + 0x93, 0x3d, 0x44, 0x69, 0x6b, 0x38, 0x8e, 0x47, 0xca, 0x5a, 0x5e, 0x76, 0x74, 0xb5, 0x63, 0x38, + 0x7f, 0xa5, 0x38, 0x4a, 0xb1, 0xbb, 0x90, 0xf7, 0xc2, 0x63, 0x2b, 0xd2, 0xe6, 0xa3, 0xc7, 0xcb, + 0x10, 0xd4, 0x6e, 0xf5, 0x70, 0xa6, 0x10, 0x5a, 0xfd, 0x93, 0x0c, 0x14, 0x45, 0x0f, 0xb0, 0x4d, + 0xa8, 0x0d, 0x3b, 0x23, 0xfd, 0x59, 0x53, 0xeb, 0x36, 0x77, 0x7a, 0x1d, 0x71, 0x43, 0xf1, 0xa9, + 0xd6, 0xec, 0x0b, 0x01, 0xa9, 0x75, 0x9e, 0x0d, 0xbe, 0xe8, 0xf0, 0xd3, 0xa8, 0x76, 0xa7, 0xff, + 0x95, 0x92, 0xe5, 0x47, 0xaf, 0x9d, 0xfd, 0xa6, 0x86, 0xb2, 0xb2, 0x02, 0xc5, 0xce, 0x97, 0x9d, + 0xd6, 0x01, 0x09, 0xcb, 0x3a, 0x40, 0xbb, 0xd3, 0xec, 0xf5, 0x06, 0x2d, 0x14, 0x9e, 0x05, 0xc6, + 0xa0, 0xde, 0xd2, 0x3a, 0xcd, 0x51, 0x47, 0x6f, 0xb6, 0x5a, 0x83, 0x83, 0xfe, 0x48, 0x29, 0x62, + 0x89, 0xcd, 0xde, 0xa8, 0xa3, 0xc5, 0x20, 0x7a, 0x50, 0xb2, 0xad, 0x0d, 0xf6, 0x63, 0x48, 0x79, + 0xa7, 0x8c, 0x36, 0x20, 0x8d, 0x95, 0xfa, 0x67, 0x9b, 0x50, 0x4f, 0x4f, 0x4d, 0xf6, 0x31, 0x94, + 0x4c, 0x33, 0x35, 0xc6, 0xd7, 0x57, 0x4d, 0xe1, 0x07, 0x6d, 0x33, 0x1a, 0x66, 0xfe, 0x83, 0xdd, + 0x8a, 0x16, 0xd2, 0xfa, 0xd2, 0x42, 0x8a, 0x96, 0xd1, 0x67, 0xb0, 0x21, 0x5e, 0xd4, 0x8a, 0x9d, + 0xb3, 0xa9, 0x55, 0xd2, 0x22, 0x64, 0x5b, 0xe0, 0x76, 0xd7, 0xb4, 0xfa, 0x38, 0x05, 0x61, 0x3f, + 0x82, 0xba, 0xc1, 0x5d, 0x9e, 0xb2, 0x73, 0x37, 0x56, 0x43, 0x9b, 0xe4, 0xf1, 0x4c, 0xd8, 0x6b, + 0x86, 0x0c, 0xc0, 0x89, 0x68, 0xfa, 0xde, 0x2c, 0x61, 0xce, 0xa7, 0x22, 0x55, 0x7c, 0x6f, 0x26, + 0xf1, 0x56, 0x4d, 0x29, 0xcd, 0x3e, 0x82, 0xaa, 0xa8, 0x79, 0xe2, 0xea, 0x88, 0x97, 0x2c, 0xaf, + 0x36, 0xa9, 0x95, 0xbb, 0x6b, 0x5a, 0x65, 0x9c, 0x24, 0xd9, 0x23, 0xd4, 0x25, 0x13, 0x25, 0xbc, + 0x28, 0xcf, 0x35, 0xaa, 0x6d, 0xc4, 0x05, 0x46, 0x9c, 0x62, 0xef, 0x01, 0x50, 0x3d, 0x39, 0x4f, + 0x29, 0x15, 0xc3, 0xe9, 0x7b, 0xb3, 0x88, 0xa5, 0x6c, 0x46, 0x09, 0xa9, 0x7a, 0xdc, 0x51, 0x55, + 0x5e, 0xae, 0x1e, 0x39, 0xab, 0x92, 0xea, 0x71, 0x1f, 0x57, 0x5c, 0x3d, 0xce, 0x06, 0x4b, 0xd5, + 0x8b, 0xb8, 0x78, 0xf5, 0x38, 0x53, 0x54, 0x3d, 0xce, 0x53, 0x59, 0xac, 0x5e, 0xc4, 0x42, 0xd5, + 0xe3, 0x1c, 0x3f, 0x5a, 0xb2, 0x1e, 0xaa, 0x2f, 0xb5, 0x1e, 0x70, 0xd8, 0xd2, 0xf6, 0xc3, 0x8f, + 0xa0, 0x1e, 0x1c, 0x7b, 0xa7, 0x92, 0x00, 0xa9, 0xc9, 0xdc, 0xc3, 0x63, 0xef, 0x54, 0x96, 0x20, + 0xb5, 0x40, 0x06, 0x60, 0x6d, 0x79, 0x13, 0x29, 0xaa, 0xa4, 0x2e, 0xd7, 0x96, 0x5a, 0xf8, 0xcc, + 0xb6, 0x4e, 0xb1, 0xb6, 0x46, 0x94, 0xc0, 0x4e, 0x49, 0xdc, 0x3e, 0x81, 0x70, 0xe4, 0xa4, 0x22, + 0x1f, 0x45, 0x49, 0x10, 0x3b, 0x80, 0x02, 0x9c, 0x5b, 0x73, 0x57, 0x66, 0x53, 0xe4, 0xb9, 0x75, + 0xe0, 0xa6, 0x18, 0xab, 0x9c, 0x54, 0xb0, 0x26, 0xab, 0x22, 0xb0, 0xbe, 0x99, 0x5b, 0xee, 0xd8, + 0x12, 0x11, 0xce, 0xa9, 0x55, 0x31, 0x14, 0xb8, 0x64, 0x55, 0x44, 0x90, 0x78, 0x5e, 0xc7, 0xec, + 0x6c, 0x71, 0x5e, 0x4b, 0xcc, 0x34, 0xaf, 0x63, 0xd6, 0x78, 0x41, 0xc5, 0xbc, 0x17, 0x96, 0x16, + 0x94, 0xc4, 0xcc, 0x17, 0x54, 0xcc, 0xfd, 0x08, 0xc4, 0x6c, 0xe2, 0x9d, 0x9b, 0x8a, 0x83, 0xe6, + 0xb5, 0x16, 0xbd, 0x0b, 0xe3, 0x38, 0x85, 0x73, 0xd5, 0xb7, 0xd0, 0x5a, 0x11, 0x53, 0xe1, 0xa2, + 0x3c, 0x57, 0x35, 0xc2, 0xc4, 0x4b, 0xc9, 0x4f, 0x92, 0x52, 0x61, 0x33, 0x3b, 0xf4, 0x1b, 0xe6, + 0x72, 0x61, 0xfb, 0x76, 0xe8, 0x27, 0x85, 0x61, 0x8a, 0xbd, 0x03, 0x34, 0x0d, 0x39, 0x8b, 0x25, + 0x8b, 0x6e, 0xec, 0x16, 0xc1, 0x50, 0x32, 0xc5, 0x6f, 0x9c, 0x2c, 0xa2, 0x8c, 0xb1, 0x39, 0x6e, + 0x4c, 0xe4, 0xc9, 0xc2, 0x8b, 0x68, 0xb5, 0x5b, 0x38, 0x59, 0x38, 0x51, 0xcb, 0x1c, 0xb3, 0xfb, + 0x40, 0xdc, 0x44, 0x7f, 0x94, 0x7a, 0x1c, 0xd3, 0xf7, 0x66, 0x9c, 0xba, 0x88, 0x04, 0x48, 0x8b, + 0x2d, 0x70, 0x3c, 0x37, 0x6a, 0xf8, 0x71, 0xaa, 0x05, 0x88, 0x88, 0x85, 0xc1, 0x38, 0x4e, 0xa9, + 0x7f, 0x50, 0x80, 0xa2, 0x90, 0xb5, 0xec, 0x02, 0x6c, 0x08, 0x91, 0xdf, 0x6e, 0x8e, 0x9a, 0x3b, + 0xcd, 0x21, 0x2a, 0x69, 0x0c, 0xea, 0x5c, 0xe6, 0xc7, 0xb0, 0x0c, 0xee, 0x03, 0x24, 0xf4, 0x63, + 0xd0, 0x3a, 0xee, 0x03, 0x82, 0x97, 0x3f, 0x42, 0x9c, 0x65, 0x1b, 0x50, 0xe1, 0x8c, 0x1c, 0x40, + 0x0f, 0x26, 0x10, 0x17, 0x4f, 0xe7, 0x25, 0x16, 0x1e, 0x9c, 0x51, 0x48, 0x58, 0x38, 0xa0, 0x18, + 0xb3, 0x44, 0xd1, 0x1b, 0x0c, 0xea, 0x23, 0xed, 0xa0, 0xdf, 0x4a, 0xca, 0x29, 0xd3, 0x25, 0x77, + 0x9e, 0xcd, 0xb3, 0x6e, 0xe7, 0xb9, 0x02, 0xc8, 0xc4, 0x73, 0xa1, 0x74, 0x05, 0xd5, 0x4c, 0xca, + 0x84, 0x92, 0x55, 0x76, 0x19, 0x2e, 0x0c, 0x77, 0x07, 0xcf, 0x75, 0xce, 0x14, 0x37, 0xa1, 0xc6, + 0xb6, 0x40, 0x91, 0x10, 0x3c, 0xfb, 0x3a, 0x16, 0x49, 0xd0, 0x88, 0x70, 0xa8, 0x6c, 0x50, 0xa0, + 0x13, 0xc2, 0x46, 0x7c, 0xdf, 0x55, 0xb0, 0x29, 0x9c, 0x75, 0xd0, 0x3b, 0xd8, 0xeb, 0x0f, 0x95, + 0x4d, 0xac, 0x04, 0x41, 0x78, 0xcd, 0x59, 0x9c, 0x4d, 0xb2, 0x5b, 0x5f, 0xa0, 0x0d, 0x1c, 0x61, + 0xcf, 0x9b, 0x5a, 0xbf, 0xdb, 0x7f, 0x3a, 0x54, 0xb6, 0xe2, 0x9c, 0x3b, 0x9a, 0x36, 0xd0, 0x86, + 0xca, 0xc5, 0x18, 0x30, 0x1c, 0x35, 0x47, 0x07, 0x43, 0xe5, 0x52, 0x5c, 0xcb, 0x7d, 0x6d, 0xd0, + 0xea, 0x0c, 0x87, 0xbd, 0xee, 0x70, 0xa4, 0x5c, 0x66, 0x17, 0x61, 0x33, 0xa9, 0x51, 0x44, 0xdc, + 0x90, 0x2a, 0xaa, 0x3d, 0xed, 0x8c, 0x94, 0x2b, 0x71, 0x35, 0x5a, 0x83, 0x5e, 0xaf, 0x49, 0x01, + 0x25, 0x57, 0x91, 0x88, 0x02, 0x97, 0x44, 0x6b, 0xae, 0x61, 0xbd, 0x0e, 0xfa, 0x32, 0xe8, 0xba, + 0x34, 0x35, 0x86, 0x9d, 0x9f, 0x1c, 0x74, 0xfa, 0xad, 0x8e, 0xf2, 0x5a, 0x32, 0x35, 0x62, 0xd8, + 0x8d, 0x78, 0x6a, 0xc4, 0xa0, 0x9b, 0x71, 0x99, 0x11, 0x68, 0xa8, 0x6c, 0x63, 0x7e, 0xa2, 0x1e, + 0xfd, 0x7e, 0xa7, 0x35, 0xc2, 0xb6, 0xde, 0x8a, 0x7b, 0xf1, 0x60, 0xff, 0xa9, 0xd6, 0x6c, 0x77, + 0x14, 0x15, 0x21, 0x5a, 0xa7, 0xdf, 0xdc, 0x8b, 0x46, 0xfb, 0xb6, 0x34, 0xda, 0xfb, 0xdd, 0x91, + 0xa6, 0xdc, 0x89, 0x47, 0x97, 0x92, 0xaf, 0xb3, 0x6b, 0x70, 0x59, 0x9e, 0x87, 0xfa, 0xf3, 0xee, + 0x68, 0x57, 0x04, 0x1d, 0xdd, 0xe5, 0x61, 0x2f, 0x84, 0x6c, 0xb5, 0x5b, 0x3c, 0xba, 0x8a, 0x78, + 0x31, 0x75, 0x6f, 0xa7, 0x4a, 0xdf, 0x92, 0x10, 0x0a, 0x88, 0xfa, 0x39, 0x30, 0xf9, 0x59, 0x75, + 0x71, 0x51, 0x84, 0x41, 0x6e, 0xe2, 0x7b, 0xd3, 0xe8, 0xc8, 0x0f, 0x7f, 0xa3, 0xfd, 0x3d, 0x9b, + 0x1f, 0x52, 0x38, 0x4e, 0xf2, 0x38, 0x89, 0x0c, 0x52, 0xff, 0x97, 0x0c, 0xd4, 0xd3, 0xca, 0x07, + 0x39, 0x5c, 0x27, 0xba, 0xeb, 0x85, 0xfc, 0x35, 0xc8, 0x20, 0x7e, 0xed, 0x7c, 0xd2, 0xf7, 0x42, + 0x7a, 0x0e, 0x32, 0x48, 0x9d, 0x32, 0xaf, 0x2f, 0x9c, 0x32, 0x77, 0xe1, 0x42, 0xea, 0x65, 0xfa, + 0xd4, 0x5b, 0x9c, 0x8d, 0xf8, 0x45, 0xe9, 0x85, 0xfa, 0x6b, 0x2c, 0x58, 0x6e, 0x93, 0x78, 0x62, + 0x26, 0x97, 0x3c, 0x31, 0xb3, 0x0b, 0xb5, 0x94, 0xae, 0x43, 0x5e, 0x9c, 0x49, 0xba, 0xa6, 0x25, + 0x7b, 0xf2, 0xea, 0x6a, 0xaa, 0xff, 0x53, 0x06, 0xaa, 0xb2, 0xe6, 0xf3, 0x83, 0x73, 0xa2, 0xf8, + 0x4d, 0xf1, 0x5b, 0xb7, 0xcd, 0xe8, 0x15, 0xc8, 0x08, 0xd4, 0xa5, 0x6f, 0xe8, 0x70, 0xdf, 0xf5, + 0x93, 0x93, 0x61, 0xdc, 0x1c, 0x19, 0x44, 0x27, 0xf3, 0xc7, 0xd6, 0xf8, 0xe4, 0xc9, 0x17, 0x48, + 0x10, 0x9d, 0xcc, 0xc7, 0x10, 0xf5, 0x26, 0x94, 0x9f, 0x9c, 0x44, 0xe1, 0xac, 0xf2, 0x9b, 0xa8, + 0x65, 0xfe, 0xa2, 0x8d, 0xfa, 0xa7, 0x19, 0xa8, 0x27, 0x3e, 0x0b, 0x0a, 0x84, 0xe2, 0x5f, 0x34, + 0xe0, 0xd3, 0x61, 0xdd, 0x3c, 0x4c, 0xa2, 0x2f, 0xd6, 0xe5, 0xe8, 0x8b, 0xdb, 0x22, 0xb3, 0xac, + 0x2c, 0xf2, 0xe3, 0xb2, 0xc4, 0x7b, 0x39, 0x8f, 0xa0, 0x8a, 0xff, 0x35, 0x6b, 0x62, 0xf9, 0xbe, + 0x65, 0xa6, 0xaf, 0xef, 0x25, 0xc4, 0x29, 0x22, 0xb2, 0xf1, 0x44, 0x5c, 0xc7, 0x4b, 0x9e, 0xb8, + 0xa3, 0xa7, 0x17, 0xff, 0x75, 0x16, 0x2a, 0x92, 0x1e, 0xf9, 0x9d, 0xa6, 0xdf, 0x75, 0x28, 0x27, + 0x0f, 0xae, 0x89, 0x47, 0x4a, 0x62, 0x40, 0x6a, 0xac, 0xb2, 0x0b, 0x63, 0xd5, 0x80, 0xa2, 0xcf, + 0x1f, 0x15, 0x10, 0x2e, 0xe4, 0x28, 0x99, 0x76, 0xd6, 0xe6, 0x5f, 0x71, 0xbe, 0xf2, 0x3e, 0x54, + 0x25, 0x4f, 0x6b, 0x14, 0x2e, 0xb1, 0x48, 0x5f, 0x49, 0xbc, 0xae, 0x01, 0xbb, 0x08, 0x85, 0xc9, + 0x89, 0x6e, 0x1e, 0xf2, 0xa7, 0x2b, 0xca, 0x5a, 0x7e, 0x72, 0xd2, 0x3e, 0xa4, 0xd3, 0xa7, 0x49, + 0xac, 0x3a, 0x71, 0xff, 0x57, 0x69, 0x12, 0x29, 0x48, 0xf7, 0xa0, 0x38, 0x39, 0x91, 0x9f, 0xa0, + 0x58, 0xea, 0xf2, 0xc2, 0xe4, 0x84, 0x1e, 0x9e, 0x78, 0x17, 0xb6, 0xc4, 0xfe, 0x6d, 0x04, 0x3a, + 0x7f, 0x0f, 0x8a, 0x1e, 0xe2, 0xe3, 0x2f, 0xa4, 0x6e, 0x72, 0x5c, 0x33, 0x18, 0x12, 0x06, 0x67, + 0x9c, 0x0a, 0x55, 0x69, 0x02, 0xf2, 0x17, 0x0b, 0xcb, 0x5a, 0x0a, 0xc6, 0x1e, 0x43, 0x75, 0x72, + 0xc2, 0x07, 0x74, 0xe4, 0xed, 0x59, 0xe2, 0x46, 0xdd, 0xd6, 0xe2, 0x50, 0x52, 0xa4, 0x5a, 0x8a, + 0x92, 0x5d, 0x82, 0x82, 0x66, 0x9c, 0x0e, 0x7f, 0xd2, 0x23, 0x25, 0xb2, 0xac, 0x89, 0xd4, 0xe7, + 0xb9, 0x52, 0x5d, 0xd9, 0x50, 0xff, 0xef, 0x0c, 0xd4, 0x13, 0x1b, 0x00, 0x17, 0x21, 0xbb, 0x2f, + 0x7f, 0x8a, 0xa4, 0xb1, 0x68, 0x26, 0x20, 0xc9, 0x83, 0xd1, 0xf9, 0x8c, 0x3f, 0xd8, 0xbd, 0xea, + 0x95, 0xc9, 0x55, 0xae, 0xef, 0xec, 0xca, 0x8f, 0x20, 0x3c, 0x85, 0xec, 0xe8, 0x7c, 0xc6, 0xfd, + 0x4d, 0xb8, 0x25, 0x72, 0xdb, 0x94, 0x6f, 0x86, 0x14, 0x50, 0xf9, 0x45, 0xe7, 0x2b, 0xfe, 0xa8, + 0xd2, 0xbe, 0xd6, 0xdd, 0x6b, 0x6a, 0x5f, 0xe9, 0x08, 0x20, 0xa5, 0xe1, 0xc9, 0x40, 0xeb, 0x74, + 0x9f, 0xf6, 0x09, 0x90, 0x23, 0x6f, 0x54, 0x52, 0xc5, 0xa6, 0x69, 0x3e, 0x39, 0x91, 0x1f, 0xe8, + 0xcb, 0xa4, 0x1e, 0xe8, 0x8b, 0xdf, 0xb2, 0x94, 0x1f, 0xf6, 0x0d, 0x63, 0x7f, 0x3c, 0x8b, 0x57, + 0x61, 0xbc, 0xa4, 0xd9, 0x1b, 0x90, 0x9b, 0x9c, 0x58, 0xe7, 0x69, 0x43, 0x2f, 0xbd, 0x80, 0x88, + 0x40, 0xfd, 0x65, 0x06, 0x58, 0xaa, 0x22, 0xdc, 0xf6, 0xf8, 0xa1, 0x75, 0xf9, 0x18, 0x1a, 0x22, + 0x62, 0x9d, 0x53, 0x49, 0xbe, 0x76, 0xd1, 0xa5, 0x17, 0xbd, 0xe4, 0x26, 0x47, 0xf2, 0x10, 0x26, + 0x7b, 0x17, 0xf8, 0x9b, 0xbd, 0x14, 0xd8, 0x98, 0x7b, 0x89, 0x9d, 0xa8, 0x25, 0x34, 0xc9, 0x23, + 0xbd, 0xf2, 0xe3, 0xc3, 0xdc, 0x4d, 0xbf, 0x91, 0x8c, 0x1a, 0xad, 0x79, 0xf5, 0x8f, 0x32, 0x70, + 0x21, 0x3d, 0x21, 0x7e, 0xb5, 0x56, 0xa6, 0x5f, 0x5a, 0xce, 0x2e, 0xbe, 0xb4, 0xbc, 0x6a, 0x3e, + 0xe5, 0x56, 0xce, 0xa7, 0xdf, 0xcf, 0xc0, 0x96, 0xd4, 0xfb, 0x89, 0xb5, 0xf8, 0x77, 0x54, 0x33, + 0xe9, 0xc1, 0xe5, 0x5c, 0xea, 0xc1, 0x65, 0xf5, 0xcf, 0x33, 0x70, 0x69, 0xa1, 0x26, 0x9a, 0xf5, + 0x77, 0x5a, 0x97, 0xf4, 0xc3, 0xcc, 0x74, 0x54, 0x10, 0x3d, 0x3c, 0x94, 0xb9, 0x97, 0x95, 0x1e, + 0x66, 0xa6, 0xf3, 0x23, 0x3a, 0xc4, 0x7c, 0x4d, 0xbc, 0x4f, 0xa7, 0x07, 0xe7, 0xee, 0x58, 0x0c, + 0x76, 0x99, 0x20, 0xc3, 0x73, 0x77, 0xac, 0xfe, 0x59, 0x06, 0xae, 0x2c, 0xb4, 0xa1, 0x39, 0x0f, + 0x3d, 0x71, 0x16, 0xfc, 0x77, 0xd4, 0x8c, 0x9b, 0x50, 0xa1, 0x93, 0x72, 0x71, 0xc0, 0xcc, 0xbb, + 0x15, 0x8c, 0xa4, 0x5c, 0x05, 0xb2, 0xa6, 0x71, 0x2e, 0x1e, 0x77, 0xc1, 0x9f, 0xb8, 0x60, 0x8f, + 0xbd, 0xb9, 0x2f, 0x62, 0x13, 0xe9, 0xb7, 0xfa, 0x01, 0x6c, 0x26, 0x55, 0x6f, 0x89, 0xf7, 0xb1, + 0x6f, 0x42, 0xc5, 0xb5, 0x4e, 0xf5, 0xe8, 0xf5, 0x6c, 0x11, 0xa5, 0xeb, 0x5a, 0xa7, 0x82, 0x40, + 0x7d, 0x22, 0xcb, 0xc2, 0xf8, 0xab, 0x3f, 0x8e, 0x99, 0x8a, 0xdb, 0xf1, 0x1c, 0x33, 0x42, 0x61, + 0x6e, 0x52, 0x2b, 0x8b, 0xae, 0x75, 0x4a, 0xf3, 0xf0, 0x54, 0xe4, 0xd3, 0x34, 0x4d, 0x11, 0xbb, + 0xb0, 0x2a, 0x08, 0xec, 0x0a, 0x94, 0x66, 0x7e, 0xaa, 0x9b, 0x8a, 0x33, 0x9f, 0x17, 0x7b, 0x47, + 0xc4, 0x00, 0xbf, 0x2c, 0xce, 0x81, 0x47, 0x05, 0x8b, 0xaf, 0x82, 0xe5, 0x92, 0xaf, 0x82, 0x7d, + 0x28, 0xc4, 0x20, 0xd9, 0x7d, 0xbc, 0x64, 0x05, 0xb2, 0xb6, 0x79, 0x46, 0x05, 0xd7, 0x34, 0xfc, + 0x49, 0x9a, 0x9c, 0xf5, 0x8d, 0x08, 0x43, 0xc6, 0x9f, 0xea, 0x0e, 0x54, 0xb4, 0x94, 0x91, 0x5b, + 0x95, 0xfc, 0x45, 0x41, 0xfa, 0xc5, 0xbf, 0xa4, 0x83, 0xb4, 0x4a, 0xe2, 0x2e, 0x0a, 0xd4, 0x40, + 0x08, 0xbe, 0x67, 0x86, 0x3f, 0x3e, 0x36, 0xfc, 0x9e, 0xe5, 0x1e, 0x85, 0xc7, 0xd8, 0xe5, 0xdc, + 0x8d, 0x2b, 0x77, 0x21, 0x70, 0x50, 0x34, 0x1d, 0xb0, 0x17, 0x1d, 0x22, 0x8f, 0xbe, 0x37, 0xe4, + 0x5a, 0xa7, 0x82, 0xff, 0x35, 0x00, 0xec, 0x7f, 0x81, 0xe6, 0x47, 0x90, 0x65, 0xcf, 0x31, 0x39, + 0x5a, 0xdd, 0x14, 0xed, 0x15, 0x8f, 0x13, 0xb5, 0xad, 0x89, 0xea, 0x88, 0x91, 0xe7, 0x0d, 0x12, + 0x9d, 0xf0, 0x83, 0x86, 0x91, 0xdd, 0x82, 0x6a, 0xe4, 0x91, 0xa0, 0x47, 0x26, 0x79, 0xf1, 0x95, + 0x08, 0xd6, 0x9f, 0x4f, 0xd5, 0x3f, 0xce, 0x42, 0xb5, 0xc9, 0x23, 0x7b, 0x66, 0xe7, 0x83, 0x59, + 0xc8, 0x7e, 0x07, 0x2e, 0xd2, 0xab, 0x53, 0xfc, 0xdd, 0x77, 0x0a, 0xa8, 0xa1, 0x6b, 0x4c, 0xa2, + 0x13, 0xef, 0x4b, 0x9d, 0x28, 0x58, 0x1e, 0x0c, 0x4f, 0xec, 0x19, 0xbf, 0x3d, 0xd7, 0x35, 0xcf, + 0xe8, 0xaa, 0x1a, 0x8f, 0x0d, 0xa0, 0x07, 0xaa, 0xd2, 0x08, 0x7a, 0xa3, 0x06, 0xb3, 0x9f, 0x9d, + 0x88, 0x6c, 0x45, 0xd8, 0x04, 0x02, 0xf7, 0x4f, 0x38, 0xcd, 0x7d, 0xd8, 0xe4, 0x17, 0x66, 0x97, + 0x37, 0xe0, 0x0d, 0x8e, 0x48, 0xe6, 0xf7, 0x10, 0x36, 0xc5, 0x23, 0x59, 0xf4, 0x1a, 0xb2, 0x3e, + 0xf6, 0x66, 0xe7, 0xe2, 0xe8, 0xf1, 0x8d, 0x97, 0x54, 0xb5, 0xcb, 0x49, 0x11, 0xc4, 0xeb, 0xb9, + 0x11, 0xa4, 0xa1, 0x57, 0x3b, 0x70, 0xf9, 0x25, 0x6d, 0x7a, 0x55, 0x78, 0x43, 0x49, 0x0a, 0x6f, + 0xb8, 0xba, 0x03, 0x5b, 0xab, 0xca, 0xfb, 0x3e, 0x79, 0xa8, 0xbf, 0xa8, 0x01, 0x24, 0x33, 0x36, + 0xa5, 0x8e, 0x66, 0x16, 0xd4, 0xd1, 0xef, 0x15, 0xd4, 0xf3, 0x01, 0xd4, 0xb1, 0xab, 0xf4, 0x84, + 0x23, 0xbb, 0x92, 0xa3, 0x8a, 0x54, 0xa3, 0xe4, 0x4d, 0x80, 0xe5, 0x90, 0x88, 0xdc, 0xca, 0x90, + 0x88, 0xf7, 0xa1, 0xc8, 0x0f, 0xda, 0x02, 0x11, 0x28, 0x79, 0x79, 0x71, 0xf5, 0x3d, 0x10, 0x37, + 0xf1, 0x22, 0x3a, 0xd6, 0x81, 0x3a, 0x8a, 0x7e, 0xdf, 0x0e, 0x8f, 0xa7, 0xf2, 0xa3, 0x14, 0x37, + 0x96, 0x39, 0x23, 0x32, 0xfe, 0x86, 0xb2, 0x21, 0x27, 0x25, 0xed, 0x35, 0x9c, 0x0a, 0xef, 0x2f, + 0x69, 0xaf, 0x45, 0x59, 0x7b, 0x1d, 0x4d, 0xb9, 0xcf, 0x17, 0xb5, 0xd7, 0x77, 0xe0, 0x82, 0xb8, + 0x1d, 0x8c, 0x0c, 0xd8, 0x9d, 0x44, 0xcf, 0x43, 0xbc, 0x15, 0xf1, 0x36, 0xd5, 0x94, 0x6c, 0x3b, + 0x24, 0xff, 0x12, 0xb6, 0xc6, 0xc7, 0x86, 0x7b, 0x64, 0xe9, 0xe1, 0xa1, 0xa3, 0xd3, 0xc7, 0x66, + 0xf4, 0xa9, 0x31, 0x13, 0x4a, 0xf5, 0x1b, 0x4b, 0x95, 0x6d, 0x11, 0xf1, 0xe8, 0xd0, 0xa1, 0x00, + 0xb4, 0x38, 0x70, 0x66, 0x73, 0xbc, 0x08, 0x5f, 0x38, 0xbf, 0x86, 0xa5, 0xf3, 0xeb, 0x45, 0x35, + 0xbb, 0xb2, 0x42, 0xcd, 0x4e, 0x94, 0xe5, 0xaa, 0xac, 0x2c, 0xb3, 0xb7, 0xa1, 0x28, 0x1e, 0x37, + 0x10, 0x7e, 0x5f, 0xb6, 0xbc, 0x3a, 0xb4, 0x88, 0x04, 0x4b, 0x8a, 0xa2, 0x29, 0xe8, 0xfd, 0x9b, + 0x3a, 0x2f, 0x49, 0x86, 0xb1, 0x1d, 0xe1, 0xf4, 0x8c, 0x83, 0xe5, 0x84, 0x8f, 0xf7, 0xaa, 0x94, + 0x71, 0x8c, 0x13, 0x76, 0xf9, 0x02, 0xc7, 0xd5, 0xff, 0xab, 0x00, 0x05, 0x71, 0xb5, 0xe7, 0x3e, + 0xe4, 0x4c, 0xdf, 0x9b, 0xc5, 0xf7, 0x63, 0x56, 0x68, 0xed, 0xf4, 0x7d, 0x51, 0x54, 0xf0, 0x1f, + 0x40, 0xc1, 0x30, 0x4d, 0x7d, 0x72, 0x92, 0x3e, 0x8f, 0x5e, 0x50, 0xa0, 0x77, 0xd7, 0xb4, 0xbc, + 0x41, 0x9a, 0xf4, 0xc7, 0x50, 0x46, 0xfa, 0x24, 0xfc, 0xb4, 0xb2, 0x6c, 0x16, 0x44, 0xaa, 0xee, + 0xee, 0x9a, 0x56, 0x32, 0x22, 0xb5, 0xf7, 0x37, 0xd3, 0x9e, 0xfd, 0xdc, 0x52, 0x03, 0x17, 0xf4, + 0xb4, 0x05, 0x1f, 0xff, 0x6f, 0x01, 0x77, 0xf5, 0xc6, 0x3b, 0x76, 0x5e, 0x3e, 0xfa, 0x5c, 0xda, + 0xdf, 0x77, 0xd7, 0x34, 0xbe, 0x6f, 0x45, 0xfb, 0xfd, 0x87, 0x91, 0xd7, 0x3d, 0xfe, 0x0e, 0xdb, + 0x8a, 0x9e, 0x41, 0x31, 0x18, 0xbb, 0xde, 0x49, 0x26, 0x22, 0x9b, 0x69, 0x46, 0x51, 0x88, 0xc5, + 0x25, 0xb6, 0x78, 0x57, 0x27, 0xb6, 0x78, 0x8b, 0x7f, 0x0c, 0x15, 0xee, 0x84, 0xe5, 0x7c, 0xa5, + 0xa5, 0xae, 0x4d, 0x36, 0x65, 0x3a, 0xd6, 0x4b, 0xb6, 0xe8, 0x56, 0xd4, 0x4e, 0xdf, 0x92, 0x4f, + 0x4e, 0xae, 0xaf, 0xec, 0x28, 0x2d, 0x3e, 0x44, 0xe1, 0x8d, 0xd5, 0x38, 0x0f, 0xeb, 0xc1, 0x96, + 0x38, 0x62, 0xe0, 0x1b, 0x70, 0xb4, 0x67, 0xc2, 0xd2, 0x78, 0xa5, 0x76, 0xe8, 0xdd, 0x35, 0x8d, + 0x19, 0xcb, 0xfb, 0x76, 0x0b, 0x36, 0xa3, 0x2a, 0xd1, 0xce, 0x2a, 0x85, 0x4d, 0xc9, 0x4d, 0x4a, + 0xf6, 0xdd, 0xdd, 0x35, 0x6d, 0xc3, 0x48, 0x83, 0x58, 0x17, 0x2e, 0x44, 0x99, 0x90, 0xab, 0x5d, + 0xf4, 0x4c, 0x75, 0x69, 0x14, 0xe5, 0xbd, 0x7a, 0x77, 0x4d, 0xdb, 0x34, 0x96, 0x36, 0xf0, 0xbd, + 0xa8, 0x3e, 0xb2, 0x72, 0xc8, 0x57, 0xe2, 0xcd, 0x95, 0xdd, 0x94, 0x68, 0xaa, 0x71, 0xcd, 0x12, + 0x50, 0x12, 0xc7, 0x70, 0x55, 0x83, 0x4b, 0xab, 0x25, 0x8c, 0xbc, 0xcd, 0xe4, 0xf8, 0x36, 0xa3, + 0xca, 0xdb, 0xcc, 0xe2, 0x7b, 0x56, 0xd2, 0xa6, 0xf3, 0x63, 0xa8, 0xa5, 0x44, 0x2c, 0xab, 0x40, + 0x31, 0xfa, 0x4a, 0x07, 0x5d, 0x04, 0x6c, 0x0d, 0xf6, 0xbf, 0x52, 0x32, 0x08, 0xee, 0xf6, 0x87, + 0xa3, 0x66, 0x7f, 0xa4, 0xac, 0xf3, 0xc4, 0x7e, 0xaf, 0xd9, 0xea, 0x28, 0x59, 0xf5, 0xcf, 0xb3, + 0x50, 0x8e, 0x4f, 0xd9, 0x7e, 0xb8, 0x37, 0x2c, 0x76, 0x33, 0x65, 0x65, 0x37, 0xd3, 0x82, 0xa9, + 0xc7, 0x3f, 0xa8, 0xc3, 0xbf, 0x71, 0xb8, 0x91, 0x36, 0xa8, 0x82, 0xe5, 0x67, 0x4e, 0xf2, 0xdf, + 0xf1, 0x99, 0x13, 0x39, 0x02, 0xbd, 0x90, 0x8e, 0x40, 0x5f, 0xf8, 0x52, 0x4b, 0x91, 0xbe, 0xa1, + 0x20, 0x7f, 0xa9, 0x85, 0xbe, 0xfc, 0xfc, 0xcc, 0xb6, 0x4e, 0x45, 0xc8, 0xb6, 0x48, 0xa5, 0x77, + 0x68, 0x78, 0xc5, 0x0e, 0xfd, 0x5d, 0xa4, 0xfd, 0x43, 0xd8, 0x9a, 0x9c, 0xc4, 0x5f, 0x6e, 0x48, + 0x9c, 0x2b, 0x55, 0xaa, 0xd2, 0x4a, 0x1c, 0x7b, 0x23, 0xfe, 0x54, 0x65, 0x4d, 0x76, 0x03, 0xc5, + 0xa3, 0x15, 0x7f, 0xbb, 0xf2, 0xbf, 0xca, 0x00, 0x24, 0xe7, 0x4f, 0xbf, 0xb2, 0x2b, 0x57, 0xf2, + 0x96, 0x65, 0xbf, 0xc5, 0x5b, 0xf6, 0xaa, 0x97, 0x3c, 0xbf, 0x81, 0x72, 0x7c, 0xe2, 0xf8, 0xc3, + 0x27, 0xd6, 0xf7, 0x2a, 0xf2, 0x77, 0x23, 0xb7, 0x76, 0x7c, 0x64, 0xf7, 0xab, 0xf6, 0x45, 0xaa, + 0xf8, 0xec, 0x2b, 0x8a, 0x3f, 0xe3, 0xbe, 0xe5, 0xb8, 0xf0, 0x5f, 0xf3, 0x6a, 0x92, 0x27, 0x7a, + 0x2e, 0x7d, 0x21, 0x68, 0x2e, 0x1c, 0xe4, 0xbf, 0x7a, 0xd1, 0xdf, 0xab, 0xc1, 0xff, 0x2a, 0x13, + 0x79, 0x71, 0xe3, 0x8f, 0x6d, 0xbc, 0x54, 0xe9, 0x5d, 0xed, 0x88, 0xfe, 0x3e, 0xc5, 0x7d, 0xab, + 0x8f, 0x2a, 0xf7, 0x6d, 0x3e, 0xaa, 0x37, 0x20, 0xcf, 0xb7, 0xbb, 0xfc, 0xcb, 0xfc, 0x53, 0x1c, + 0xff, 0xca, 0x4f, 0x62, 0xa9, 0xaa, 0x50, 0xf2, 0x79, 0x7b, 0xb7, 0xa2, 0x7c, 0xa3, 0xcf, 0x79, + 0xd1, 0x0d, 0x99, 0xff, 0x84, 0x4b, 0xd4, 0x1f, 0xda, 0x25, 0xdf, 0xee, 0xb6, 0x50, 0xff, 0x7d, + 0x06, 0x6a, 0xa9, 0x08, 0x82, 0x1f, 0x50, 0xc4, 0x4a, 0xb9, 0x9c, 0xfd, 0x8f, 0x48, 0x2e, 0xa7, + 0x42, 0x78, 0x4b, 0xe9, 0x10, 0x5e, 0x14, 0x77, 0xd5, 0x94, 0x09, 0xb3, 0xca, 0xd8, 0xc9, 0xac, + 0x34, 0x76, 0x6e, 0xc4, 0xdf, 0x1c, 0xee, 0xb6, 0x79, 0xc4, 0x6c, 0x4d, 0x93, 0x20, 0xec, 0x13, + 0xb8, 0x22, 0x9c, 0x08, 0xbc, 0x7f, 0xbc, 0x89, 0x1e, 0x7f, 0x91, 0x58, 0x18, 0xe5, 0x97, 0x38, + 0x01, 0xff, 0xa0, 0xd9, 0xa4, 0x19, 0x61, 0xd5, 0x2e, 0xd4, 0x52, 0xa1, 0x19, 0xd2, 0x17, 0xd0, + 0x33, 0xf2, 0x17, 0xd0, 0xd9, 0x36, 0xe4, 0x4f, 0x8f, 0x2d, 0xdf, 0x5a, 0xf1, 0x90, 0x3e, 0x47, + 0xa8, 0x3f, 0x82, 0xaa, 0x1c, 0x26, 0xc6, 0xde, 0x86, 0xbc, 0x1d, 0x5a, 0xd3, 0xc8, 0x3d, 0x72, + 0x69, 0x39, 0x92, 0xac, 0x1b, 0x5a, 0x53, 0x8d, 0x13, 0xa9, 0x7f, 0x92, 0x01, 0x65, 0x11, 0x27, + 0x7d, 0xa6, 0x3d, 0xf3, 0x92, 0xcf, 0xb4, 0xaf, 0xa7, 0x2a, 0xb9, 0xea, 0x4b, 0xeb, 0xdb, 0x91, + 0x52, 0xb2, 0xe2, 0x2b, 0xdf, 0x84, 0x60, 0x77, 0xa1, 0xe4, 0x5b, 0xf4, 0x0d, 0x6c, 0x73, 0xc5, + 0xcd, 0x91, 0x18, 0xa7, 0xfe, 0x61, 0x06, 0x8a, 0x22, 0xa6, 0x6d, 0xa5, 0xbf, 0xea, 0x4d, 0x28, + 0xf2, 0xef, 0x61, 0x47, 0x0f, 0x7a, 0x2e, 0x85, 0x99, 0x47, 0x78, 0x76, 0x83, 0x47, 0xfa, 0xa5, + 0xfd, 0x57, 0xfb, 0x8e, 0xe1, 0x6a, 0x04, 0x17, 0xdf, 0x29, 0x34, 0xa6, 0xe2, 0x05, 0x18, 0xfe, + 0x12, 0x23, 0x10, 0x88, 0x1e, 0x7b, 0x51, 0x7f, 0x13, 0x8a, 0x22, 0x66, 0x6e, 0x65, 0x55, 0x5e, + 0xf5, 0x2d, 0xe4, 0x6d, 0x80, 0x24, 0x88, 0x6e, 0x55, 0x0e, 0xea, 0x7d, 0x28, 0x45, 0x71, 0x73, + 0x38, 0xff, 0x92, 0xa2, 0xc5, 0x95, 0x24, 0xb9, 0x32, 0x8e, 0xf8, 0x38, 0x4d, 0xcf, 0x1b, 0x9f, + 0x90, 0xb3, 0xfc, 0x5d, 0xa0, 0xfb, 0x59, 0xa3, 0xa5, 0x27, 0x2b, 0xd3, 0x5f, 0x27, 0x8a, 0x89, + 0xd8, 0x7d, 0x88, 0xe5, 0xe5, 0xab, 0x5c, 0x0b, 0x6a, 0x33, 0xba, 0xc9, 0x47, 0xb3, 0xec, 0x91, + 0xf0, 0xa6, 0xf6, 0xe8, 0xc9, 0xe4, 0x8c, 0xfc, 0x88, 0x7c, 0xaa, 0x4e, 0x9a, 0x44, 0xa6, 0xd6, + 0xa1, 0x2a, 0x07, 0xfb, 0xa8, 0x4d, 0xd8, 0xdc, 0xb3, 0x42, 0x03, 0xe5, 0x4f, 0xf4, 0x90, 0x1f, + 0x9f, 0xbf, 0xf8, 0x23, 0x3d, 0x7f, 0x17, 0xe9, 0x34, 0x4e, 0xa4, 0xfe, 0x79, 0x0e, 0x94, 0x45, + 0xdc, 0xb7, 0xdd, 0x6a, 0xbc, 0x09, 0x15, 0x8f, 0xe6, 0x45, 0xea, 0x4b, 0x94, 0x1c, 0x24, 0xdd, + 0x07, 0x48, 0x7d, 0x8e, 0xac, 0x64, 0x07, 0xbb, 0xfc, 0x83, 0x64, 0x97, 0xf9, 0x15, 0x36, 0xc7, + 0x1b, 0xd3, 0xb4, 0xae, 0xd2, 0x8d, 0xb5, 0x9e, 0x37, 0xa6, 0xcb, 0x92, 0xc2, 0x3b, 0xc1, 0x23, + 0x50, 0xab, 0x5a, 0x49, 0xb8, 0x24, 0xe8, 0xfc, 0x4e, 0xdc, 0x12, 0x08, 0x03, 0xf1, 0x6a, 0x41, + 0x89, 0x03, 0x46, 0x41, 0xf4, 0x09, 0x94, 0xb1, 0xf8, 0x6c, 0x62, 0x96, 0x3e, 0x81, 0xd2, 0x72, + 0xe9, 0xae, 0x24, 0x3d, 0x0c, 0x3f, 0x16, 0x1f, 0x8c, 0x15, 0x1f, 0xa1, 0x41, 0xd4, 0x6d, 0xfe, + 0x61, 0x49, 0xdf, 0x0a, 0x02, 0xfe, 0x72, 0x6e, 0x59, 0x3c, 0x99, 0x2c, 0x80, 0xf1, 0xc3, 0xe4, + 0xe2, 0x9b, 0x9f, 0x48, 0x02, 0xe2, 0xfd, 0x5e, 0xfe, 0xc5, 0x4f, 0x24, 0xb8, 0x02, 0xa5, 0x9f, + 0x79, 0xae, 0x45, 0x5e, 0x8e, 0x0a, 0xd5, 0xaa, 0x88, 0xe9, 0x3d, 0x63, 0x86, 0x1b, 0x81, 0x43, + 0x0f, 0x64, 0xf0, 0x5b, 0x82, 0x3c, 0xa1, 0xfe, 0xc3, 0x0c, 0x6c, 0x2d, 0xf6, 0x35, 0x4d, 0xa3, + 0x2a, 0x94, 0x5a, 0x83, 0x9e, 0xde, 0x6f, 0xee, 0x75, 0x94, 0x35, 0xb6, 0x01, 0x95, 0xc1, 0xce, + 0xe7, 0x9d, 0xd6, 0x88, 0x03, 0x32, 0xf4, 0x5e, 0xcd, 0x50, 0xdf, 0xed, 0xb6, 0xdb, 0x9d, 0x3e, + 0xb7, 0x28, 0x06, 0x3b, 0x9f, 0xeb, 0xbd, 0x41, 0x8b, 0x7f, 0x1b, 0x30, 0x8a, 0x78, 0x18, 0x2a, + 0x39, 0x8a, 0x87, 0xa0, 0x60, 0x78, 0x4c, 0xe6, 0x79, 0x94, 0xf7, 0xf3, 0xa1, 0xde, 0xea, 0x8f, + 0x94, 0x02, 0xa6, 0xfa, 0x07, 0xbd, 0x1e, 0xa5, 0x28, 0x9c, 0xb3, 0x35, 0xd8, 0xdb, 0xd7, 0x3a, + 0xc3, 0xa1, 0x3e, 0xec, 0xfe, 0xb4, 0xa3, 0x94, 0xa8, 0x64, 0xad, 0xfb, 0xb4, 0xdb, 0xe7, 0x80, + 0x32, 0x2b, 0x42, 0x76, 0xaf, 0xdb, 0xe7, 0xef, 0xf4, 0xec, 0x35, 0xbf, 0x54, 0x2a, 0xf8, 0x63, + 0x78, 0xb0, 0xa7, 0x54, 0x59, 0x19, 0xf2, 0xbd, 0xce, 0xb3, 0x4e, 0x4f, 0xa9, 0xa9, 0xff, 0x2c, + 0x1b, 0x69, 0xc4, 0x14, 0xe7, 0xf4, 0x5d, 0xb4, 0xc0, 0x55, 0xe7, 0x8b, 0x71, 0xa7, 0x65, 0xa5, + 0x4e, 0xfb, 0x2e, 0x1f, 0xa0, 0xbf, 0x0d, 0xb5, 0x38, 0x38, 0x40, 0xfa, 0x6c, 0x49, 0x35, 0x02, + 0xae, 0x38, 0xbe, 0x28, 0xac, 0x38, 0xbe, 0x98, 0xd9, 0x21, 0x5a, 0xd9, 0x28, 0x73, 0xf9, 0x4c, + 0x2a, 0x23, 0x84, 0x3e, 0x7f, 0x4d, 0x17, 0x18, 0x11, 0x3d, 0x77, 0xed, 0xe8, 0xf3, 0xc3, 0x25, + 0x04, 0x1c, 0xb8, 0x76, 0xb8, 0x18, 0x9c, 0x50, 0x5e, 0x0a, 0x4e, 0x90, 0x37, 0x67, 0x48, 0x6f, + 0xce, 0xe9, 0xef, 0xf2, 0xf3, 0xef, 0x0e, 0x4b, 0xdf, 0xe5, 0x7f, 0x1b, 0xd8, 0x78, 0xee, 0xd3, + 0x23, 0xa2, 0x12, 0x59, 0x95, 0xc8, 0x14, 0x81, 0x89, 0x77, 0x45, 0xba, 0x3f, 0x9e, 0xa6, 0x26, + 0x5b, 0xba, 0xac, 0xd5, 0xd3, 0xa4, 0xec, 0x01, 0x5c, 0x10, 0x73, 0x3b, 0xd5, 0xb7, 0xe2, 0xea, + 0x29, 0x47, 0x35, 0x93, 0x1e, 0x56, 0x7f, 0x03, 0x4a, 0x51, 0x48, 0xdb, 0xb7, 0x2b, 0xbb, 0x2b, + 0xc6, 0x55, 0xfd, 0xdf, 0xd7, 0xa1, 0x1c, 0x07, 0xb8, 0x7d, 0xa7, 0xd9, 0x41, 0xdf, 0x67, 0x0a, + 0x4e, 0x64, 0x11, 0x53, 0x42, 0x40, 0x34, 0x52, 0xe2, 0xb6, 0xd6, 0xdc, 0xb7, 0x23, 0x8d, 0x8d, + 0x43, 0x0e, 0x7c, 0x9b, 0x5e, 0x0a, 0xb3, 0x5d, 0xe9, 0x92, 0x68, 0x59, 0x2b, 0x21, 0x80, 0x16, + 0xda, 0x15, 0xa0, 0xdf, 0xc4, 0xc9, 0x27, 0x49, 0x11, 0xd3, 0xc8, 0x77, 0x29, 0xb6, 0xff, 0xf8, + 0xdc, 0x10, 0x29, 0xfa, 0xba, 0x14, 0x8f, 0xae, 0xe1, 0x31, 0x05, 0xd1, 0xf7, 0x54, 0xaf, 0x41, + 0x79, 0x1e, 0x7f, 0x90, 0x57, 0xcc, 0x88, 0x79, 0xf4, 0x39, 0xde, 0xf4, 0xa8, 0x96, 0x17, 0x47, + 0x75, 0x71, 0x4e, 0xc3, 0xd2, 0x9c, 0x56, 0x43, 0x28, 0x8a, 0x20, 0xbf, 0x6f, 0xef, 0xf0, 0x6f, + 0xed, 0x2a, 0x05, 0xb2, 0x86, 0x13, 0xdd, 0x4c, 0xc5, 0x9f, 0x0b, 0x15, 0xcb, 0x2d, 0x54, 0x4c, + 0xfd, 0x1f, 0xd7, 0x01, 0x92, 0x60, 0x41, 0xf6, 0xce, 0x42, 0x60, 0x72, 0x66, 0x69, 0xdb, 0x5f, + 0x88, 0x47, 0x5e, 0x78, 0x3a, 0x6f, 0xfd, 0x3b, 0x3c, 0x9d, 0xf7, 0x10, 0x6a, 0x81, 0x3f, 0x7e, + 0xa5, 0xc3, 0xbd, 0x12, 0xf8, 0xe3, 0xd8, 0xdf, 0xfe, 0x2e, 0x60, 0x92, 0x9e, 0xd5, 0x4d, 0x0c, + 0xd5, 0x25, 0xad, 0xa5, 0x1c, 0xf8, 0xe3, 0xc1, 0xe1, 0xd7, 0x6d, 0x7e, 0x45, 0xce, 0x0c, 0x42, + 0x7d, 0x95, 0x94, 0xd8, 0x30, 0x83, 0xb0, 0x2d, 0x0b, 0x8a, 0x3b, 0x50, 0x47, 0xda, 0x25, 0x61, + 0x51, 0x35, 0x83, 0xe4, 0x80, 0x45, 0xfd, 0x83, 0xe8, 0x48, 0x7a, 0xc1, 0x97, 0xcb, 0x3e, 0x12, + 0x86, 0xb8, 0xa4, 0x44, 0x34, 0x56, 0xb9, 0x7e, 0xf9, 0x43, 0x7f, 0x31, 0xe9, 0xf2, 0x67, 0x58, + 0xd7, 0xbf, 0xeb, 0x67, 0x58, 0xb7, 0x01, 0x92, 0x87, 0x8d, 0x71, 0x05, 0xc6, 0x97, 0x75, 0xca, + 0xfc, 0x1a, 0xce, 0xfd, 0x5b, 0x50, 0x95, 0xbf, 0xdb, 0x4e, 0x97, 0x70, 0x3c, 0xd7, 0xe2, 0x9f, + 0xba, 0xea, 0xfd, 0xec, 0x03, 0x25, 0x73, 0x5f, 0x85, 0x8a, 0xf4, 0xa1, 0x39, 0xa4, 0xd8, 0x35, + 0x82, 0x63, 0xf1, 0xd9, 0x23, 0xc3, 0x3d, 0xb2, 0x94, 0xcc, 0xfd, 0xbb, 0xa8, 0x74, 0xcb, 0x9f, + 0x79, 0x03, 0x28, 0xf4, 0x3d, 0x7f, 0x6a, 0x38, 0x82, 0xce, 0x9a, 0x07, 0x48, 0xf7, 0x2e, 0x5c, + 0x5c, 0xf9, 0xd1, 0x3a, 0xba, 0xc2, 0x65, 0x4f, 0x67, 0x8e, 0xc5, 0x2f, 0x23, 0xed, 0x9e, 0x1f, + 0xfa, 0xb6, 0xa9, 0x64, 0xee, 0x3f, 0x5e, 0xf8, 0xa8, 0xd1, 0x41, 0x7f, 0x67, 0x70, 0xd0, 0x6f, + 0x77, 0xda, 0xfc, 0x9a, 0x50, 0xb7, 0xdf, 0xea, 0x1d, 0x0c, 0xbb, 0xcf, 0xc4, 0x5e, 0xd8, 0xf9, + 0x32, 0x4a, 0xae, 0xdf, 0xff, 0x32, 0x7a, 0x8d, 0x21, 0xaa, 0x75, 0x6f, 0xd0, 0x6c, 0xf3, 0x3d, + 0x34, 0x7e, 0x7b, 0x6e, 0xb4, 0xc3, 0x3f, 0x86, 0xa4, 0x75, 0x86, 0x07, 0xbd, 0x51, 0xf4, 0xce, + 0x5d, 0x1d, 0xa0, 0xdb, 0xea, 0xec, 0x74, 0xb4, 0xa7, 0x48, 0x90, 0xc5, 0xf4, 0xde, 0xa0, 0xff, + 0x74, 0xd0, 0xde, 0xc1, 0x74, 0xee, 0xfe, 0xdf, 0x5f, 0x07, 0x65, 0xf1, 0x01, 0x0d, 0x76, 0x0d, + 0x2e, 0x13, 0x91, 0xbe, 0xaf, 0x75, 0xda, 0xdd, 0x16, 0x8f, 0x5e, 0x7d, 0xd6, 0xec, 0x75, 0xb1, + 0xcc, 0xcb, 0x70, 0x61, 0x11, 0xd9, 0xec, 0xb7, 0x95, 0x0c, 0xbb, 0x02, 0x17, 0x17, 0x11, 0x9d, + 0x9f, 0x1c, 0x34, 0x7b, 0xca, 0x3a, 0x7b, 0x0d, 0xae, 0x2c, 0xa2, 0xfa, 0x83, 0x91, 0x40, 0x67, + 0x59, 0x03, 0xb6, 0x16, 0xd1, 0xbd, 0xce, 0x10, 0x37, 0xfa, 0x1b, 0x70, 0x75, 0x15, 0x46, 0x70, + 0xe6, 0x57, 0xd5, 0xf4, 0x29, 0xe9, 0x09, 0x9a, 0x52, 0x60, 0xb7, 0xe0, 0xb5, 0x97, 0x20, 0x05, + 0x7f, 0x91, 0x5d, 0x02, 0xb6, 0xdc, 0x52, 0xa5, 0xb4, 0xb2, 0x07, 0x86, 0xfc, 0xcb, 0xc5, 0x65, + 0x76, 0x13, 0xae, 0xad, 0x42, 0x0e, 0xc4, 0xa7, 0x8d, 0xe1, 0xfe, 0x8f, 0xa1, 0xf1, 0xb2, 0x4b, + 0x54, 0x38, 0x81, 0x5a, 0xbb, 0x4d, 0xba, 0xa8, 0x86, 0x8a, 0xca, 0x40, 0xe7, 0x29, 0x72, 0xa7, + 0x6a, 0x9d, 0x5e, 0x87, 0x22, 0x8d, 0xef, 0xff, 0x3c, 0x23, 0x29, 0xed, 0xd1, 0x45, 0x98, 0x18, + 0x20, 0x66, 0xb5, 0x0c, 0xd2, 0x2c, 0xc3, 0x54, 0x32, 0xd8, 0x9e, 0x14, 0xa8, 0xe7, 0x8d, 0x0d, + 0x47, 0x59, 0xa7, 0x98, 0xe2, 0x08, 0x4e, 0x17, 0x26, 0x95, 0x2c, 0x0e, 0x4a, 0x0c, 0xeb, 0x79, + 0xa7, 0xfb, 0xbe, 0xed, 0xf9, 0x76, 0x78, 0xce, 0xd1, 0xb9, 0xfb, 0xff, 0xa9, 0x38, 0x11, 0x4f, + 0x2d, 0x65, 0x2c, 0xa0, 0x69, 0x9a, 0x09, 0x8c, 0x76, 0x0f, 0x3e, 0x2b, 0x68, 0xeb, 0x5c, 0x40, + 0x64, 0xb0, 0x27, 0x23, 0xcf, 0xc2, 0x22, 0x72, 0x1d, 0x91, 0x9a, 0x45, 0xf1, 0xa8, 0x4b, 0xc8, + 0xec, 0xce, 0x67, 0x7f, 0xf1, 0xcb, 0x1b, 0x99, 0xbf, 0xf7, 0xcb, 0x1b, 0x99, 0x7f, 0xfe, 0xcb, + 0x1b, 0x6b, 0x7f, 0xf2, 0x2f, 0x6f, 0x64, 0x7e, 0xfa, 0xce, 0x91, 0x1d, 0x1e, 0xcf, 0x0f, 0x1f, + 0x8c, 0xbd, 0xe9, 0xbb, 0x53, 0x23, 0xf4, 0xed, 0x33, 0xbe, 0x87, 0x47, 0x09, 0xd7, 0x7a, 0x77, + 0x76, 0x72, 0xf4, 0xee, 0xec, 0xf0, 0x5d, 0x94, 0x26, 0x87, 0x85, 0x99, 0xef, 0x85, 0xde, 0xa3, + 0xff, 0x10, 0x00, 0x00, 0xff, 0xff, 0xd4, 0x70, 0xf7, 0x1c, 0xf0, 0x90, 0x00, 0x00, } func (m *Type) Marshal() (dAtA []byte, err error) { @@ -19527,6 +20092,50 @@ func (m *Node) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0xca } + if m.GapFillMode != 0 { + i = encodeVarintPlan(dAtA, i, uint64(m.GapFillMode)) + i-- + dAtA[i] = 0x4 + i-- + dAtA[i] = 0xd8 + } + if len(m.TimeWindowPartitionColPos) > 0 { + dAtA76 := make([]byte, len(m.TimeWindowPartitionColPos)*10) + var j75 int + for _, num1 := range m.TimeWindowPartitionColPos { + num := uint64(num1) + for num >= 1<<7 { + dAtA76[j75] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j75++ + } + dAtA76[j75] = uint8(num) + j75++ + } + i -= j75 + copy(dAtA[i:], dAtA76[:j75]) + i = encodeVarintPlan(dAtA, i, uint64(j75)) + i-- + dAtA[i] = 0x4 + i-- + dAtA[i] = 0xd2 + } + if len(m.TimeWindowPartitionBy) > 0 { + for iNdEx := len(m.TimeWindowPartitionBy) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.TimeWindowPartitionBy[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPlan(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x4 + i-- + dAtA[i] = 0xca + } + } if len(m.DirectView) > 0 { i -= len(m.DirectView) copy(dAtA[i:], m.DirectView) @@ -20057,21 +20666,21 @@ func (m *Node) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0xe2 } if len(m.SourceStep) > 0 { - dAtA92 := make([]byte, len(m.SourceStep)*10) - var j91 int + dAtA94 := make([]byte, len(m.SourceStep)*10) + var j93 int for _, num1 := range m.SourceStep { num := uint64(num1) for num >= 1<<7 { - dAtA92[j91] = uint8(uint64(num)&0x7f | 0x80) + dAtA94[j93] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j91++ + j93++ } - dAtA92[j91] = uint8(num) - j91++ + dAtA94[j93] = uint8(num) + j93++ } - i -= j91 - copy(dAtA[i:], dAtA92[:j91]) - i = encodeVarintPlan(dAtA, i, uint64(j91)) + i -= j93 + copy(dAtA[i:], dAtA94[:j93]) + i = encodeVarintPlan(dAtA, i, uint64(j93)) i-- dAtA[i] = 0x1 i-- @@ -20108,21 +20717,21 @@ func (m *Node) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0xca } if len(m.BindingTags) > 0 { - dAtA95 := make([]byte, len(m.BindingTags)*10) - var j94 int + dAtA97 := make([]byte, len(m.BindingTags)*10) + var j96 int for _, num1 := range m.BindingTags { num := uint64(num1) for num >= 1<<7 { - dAtA95[j94] = uint8(uint64(num)&0x7f | 0x80) + dAtA97[j96] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j94++ + j96++ } - dAtA95[j94] = uint8(num) - j94++ + dAtA97[j96] = uint8(num) + j96++ } - i -= j94 - copy(dAtA[i:], dAtA95[:j94]) - i = encodeVarintPlan(dAtA, i, uint64(j94)) + i -= j96 + copy(dAtA[i:], dAtA97[:j96]) + i = encodeVarintPlan(dAtA, i, uint64(j96)) i-- dAtA[i] = 0x1 i-- @@ -20372,21 +20981,21 @@ func (m *Node) MarshalToSizedBuffer(dAtA []byte) (int, error) { } } if len(m.Children) > 0 { - dAtA105 := make([]byte, len(m.Children)*10) - var j104 int + dAtA107 := make([]byte, len(m.Children)*10) + var j106 int for _, num1 := range m.Children { num := uint64(num1) for num >= 1<<7 { - dAtA105[j104] = uint8(uint64(num)&0x7f | 0x80) + dAtA107[j106] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j104++ + j106++ } - dAtA105[j104] = uint8(num) - j104++ + dAtA107[j106] = uint8(num) + j106++ } - i -= j104 - copy(dAtA[i:], dAtA105[:j104]) - i = encodeVarintPlan(dAtA, i, uint64(j104)) + i -= j106 + copy(dAtA[i:], dAtA107[:j106]) + i = encodeVarintPlan(dAtA, i, uint64(j106)) i-- dAtA[i] = 0x22 } @@ -20587,6 +21196,18 @@ func (m *ExternScan) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.MongodbScan != nil { + { + size, err := m.MongodbScan.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPlan(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x62 + } if m.IcebergScan != nil { { size, err := m.IcebergScan.MarshalToSizedBuffer(dAtA[:i]) @@ -20708,21 +21329,21 @@ func (m *IcebergScan) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x52 } if len(m.ProjectedFieldIds) > 0 { - dAtA112 := make([]byte, len(m.ProjectedFieldIds)*10) - var j111 int + dAtA115 := make([]byte, len(m.ProjectedFieldIds)*10) + var j114 int for _, num1 := range m.ProjectedFieldIds { num := uint64(num1) for num >= 1<<7 { - dAtA112[j111] = uint8(uint64(num)&0x7f | 0x80) + dAtA115[j114] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j111++ + j114++ } - dAtA112[j111] = uint8(num) - j111++ + dAtA115[j114] = uint8(num) + j114++ } - i -= j111 - copy(dAtA[i:], dAtA112[:j111]) - i = encodeVarintPlan(dAtA, i, uint64(j111)) + i -= j114 + copy(dAtA[i:], dAtA115[:j114]) + i = encodeVarintPlan(dAtA, i, uint64(j114)) i-- dAtA[i] = 0x4a } @@ -20777,6 +21398,336 @@ func (m *IcebergScan) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *MongoScan) Marshal() (dAtA []byte, err error) { + size := m.ProtoSize() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MongoScan) MarshalTo(dAtA []byte) (int, error) { + size := m.ProtoSize() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MongoScan) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.TableId != 0 { + i = encodeVarintPlan(dAtA, i, uint64(m.TableId)) + i-- + dAtA[i] = 0x78 + } + if m.MappingVersion != 0 { + i = encodeVarintPlan(dAtA, i, uint64(m.MappingVersion)) + i-- + dAtA[i] = 0x70 + } + if m.MaxScanBytes != 0 { + i = encodeVarintPlan(dAtA, i, uint64(m.MaxScanBytes)) + i-- + dAtA[i] = 0x68 + } + if m.MaxScanRows != 0 { + i = encodeVarintPlan(dAtA, i, uint64(m.MaxScanRows)) + i-- + dAtA[i] = 0x60 + } + if m.Split != nil { + { + size, err := m.Split.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPlan(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + } + if m.MaxParallelism != 0 { + i = encodeVarintPlan(dAtA, i, uint64(m.MaxParallelism)) + i-- + dAtA[i] = 0x50 + } + if len(m.ResidualFilterDigest) > 0 { + i -= len(m.ResidualFilterDigest) + copy(dAtA[i:], m.ResidualFilterDigest) + i = encodeVarintPlan(dAtA, i, uint64(len(m.ResidualFilterDigest))) + i-- + dAtA[i] = 0x4a + } + if len(m.ProjectedPaths) > 0 { + for iNdEx := len(m.ProjectedPaths) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ProjectedPaths[iNdEx]) + copy(dAtA[i:], m.ProjectedPaths[iNdEx]) + i = encodeVarintPlan(dAtA, i, uint64(len(m.ProjectedPaths[iNdEx]))) + i-- + dAtA[i] = 0x42 + } + } + if m.PushedPredicate != nil { + { + size, err := m.PushedPredicate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPlan(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + if len(m.Columns) > 0 { + for iNdEx := len(m.Columns) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Columns[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPlan(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } + if len(m.Collection) > 0 { + i -= len(m.Collection) + copy(dAtA[i:], m.Collection) + i = encodeVarintPlan(dAtA, i, uint64(len(m.Collection))) + i-- + dAtA[i] = 0x2a + } + if len(m.Database) > 0 { + i -= len(m.Database) + copy(dAtA[i:], m.Database) + i = encodeVarintPlan(dAtA, i, uint64(len(m.Database))) + i-- + dAtA[i] = 0x22 + } + if m.ConnectionVersion != 0 { + i = encodeVarintPlan(dAtA, i, uint64(m.ConnectionVersion)) + i-- + dAtA[i] = 0x18 + } + if m.ConnectionId != 0 { + i = encodeVarintPlan(dAtA, i, uint64(m.ConnectionId)) + i-- + dAtA[i] = 0x10 + } + if m.MappingId != 0 { + i = encodeVarintPlan(dAtA, i, uint64(m.MappingId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MongoColumnMapping) Marshal() (dAtA []byte, err error) { + size := m.ProtoSize() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MongoColumnMapping) MarshalTo(dAtA []byte) (int, error) { + size := m.ProtoSize() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MongoColumnMapping) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.ConversionMode) > 0 { + i -= len(m.ConversionMode) + copy(dAtA[i:], m.ConversionMode) + i = encodeVarintPlan(dAtA, i, uint64(len(m.ConversionMode))) + i-- + dAtA[i] = 0x22 + } + { + size, err := m.MoType.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPlan(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.Path) > 0 { + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = encodeVarintPlan(dAtA, i, uint64(len(m.Path))) + i-- + dAtA[i] = 0x12 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintPlan(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MongoPredicate) Marshal() (dAtA []byte, err error) { + size := m.ProtoSize() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MongoPredicate) MarshalTo(dAtA []byte) (int, error) { + size := m.ProtoSize() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MongoPredicate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Children) > 0 { + for iNdEx := len(m.Children) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Children[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPlan(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + if len(m.ValuesBson) > 0 { + for iNdEx := len(m.ValuesBson) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ValuesBson[iNdEx]) + copy(dAtA[i:], m.ValuesBson[iNdEx]) + i = encodeVarintPlan(dAtA, i, uint64(len(m.ValuesBson[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } + if len(m.ValueBson) > 0 { + i -= len(m.ValueBson) + copy(dAtA[i:], m.ValueBson) + i = encodeVarintPlan(dAtA, i, uint64(len(m.ValueBson))) + i-- + dAtA[i] = 0x1a + } + if len(m.Path) > 0 { + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = encodeVarintPlan(dAtA, i, uint64(len(m.Path))) + i-- + dAtA[i] = 0x12 + } + if m.Op != 0 { + i = encodeVarintPlan(dAtA, i, uint64(m.Op)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MongoSplit) Marshal() (dAtA []byte, err error) { + size := m.ProtoSize() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MongoSplit) MarshalTo(dAtA []byte) (int, error) { + size := m.ProtoSize() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MongoSplit) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.UpperInclusive { + i-- + if m.UpperInclusive { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x28 + } + if m.LowerInclusive { + i-- + if m.LowerInclusive { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } + if len(m.UpperBson) > 0 { + i -= len(m.UpperBson) + copy(dAtA[i:], m.UpperBson) + i = encodeVarintPlan(dAtA, i, uint64(len(m.UpperBson))) + i-- + dAtA[i] = 0x1a + } + if len(m.LowerBson) > 0 { + i -= len(m.LowerBson) + copy(dAtA[i:], m.LowerBson) + i = encodeVarintPlan(dAtA, i, uint64(len(m.LowerBson))) + i-- + dAtA[i] = 0x12 + } + if len(m.KeyPath) > 0 { + i -= len(m.KeyPath) + copy(dAtA[i:], m.KeyPath) + i = encodeVarintPlan(dAtA, i, uint64(len(m.KeyPath))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *ExternAttr) Marshal() (dAtA []byte, err error) { size := m.ProtoSize() dAtA = make([]byte, size) @@ -21016,21 +21967,21 @@ func (m *PreInsertUkCtx) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x10 } if len(m.Columns) > 0 { - dAtA119 := make([]byte, len(m.Columns)*10) - var j118 int + dAtA125 := make([]byte, len(m.Columns)*10) + var j124 int for _, num1 := range m.Columns { num := uint64(num1) for num >= 1<<7 { - dAtA119[j118] = uint8(uint64(num)&0x7f | 0x80) + dAtA125[j124] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j118++ + j124++ } - dAtA119[j118] = uint8(num) - j118++ + dAtA125[j124] = uint8(num) + j124++ } - i -= j118 - copy(dAtA[i:], dAtA119[:j118]) - i = encodeVarintPlan(dAtA, i, uint64(j118)) + i -= j124 + copy(dAtA[i:], dAtA125[:j124]) + i = encodeVarintPlan(dAtA, i, uint64(j124)) i-- dAtA[i] = 0xa } @@ -21251,21 +22202,21 @@ func (m *IdList) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.XXX_unrecognized) } if len(m.List) > 0 { - dAtA126 := make([]byte, len(m.List)*10) - var j125 int + dAtA132 := make([]byte, len(m.List)*10) + var j131 int for _, num1 := range m.List { num := uint64(num1) for num >= 1<<7 { - dAtA126[j125] = uint8(uint64(num)&0x7f | 0x80) + dAtA132[j131] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j125++ + j131++ } - dAtA126[j125] = uint8(num) - j125++ + dAtA132[j131] = uint8(num) + j131++ } - i -= j125 - copy(dAtA[i:], dAtA126[:j125]) - i = encodeVarintPlan(dAtA, i, uint64(j125)) + i -= j131 + copy(dAtA[i:], dAtA132[:j131]) + i = encodeVarintPlan(dAtA, i, uint64(j131)) i-- dAtA[i] = 0xa } @@ -21699,21 +22650,21 @@ func (m *Query) MarshalToSizedBuffer(dAtA []byte) (int, error) { } } if len(m.Steps) > 0 { - dAtA133 := make([]byte, len(m.Steps)*10) - var j132 int + dAtA139 := make([]byte, len(m.Steps)*10) + var j138 int for _, num1 := range m.Steps { num := uint64(num1) for num >= 1<<7 { - dAtA133[j132] = uint8(uint64(num)&0x7f | 0x80) + dAtA139[j138] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j132++ + j138++ } - dAtA133[j132] = uint8(num) - j132++ + dAtA139[j138] = uint8(num) + j138++ } - i -= j132 - copy(dAtA[i:], dAtA133[:j132]) - i = encodeVarintPlan(dAtA, i, uint64(j132)) + i -= j138 + copy(dAtA[i:], dAtA139[:j138]) + i = encodeVarintPlan(dAtA, i, uint64(j138)) i-- dAtA[i] = 0x12 } @@ -24676,20 +25627,20 @@ func (m *DropTable) MarshalToSizedBuffer(dAtA []byte) (int, error) { } } if len(m.FkChildTblsReferToMe) > 0 { - dAtA198 := make([]byte, len(m.FkChildTblsReferToMe)*10) - var j197 int + dAtA204 := make([]byte, len(m.FkChildTblsReferToMe)*10) + var j203 int for _, num := range m.FkChildTblsReferToMe { for num >= 1<<7 { - dAtA198[j197] = uint8(uint64(num)&0x7f | 0x80) + dAtA204[j203] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j197++ + j203++ } - dAtA198[j197] = uint8(num) - j197++ + dAtA204[j203] = uint8(num) + j203++ } - i -= j197 - copy(dAtA[i:], dAtA198[:j197]) - i = encodeVarintPlan(dAtA, i, uint64(j197)) + i -= j203 + copy(dAtA[i:], dAtA204[:j203]) + i = encodeVarintPlan(dAtA, i, uint64(j203)) i-- dAtA[i] = 0x62 } @@ -24725,20 +25676,20 @@ func (m *DropTable) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x48 } if len(m.ForeignTbl) > 0 { - dAtA201 := make([]byte, len(m.ForeignTbl)*10) - var j200 int + dAtA207 := make([]byte, len(m.ForeignTbl)*10) + var j206 int for _, num := range m.ForeignTbl { for num >= 1<<7 { - dAtA201[j200] = uint8(uint64(num)&0x7f | 0x80) + dAtA207[j206] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j200++ + j206++ } - dAtA201[j200] = uint8(num) - j200++ + dAtA207[j206] = uint8(num) + j206++ } - i -= j200 - copy(dAtA[i:], dAtA201[:j200]) - i = encodeVarintPlan(dAtA, i, uint64(j200)) + i -= j206 + copy(dAtA[i:], dAtA207[:j206]) + i = encodeVarintPlan(dAtA, i, uint64(j206)) i-- dAtA[i] = 0x3a } @@ -25284,20 +26235,20 @@ func (m *TruncateTable) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x40 } if len(m.ForeignTbl) > 0 { - dAtA210 := make([]byte, len(m.ForeignTbl)*10) - var j209 int + dAtA216 := make([]byte, len(m.ForeignTbl)*10) + var j215 int for _, num := range m.ForeignTbl { for num >= 1<<7 { - dAtA210[j209] = uint8(uint64(num)&0x7f | 0x80) + dAtA216[j215] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j209++ + j215++ } - dAtA210[j209] = uint8(num) - j209++ + dAtA216[j215] = uint8(num) + j215++ } - i -= j209 - copy(dAtA[i:], dAtA210[:j209]) - i = encodeVarintPlan(dAtA, i, uint64(j209)) + i -= j215 + copy(dAtA[i:], dAtA216[:j215]) + i = encodeVarintPlan(dAtA, i, uint64(j215)) i-- dAtA[i] = 0x3a } @@ -25374,20 +26325,20 @@ func (m *ClusterTable) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x18 } if len(m.AccountIDs) > 0 { - dAtA213 := make([]byte, len(m.AccountIDs)*10) - var j212 int + dAtA219 := make([]byte, len(m.AccountIDs)*10) + var j218 int for _, num := range m.AccountIDs { for num >= 1<<7 { - dAtA213[j212] = uint8(uint64(num)&0x7f | 0x80) + dAtA219[j218] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j212++ + j218++ } - dAtA213[j212] = uint8(num) - j212++ + dAtA219[j218] = uint8(num) + j218++ } - i -= j212 - copy(dAtA[i:], dAtA213[:j212]) - i = encodeVarintPlan(dAtA, i, uint64(j212)) + i -= j218 + copy(dAtA[i:], dAtA219[:j218]) + i = encodeVarintPlan(dAtA, i, uint64(j218)) i-- dAtA[i] = 0x12 } @@ -25599,21 +26550,21 @@ func (m *Prepare) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.XXX_unrecognized) } if len(m.ParamTypes) > 0 { - dAtA217 := make([]byte, len(m.ParamTypes)*10) - var j216 int + dAtA223 := make([]byte, len(m.ParamTypes)*10) + var j222 int for _, num1 := range m.ParamTypes { num := uint64(num1) for num >= 1<<7 { - dAtA217[j216] = uint8(uint64(num)&0x7f | 0x80) + dAtA223[j222] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j216++ + j222++ } - dAtA217[j216] = uint8(num) - j216++ + dAtA223[j222] = uint8(num) + j222++ } - i -= j216 - copy(dAtA[i:], dAtA217[:j216]) - i = encodeVarintPlan(dAtA, i, uint64(j216)) + i -= j222 + copy(dAtA[i:], dAtA223[:j222]) + i = encodeVarintPlan(dAtA, i, uint64(j222)) i-- dAtA[i] = 0x22 } @@ -25760,21 +26711,21 @@ func (m *OtherDCL) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.XXX_unrecognized) } if len(m.ParamTypes) > 0 { - dAtA220 := make([]byte, len(m.ParamTypes)*10) - var j219 int + dAtA226 := make([]byte, len(m.ParamTypes)*10) + var j225 int for _, num1 := range m.ParamTypes { num := uint64(num1) for num >= 1<<7 { - dAtA220[j219] = uint8(uint64(num)&0x7f | 0x80) + dAtA226[j225] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j219++ + j225++ } - dAtA220[j219] = uint8(num) - j219++ + dAtA226[j225] = uint8(num) + j225++ } - i -= j219 - copy(dAtA[i:], dAtA220[:j219]) - i = encodeVarintPlan(dAtA, i, uint64(j219)) + i -= j225 + copy(dAtA[i:], dAtA226[:j225]) + i = encodeVarintPlan(dAtA, i, uint64(j225)) i-- dAtA[i] = 0xa } @@ -29053,6 +30004,22 @@ func (m *Node) ProtoSize() (n int) { if l > 0 { n += 2 + l + sovPlan(uint64(l)) } + if len(m.TimeWindowPartitionBy) > 0 { + for _, e := range m.TimeWindowPartitionBy { + l = e.ProtoSize() + n += 2 + l + sovPlan(uint64(l)) + } + } + if len(m.TimeWindowPartitionColPos) > 0 { + l = 0 + for _, e := range m.TimeWindowPartitionColPos { + l += sovPlan(uint64(e)) + } + n += 2 + sovPlan(uint64(l)) + l + } + if m.GapFillMode != 0 { + n += 2 + sovPlan(uint64(m.GapFillMode)) + } if m.RankOption != nil { l = m.RankOption.ProtoSize() n += 2 + l + sovPlan(uint64(l)) @@ -29180,6 +30147,10 @@ func (m *ExternScan) ProtoSize() (n int) { l = m.IcebergScan.ProtoSize() n += 1 + l + sovPlan(uint64(l)) } + if m.MongodbScan != nil { + l = m.MongodbScan.ProtoSize() + n += 1 + l + sovPlan(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -29237,6 +30208,165 @@ func (m *IcebergScan) ProtoSize() (n int) { return n } +func (m *MongoScan) ProtoSize() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.MappingId != 0 { + n += 1 + sovPlan(uint64(m.MappingId)) + } + if m.ConnectionId != 0 { + n += 1 + sovPlan(uint64(m.ConnectionId)) + } + if m.ConnectionVersion != 0 { + n += 1 + sovPlan(uint64(m.ConnectionVersion)) + } + l = len(m.Database) + if l > 0 { + n += 1 + l + sovPlan(uint64(l)) + } + l = len(m.Collection) + if l > 0 { + n += 1 + l + sovPlan(uint64(l)) + } + if len(m.Columns) > 0 { + for _, e := range m.Columns { + l = e.ProtoSize() + n += 1 + l + sovPlan(uint64(l)) + } + } + if m.PushedPredicate != nil { + l = m.PushedPredicate.ProtoSize() + n += 1 + l + sovPlan(uint64(l)) + } + if len(m.ProjectedPaths) > 0 { + for _, s := range m.ProjectedPaths { + l = len(s) + n += 1 + l + sovPlan(uint64(l)) + } + } + l = len(m.ResidualFilterDigest) + if l > 0 { + n += 1 + l + sovPlan(uint64(l)) + } + if m.MaxParallelism != 0 { + n += 1 + sovPlan(uint64(m.MaxParallelism)) + } + if m.Split != nil { + l = m.Split.ProtoSize() + n += 1 + l + sovPlan(uint64(l)) + } + if m.MaxScanRows != 0 { + n += 1 + sovPlan(uint64(m.MaxScanRows)) + } + if m.MaxScanBytes != 0 { + n += 1 + sovPlan(uint64(m.MaxScanBytes)) + } + if m.MappingVersion != 0 { + n += 1 + sovPlan(uint64(m.MappingVersion)) + } + if m.TableId != 0 { + n += 1 + sovPlan(uint64(m.TableId)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *MongoColumnMapping) ProtoSize() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovPlan(uint64(l)) + } + l = len(m.Path) + if l > 0 { + n += 1 + l + sovPlan(uint64(l)) + } + l = m.MoType.ProtoSize() + n += 1 + l + sovPlan(uint64(l)) + l = len(m.ConversionMode) + if l > 0 { + n += 1 + l + sovPlan(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *MongoPredicate) ProtoSize() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Op != 0 { + n += 1 + sovPlan(uint64(m.Op)) + } + l = len(m.Path) + if l > 0 { + n += 1 + l + sovPlan(uint64(l)) + } + l = len(m.ValueBson) + if l > 0 { + n += 1 + l + sovPlan(uint64(l)) + } + if len(m.ValuesBson) > 0 { + for _, b := range m.ValuesBson { + l = len(b) + n += 1 + l + sovPlan(uint64(l)) + } + } + if len(m.Children) > 0 { + for _, e := range m.Children { + l = e.ProtoSize() + n += 1 + l + sovPlan(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *MongoSplit) ProtoSize() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.KeyPath) + if l > 0 { + n += 1 + l + sovPlan(uint64(l)) + } + l = len(m.LowerBson) + if l > 0 { + n += 1 + l + sovPlan(uint64(l)) + } + l = len(m.UpperBson) + if l > 0 { + n += 1 + l + sovPlan(uint64(l)) + } + if m.LowerInclusive { + n += 2 + } + if m.UpperInclusive { + n += 2 + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *ExternAttr) ProtoSize() (n int) { if m == nil { return 0 @@ -46221,9 +47351,9 @@ func (m *Node) Unmarshal(dAtA []byte) error { } m.DirectView = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 89: + case 73: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RankOption", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TimeWindowPartitionBy", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -46250,101 +47380,92 @@ func (m *Node) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.RankOption == nil { - m.RankOption = &RankOption{} - } - if err := m.RankOption.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.TimeWindowPartitionBy = append(m.TimeWindowPartitionBy, &Expr{}) + if err := m.TimeWindowPartitionBy[len(m.TimeWindowPartitionBy)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipPlan(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthPlan - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SnapshotExtraInfo) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPlan - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: SnapshotExtraInfo: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SnapshotExtraInfo: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Level", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPlan + case 74: + if wireType == 0 { + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } } - if iNdEx >= l { + m.TimeWindowPartitionColPos = append(m.TimeWindowPartitionColPos, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } } + elementCount = count + if elementCount != 0 && len(m.TimeWindowPartitionColPos) == 0 { + m.TimeWindowPartitionColPos = make([]int32, 0, elementCount) + } + for iNdEx < postIndex { + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.TimeWindowPartitionColPos = append(m.TimeWindowPartitionColPos, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field TimeWindowPartitionColPos", wireType) } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPlan - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthPlan - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Level = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: + case 75: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field GapFillMode", wireType) } - m.ObjId = 0 + m.GapFillMode = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowPlan @@ -46354,16 +47475,16 @@ func (m *SnapshotExtraInfo) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ObjId |= uint64(b&0x7F) << shift + m.GapFillMode |= Node_GapFillMode(b&0x7F) << shift if b < 0x80 { break } } - case 3: + case 89: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RankOption", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowPlan @@ -46373,23 +47494,161 @@ func (m *SnapshotExtraInfo) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthPlan } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthPlan } if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + if m.RankOption == nil { + m.RankOption = &RankOption{} + } + if err := m.RankOption.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPlan(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPlan + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SnapshotExtraInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SnapshotExtraInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SnapshotExtraInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Level", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Level = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjId", wireType) + } + m.ObjId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ObjId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -47105,6 +48364,42 @@ func (m *ExternScan) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MongodbScan", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.MongodbScan == nil { + m.MongodbScan = &MongoScan{} + } + if err := m.MongodbScan.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipPlan(dAtA[iNdEx:]) @@ -47490,6 +48785,1016 @@ func (m *IcebergScan) Unmarshal(dAtA []byte) error { } return nil } +func (m *MongoScan) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MongoScan: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MongoScan: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MappingId", wireType) + } + m.MappingId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MappingId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", wireType) + } + m.ConnectionId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ConnectionId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionVersion", wireType) + } + m.ConnectionVersion = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ConnectionVersion |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Database", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Database = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Collection", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Collection = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Columns", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Columns = append(m.Columns, &MongoColumnMapping{}) + if err := m.Columns[len(m.Columns)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PushedPredicate", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PushedPredicate == nil { + m.PushedPredicate = &MongoPredicate{} + } + if err := m.PushedPredicate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProjectedPaths", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProjectedPaths = append(m.ProjectedPaths, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResidualFilterDigest", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResidualFilterDigest = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxParallelism", wireType) + } + m.MaxParallelism = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxParallelism |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Split", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Split == nil { + m.Split = &MongoSplit{} + } + if err := m.Split.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 12: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxScanRows", wireType) + } + m.MaxScanRows = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxScanRows |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 13: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxScanBytes", wireType) + } + m.MaxScanBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxScanBytes |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 14: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MappingVersion", wireType) + } + m.MappingVersion = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MappingVersion |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TableId", wireType) + } + m.TableId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TableId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipPlan(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPlan + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MongoColumnMapping) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MongoColumnMapping: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MongoColumnMapping: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MoType", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MoType.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConversionMode", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConversionMode = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPlan(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPlan + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MongoPredicate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MongoPredicate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MongoPredicate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Op", wireType) + } + m.Op = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Op |= MongoPredicateOp(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValueBson", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValueBson = append(m.ValueBson[:0], dAtA[iNdEx:postIndex]...) + if m.ValueBson == nil { + m.ValueBson = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValuesBson", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValuesBson = append(m.ValuesBson, make([]byte, postIndex-iNdEx)) + copy(m.ValuesBson[len(m.ValuesBson)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Children", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Children = append(m.Children, &MongoPredicate{}) + if err := m.Children[len(m.Children)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPlan(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPlan + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MongoSplit) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MongoSplit: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MongoSplit: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KeyPath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.KeyPath = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LowerBson", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.LowerBson = append(m.LowerBson[:0], dAtA[iNdEx:postIndex]...) + if m.LowerBson == nil { + m.LowerBson = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UpperBson", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPlan + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPlan + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UpperBson = append(m.UpperBson[:0], dAtA[iNdEx:postIndex]...) + if m.UpperBson == nil { + m.UpperBson = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LowerInclusive", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.LowerInclusive = bool(v != 0) + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UpperInclusive", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlan + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.UpperInclusive = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipPlan(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPlan + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ExternAttr) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/pkg/pb/query/query.pb.go b/pkg/pb/query/query.pb.go index 8493fe78bd7ed..7c8bbf4dde31e 100644 --- a/pkg/pb/query/query.pb.go +++ b/pkg/pb/query/query.pb.go @@ -105,6 +105,8 @@ const ( CmdMethod_CtlPrefetchOnSubscribed CmdMethod = 36 // IcebergCacheInvalidate invalidates Iceberg metadata/manifest cache after commit. CmdMethod_IcebergCacheInvalidate CmdMethod = 37 + // MongoDBClientRetire drains obsolete MongoDB driver clients after catalog DDL. + CmdMethod_MongoDBClientRetire CmdMethod = 39 ) var CmdMethod_name = map[int32]string{ @@ -146,6 +148,7 @@ var CmdMethod_name = map[int32]string{ 35: "MinTimestamp", 36: "CtlPrefetchOnSubscribed", 37: "IcebergCacheInvalidate", + 39: "MongoDBClientRetire", } var CmdMethod_value = map[string]int32{ @@ -187,6 +190,7 @@ var CmdMethod_value = map[string]int32{ "MinTimestamp": 35, "CtlPrefetchOnSubscribed": 36, "IcebergCacheInvalidate": 37, + "MongoDBClientRetire": 39, } func (x CmdMethod) String() string { @@ -974,6 +978,7 @@ type Request struct { WorkspaceThresholdRequest *WorkspaceThresholdRequest `protobuf:"bytes,37,opt,name=WorkspaceThresholdRequest,proto3" json:"WorkspaceThresholdRequest,omitempty"` CtlPrefetchOnSubscribedRequest *CtlPrefetchOnSubscribedRequest `protobuf:"bytes,38,opt,name=CtlPrefetchOnSubscribedRequest,proto3" json:"CtlPrefetchOnSubscribedRequest,omitempty"` IcebergCacheInvalidateRequest IcebergCacheInvalidateRequest `protobuf:"bytes,39,opt,name=IcebergCacheInvalidateRequest,proto3" json:"IcebergCacheInvalidateRequest"` + MongoDBClientRetireRequest MongoDBClientRetireRequest `protobuf:"bytes,41,opt,name=MongoDBClientRetireRequest,proto3" json:"MongoDBClientRetireRequest"` } func (m *Request) Reset() { *m = Request{} } @@ -1282,6 +1287,13 @@ func (m *Request) GetIcebergCacheInvalidateRequest() IcebergCacheInvalidateReque return IcebergCacheInvalidateRequest{} } +func (m *Request) GetMongoDBClientRetireRequest() MongoDBClientRetireRequest { + if m != nil { + return m.MongoDBClientRetireRequest + } + return MongoDBClientRetireRequest{} +} + // ShowProcessListResponse is the response of command ShowProcessList. type ShowProcessListResponse struct { Sessions []*status.Session `protobuf:"bytes,1,rep,name=Sessions,proto3" json:"Sessions,omitempty"` @@ -1382,6 +1394,7 @@ type Response struct { MinTimestampResponse *MinTimestampResponse `protobuf:"bytes,38,opt,name=MinTimestampResponse,proto3" json:"MinTimestampResponse,omitempty"` CtlPrefetchOnSubscribedResponse *CtlPrefetchOnSubscribedResponse `protobuf:"bytes,39,opt,name=CtlPrefetchOnSubscribedResponse,proto3" json:"CtlPrefetchOnSubscribedResponse,omitempty"` IcebergCacheInvalidateResponse IcebergCacheInvalidateResponse `protobuf:"bytes,40,opt,name=IcebergCacheInvalidateResponse,proto3" json:"IcebergCacheInvalidateResponse"` + MongoDBClientRetireResponse MongoDBClientRetireResponse `protobuf:"bytes,42,opt,name=MongoDBClientRetireResponse,proto3" json:"MongoDBClientRetireResponse"` } func (m *Response) Reset() { *m = Response{} } @@ -1697,6 +1710,13 @@ func (m *Response) GetIcebergCacheInvalidateResponse() IcebergCacheInvalidateRes return IcebergCacheInvalidateResponse{} } +func (m *Response) GetMongoDBClientRetireResponse() MongoDBClientRetireResponse { + if m != nil { + return m.MongoDBClientRetireResponse + } + return MongoDBClientRetireResponse{} +} + // AlterAccountRequest is the "alter account restricted" query request. type AlterAccountRequest struct { // Tenant is the tenant which to alter. @@ -5064,6 +5084,112 @@ func (m *MinTimestampResponse) GetMinTimestamp() timestamp.Timestamp { return timestamp.Timestamp{} } +type MongoDBClientRetireRequest struct { + AccountID uint32 `protobuf:"varint,1,opt,name=AccountID,proto3" json:"AccountID,omitempty"` + // Zero retires every MongoDB client for AccountID. + ConnectionID uint64 `protobuf:"varint,2,opt,name=ConnectionID,proto3" json:"ConnectionID,omitempty"` + // Zero retires the whole connection; otherwise generations below this value. + VersionExclusive uint64 `protobuf:"varint,3,opt,name=VersionExclusive,proto3" json:"VersionExclusive,omitempty"` +} + +func (m *MongoDBClientRetireRequest) Reset() { *m = MongoDBClientRetireRequest{} } +func (m *MongoDBClientRetireRequest) String() string { return proto.CompactTextString(m) } +func (*MongoDBClientRetireRequest) ProtoMessage() {} +func (*MongoDBClientRetireRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_5c6ac9b241082464, []int{85} +} +func (m *MongoDBClientRetireRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MongoDBClientRetireRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MongoDBClientRetireRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MongoDBClientRetireRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_MongoDBClientRetireRequest.Merge(m, src) +} +func (m *MongoDBClientRetireRequest) XXX_Size() int { + return m.ProtoSize() +} +func (m *MongoDBClientRetireRequest) XXX_DiscardUnknown() { + xxx_messageInfo_MongoDBClientRetireRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_MongoDBClientRetireRequest proto.InternalMessageInfo + +func (m *MongoDBClientRetireRequest) GetAccountID() uint32 { + if m != nil { + return m.AccountID + } + return 0 +} + +func (m *MongoDBClientRetireRequest) GetConnectionID() uint64 { + if m != nil { + return m.ConnectionID + } + return 0 +} + +func (m *MongoDBClientRetireRequest) GetVersionExclusive() uint64 { + if m != nil { + return m.VersionExclusive + } + return 0 +} + +type MongoDBClientRetireResponse struct { + Success bool `protobuf:"varint,1,opt,name=Success,proto3" json:"Success,omitempty"` +} + +func (m *MongoDBClientRetireResponse) Reset() { *m = MongoDBClientRetireResponse{} } +func (m *MongoDBClientRetireResponse) String() string { return proto.CompactTextString(m) } +func (*MongoDBClientRetireResponse) ProtoMessage() {} +func (*MongoDBClientRetireResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_5c6ac9b241082464, []int{86} +} +func (m *MongoDBClientRetireResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MongoDBClientRetireResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MongoDBClientRetireResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MongoDBClientRetireResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MongoDBClientRetireResponse.Merge(m, src) +} +func (m *MongoDBClientRetireResponse) XXX_Size() int { + return m.ProtoSize() +} +func (m *MongoDBClientRetireResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MongoDBClientRetireResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MongoDBClientRetireResponse proto.InternalMessageInfo + +func (m *MongoDBClientRetireResponse) GetSuccess() bool { + if m != nil { + return m.Success + } + return false +} + func init() { proto.RegisterEnum("query.CmdMethod", CmdMethod_name, CmdMethod_value) proto.RegisterEnum("query.FileServiceCacheType", FileServiceCacheType_name, FileServiceCacheType_value) @@ -5152,241 +5278,249 @@ func init() { proto.RegisterType((*WorkspaceThresholdRequest)(nil), "query.WorkspaceThresholdRequest") proto.RegisterType((*WorkspaceThresholdResponse)(nil), "query.WorkspaceThresholdResponse") proto.RegisterType((*MinTimestampResponse)(nil), "query.MinTimestampResponse") + proto.RegisterType((*MongoDBClientRetireRequest)(nil), "query.MongoDBClientRetireRequest") + proto.RegisterType((*MongoDBClientRetireResponse)(nil), "query.MongoDBClientRetireResponse") } func init() { proto.RegisterFile("query.proto", fileDescriptor_5c6ac9b241082464) } var fileDescriptor_5c6ac9b241082464 = []byte{ - // 3650 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5b, 0xcd, 0x72, 0xdc, 0x46, - 0x92, 0x56, 0xf3, 0xb7, 0x3b, 0xf9, 0x07, 0x96, 0x9a, 0x24, 0x48, 0x51, 0x4d, 0x0a, 0xfa, 0xb5, - 0x64, 0x93, 0x5a, 0xda, 0xd2, 0xae, 0xed, 0xdd, 0x0d, 0x93, 0x4d, 0x91, 0xa2, 0x45, 0x8a, 0x54, - 0x35, 0x65, 0xc9, 0xda, 0x08, 0x45, 0x80, 0xdd, 0x45, 0x12, 0xab, 0x6e, 0xa0, 0x0d, 0xa0, 0x65, - 0xd2, 0x11, 0xfb, 0x08, 0x1b, 0xe1, 0x47, 0x98, 0x79, 0x8c, 0xb9, 0xcf, 0xc1, 0x47, 0x1f, 0x7d, - 0x9a, 0x99, 0xb0, 0x5e, 0x60, 0x0e, 0x33, 0xe7, 0x99, 0xa8, 0x42, 0x16, 0x80, 0x02, 0x0a, 0x4d, - 0xdb, 0x63, 0x5f, 0x18, 0xa8, 0xac, 0xcc, 0xaf, 0x0a, 0x85, 0xaa, 0xac, 0xfc, 0x32, 0x9b, 0x30, - 0xf6, 0x55, 0x8f, 0xf9, 0xe7, 0x2b, 0x5d, 0xdf, 0x0b, 0x3d, 0x32, 0x2c, 0x1a, 0x0b, 0xe3, 0x41, - 0x68, 0x87, 0xbd, 0x20, 0x12, 0x2e, 0x40, 0xdb, 0x6b, 0xbe, 0xc1, 0xe7, 0x4a, 0x78, 0xe6, 0xe2, - 0xe3, 0x54, 0xe8, 0x74, 0x58, 0x10, 0xda, 0x9d, 0xae, 0x14, 0x70, 0xab, 0xc0, 0x71, 0x8f, 0x3d, - 0x14, 0x7c, 0x70, 0xe2, 0x84, 0xa7, 0xbd, 0xa3, 0x95, 0xa6, 0xd7, 0x59, 0x3d, 0xf1, 0x4e, 0xbc, - 0x55, 0x21, 0x3e, 0xea, 0x1d, 0x8b, 0x96, 0x68, 0x88, 0x27, 0x54, 0x5f, 0x3a, 0xf1, 0xbc, 0x93, - 0x36, 0x4b, 0xb4, 0x32, 0x03, 0x58, 0x37, 0x60, 0xfc, 0x19, 0x9f, 0x1f, 0x65, 0x5f, 0xf5, 0x58, - 0x10, 0x92, 0x2a, 0x0c, 0x8b, 0xb6, 0x59, 0x5a, 0x2e, 0xdd, 0xa9, 0xd0, 0xa8, 0x61, 0x3d, 0x85, - 0xd9, 0xc6, 0xa9, 0xf7, 0xf5, 0x81, 0xef, 0x35, 0x59, 0x10, 0xec, 0x3a, 0x41, 0x28, 0xf5, 0x67, - 0x61, 0xe4, 0x90, 0xb9, 0xb6, 0x1b, 0xa2, 0x01, 0xb6, 0xc8, 0x22, 0x54, 0x1a, 0xe7, 0x01, 0x76, - 0x0d, 0x2c, 0x97, 0xee, 0x94, 0x69, 0x22, 0xb0, 0x5e, 0xc0, 0x74, 0xe3, 0xdc, 0x6d, 0xd6, 0xbd, - 0x4e, 0xc7, 0x89, 0xa1, 0x36, 0x60, 0x72, 0xd7, 0x0e, 0x59, 0x10, 0x46, 0xe2, 0xc3, 0x86, 0x80, - 0x1c, 0x5b, 0xab, 0xae, 0x24, 0x93, 0x3e, 0x94, 0x4f, 0x1b, 0x43, 0xdf, 0xfd, 0x69, 0xe9, 0x12, - 0xcd, 0x58, 0x58, 0xaf, 0x80, 0xa4, 0x81, 0x83, 0xae, 0xe7, 0x06, 0x8c, 0x6c, 0xc2, 0x54, 0xbd, - 0xe7, 0xfb, 0xcc, 0xfd, 0x39, 0xd0, 0x59, 0x13, 0x8b, 0x80, 0xb1, 0xcd, 0x42, 0x65, 0xce, 0xd6, - 0x97, 0x30, 0x9d, 0x92, 0xfd, 0xaa, 0xc3, 0xad, 0xc2, 0x4c, 0xdd, 0xf3, 0xd9, 0x66, 0xaf, 0xd3, - 0xad, 0x7b, 0xee, 0xb1, 0x73, 0x92, 0x5a, 0xf2, 0xf5, 0x66, 0xe8, 0x78, 0xae, 0x5c, 0xf2, 0xa8, - 0x65, 0x99, 0x30, 0x9b, 0x35, 0x88, 0x26, 0x64, 0x5d, 0x81, 0xf9, 0x6d, 0x16, 0x1e, 0xf0, 0x0f, - 0xde, 0xf4, 0xda, 0x5f, 0x30, 0x3f, 0x70, 0x3c, 0x57, 0xbe, 0xc2, 0x43, 0x58, 0xd0, 0x75, 0xe2, - 0xbb, 0x98, 0x30, 0x8a, 0x22, 0x31, 0xda, 0x20, 0x95, 0x4d, 0xeb, 0x01, 0xcc, 0x37, 0x8a, 0x40, - 0xfb, 0x98, 0x3d, 0x84, 0x85, 0xc6, 0x2f, 0x19, 0xee, 0x7d, 0x98, 0xa4, 0x3d, 0xf7, 0xd0, 0x0e, - 0xde, 0xc8, 0x31, 0x16, 0xa0, 0xcc, 0x9b, 0x75, 0xaf, 0xc5, 0x84, 0xf2, 0x30, 0x8d, 0xdb, 0xd6, - 0x7b, 0x30, 0x15, 0x6b, 0x23, 0xf4, 0x2c, 0x8c, 0x50, 0x16, 0xf4, 0xda, 0xf1, 0x4e, 0x8d, 0x5a, - 0x7c, 0xd9, 0xf8, 0xfb, 0x3b, 0x5d, 0xd6, 0x76, 0x5c, 0xb6, 0xe3, 0x1e, 0x7b, 0x72, 0x65, 0x56, - 0x61, 0x2e, 0xd7, 0x83, 0x60, 0x55, 0x18, 0xae, 0x7b, 0x3d, 0xdc, 0xf5, 0x83, 0x34, 0x6a, 0x58, - 0x7f, 0x9d, 0x83, 0x51, 0x39, 0xbb, 0x45, 0xa8, 0xe0, 0xe3, 0xce, 0xa6, 0xd0, 0x1a, 0xa2, 0x89, - 0x80, 0xac, 0x40, 0xa5, 0xde, 0x69, 0xed, 0xb1, 0xf0, 0xd4, 0x6b, 0x89, 0xe3, 0x31, 0xb9, 0x66, - 0xac, 0x44, 0x5e, 0x23, 0x96, 0xd3, 0x44, 0x85, 0xfc, 0xbb, 0x7a, 0x4c, 0xcd, 0x41, 0xb1, 0x9f, - 0x2e, 0xa3, 0x49, 0xba, 0x8b, 0xaa, 0xe7, 0xf9, 0x79, 0xd1, 0xc9, 0x35, 0x87, 0x04, 0xc4, 0x55, - 0x84, 0xd0, 0x2b, 0xd1, 0xa2, 0x63, 0xbf, 0x0b, 0x97, 0xd7, 0xdb, 0x21, 0xf3, 0xd7, 0x9b, 0x4d, - 0xfe, 0xe6, 0x12, 0x73, 0x58, 0x60, 0x2e, 0x20, 0xa6, 0x46, 0x83, 0xea, 0xcc, 0xc8, 0x67, 0x30, - 0xf5, 0xc4, 0x69, 0xb7, 0xeb, 0x9e, 0x2b, 0x37, 0x90, 0x39, 0x22, 0x90, 0x66, 0x11, 0x29, 0xd3, - 0x4b, 0xb3, 0xea, 0xa4, 0x0e, 0xc6, 0xa1, 0x6f, 0x37, 0x59, 0xa3, 0x6b, 0xc7, 0x10, 0xa3, 0x02, - 0x62, 0x0e, 0x21, 0xb2, 0xdd, 0x34, 0x67, 0x40, 0x76, 0x80, 0x6c, 0xb3, 0x70, 0xd7, 0x6b, 0xbe, - 0x49, 0xed, 0x02, 0xb3, 0x2c, 0x60, 0xe6, 0x11, 0x26, 0xaf, 0x40, 0x35, 0x46, 0x64, 0x4b, 0xf8, - 0x85, 0xc3, 0x33, 0x37, 0x8d, 0x54, 0x11, 0x48, 0x66, 0x82, 0xa4, 0xf6, 0xd3, 0xbc, 0x09, 0x5f, - 0x67, 0xee, 0x5f, 0xec, 0xe6, 0x69, 0x7a, 0x67, 0x9a, 0xa0, 0xac, 0xb3, 0x46, 0x83, 0xea, 0xcc, - 0xc8, 0x7f, 0x00, 0x34, 0xce, 0x9b, 0x6e, 0xe4, 0x62, 0xcc, 0x31, 0x65, 0x3a, 0x39, 0x7f, 0x4c, - 0x53, 0xba, 0xe4, 0x01, 0x54, 0x62, 0x3f, 0x67, 0x8e, 0x2b, 0x0b, 0x9b, 0xf5, 0x89, 0x34, 0xd1, - 0x24, 0x07, 0x62, 0x45, 0x33, 0x87, 0xdd, 0x9c, 0x10, 0xf6, 0xcb, 0x89, 0xbd, 0xde, 0x89, 0x50, - 0x8d, 0x2d, 0x47, 0xcc, 0xbb, 0x0f, 0x73, 0x52, 0x41, 0x6c, 0x14, 0x23, 0xe6, 0xbb, 0xc8, 0x26, - 0x4c, 0xaa, 0x6e, 0xd3, 0x9c, 0x12, 0x68, 0x8b, 0xf2, 0x3c, 0xea, 0x9c, 0x30, 0xcd, 0xd8, 0x90, - 0x55, 0x18, 0x45, 0x87, 0x63, 0x1a, 0xc2, 0x7c, 0x06, 0xcd, 0x55, 0xa7, 0x45, 0xa5, 0x16, 0xf9, - 0x12, 0x66, 0x28, 0xeb, 0x78, 0x6f, 0x19, 0xff, 0x1b, 0x32, 0xbe, 0x81, 0x0e, 0xed, 0xa3, 0x36, - 0x33, 0xa7, 0x85, 0xf9, 0x75, 0x69, 0xae, 0xd3, 0x91, 0x60, 0x7a, 0x04, 0xb2, 0x0e, 0x13, 0x7c, - 0x4b, 0x8a, 0x9b, 0x71, 0xc3, 0x71, 0x5b, 0x26, 0x11, 0x90, 0x57, 0x52, 0x5b, 0x38, 0xee, 0x93, - 0x50, 0xaa, 0x05, 0xf9, 0x1c, 0x8c, 0xe7, 0x6e, 0xd0, 0x3b, 0x0a, 0x9a, 0xbe, 0x73, 0xc4, 0xa2, - 0x89, 0x5d, 0x16, 0x28, 0x35, 0x44, 0xc9, 0x76, 0xc7, 0xc7, 0x2a, 0xdb, 0x91, 0xde, 0xc3, 0x9b, - 0x76, 0x68, 0xcb, 0x3d, 0x5c, 0xd5, 0xee, 0xe1, 0x94, 0x06, 0xd5, 0x99, 0x21, 0x5a, 0x83, 0x87, - 0x45, 0xe9, 0x13, 0x31, 0x93, 0x45, 0xcb, 0x6a, 0x50, 0x9d, 0x19, 0x77, 0x8f, 0x7a, 0xe7, 0x6f, - 0xce, 0x2a, 0xee, 0x51, 0xaf, 0x44, 0x0b, 0x8c, 0x39, 0xec, 0x9e, 0x73, 0xe2, 0xdb, 0x21, 0xe3, - 0x4e, 0x6a, 0xcb, 0xf7, 0x3a, 0x12, 0x76, 0x4e, 0x81, 0xd5, 0x2b, 0xd1, 0x02, 0x63, 0xb2, 0x0f, - 0xd5, 0x54, 0xcf, 0x61, 0x3c, 0x57, 0x53, 0xf9, 0xbe, 0x3a, 0x15, 0xaa, 0x35, 0x24, 0x47, 0x60, - 0x52, 0xd6, 0xf6, 0xec, 0xd6, 0x7a, 0x2f, 0xf4, 0x76, 0xdc, 0xa6, 0xcf, 0x3a, 0x3c, 0x04, 0xe1, - 0x6b, 0x6e, 0xce, 0x0b, 0xd0, 0x5b, 0xf1, 0x3e, 0xd4, 0xab, 0x49, 0xfc, 0x42, 0x1c, 0xee, 0x9a, - 0xeb, 0x61, 0x9b, 0x32, 0xbb, 0xc5, 0x7c, 0x39, 0xe1, 0x05, 0xc5, 0x83, 0x64, 0xbb, 0x69, 0xce, - 0x80, 0xec, 0xc1, 0xd4, 0x36, 0x0b, 0x29, 0xeb, 0xb6, 0x9d, 0xa6, 0x1d, 0xdd, 0xbc, 0x57, 0xb2, - 0x1f, 0x28, 0xdd, 0x8b, 0x76, 0x32, 0xb6, 0xca, 0xf4, 0xf2, 0x4d, 0x44, 0x59, 0xc0, 0xc2, 0x06, - 0x0b, 0x52, 0xee, 0xc1, 0x5c, 0x54, 0x36, 0x91, 0x46, 0x83, 0xea, 0xcc, 0xc8, 0x2e, 0x4c, 0x6f, - 0x7b, 0x7b, 0xf6, 0x19, 0xbf, 0x27, 0x03, 0x89, 0x75, 0x55, 0x75, 0xf6, 0xd9, 0x7e, 0x9c, 0x59, - 0xde, 0x10, 0xd1, 0x58, 0x67, 0xd7, 0x49, 0x7c, 0xaa, 0x59, 0xcb, 0xa2, 0xa9, 0xfd, 0x29, 0x34, - 0xb5, 0x83, 0xbc, 0x86, 0xb9, 0x2d, 0xa7, 0xcd, 0x1a, 0xcc, 0x7f, 0xeb, 0x34, 0x59, 0xfa, 0x93, - 0x99, 0x4b, 0xca, 0x79, 0x2e, 0xd0, 0x42, 0xe4, 0x22, 0x10, 0xd2, 0x81, 0xc5, 0x6c, 0xd7, 0xa3, - 0xb7, 0x4e, 0x33, 0x9e, 0xf8, 0xb2, 0xe2, 0xcd, 0xfa, 0xa9, 0xe2, 0x48, 0x7d, 0xe1, 0xc8, 0x73, - 0xa8, 0xee, 0xb1, 0xd0, 0x6e, 0xd9, 0xa1, 0xad, 0xbc, 0xcb, 0x35, 0xf5, 0x04, 0x68, 0x54, 0x10, - 0x5e, 0x6b, 0x4e, 0xf6, 0x81, 0x6c, 0x7b, 0xdb, 0xf5, 0x03, 0xe6, 0x37, 0x59, 0x12, 0xcd, 0x58, - 0xea, 0xcd, 0x9f, 0x53, 0x40, 0x48, 0x8d, 0x29, 0x0f, 0x25, 0xb6, 0xec, 0x5e, 0x3b, 0xdc, 0x71, - 0xff, 0x97, 0x25, 0x8b, 0x71, 0x5d, 0x01, 0xcc, 0x2b, 0x50, 0x8d, 0x11, 0xf9, 0x1f, 0x98, 0xad, - 0x87, 0xed, 0x3d, 0x4f, 0x38, 0x53, 0xe1, 0xc0, 0x24, 0xdc, 0x0d, 0xe5, 0x04, 0xe8, 0x95, 0x70, - 0x8e, 0x05, 0x10, 0xe4, 0x35, 0xcc, 0xbf, 0xf0, 0xfc, 0x37, 0x41, 0xd7, 0x6e, 0xb2, 0xc3, 0x53, - 0x9f, 0x05, 0xa7, 0x5e, 0x5b, 0xde, 0x09, 0xe6, 0x4d, 0xe5, 0x56, 0x2d, 0xd4, 0xa3, 0xc5, 0x10, - 0xa4, 0x03, 0xb5, 0x7a, 0xd8, 0x3e, 0xf0, 0xd9, 0x31, 0x0b, 0x9b, 0xa7, 0xfb, 0x6e, 0x43, 0x5e, - 0x0d, 0xf1, 0x20, 0xb7, 0xc4, 0x20, 0x37, 0x93, 0x97, 0xe8, 0xa3, 0x4c, 0x2f, 0x00, 0x23, 0x5d, - 0xb8, 0xba, 0xd3, 0x64, 0x47, 0xcc, 0x3f, 0xc1, 0xd8, 0xe7, 0xad, 0xdd, 0x76, 0x5a, 0x76, 0x18, - 0xef, 0x93, 0xdb, 0x62, 0xb4, 0x1b, 0x38, 0x5a, 0x5f, 0x5d, 0x5c, 0xb9, 0xfe, 0x80, 0xd6, 0x16, - 0xcc, 0xe5, 0x42, 0x64, 0xe4, 0x08, 0xf7, 0xa0, 0x8c, 0x8e, 0x22, 0x30, 0x4b, 0xcb, 0x83, 0x77, - 0xc6, 0xd6, 0xa6, 0x56, 0x30, 0x09, 0x20, 0x1d, 0x48, 0xac, 0x60, 0xfd, 0xdd, 0x84, 0x72, 0x6c, - 0xf9, 0xeb, 0x72, 0x87, 0x2a, 0x0c, 0x3f, 0xf2, 0x7d, 0xcf, 0x17, 0xa4, 0x61, 0x9c, 0x46, 0x0d, - 0xf2, 0xb2, 0x70, 0xe2, 0xc8, 0x0c, 0x6a, 0x45, 0xcc, 0x20, 0xd2, 0xa2, 0x85, 0xef, 0xbd, 0x0f, - 0x55, 0x35, 0xc8, 0x47, 0xd8, 0x61, 0xe5, 0x8c, 0xea, 0x54, 0xa8, 0xd6, 0x90, 0xdf, 0x20, 0x49, - 0xbc, 0x8f, 0x60, 0x23, 0xca, 0x0d, 0x92, 0xed, 0xa6, 0x39, 0x03, 0x1e, 0x91, 0xa7, 0x02, 0x7e, - 0x44, 0x19, 0x55, 0xdc, 0x6a, 0xae, 0x9f, 0xe6, 0x4d, 0x30, 0xfe, 0x48, 0xe2, 0x7d, 0x44, 0x2a, - 0x67, 0xe3, 0x8f, 0xac, 0x06, 0xd5, 0x99, 0x21, 0xe5, 0x88, 0x83, 0x7e, 0x04, 0xab, 0x64, 0x29, - 0x47, 0x46, 0x81, 0x6a, 0x8c, 0xf8, 0xb2, 0xab, 0x31, 0x3f, 0x82, 0x41, 0x36, 0xf8, 0xcb, 0xa9, - 0x50, 0xad, 0x21, 0xf9, 0x98, 0xb3, 0x05, 0x49, 0x0a, 0x90, 0x2d, 0xcc, 0x6b, 0xd8, 0x02, 0x82, - 0xa4, 0x94, 0xc9, 0xc3, 0x3c, 0x5d, 0x30, 0xf3, 0x74, 0x01, 0x0d, 0x53, 0x7c, 0xe1, 0x59, 0x1f, - 0xbe, 0x70, 0xad, 0x0f, 0x5f, 0x48, 0x2d, 0x4b, 0x36, 0xbc, 0x7f, 0xd6, 0x87, 0x30, 0x5c, 0xeb, - 0x43, 0x18, 0x24, 0xa4, 0x86, 0x31, 0x3c, 0x2a, 0x60, 0x0c, 0x57, 0x0b, 0x18, 0x03, 0x42, 0x65, - 0x29, 0xc3, 0xfd, 0x2c, 0x65, 0x98, 0xcd, 0x52, 0x06, 0x34, 0x8c, 0x39, 0xc3, 0xab, 0xfe, 0x9c, - 0xe1, 0x46, 0x7f, 0xce, 0x80, 0x68, 0x05, 0xa4, 0x61, 0x43, 0x4f, 0x1a, 0x16, 0xf5, 0xa4, 0x01, - 0xb1, 0x32, 0xac, 0xe1, 0x49, 0x21, 0x6b, 0x58, 0x2a, 0x64, 0x0d, 0xf2, 0xc0, 0xe6, 0x68, 0x43, - 0x6a, 0x3f, 0x47, 0xf1, 0x3f, 0xee, 0xe7, 0xaa, 0x76, 0x3f, 0xa7, 0x55, 0xa8, 0xd6, 0x10, 0x01, - 0x53, 0x14, 0x00, 0x01, 0x67, 0xb2, 0x80, 0x39, 0x15, 0xaa, 0x35, 0xe4, 0x2e, 0xb4, 0x20, 0x3f, - 0x84, 0xec, 0xa1, 0x56, 0xc4, 0x1e, 0xa4, 0x0b, 0x2d, 0x4a, 0x2f, 0xbd, 0x84, 0xb9, 0x1c, 0x05, - 0x40, 0xe4, 0x39, 0x05, 0xb9, 0x40, 0x8b, 0x16, 0x99, 0x13, 0x0a, 0x33, 0x19, 0x26, 0x80, 0xb8, - 0xa6, 0xf2, 0xb9, 0xb5, 0x3a, 0x54, 0x6f, 0x4a, 0x9a, 0x17, 0xb2, 0x88, 0xdb, 0x17, 0xb2, 0x08, - 0x1c, 0xa1, 0x98, 0x46, 0x6c, 0xc1, 0x74, 0x8a, 0x15, 0xe0, 0xa4, 0x17, 0x14, 0xd7, 0x92, 0xeb, - 0xa7, 0x79, 0x13, 0xf2, 0xb4, 0x88, 0x49, 0xd4, 0x8a, 0x98, 0x44, 0x64, 0x58, 0x44, 0x25, 0xf6, - 0xa1, 0xaa, 0x72, 0x02, 0x9c, 0xda, 0xa2, 0xb2, 0xab, 0x74, 0x2a, 0x54, 0x6b, 0x18, 0xc5, 0xa2, - 0x09, 0x29, 0x40, 0xb8, 0xab, 0x99, 0x58, 0x34, 0xab, 0x90, 0xc4, 0xa2, 0xd9, 0x1e, 0x04, 0x8c, - 0x79, 0x01, 0x02, 0xd6, 0xb2, 0x80, 0x19, 0x85, 0x14, 0x60, 0xa6, 0x87, 0xd8, 0x60, 0xe6, 0xe9, - 0x00, 0xc2, 0x2e, 0x29, 0xc7, 0xbd, 0x48, 0x0d, 0xc1, 0x0b, 0x61, 0x78, 0x20, 0x57, 0xc0, 0x03, - 0x70, 0x9c, 0x65, 0xc5, 0xe3, 0xf5, 0xd5, 0x95, 0x81, 0x5c, 0x5f, 0x25, 0xf2, 0x12, 0x66, 0x32, - 0xd4, 0x00, 0x47, 0xba, 0xa6, 0x1e, 0x0c, 0x9d, 0x0e, 0x8e, 0xa0, 0x07, 0x20, 0x14, 0x2e, 0x2b, - 0x0c, 0x01, 0x71, 0x2d, 0x35, 0x62, 0xc8, 0x6b, 0x20, 0xaa, 0xce, 0x98, 0x47, 0x21, 0x0a, 0x55, - 0x40, 0xcc, 0xeb, 0x0a, 0xa6, 0x46, 0x83, 0xea, 0xcc, 0x38, 0x49, 0xcc, 0xf1, 0x03, 0x44, 0xbc, - 0xa1, 0x9c, 0x8d, 0x02, 0x2d, 0x49, 0x12, 0x0b, 0xba, 0x89, 0x0d, 0x0b, 0x3a, 0x8a, 0x80, 0x43, - 0xdc, 0x54, 0xee, 0xe2, 0x62, 0x45, 0xda, 0x07, 0x24, 0x4a, 0x8d, 0xb8, 0x71, 0x51, 0x25, 0x06, - 0xbf, 0x95, 0x49, 0x8d, 0xe4, 0x55, 0xa8, 0xd6, 0x90, 0x74, 0x61, 0xa9, 0x90, 0x6c, 0x20, 0xf6, - 0x6d, 0x25, 0x43, 0x72, 0x81, 0x36, 0xbd, 0x08, 0x8e, 0x04, 0x50, 0x2b, 0xe2, 0x1a, 0x38, 0xe0, - 0x1d, 0x85, 0x2b, 0xf5, 0x57, 0xc6, 0x6f, 0x72, 0x01, 0xa4, 0xb5, 0xa3, 0x4d, 0xe4, 0x8b, 0xda, - 0x8a, 0x28, 0xd5, 0xed, 0xb4, 0xb0, 0xc4, 0x11, 0xb7, 0xc9, 0x2c, 0x8c, 0x34, 0x04, 0x8d, 0x11, - 0x84, 0xa2, 0x42, 0xb1, 0x65, 0x7d, 0xa2, 0x8f, 0xfb, 0x89, 0x05, 0xe3, 0x36, 0x97, 0x37, 0x7a, - 0x4d, 0xce, 0x15, 0x04, 0x5e, 0x99, 0x2a, 0x32, 0x6b, 0x27, 0x57, 0x01, 0xe0, 0x24, 0x08, 0x91, - 0x90, 0x04, 0x0d, 0xd2, 0x44, 0x90, 0x2e, 0x14, 0x0d, 0x08, 0x82, 0x94, 0x2a, 0x14, 0xe5, 0x83, - 0x7f, 0x13, 0x46, 0xd5, 0xd1, 0x65, 0xd3, 0xda, 0xcd, 0x67, 0xa7, 0x88, 0x01, 0x83, 0xf5, 0x4e, - 0x0b, 0xcb, 0x44, 0xfc, 0x51, 0x48, 0x8e, 0x4f, 0xc4, 0x48, 0x5c, 0x72, 0x7c, 0x22, 0x48, 0xd5, - 0x59, 0xe8, 0xdb, 0x31, 0xa9, 0xe2, 0x0d, 0xeb, 0xb6, 0xe6, 0x92, 0x22, 0x04, 0x86, 0xf8, 0x33, - 0xe2, 0x89, 0x67, 0xeb, 0x3f, 0x2f, 0xe2, 0xc5, 0xfc, 0x0b, 0x1c, 0xd8, 0x61, 0xc8, 0x7c, 0x64, - 0x8f, 0x15, 0x1a, 0xb7, 0xad, 0x07, 0x17, 0xee, 0x4d, 0xed, 0xa0, 0x2f, 0xf3, 0x45, 0x12, 0xcd, - 0xbb, 0x56, 0x61, 0x98, 0x2b, 0x04, 0xf8, 0xb6, 0x51, 0x83, 0x7f, 0x8d, 0xf8, 0xd0, 0x89, 0x77, - 0x1e, 0xa4, 0x89, 0x80, 0xbf, 0x77, 0x9e, 0x29, 0xe9, 0xa6, 0x50, 0xd5, 0x95, 0x58, 0xac, 0x1f, - 0x4a, 0x50, 0x96, 0x32, 0xfe, 0xad, 0x84, 0x0b, 0xc1, 0x9d, 0x37, 0x44, 0x65, 0x93, 0x03, 0x3e, - 0x61, 0xe7, 0x7c, 0x62, 0x83, 0x77, 0xc6, 0xa9, 0x78, 0x26, 0x77, 0x23, 0xcb, 0x3d, 0xaf, 0xc5, - 0xc4, 0xb4, 0x26, 0xd7, 0x26, 0x57, 0x44, 0x6d, 0x5d, 0x4a, 0x69, 0xdc, 0x4f, 0x96, 0x61, 0xcc, - 0x09, 0xa8, 0xed, 0x9e, 0x88, 0xb0, 0x57, 0xd0, 0xdc, 0x32, 0x4d, 0x8b, 0xc8, 0x6d, 0x18, 0x7d, - 0xec, 0xb5, 0x5b, 0xcc, 0x0f, 0xcc, 0x61, 0xc1, 0xd8, 0x27, 0x22, 0xb0, 0x17, 0xb6, 0xc3, 0xf9, - 0x16, 0x95, 0xbd, 0x5c, 0x91, 0xcb, 0xb8, 0xe2, 0x88, 0x56, 0x11, 0x7b, 0xad, 0xd7, 0x5a, 0xba, - 0xc8, 0x5f, 0xa5, 0xee, 0xee, 0xc8, 0x75, 0x17, 0xcf, 0xe4, 0x43, 0x18, 0x97, 0x7a, 0x9c, 0x4f, - 0x8b, 0xd7, 0x1c, 0x5b, 0x9b, 0xc2, 0xd3, 0x1e, 0x43, 0x28, 0x4a, 0xd6, 0x65, 0x4d, 0xa1, 0xc9, - 0x3a, 0x85, 0xb1, 0xc3, 0x33, 0xf7, 0xa7, 0xad, 0x28, 0xf5, 0xbe, 0x8e, 0x57, 0x94, 0x3f, 0x93, - 0x7b, 0x30, 0xba, 0xdf, 0x0d, 0x45, 0xd6, 0x22, 0xaa, 0x32, 0x4e, 0x27, 0x0b, 0x8a, 0x1d, 0x54, - 0x6a, 0x58, 0x7f, 0x28, 0xc1, 0x28, 0x0e, 0x4e, 0x3e, 0x83, 0x72, 0xdd, 0x67, 0x76, 0xc8, 0xd6, - 0x43, 0xac, 0x77, 0x2f, 0xac, 0x44, 0x3f, 0x3f, 0x58, 0x91, 0x3f, 0x3f, 0x48, 0x55, 0xbd, 0xcb, - 0xdc, 0x3d, 0x7d, 0xfb, 0xe7, 0xa5, 0x12, 0x8d, 0xad, 0xc8, 0x32, 0x0c, 0xf1, 0x2b, 0x54, 0xec, - 0xbc, 0xb1, 0xb5, 0xf1, 0x95, 0xf0, 0xcc, 0x5d, 0x39, 0x3c, 0x73, 0xb9, 0x8c, 0x8a, 0x1e, 0xfe, - 0x2a, 0xcf, 0x03, 0xe6, 0x1f, 0x9e, 0xb9, 0x62, 0x72, 0x65, 0x2a, 0x9b, 0xe4, 0x3e, 0x54, 0xf8, - 0x9a, 0xf3, 0x59, 0x06, 0xe6, 0x90, 0x58, 0x3a, 0x22, 0x79, 0x7d, 0xb2, 0x16, 0x34, 0x51, 0xb2, - 0x5e, 0xe9, 0xb8, 0xb7, 0xf6, 0xcb, 0xdc, 0x17, 0xeb, 0x99, 0xf9, 0x30, 0x93, 0x09, 0xba, 0x00, - 0x48, 0xab, 0x58, 0x33, 0xda, 0xba, 0x9d, 0xf5, 0xfb, 0x12, 0x54, 0x62, 0x21, 0x3f, 0xe2, 0x4f, - 0xbd, 0x16, 0x3b, 0x3c, 0xef, 0x32, 0x1c, 0x2e, 0x6e, 0x73, 0x27, 0xcb, 0x9f, 0x77, 0x5a, 0x78, - 0x0c, 0xb1, 0xc5, 0xcf, 0xa1, 0x00, 0x10, 0x46, 0x91, 0xff, 0x4d, 0x04, 0x7c, 0xf2, 0xcf, 0x03, - 0xd6, 0x12, 0x5b, 0x7b, 0x88, 0x8a, 0x67, 0x2e, 0xdb, 0xf2, 0x59, 0x94, 0x7e, 0x19, 0xa2, 0xe2, - 0x99, 0x8f, 0xfc, 0xd8, 0x09, 0xa9, 0x1d, 0x3a, 0x9e, 0xc8, 0xa4, 0x0c, 0xd0, 0xb8, 0x6d, 0x3d, - 0xd5, 0xe7, 0x11, 0xc8, 0x43, 0x98, 0x88, 0x85, 0x62, 0x19, 0xa2, 0x9c, 0x56, 0x9c, 0x7a, 0x8a, - 0x0d, 0x54, 0x35, 0xab, 0x0d, 0x8b, 0xfd, 0x8a, 0x58, 0xfc, 0x93, 0x6e, 0xfb, 0x5e, 0xaf, 0x8b, - 0x5e, 0x7e, 0x82, 0xca, 0x66, 0xb2, 0x6f, 0x37, 0xa5, 0x8f, 0xc7, 0x66, 0xda, 0xfb, 0x0f, 0xaa, - 0xde, 0xff, 0x01, 0x5c, 0xed, 0x4b, 0x7f, 0xd5, 0xca, 0xfd, 0xb0, 0xac, 0xdc, 0x7f, 0x2e, 0x5e, - 0x3a, 0x57, 0x16, 0xfb, 0x25, 0x93, 0xb3, 0xee, 0xc1, 0x8c, 0x96, 0x2d, 0xf3, 0x2f, 0x21, 0x98, - 0x35, 0x6e, 0x2d, 0xfe, 0x6c, 0x35, 0x60, 0xae, 0xa0, 0x92, 0x46, 0x6a, 0x00, 0x9c, 0xbf, 0x1e, - 0xd9, 0x01, 0x8b, 0xd3, 0x80, 0x29, 0x49, 0x9f, 0x19, 0x7c, 0x04, 0x66, 0x11, 0xd1, 0xee, 0x73, - 0x15, 0x6e, 0x41, 0x59, 0x7c, 0xb9, 0x27, 0xec, 0x9c, 0x4f, 0xf5, 0xc0, 0x0e, 0x4f, 0xe5, 0x54, - 0xf9, 0x33, 0xdf, 0x92, 0xfb, 0xc7, 0xc7, 0x01, 0x8b, 0x7e, 0xcf, 0x33, 0x48, 0xb1, 0x45, 0x26, - 0x61, 0xa0, 0xf1, 0x0d, 0xde, 0x09, 0x03, 0x8d, 0x6f, 0xac, 0x87, 0xb8, 0x45, 0x85, 0x7f, 0x7e, - 0x0f, 0x86, 0xde, 0x70, 0x9f, 0x5d, 0x52, 0x9c, 0x99, 0xec, 0xc7, 0x20, 0x45, 0xa8, 0x58, 0x87, - 0x30, 0x85, 0xaf, 0x1e, 0x4f, 0xa3, 0x0a, 0xc3, 0x3b, 0x6e, 0x8b, 0x9d, 0xc9, 0x8f, 0x25, 0x1a, - 0xe4, 0x5e, 0x32, 0x51, 0x74, 0x15, 0x59, 0x5c, 0x1a, 0x2b, 0x58, 0x2f, 0xb4, 0xd5, 0x47, 0xf2, - 0x59, 0x6e, 0x30, 0x9c, 0x62, 0x9c, 0x84, 0x51, 0x7b, 0x69, 0x56, 0xdd, 0xda, 0x87, 0x69, 0xb9, - 0xa8, 0x31, 0x7a, 0xc1, 0x84, 0x0d, 0x18, 0x7c, 0xec, 0xc8, 0x9f, 0x41, 0xf1, 0x47, 0xbe, 0xbe, - 0x5c, 0x1f, 0xa3, 0x07, 0xf1, 0x6c, 0xbd, 0xd6, 0x27, 0x3c, 0x38, 0xf3, 0xcd, 0x0d, 0x84, 0x93, - 0x35, 0x13, 0x7a, 0xa9, 0xf6, 0xd3, 0xbc, 0x89, 0x45, 0xb5, 0x95, 0x53, 0xf2, 0x29, 0x8c, 0xc7, - 0xb2, 0x68, 0x19, 0xa2, 0xcc, 0x6a, 0xf2, 0xcb, 0xb3, 0x74, 0x37, 0x55, 0x94, 0xf1, 0xdc, 0xe4, - 0x53, 0x23, 0x6b, 0x50, 0x89, 0x85, 0xf1, 0x8f, 0x9f, 0x34, 0x88, 0x34, 0x51, 0xb3, 0x1a, 0x30, - 0x76, 0xe0, 0xb3, 0xae, 0xed, 0xb3, 0x46, 0xd8, 0x11, 0x4b, 0xf4, 0xd4, 0xee, 0x48, 0xcf, 0x28, - 0x9e, 0xf9, 0x42, 0x36, 0x9e, 0xed, 0xca, 0x38, 0xac, 0xf1, 0x6c, 0x97, 0x1f, 0x92, 0x03, 0xdb, - 0xb7, 0x3b, 0xdc, 0xfd, 0x05, 0xb8, 0x9c, 0x29, 0x89, 0x75, 0xbf, 0xa8, 0x12, 0xcb, 0xb7, 0x33, - 0x17, 0xc5, 0x27, 0x1b, 0x5b, 0xd6, 0xff, 0x97, 0x0a, 0x93, 0x2f, 0x7c, 0xab, 0x6f, 0x6e, 0xe0, - 0x8c, 0x06, 0x36, 0x37, 0xc8, 0x43, 0x18, 0x4f, 0x4d, 0x39, 0xc0, 0x9b, 0x41, 0xde, 0x3b, 0xa9, - 0x2e, 0xaa, 0xe8, 0x91, 0xbb, 0x60, 0xec, 0xda, 0x41, 0xb8, 0x7e, 0x7c, 0xcc, 0x9a, 0x21, 0x6b, - 0x89, 0x3b, 0x38, 0x3a, 0x40, 0x39, 0xb9, 0xf5, 0xc7, 0x92, 0xbe, 0xea, 0x5b, 0xf4, 0x02, 0x38, - 0xc9, 0x81, 0x78, 0x92, 0xcb, 0x30, 0xd6, 0x60, 0xe1, 0x17, 0xb6, 0x1f, 0xcd, 0x71, 0x50, 0x04, - 0x93, 0x69, 0x51, 0xee, 0x35, 0x86, 0xfe, 0x85, 0xd7, 0x18, 0x2e, 0x78, 0x8d, 0x7f, 0x2b, 0x48, - 0x3c, 0xf5, 0x71, 0x48, 0x9f, 0xc2, 0xd2, 0x05, 0x65, 0xe7, 0xb4, 0x0f, 0x2c, 0xa9, 0x3e, 0xd0, - 0x82, 0xe5, 0x8b, 0xb2, 0x4d, 0xd6, 0x1d, 0x51, 0xfd, 0xd7, 0xd4, 0x8d, 0xf9, 0x1a, 0xd6, 0x9f, - 0xca, 0x0f, 0x5d, 0x7f, 0x8a, 0x3f, 0x05, 0xd3, 0xe5, 0x85, 0x0a, 0x7e, 0x0a, 0xf6, 0x81, 0xb6, - 0xc2, 0x5c, 0xb8, 0xe9, 0x0e, 0xf4, 0x59, 0xa4, 0xe2, 0xc5, 0xe1, 0x1b, 0x7f, 0xbd, 0x17, 0x9e, - 0x36, 0x42, 0xdf, 0x71, 0x23, 0x66, 0x32, 0x4e, 0x53, 0x12, 0x6b, 0x55, 0x53, 0x94, 0xe6, 0xf7, - 0xbe, 0x14, 0xc9, 0x9f, 0xcc, 0xc9, 0xb6, 0x75, 0x5f, 0x97, 0x77, 0xea, 0x6b, 0xf1, 0xb1, 0xa6, - 0x52, 0x4d, 0x6e, 0xc0, 0x84, 0x14, 0x6d, 0x9c, 0x87, 0x2c, 0xc0, 0x65, 0x51, 0x85, 0xd6, 0x27, - 0xba, 0x9c, 0xd4, 0x4f, 0xb4, 0x3d, 0x2d, 0x2c, 0x69, 0x93, 0x55, 0x18, 0x8a, 0xa3, 0xa9, 0xc9, - 0x98, 0xf5, 0x67, 0xb5, 0xb9, 0x0a, 0x15, 0x8a, 0x71, 0x38, 0xd5, 0x70, 0xbe, 0x61, 0x78, 0xad, - 0x25, 0x02, 0xeb, 0xac, 0x38, 0xd1, 0xa5, 0x5a, 0x96, 0x32, 0x96, 0xfc, 0x4d, 0x44, 0xa3, 0x6e, - 0x77, 0xed, 0xa6, 0x13, 0x9e, 0x23, 0xb6, 0x2a, 0xe4, 0x5f, 0x77, 0x8f, 0x05, 0x81, 0x7d, 0x22, - 0x43, 0x39, 0xd9, 0xb4, 0xf6, 0xfb, 0x97, 0xd5, 0x7f, 0xf6, 0x8b, 0x5a, 0xff, 0x77, 0x41, 0x42, - 0xed, 0x37, 0x7e, 0x9f, 0x8f, 0xf4, 0x75, 0xfb, 0xfe, 0xa3, 0x5a, 0xff, 0x55, 0x90, 0x93, 0xcb, - 0x4f, 0xa7, 0xa4, 0x99, 0x8e, 0xf5, 0x8f, 0xd2, 0x05, 0xe5, 0xe0, 0x7c, 0x8e, 0x61, 0x22, 0x9d, - 0x63, 0x10, 0x93, 0x0b, 0xed, 0xb6, 0x77, 0x12, 0x87, 0x58, 0x89, 0x80, 0xf7, 0xf2, 0x3b, 0x49, - 0xe4, 0xa3, 0x64, 0x24, 0x1e, 0x0b, 0xb8, 0x57, 0x88, 0xea, 0x1f, 0x43, 0x11, 0x8b, 0x8e, 0x6a, - 0x1a, 0x35, 0x80, 0x86, 0x6b, 0x77, 0x83, 0x53, 0x8f, 0x0f, 0x18, 0xb9, 0xca, 0x94, 0x84, 0xac, - 0x25, 0xcb, 0xb4, 0xeb, 0x35, 0x79, 0x38, 0xee, 0x3e, 0xb6, 0x83, 0x53, 0x11, 0xa3, 0x57, 0xa8, - 0xb6, 0x8f, 0x9f, 0xd0, 0xa8, 0x7a, 0xb6, 0xb3, 0x29, 0xea, 0x99, 0x15, 0x1a, 0xb7, 0xad, 0xc7, - 0x17, 0xa5, 0x94, 0xc8, 0x2d, 0x98, 0x8c, 0xe2, 0xe5, 0xd6, 0x23, 0x37, 0xf4, 0x9d, 0xf8, 0xcc, - 0x65, 0xa4, 0xd6, 0x8a, 0xee, 0x17, 0x12, 0xfc, 0x83, 0xa3, 0x04, 0x9d, 0x83, 0x6c, 0x5a, 0xab, - 0xda, 0xa4, 0x67, 0x1f, 0x83, 0x5d, 0xdd, 0x2f, 0x26, 0xb8, 0xbf, 0xc4, 0x42, 0x37, 0xfe, 0x68, - 0x17, 0x6b, 0xda, 0xf2, 0xda, 0x67, 0x82, 0x82, 0x47, 0x77, 0x5d, 0x4a, 0x62, 0xbd, 0xa7, 0xcd, - 0x8f, 0x6a, 0x53, 0x12, 0x77, 0x8b, 0x7e, 0x5f, 0x91, 0xcf, 0x8d, 0x58, 0x1f, 0x14, 0x26, 0x4a, - 0xb5, 0xd0, 0x9d, 0x3e, 0xbf, 0xae, 0x20, 0x77, 0x60, 0x0a, 0x7f, 0xeb, 0x1d, 0xe7, 0x55, 0xa2, - 0x2b, 0x2c, 0x2b, 0xe6, 0xdf, 0xe8, 0x85, 0xef, 0x84, 0x09, 0x04, 0x6e, 0xc6, 0x8c, 0xd4, 0x72, - 0xfb, 0xa5, 0x59, 0x7f, 0x83, 0xf1, 0xbe, 0xd0, 0xe7, 0x5c, 0xc9, 0x7f, 0xc3, 0x78, 0x5a, 0xfe, - 0x13, 0x7e, 0xfc, 0xae, 0xe8, 0xdf, 0xfd, 0xdb, 0x70, 0xea, 0x17, 0x0e, 0xa4, 0x82, 0xff, 0x91, - 0x60, 0x5c, 0x22, 0x97, 0x61, 0x2a, 0xf3, 0xa3, 0x03, 0xa3, 0x44, 0x0c, 0x18, 0x4f, 0xa7, 0x1d, - 0x8d, 0x01, 0x32, 0x0e, 0x65, 0x99, 0x01, 0x34, 0x06, 0xc9, 0x04, 0x54, 0xe2, 0xdc, 0x94, 0x31, - 0x44, 0xa6, 0x60, 0x2c, 0x95, 0x90, 0x31, 0x86, 0xc9, 0x24, 0x40, 0x92, 0x06, 0x30, 0x46, 0x38, - 0x5e, 0x9a, 0xff, 0x1a, 0xa3, 0x5c, 0x23, 0xa9, 0x6d, 0x1b, 0x65, 0x8e, 0x18, 0x97, 0xac, 0x8d, - 0x0a, 0x99, 0xd5, 0x15, 0xad, 0x0d, 0xe0, 0xf2, 0x7c, 0xf1, 0xd8, 0x18, 0x23, 0x24, 0x5b, 0x3e, - 0x36, 0xc6, 0xc9, 0x58, 0x5c, 0x0b, 0x36, 0x26, 0xc8, 0x7c, 0x41, 0x99, 0xd7, 0x98, 0x24, 0xd3, - 0x99, 0x2a, 0xad, 0x31, 0x45, 0xaa, 0xf9, 0xa2, 0xab, 0x61, 0xa4, 0xdf, 0x82, 0x07, 0xff, 0xc6, - 0x34, 0x4a, 0xe2, 0x70, 0xdb, 0x20, 0x7c, 0x39, 0x33, 0x05, 0x48, 0xe3, 0x32, 0x17, 0x66, 0xa2, - 0x5f, 0xa3, 0xca, 0x87, 0x55, 0x82, 0x37, 0x63, 0x86, 0x2c, 0x16, 0x17, 0xfd, 0x8c, 0x59, 0xbe, - 0x44, 0x71, 0x22, 0xd4, 0x98, 0xc3, 0x91, 0xd2, 0xe1, 0x93, 0x61, 0xf2, 0x09, 0xa5, 0x63, 0x1e, - 0x63, 0x5e, 0x7c, 0x8a, 0xfd, 0xbd, 0xf5, 0x97, 0x07, 0x74, 0xbf, 0xde, 0x30, 0x16, 0xb0, 0xfd, - 0x68, 0x6f, 0x77, 0x67, 0x6f, 0xe7, 0xd0, 0xb8, 0xc2, 0x5f, 0x35, 0x7b, 0x89, 0x19, 0x8b, 0x7c, - 0xb9, 0xb4, 0x57, 0x9b, 0x71, 0x55, 0xcc, 0x3b, 0x7d, 0x81, 0x18, 0x35, 0xf1, 0xfd, 0xf7, 0x63, - 0xc7, 0x64, 0x2c, 0x71, 0x41, 0xca, 0x55, 0x18, 0xcb, 0x7c, 0xb2, 0x99, 0x43, 0x6e, 0x5c, 0xe3, - 0x1f, 0x33, 0x7f, 0xb6, 0x0c, 0x8b, 0xbf, 0x44, 0x7a, 0xef, 0x1a, 0xd7, 0xc9, 0x15, 0xe1, 0x23, - 0x74, 0xc9, 0x59, 0xe3, 0x06, 0x59, 0x80, 0x59, 0xbd, 0x43, 0x36, 0x6e, 0xde, 0x7d, 0x1f, 0xaa, - 0xba, 0x0b, 0x9c, 0x00, 0xf7, 0x81, 0x1d, 0x4f, 0x9c, 0x80, 0x32, 0x0c, 0x6d, 0x3a, 0xc1, 0x1b, - 0xa3, 0xb4, 0xb1, 0xfb, 0xdd, 0x8f, 0xb5, 0xd2, 0xf7, 0x3f, 0xd6, 0x4a, 0x7f, 0xf9, 0xb1, 0x76, - 0xe9, 0xdb, 0x77, 0xb5, 0x4b, 0xbf, 0x7b, 0x57, 0x2b, 0x7d, 0xff, 0xae, 0x76, 0xe9, 0x87, 0x77, - 0xb5, 0x4b, 0xaf, 0x56, 0x52, 0xff, 0x26, 0xd4, 0xb1, 0x43, 0xdf, 0x39, 0xf3, 0x7c, 0xe7, 0xc4, - 0x71, 0x65, 0xc3, 0x65, 0xab, 0xdd, 0x37, 0x27, 0xab, 0xdd, 0xa3, 0x55, 0x11, 0x39, 0x1c, 0x8d, - 0x88, 0x0c, 0xdd, 0x87, 0xff, 0x0c, 0x00, 0x00, 0xff, 0xff, 0x8a, 0x8f, 0x8a, 0x1f, 0xba, 0x34, - 0x00, 0x00, + // 3753 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5b, 0xdd, 0x72, 0xdc, 0xc8, + 0x75, 0xd6, 0x88, 0xbf, 0x73, 0x38, 0x24, 0xc1, 0xd6, 0x90, 0x04, 0x29, 0x6a, 0x48, 0xf5, 0x6a, + 0x57, 0x5a, 0xad, 0x97, 0x54, 0x64, 0xaf, 0x1c, 0xdb, 0x49, 0x6a, 0xc9, 0xa1, 0x7e, 0xe8, 0x25, + 0x45, 0xaa, 0x87, 0x5a, 0xc9, 0x9b, 0xaa, 0xad, 0x02, 0x67, 0x9a, 0x43, 0x58, 0x33, 0xc0, 0x18, + 0xc0, 0xc8, 0xe4, 0x56, 0xe5, 0x05, 0x52, 0xe5, 0x2a, 0x3f, 0x42, 0xf2, 0x18, 0xb9, 0xcf, 0x85, + 0x2f, 0x7d, 0xe9, 0xdc, 0xe4, 0x67, 0xf7, 0x41, 0x92, 0xea, 0xc6, 0x69, 0x00, 0x0d, 0x34, 0xc0, + 0xb5, 0xe3, 0xbd, 0x61, 0x4d, 0x9f, 0x3e, 0xe7, 0xeb, 0x1f, 0x74, 0x9f, 0xee, 0xef, 0x9c, 0x26, + 0xcc, 0xfd, 0x66, 0xcc, 0x83, 0xab, 0xed, 0x51, 0xe0, 0x47, 0x3e, 0x99, 0x92, 0x85, 0xf5, 0x46, + 0x18, 0x39, 0xd1, 0x38, 0x8c, 0x85, 0xeb, 0x30, 0xf0, 0xbb, 0xef, 0xf0, 0x77, 0x3d, 0xba, 0xf4, + 0xf0, 0xe7, 0x62, 0xe4, 0x0e, 0x79, 0x18, 0x39, 0xc3, 0x91, 0x12, 0x08, 0xab, 0xd0, 0xf5, 0xce, + 0x7d, 0x14, 0x7c, 0xda, 0x77, 0xa3, 0x8b, 0xf1, 0xd9, 0x76, 0xd7, 0x1f, 0xee, 0xf4, 0xfd, 0xbe, + 0xbf, 0x23, 0xc5, 0x67, 0xe3, 0x73, 0x59, 0x92, 0x05, 0xf9, 0x0b, 0xd5, 0x37, 0xfb, 0xbe, 0xdf, + 0x1f, 0xf0, 0x54, 0x2b, 0xd7, 0x00, 0xbd, 0x07, 0x8d, 0x57, 0xa2, 0x7f, 0x8c, 0xff, 0x66, 0xcc, + 0xc3, 0x88, 0x34, 0x61, 0x4a, 0x96, 0xed, 0xda, 0x56, 0xed, 0x41, 0x9d, 0xc5, 0x05, 0xfa, 0x12, + 0x56, 0x3a, 0x17, 0xfe, 0x6f, 0x4f, 0x02, 0xbf, 0xcb, 0xc3, 0xf0, 0xd0, 0x0d, 0x23, 0xa5, 0xbf, + 0x02, 0xd3, 0xa7, 0xdc, 0x73, 0xbc, 0x08, 0x0d, 0xb0, 0x44, 0x36, 0xa0, 0xde, 0xb9, 0x0a, 0xb1, + 0xea, 0xe6, 0x56, 0xed, 0xc1, 0x2c, 0x4b, 0x05, 0xf4, 0x0d, 0x2c, 0x75, 0xae, 0xbc, 0x6e, 0xdb, + 0x1f, 0x0e, 0xdd, 0x04, 0x6a, 0x0f, 0x16, 0x0e, 0x9d, 0x88, 0x87, 0x51, 0x2c, 0x3e, 0xed, 0x48, + 0xc8, 0xb9, 0xc7, 0xcd, 0xed, 0xb4, 0xd3, 0xa7, 0xea, 0xd7, 0xde, 0xe4, 0x1f, 0xfe, 0x73, 0xf3, + 0x06, 0xcb, 0x59, 0xd0, 0xaf, 0x80, 0x64, 0x81, 0xc3, 0x91, 0xef, 0x85, 0x9c, 0xec, 0xc3, 0x62, + 0x7b, 0x1c, 0x04, 0xdc, 0xfb, 0x73, 0xa0, 0xf3, 0x26, 0x94, 0x80, 0xf5, 0x9c, 0x47, 0x5a, 0x9f, + 0xe9, 0xaf, 0x60, 0x29, 0x23, 0xfb, 0xab, 0x36, 0xb7, 0x03, 0xcb, 0x6d, 0x3f, 0xe0, 0xfb, 0xe3, + 0xe1, 0xa8, 0xed, 0x7b, 0xe7, 0x6e, 0x3f, 0x33, 0xe5, 0xbb, 0xdd, 0xc8, 0xf5, 0x3d, 0x35, 0xe5, + 0x71, 0x89, 0xda, 0xb0, 0x92, 0x37, 0x88, 0x3b, 0x44, 0x6f, 0xc3, 0xda, 0x73, 0x1e, 0x9d, 0x88, + 0x0f, 0xde, 0xf5, 0x07, 0x5f, 0xf2, 0x20, 0x74, 0x7d, 0x4f, 0x0d, 0xe1, 0x09, 0xac, 0x9b, 0x2a, + 0x71, 0x2c, 0x36, 0xcc, 0xa0, 0x48, 0xb6, 0x36, 0xc1, 0x54, 0x91, 0x7e, 0x06, 0x6b, 0x9d, 0x32, + 0xd0, 0x0a, 0xb3, 0x27, 0xb0, 0xde, 0xf9, 0x4b, 0x9a, 0xfb, 0x11, 0x2c, 0xb0, 0xb1, 0x77, 0xea, + 0x84, 0xef, 0x54, 0x1b, 0xeb, 0x30, 0x2b, 0x8a, 0x6d, 0xbf, 0xc7, 0xa5, 0xf2, 0x14, 0x4b, 0xca, + 0xf4, 0x63, 0x58, 0x4c, 0xb4, 0x11, 0x7a, 0x05, 0xa6, 0x19, 0x0f, 0xc7, 0x83, 0x64, 0xa5, 0xc6, + 0x25, 0x31, 0x6d, 0x62, 0xfc, 0xee, 0x88, 0x0f, 0x5c, 0x8f, 0x1f, 0x78, 0xe7, 0xbe, 0x9a, 0x99, + 0x1d, 0x58, 0x2d, 0xd4, 0x20, 0x58, 0x13, 0xa6, 0xda, 0xfe, 0x18, 0x57, 0xfd, 0x04, 0x8b, 0x0b, + 0xf4, 0x3f, 0x6c, 0x98, 0x51, 0xbd, 0xdb, 0x80, 0x3a, 0xfe, 0x3c, 0xd8, 0x97, 0x5a, 0x93, 0x2c, + 0x15, 0x90, 0x6d, 0xa8, 0xb7, 0x87, 0xbd, 0x23, 0x1e, 0x5d, 0xf8, 0x3d, 0xb9, 0x3d, 0x16, 0x1e, + 0x5b, 0xdb, 0xb1, 0xd7, 0x48, 0xe4, 0x2c, 0x55, 0x21, 0x3f, 0xd5, 0xb7, 0xa9, 0x3d, 0x21, 0xd7, + 0xd3, 0x2d, 0x34, 0xc9, 0x56, 0x31, 0x7d, 0x3f, 0xbf, 0x2e, 0xdb, 0xb9, 0xf6, 0xa4, 0x84, 0xb8, + 0x83, 0x10, 0x66, 0x25, 0x56, 0xb6, 0xed, 0x0f, 0xe1, 0xd6, 0xee, 0x20, 0xe2, 0xc1, 0x6e, 0xb7, + 0x2b, 0x46, 0xae, 0x30, 0xa7, 0x24, 0xe6, 0x3a, 0x62, 0x1a, 0x34, 0x98, 0xc9, 0x8c, 0x7c, 0x0e, + 0x8b, 0x5f, 0xb8, 0x83, 0x41, 0xdb, 0xf7, 0xd4, 0x02, 0xb2, 0xa7, 0x25, 0xd2, 0x0a, 0x22, 0xe5, + 0x6a, 0x59, 0x5e, 0x9d, 0xb4, 0xc1, 0x3a, 0x0d, 0x9c, 0x2e, 0xef, 0x8c, 0x9c, 0x04, 0x62, 0x46, + 0x42, 0xac, 0x22, 0x44, 0xbe, 0x9a, 0x15, 0x0c, 0xc8, 0x01, 0x90, 0xe7, 0x3c, 0x3a, 0xf4, 0xbb, + 0xef, 0x32, 0xab, 0xc0, 0x9e, 0x95, 0x30, 0x6b, 0x08, 0x53, 0x54, 0x60, 0x06, 0x23, 0xf2, 0x4c, + 0xfa, 0x85, 0xd3, 0x4b, 0x2f, 0x8b, 0x54, 0x97, 0x48, 0x76, 0x8a, 0xa4, 0xd7, 0xb3, 0xa2, 0x89, + 0x98, 0x67, 0xe1, 0x5f, 0x9c, 0xee, 0x45, 0x76, 0x65, 0xda, 0xa0, 0xcd, 0xb3, 0x41, 0x83, 0x99, + 0xcc, 0xc8, 0xdf, 0x02, 0x74, 0xae, 0xba, 0x5e, 0xec, 0x62, 0xec, 0x39, 0xad, 0x3b, 0x05, 0x7f, + 0xcc, 0x32, 0xba, 0xe4, 0x33, 0xa8, 0x27, 0x7e, 0xce, 0x6e, 0x68, 0x13, 0x9b, 0xf7, 0x89, 0x2c, + 0xd5, 0x24, 0x27, 0x72, 0x46, 0x73, 0x9b, 0xdd, 0x9e, 0x97, 0xf6, 0x5b, 0xa9, 0xbd, 0xd9, 0x89, + 0x30, 0x83, 0xad, 0x40, 0x2c, 0xba, 0x0f, 0x7b, 0x41, 0x43, 0xec, 0x94, 0x23, 0x16, 0xab, 0xc8, + 0x3e, 0x2c, 0xe8, 0x6e, 0xd3, 0x5e, 0x94, 0x68, 0x1b, 0x6a, 0x3f, 0x9a, 0x9c, 0x30, 0xcb, 0xd9, + 0x90, 0x1d, 0x98, 0x41, 0x87, 0x63, 0x5b, 0xd2, 0x7c, 0x19, 0xcd, 0x75, 0xa7, 0xc5, 0x94, 0x16, + 0xf9, 0x15, 0x2c, 0x33, 0x3e, 0xf4, 0xdf, 0x73, 0xf1, 0x37, 0xe2, 0x62, 0x01, 0x9d, 0x3a, 0x67, + 0x03, 0x6e, 0x2f, 0x49, 0xf3, 0x0f, 0x94, 0xb9, 0x49, 0x47, 0x81, 0x99, 0x11, 0xc8, 0x2e, 0xcc, + 0x8b, 0x25, 0x29, 0x4f, 0xc6, 0x3d, 0xd7, 0xeb, 0xd9, 0x44, 0x42, 0xde, 0xce, 0x2c, 0xe1, 0xa4, + 0x4e, 0x41, 0xe9, 0x16, 0xe4, 0x97, 0x60, 0xbd, 0xf6, 0xc2, 0xf1, 0x59, 0xd8, 0x0d, 0xdc, 0x33, + 0x1e, 0x77, 0xec, 0x96, 0x44, 0x69, 0x21, 0x4a, 0xbe, 0x3a, 0xd9, 0x56, 0xf9, 0x8a, 0xec, 0x1a, + 0xde, 0x77, 0x22, 0x47, 0xad, 0xe1, 0xa6, 0x71, 0x0d, 0x67, 0x34, 0x98, 0xc9, 0x0c, 0xd1, 0x3a, + 0xe2, 0x5a, 0x94, 0xdd, 0x11, 0xcb, 0x79, 0xb4, 0xbc, 0x06, 0x33, 0x99, 0x09, 0xf7, 0x68, 0x76, + 0xfe, 0xf6, 0x8a, 0xe6, 0x1e, 0xcd, 0x4a, 0xac, 0xc4, 0x58, 0xc0, 0x1e, 0xb9, 0xfd, 0xc0, 0x89, + 0xb8, 0x70, 0x52, 0xcf, 0x02, 0x7f, 0xa8, 0x60, 0x57, 0x35, 0x58, 0xb3, 0x12, 0x2b, 0x31, 0x26, + 0xc7, 0xd0, 0xcc, 0xd4, 0x9c, 0x26, 0x7d, 0xb5, 0xb5, 0xef, 0x6b, 0x52, 0x61, 0x46, 0x43, 0x72, + 0x06, 0x36, 0xe3, 0x03, 0xdf, 0xe9, 0xed, 0x8e, 0x23, 0xff, 0xc0, 0xeb, 0x06, 0x7c, 0x28, 0xae, + 0x20, 0x62, 0xce, 0xed, 0x35, 0x09, 0xfa, 0x51, 0xb2, 0x0e, 0xcd, 0x6a, 0x0a, 0xbf, 0x14, 0x47, + 0xb8, 0xe6, 0x76, 0x34, 0x60, 0xdc, 0xe9, 0xf1, 0x40, 0x75, 0x78, 0x5d, 0xf3, 0x20, 0xf9, 0x6a, + 0x56, 0x30, 0x20, 0x47, 0xb0, 0xf8, 0x9c, 0x47, 0x8c, 0x8f, 0x06, 0x6e, 0xd7, 0x89, 0x4f, 0xde, + 0xdb, 0xf9, 0x0f, 0x94, 0xad, 0x45, 0x3b, 0x75, 0xb7, 0xca, 0xd5, 0x8a, 0x45, 0xc4, 0x78, 0xc8, + 0xa3, 0x0e, 0x0f, 0x33, 0xee, 0xc1, 0xde, 0xd0, 0x16, 0x91, 0x41, 0x83, 0x99, 0xcc, 0xc8, 0x21, + 0x2c, 0x3d, 0xf7, 0x8f, 0x9c, 0x4b, 0x71, 0x4e, 0x86, 0x0a, 0xeb, 0x8e, 0xee, 0xec, 0xf3, 0xf5, + 0xd8, 0xb3, 0xa2, 0x21, 0xa2, 0xf1, 0xe1, 0xa1, 0x9b, 0xfa, 0x54, 0xbb, 0x95, 0x47, 0xd3, 0xeb, + 0x33, 0x68, 0x7a, 0x05, 0xf9, 0x1a, 0x56, 0x9f, 0xb9, 0x03, 0xde, 0xe1, 0xc1, 0x7b, 0xb7, 0xcb, + 0xb3, 0x9f, 0xcc, 0xde, 0xd4, 0xf6, 0x73, 0x89, 0x16, 0x22, 0x97, 0x81, 0x90, 0x21, 0x6c, 0xe4, + 0xab, 0x9e, 0xbe, 0x77, 0xbb, 0x49, 0xc7, 0xb7, 0x34, 0x6f, 0x56, 0xa5, 0x8a, 0x2d, 0x55, 0xc2, + 0x91, 0xd7, 0xd0, 0x3c, 0xe2, 0x91, 0xd3, 0x73, 0x22, 0x47, 0x1b, 0xcb, 0x5d, 0x7d, 0x07, 0x18, + 0x54, 0x10, 0xde, 0x68, 0x4e, 0x8e, 0x81, 0x3c, 0xf7, 0x9f, 0xb7, 0x4f, 0x78, 0xd0, 0xe5, 0xe9, + 0x6d, 0x86, 0xea, 0x27, 0x7f, 0x41, 0x01, 0x21, 0x0d, 0xa6, 0xe2, 0x2a, 0xf1, 0xcc, 0x19, 0x0f, + 0xa2, 0x03, 0xef, 0xd7, 0x3c, 0x9d, 0x8c, 0x0f, 0x34, 0xc0, 0xa2, 0x02, 0x33, 0x18, 0x91, 0x7f, + 0x84, 0x95, 0x76, 0x34, 0x38, 0xf2, 0xa5, 0x33, 0x95, 0x0e, 0x4c, 0xc1, 0xdd, 0xd3, 0x76, 0x80, + 0x59, 0x09, 0xfb, 0x58, 0x02, 0x41, 0xbe, 0x86, 0xb5, 0x37, 0x7e, 0xf0, 0x2e, 0x1c, 0x39, 0x5d, + 0x7e, 0x7a, 0x11, 0xf0, 0xf0, 0xc2, 0x1f, 0xa8, 0x33, 0xc1, 0xfe, 0x50, 0x3b, 0x55, 0x4b, 0xf5, + 0x58, 0x39, 0x04, 0x19, 0x42, 0xab, 0x1d, 0x0d, 0x4e, 0x02, 0x7e, 0xce, 0xa3, 0xee, 0xc5, 0xb1, + 0xd7, 0x51, 0x47, 0x43, 0xd2, 0xc8, 0x47, 0xb2, 0x91, 0x0f, 0xd3, 0x41, 0x54, 0x28, 0xb3, 0x6b, + 0xc0, 0xc8, 0x08, 0xee, 0x1c, 0x74, 0xf9, 0x19, 0x0f, 0xfa, 0x78, 0xf7, 0x79, 0xef, 0x0c, 0xdc, + 0x9e, 0x13, 0x25, 0xeb, 0xe4, 0xbe, 0x6c, 0xed, 0x1e, 0xb6, 0x56, 0xa9, 0x8b, 0x33, 0x57, 0x0d, + 0x48, 0xfa, 0xb0, 0x7e, 0xe4, 0x7b, 0x7d, 0x7f, 0x7f, 0xaf, 0x3d, 0x70, 0xe5, 0x02, 0x88, 0xdc, + 0x20, 0x69, 0xee, 0x63, 0xd9, 0xdc, 0x5d, 0xb5, 0x2c, 0x4b, 0x15, 0xb1, 0xad, 0x0a, 0x28, 0xfa, + 0x0c, 0x56, 0x0b, 0x77, 0x71, 0x24, 0x23, 0x9f, 0xc0, 0x2c, 0x7a, 0xa4, 0xd0, 0xae, 0x6d, 0x4d, + 0x3c, 0x98, 0x7b, 0xbc, 0xb8, 0x8d, 0xd1, 0x06, 0xe5, 0xa9, 0x12, 0x05, 0xfa, 0x3f, 0x6b, 0x30, + 0x9b, 0x58, 0xfe, 0x75, 0x49, 0x4a, 0x13, 0xa6, 0x9e, 0x06, 0x81, 0x1f, 0x48, 0x76, 0xd2, 0x60, + 0x71, 0x81, 0xbc, 0x2d, 0xed, 0x38, 0x52, 0x90, 0x56, 0x19, 0x05, 0x89, 0xb5, 0x58, 0xe9, 0xb8, + 0x8f, 0xa1, 0xa9, 0xb3, 0x09, 0x84, 0x9d, 0xd2, 0x9c, 0x81, 0x49, 0x85, 0x19, 0x0d, 0xc5, 0x51, + 0x95, 0x12, 0x0b, 0x04, 0x9b, 0xd6, 0x8e, 0xaa, 0x7c, 0x35, 0x2b, 0x18, 0x88, 0xab, 0x7f, 0x86, + 0x59, 0x20, 0xca, 0x8c, 0xe6, 0xbf, 0x0b, 0xf5, 0xac, 0x68, 0x82, 0x17, 0x9d, 0x94, 0x58, 0x20, + 0xd2, 0x6c, 0xfe, 0xa2, 0x93, 0xd7, 0x60, 0x26, 0x33, 0xe4, 0x36, 0x09, 0xbb, 0x40, 0xb0, 0x7a, + 0x9e, 0xdb, 0xe4, 0x14, 0x98, 0xc1, 0x48, 0x4c, 0xbb, 0x4e, 0x2e, 0x10, 0x0c, 0xf2, 0xb7, 0xcc, + 0x82, 0x0a, 0x33, 0x1a, 0x92, 0x9f, 0x09, 0x5a, 0xa2, 0xd8, 0x07, 0xd2, 0x92, 0x35, 0x03, 0x2d, + 0x41, 0x90, 0x8c, 0x32, 0x79, 0x52, 0xe4, 0x25, 0x76, 0x91, 0x97, 0xa0, 0x61, 0x86, 0x98, 0xbc, + 0xaa, 0x20, 0x26, 0x77, 0x2b, 0x88, 0x49, 0x66, 0x5a, 0xf2, 0x3c, 0xe2, 0x55, 0x05, 0x33, 0xb9, + 0x5b, 0xc1, 0x4c, 0x14, 0xa4, 0x81, 0x9a, 0x3c, 0x2d, 0xa1, 0x26, 0x77, 0x4a, 0xa8, 0x09, 0x42, + 0xe5, 0xb9, 0xc9, 0xa3, 0x3c, 0x37, 0x59, 0xc9, 0x73, 0x13, 0x34, 0x4c, 0xc8, 0xc9, 0x57, 0xd5, + 0xe4, 0xe4, 0x5e, 0x35, 0x39, 0x41, 0xb4, 0x12, 0x76, 0xb2, 0x67, 0x66, 0x27, 0x1b, 0x66, 0x76, + 0x82, 0x58, 0x39, 0x7a, 0xf2, 0x45, 0x29, 0x3d, 0xd9, 0x2c, 0xa5, 0x27, 0x6a, 0xc3, 0x16, 0xf8, + 0x49, 0x66, 0x3d, 0xc7, 0x44, 0x03, 0xd7, 0x73, 0xd3, 0xb8, 0x9e, 0xb3, 0x2a, 0xcc, 0x68, 0x88, + 0x80, 0x19, 0xae, 0x81, 0x80, 0xcb, 0x79, 0xc0, 0x82, 0x0a, 0x33, 0x1a, 0x0a, 0x17, 0x5a, 0x12, + 0x88, 0x42, 0x9a, 0xd2, 0x2a, 0xa3, 0x29, 0xca, 0x85, 0x96, 0xc5, 0xb1, 0xde, 0xc2, 0x6a, 0x81, + 0x6b, 0x20, 0xf2, 0xaa, 0x86, 0x5c, 0xa2, 0xc5, 0xca, 0xcc, 0x09, 0x83, 0xe5, 0x1c, 0xe5, 0x40, + 0x5c, 0x5b, 0xfb, 0xdc, 0x46, 0x1d, 0x66, 0x36, 0x25, 0xdd, 0x6b, 0xe9, 0xca, 0xfd, 0x6b, 0xe9, + 0x0a, 0xb6, 0x50, 0xce, 0x57, 0x9e, 0xc1, 0x52, 0x86, 0x7e, 0x60, 0xa7, 0xd7, 0x35, 0xd7, 0x52, + 0xa8, 0x67, 0x45, 0x13, 0xf2, 0xb2, 0x8c, 0xb2, 0xb4, 0xca, 0x28, 0x4b, 0x6c, 0x58, 0xc6, 0x59, + 0x8e, 0xa1, 0xa9, 0x93, 0x0f, 0xec, 0xda, 0x86, 0xb6, 0xaa, 0x4c, 0x2a, 0xcc, 0x68, 0x18, 0x5f, + 0x7a, 0x53, 0xf6, 0x81, 0x70, 0x77, 0x72, 0x97, 0xde, 0xbc, 0x42, 0x7a, 0xe9, 0xcd, 0xd7, 0x20, + 0x60, 0x42, 0x40, 0x10, 0xb0, 0x95, 0x07, 0xcc, 0x29, 0x64, 0x00, 0x73, 0x35, 0xc4, 0x01, 0xbb, + 0xc8, 0x3b, 0x10, 0x76, 0x53, 0xdb, 0xee, 0x65, 0x6a, 0x08, 0x5e, 0x0a, 0x23, 0x6e, 0x8c, 0x25, + 0x84, 0x03, 0xdb, 0xd9, 0xd2, 0x3c, 0x5e, 0xa5, 0xae, 0xba, 0x31, 0x56, 0x2a, 0x91, 0xb7, 0xb0, + 0x9c, 0xe3, 0x20, 0xd8, 0xd2, 0x5d, 0x7d, 0x63, 0x98, 0x74, 0xb0, 0x05, 0x33, 0x00, 0x61, 0x70, + 0x4b, 0xa3, 0x22, 0x88, 0x4b, 0xf5, 0x1b, 0x43, 0x51, 0x03, 0x51, 0x4d, 0xc6, 0xe2, 0x16, 0xa2, + 0x71, 0x12, 0xc4, 0xfc, 0x40, 0xc3, 0x34, 0x68, 0x30, 0x93, 0x99, 0x60, 0xa3, 0x05, 0x22, 0x82, + 0x88, 0xf7, 0xb4, 0xbd, 0x51, 0xa2, 0xa5, 0xd8, 0x68, 0x49, 0x35, 0x71, 0x60, 0xdd, 0xc4, 0x45, + 0xb0, 0x89, 0x0f, 0xb5, 0xb3, 0xb8, 0x5c, 0x91, 0x55, 0x80, 0xc4, 0x31, 0x18, 0x2f, 0xc9, 0xde, + 0x24, 0xe0, 0x1f, 0xe5, 0x62, 0x30, 0x45, 0x15, 0x66, 0x34, 0x24, 0x23, 0xd8, 0x2c, 0x65, 0x35, + 0x88, 0x7d, 0x5f, 0x0b, 0xc5, 0x5c, 0xa3, 0xcd, 0xae, 0x83, 0x23, 0x21, 0xb4, 0xca, 0x48, 0x0d, + 0x36, 0xf8, 0x40, 0x23, 0x65, 0xd5, 0xca, 0xf8, 0x4d, 0xae, 0x81, 0x24, 0xbf, 0x86, 0xdb, 0x46, + 0x76, 0x83, 0x2d, 0x3e, 0x94, 0x2d, 0xd2, 0x2a, 0xa6, 0xa4, 0x35, 0x57, 0x05, 0x46, 0x0f, 0x8c, + 0xd9, 0x09, 0x99, 0x30, 0x92, 0xf9, 0xc7, 0x83, 0x1e, 0xe6, 0x6d, 0x92, 0x32, 0x59, 0x81, 0xe9, + 0x8e, 0xa4, 0x4c, 0x92, 0xbc, 0xd4, 0x19, 0x96, 0xe8, 0xcf, 0xcd, 0x1c, 0x83, 0x50, 0x68, 0x38, + 0x42, 0xde, 0x19, 0x77, 0x05, 0x2f, 0x91, 0x78, 0xb3, 0x4c, 0x93, 0xd1, 0x83, 0x42, 0x5a, 0x43, + 0x10, 0x2e, 0x44, 0x42, 0xc2, 0x35, 0xc1, 0x52, 0x41, 0x36, 0xfb, 0x75, 0x53, 0x92, 0xb1, 0x4c, + 0xf6, 0xab, 0x48, 0x34, 0x6c, 0x98, 0xd1, 0x5b, 0x57, 0x45, 0x7a, 0x58, 0x0c, 0xb9, 0x11, 0x0b, + 0x26, 0xda, 0xc3, 0x1e, 0xe6, 0xbe, 0xc4, 0x4f, 0x29, 0x39, 0xef, 0xcb, 0x96, 0x84, 0xe4, 0xbc, + 0x2f, 0x09, 0xdc, 0x65, 0x14, 0x38, 0x09, 0x81, 0x13, 0x05, 0x7a, 0xdf, 0x70, 0x20, 0x12, 0x02, + 0x93, 0xe2, 0x37, 0xe2, 0xc9, 0xdf, 0xf4, 0xef, 0xae, 0x23, 0xfb, 0xe2, 0x0b, 0x9c, 0x38, 0x51, + 0xc4, 0x03, 0x64, 0xaa, 0x75, 0x96, 0x94, 0xe9, 0x67, 0xd7, 0xee, 0x03, 0x63, 0xa3, 0x6f, 0x8b, + 0x99, 0x1f, 0xc3, 0x58, 0x9b, 0x30, 0x25, 0x14, 0x42, 0x1c, 0x6d, 0x5c, 0x10, 0x5f, 0x23, 0xd9, + 0xe0, 0x72, 0xcc, 0x13, 0x2c, 0x15, 0x88, 0x71, 0x17, 0x59, 0x99, 0xa9, 0x0b, 0x4d, 0x53, 0xde, + 0x88, 0xfe, 0xa9, 0x06, 0xb3, 0x4a, 0x26, 0xbe, 0x95, 0x74, 0x57, 0xb8, 0xf2, 0x26, 0x99, 0x2a, + 0x0a, 0xc0, 0x2f, 0xf8, 0x95, 0xe8, 0xd8, 0xc4, 0x83, 0x06, 0x93, 0xbf, 0xc9, 0xc3, 0xd8, 0xf2, + 0xc8, 0xef, 0x71, 0xd9, 0xad, 0x85, 0xc7, 0x0b, 0xdb, 0xf2, 0xc1, 0x80, 0x92, 0xb2, 0xa4, 0x9e, + 0x6c, 0xc1, 0x9c, 0x1b, 0x32, 0xc7, 0xeb, 0xcb, 0x2b, 0xb6, 0xa4, 0xd4, 0xb3, 0x2c, 0x2b, 0x22, + 0xf7, 0x61, 0xe6, 0x85, 0x3f, 0xe8, 0xf1, 0x20, 0xb4, 0xa7, 0x64, 0x74, 0x60, 0x3e, 0x06, 0x7b, + 0xe3, 0xb8, 0x82, 0xdb, 0x31, 0x55, 0x2b, 0x14, 0x85, 0x4c, 0x28, 0x4e, 0x1b, 0x15, 0xb1, 0x96, + 0x7e, 0x6d, 0xa4, 0xa6, 0x62, 0x28, 0x6d, 0xef, 0x40, 0xcd, 0xbb, 0xfc, 0x4d, 0x7e, 0x0c, 0x0d, + 0xa5, 0x27, 0xb8, 0xbb, 0x1c, 0xe6, 0xdc, 0xe3, 0x45, 0xdc, 0xe7, 0x09, 0x84, 0xa6, 0x44, 0x6f, + 0x19, 0xb2, 0x67, 0xf4, 0x02, 0xe6, 0x4e, 0x2f, 0xbd, 0xef, 0x37, 0xa3, 0xcc, 0xff, 0x6d, 0x32, + 0xa3, 0xe2, 0x37, 0xf9, 0x04, 0x66, 0x8e, 0x47, 0x91, 0x8c, 0x90, 0xc4, 0xa9, 0xd3, 0xa5, 0x74, + 0x42, 0xb1, 0x82, 0x29, 0x0d, 0xfa, 0x6f, 0x35, 0x98, 0xc1, 0xc6, 0xc9, 0xe7, 0x30, 0xdb, 0x0e, + 0xb8, 0x13, 0xf1, 0xdd, 0x08, 0x93, 0xf8, 0xeb, 0xdb, 0xf1, 0x9b, 0x8a, 0x6d, 0xf5, 0xa6, 0x22, + 0x93, 0xca, 0x9f, 0x15, 0xbe, 0xe9, 0xf7, 0xff, 0xb5, 0x59, 0x63, 0x89, 0x15, 0xd9, 0x82, 0x49, + 0x71, 0x5c, 0xcb, 0x95, 0x37, 0xf7, 0xb8, 0xb1, 0x1d, 0x5d, 0x7a, 0xdb, 0xa7, 0x97, 0x9e, 0x90, + 0x31, 0x59, 0x23, 0x86, 0xf2, 0x3a, 0xe4, 0xc1, 0xe9, 0xa5, 0x27, 0x3b, 0x37, 0xcb, 0x54, 0x91, + 0x3c, 0x82, 0xba, 0x98, 0x73, 0xd1, 0xcb, 0xd0, 0x9e, 0x94, 0x53, 0x47, 0x54, 0x0c, 0x21, 0x9d, + 0x0b, 0x96, 0x2a, 0xd1, 0xaf, 0x4c, 0x3c, 0xdf, 0xf8, 0x65, 0x1e, 0xc9, 0xf9, 0xcc, 0x7d, 0x98, + 0x85, 0x14, 0x5d, 0x02, 0x64, 0x55, 0xe8, 0xb2, 0x31, 0x19, 0x49, 0xff, 0xb5, 0x06, 0xf5, 0x44, + 0x28, 0xb6, 0xf8, 0x4b, 0xbf, 0xc7, 0x4f, 0xaf, 0x46, 0x1c, 0x9b, 0x4b, 0xca, 0xc2, 0xc9, 0x8a, + 0xdf, 0x07, 0x3d, 0xdc, 0x86, 0x58, 0x12, 0xfb, 0x50, 0x02, 0x48, 0xa3, 0xd8, 0xff, 0xa6, 0x02, + 0xd1, 0xf9, 0xd7, 0x21, 0xef, 0xc9, 0xa5, 0x3d, 0xc9, 0xe4, 0x6f, 0x21, 0x7b, 0x16, 0xf0, 0x38, + 0xd4, 0x33, 0xc9, 0xe4, 0x6f, 0xd1, 0xf2, 0x0b, 0x37, 0x62, 0x4e, 0xe4, 0xfa, 0x32, 0x6a, 0x73, + 0x93, 0x25, 0x65, 0xfa, 0xd2, 0x1c, 0xb3, 0x20, 0x4f, 0x60, 0x3e, 0x11, 0xca, 0x69, 0x88, 0xe3, + 0x67, 0x49, 0x98, 0x2b, 0x31, 0xd0, 0xd5, 0xe8, 0x00, 0x36, 0xaa, 0x32, 0x73, 0xe2, 0x93, 0x3e, + 0x0f, 0xfc, 0xf1, 0x08, 0xbd, 0xfc, 0x3c, 0x53, 0xc5, 0x74, 0xdd, 0xee, 0x2b, 0x1f, 0x8f, 0xc5, + 0xac, 0xf7, 0x9f, 0xd0, 0xbd, 0xff, 0x67, 0x70, 0xa7, 0x92, 0x6a, 0xeb, 0xcf, 0x11, 0xa6, 0xd4, + 0x73, 0x84, 0x5f, 0xca, 0x41, 0x17, 0x72, 0x7d, 0x7f, 0x49, 0xe7, 0xe8, 0x27, 0xb0, 0x6c, 0x64, + 0xe6, 0xe2, 0x4b, 0x48, 0x16, 0x8f, 0x4b, 0x4b, 0xfc, 0xa6, 0x1d, 0x58, 0x2d, 0x49, 0x0f, 0x92, + 0x16, 0x80, 0xe0, 0xca, 0x67, 0x4e, 0xc8, 0x93, 0x90, 0x63, 0x46, 0x52, 0xd1, 0x83, 0x9f, 0x80, + 0x5d, 0x46, 0xea, 0x2b, 0x8e, 0xc2, 0x67, 0x30, 0x2b, 0xbf, 0xdc, 0x17, 0xfc, 0x4a, 0x74, 0xf5, + 0xc4, 0x89, 0x2e, 0x54, 0x57, 0xc5, 0x6f, 0xb1, 0x24, 0x8f, 0xcf, 0xcf, 0x43, 0x1e, 0x3f, 0x52, + 0x9a, 0x60, 0x58, 0x22, 0x0b, 0x70, 0xb3, 0xf3, 0x0d, 0x9e, 0x09, 0x37, 0x3b, 0xdf, 0xd0, 0x27, + 0xb8, 0x44, 0xa5, 0x7f, 0xfe, 0x18, 0x26, 0xdf, 0x09, 0x9f, 0x5d, 0xd3, 0x9c, 0x99, 0xaa, 0xc7, + 0x1b, 0x8a, 0x54, 0xa1, 0xa7, 0xb0, 0x88, 0x43, 0x4f, 0xba, 0xd1, 0x84, 0xa9, 0x03, 0xaf, 0xc7, + 0x2f, 0xd5, 0xc7, 0x92, 0x05, 0xf2, 0x49, 0xda, 0x51, 0x74, 0x15, 0x79, 0x5c, 0x96, 0x28, 0xd0, + 0x37, 0xc6, 0x94, 0x2a, 0xf9, 0xbc, 0xd0, 0x18, 0x76, 0x31, 0x09, 0xf8, 0xe8, 0xb5, 0x2c, 0xaf, + 0x4e, 0x8f, 0x61, 0x49, 0x4d, 0x6a, 0x82, 0x5e, 0xd2, 0x61, 0x0b, 0x26, 0x5e, 0xb8, 0xea, 0x6d, + 0x97, 0xf8, 0x29, 0xe6, 0x57, 0xe8, 0xe3, 0xed, 0x41, 0xfe, 0xa6, 0x5f, 0x9b, 0x83, 0x2b, 0x82, + 0x65, 0x17, 0x1a, 0xc2, 0xce, 0xda, 0x29, 0x95, 0xd5, 0xeb, 0x59, 0xd1, 0x84, 0x32, 0x63, 0x3a, + 0x98, 0xfc, 0x02, 0x1a, 0x89, 0x2c, 0x9e, 0x86, 0x38, 0x8a, 0x9b, 0x3e, 0xa7, 0xcb, 0x56, 0x33, + 0x4d, 0x19, 0xf7, 0x4d, 0x31, 0x0c, 0xf3, 0x18, 0xea, 0x89, 0x30, 0x79, 0xd1, 0x65, 0x40, 0x64, + 0xa9, 0x1a, 0xed, 0xc0, 0xdc, 0x49, 0xc0, 0x47, 0x4e, 0xc0, 0x3b, 0xd1, 0x50, 0x4e, 0xd1, 0x4b, + 0x67, 0xa8, 0x3c, 0xa3, 0xfc, 0x2d, 0x26, 0xb2, 0xf3, 0xea, 0x50, 0xdd, 0xc3, 0x3a, 0xaf, 0x0e, + 0xc5, 0x26, 0x39, 0x71, 0x02, 0x67, 0x28, 0xdc, 0x5f, 0x88, 0xd3, 0x99, 0x91, 0xd0, 0x47, 0x65, + 0xe9, 0x65, 0xb1, 0x9c, 0x85, 0x28, 0xd9, 0xd9, 0x58, 0xa2, 0xbf, 0xab, 0x95, 0x06, 0x7a, 0xc4, + 0x52, 0xdf, 0xdf, 0xc3, 0x1e, 0xdd, 0xdc, 0xdf, 0x23, 0x4f, 0xa0, 0x91, 0xe9, 0x72, 0x88, 0x27, + 0x83, 0x3a, 0x77, 0x32, 0x55, 0x4c, 0xd3, 0x23, 0x0f, 0xc1, 0x3a, 0x74, 0xc2, 0x68, 0xf7, 0xfc, + 0x9c, 0x77, 0x23, 0xde, 0x93, 0x67, 0x70, 0xbc, 0x81, 0x0a, 0x72, 0xfa, 0xef, 0x35, 0x73, 0x2a, + 0xbb, 0x6c, 0x00, 0xd8, 0xc9, 0x9b, 0x49, 0x27, 0xb7, 0x60, 0xae, 0xc3, 0xa3, 0x2f, 0x9d, 0x20, + 0xee, 0xe3, 0x84, 0xbc, 0x4c, 0x66, 0x45, 0x85, 0x61, 0x4c, 0xfe, 0x3f, 0x86, 0x31, 0x55, 0x32, + 0x8c, 0xbf, 0x29, 0x09, 0x72, 0x55, 0x38, 0xa4, 0x5f, 0xc0, 0xe6, 0x35, 0xb9, 0xf4, 0xac, 0x0f, + 0xac, 0xe9, 0x3e, 0x90, 0xc2, 0xd6, 0x75, 0x91, 0x2d, 0xfa, 0x40, 0x3e, 0x69, 0x30, 0x24, 0xc3, + 0xc5, 0x1c, 0xb6, 0x5f, 0xaa, 0x0f, 0xdd, 0x7e, 0x89, 0xef, 0xdb, 0x4c, 0x31, 0xa8, 0x92, 0xf7, + 0x6d, 0x9f, 0x1a, 0xd3, 0xe6, 0xa5, 0x8b, 0xee, 0xc4, 0x1c, 0xb1, 0x2a, 0x9f, 0x1c, 0xb1, 0xf0, + 0x77, 0xc7, 0xd1, 0x45, 0x27, 0x0a, 0x5c, 0x2f, 0x66, 0x26, 0x0d, 0x96, 0x91, 0xd0, 0x1d, 0x43, + 0xa6, 0x5d, 0x9c, 0xfb, 0x4a, 0xa4, 0xde, 0x01, 0xaa, 0x32, 0x7d, 0x64, 0x8a, 0x71, 0x55, 0x5a, + 0xfc, 0xcc, 0x90, 0x7e, 0x27, 0xf7, 0x60, 0x5e, 0x89, 0xf6, 0xae, 0x22, 0x1e, 0xe2, 0xb4, 0xe8, + 0x42, 0xfa, 0x73, 0x53, 0xfc, 0xeb, 0x7b, 0xda, 0x5e, 0x94, 0xe6, 0xe9, 0xc9, 0x0e, 0x4c, 0x26, + 0xb7, 0xa9, 0x85, 0x24, 0xc2, 0x90, 0xd7, 0x16, 0x2a, 0x4c, 0x2a, 0x26, 0xd7, 0xa9, 0x8e, 0xfb, + 0x0d, 0xc7, 0x63, 0x2d, 0x15, 0xd0, 0xcb, 0xf2, 0xa0, 0x9a, 0x6e, 0x59, 0xcb, 0x59, 0x8a, 0x91, + 0xc8, 0x42, 0xdb, 0x19, 0x39, 0x5d, 0x37, 0xba, 0x42, 0x6c, 0x5d, 0x28, 0xbe, 0xee, 0x11, 0x0f, + 0x43, 0xa7, 0xaf, 0xae, 0x72, 0xaa, 0x48, 0x8f, 0xab, 0xdf, 0x0a, 0xfc, 0xd9, 0x03, 0xa5, 0xff, + 0x74, 0x4d, 0xf0, 0xee, 0x07, 0x1e, 0xcf, 0x4f, 0xcc, 0x8f, 0x11, 0xaa, 0x5b, 0xa5, 0x7f, 0x5f, + 0x12, 0xff, 0x2b, 0x76, 0xa7, 0x66, 0xe8, 0x0e, 0xfd, 0xdf, 0xda, 0x35, 0x39, 0xee, 0x62, 0x8c, + 0x61, 0x3e, 0x1b, 0x63, 0x90, 0x9d, 0x8b, 0x9c, 0x81, 0xdf, 0x4f, 0xae, 0x58, 0xa9, 0x40, 0xd4, + 0x8a, 0x33, 0x49, 0xc6, 0xbe, 0xd4, 0x4d, 0x3c, 0x11, 0x08, 0xaf, 0x10, 0xe7, 0x5a, 0x26, 0x63, + 0x16, 0x1d, 0xe7, 0x4f, 0x5a, 0x00, 0x1d, 0xcf, 0x19, 0x85, 0x17, 0xbe, 0x68, 0x30, 0x76, 0x95, + 0x19, 0x09, 0x79, 0x9c, 0x4e, 0xd3, 0xa1, 0xdf, 0x15, 0xd7, 0x71, 0xef, 0x85, 0x13, 0x5e, 0xc8, + 0x3b, 0x7a, 0x9d, 0x19, 0xeb, 0xc4, 0x0e, 0x8d, 0x33, 0x75, 0x07, 0xfb, 0x32, 0x77, 0x5a, 0x67, + 0x49, 0x99, 0xbe, 0xb8, 0x2e, 0x7c, 0x45, 0x3e, 0x82, 0x85, 0xf8, 0xbe, 0xdc, 0x7b, 0xea, 0x45, + 0x81, 0x9b, 0xec, 0xb9, 0x9c, 0x94, 0x6e, 0x9b, 0x9e, 0x7d, 0x88, 0x0f, 0x8e, 0x12, 0x74, 0x0e, + 0xaa, 0x48, 0x77, 0x8c, 0x01, 0xd6, 0x0a, 0x83, 0x43, 0xd3, 0x33, 0x10, 0xe1, 0x2f, 0x31, 0xa9, + 0x8e, 0x2f, 0x91, 0x31, 0x7f, 0xae, 0x8e, 0x7d, 0x2e, 0x29, 0x78, 0x7c, 0xd6, 0x65, 0x24, 0xf4, + 0x63, 0x63, 0x2c, 0xd6, 0x18, 0x92, 0x78, 0x58, 0xf6, 0x68, 0xa4, 0x18, 0x1b, 0xa1, 0x9f, 0x96, + 0x06, 0x65, 0x8d, 0xd0, 0xc3, 0x8a, 0x27, 0x23, 0xe4, 0x01, 0x2c, 0xe2, 0x03, 0xf6, 0x24, 0xae, + 0x12, 0x1f, 0x61, 0x79, 0xb1, 0xf8, 0x46, 0x6f, 0x02, 0x37, 0x4a, 0x21, 0x70, 0x31, 0xe6, 0xa4, + 0xd4, 0xab, 0x0a, 0xe9, 0xfe, 0x00, 0xed, 0x7d, 0x69, 0x8e, 0xef, 0x92, 0x7f, 0x80, 0x46, 0x56, + 0xfe, 0x3d, 0x5e, 0xf4, 0x6b, 0xfa, 0xf4, 0x9f, 0x6b, 0x55, 0x2f, 0x45, 0xae, 0xd9, 0xb4, 0x14, + 0x1a, 0xe2, 0x4c, 0xe5, 0xf2, 0xa1, 0x7f, 0xb2, 0x6f, 0x35, 0x99, 0xb8, 0xb7, 0x20, 0x5f, 0x7c, + 0x7a, 0xd9, 0x1d, 0x8c, 0x43, 0xf7, 0x3d, 0x47, 0x1e, 0x59, 0x90, 0xd3, 0x9f, 0x56, 0x06, 0x63, + 0xcb, 0x0f, 0xe8, 0x87, 0xbf, 0x9b, 0xce, 0xbc, 0x09, 0x21, 0x75, 0xfc, 0x67, 0x11, 0xeb, 0x06, + 0xb9, 0x05, 0x8b, 0xb9, 0x67, 0x1a, 0x56, 0x8d, 0x58, 0xd0, 0xc8, 0x06, 0x4f, 0xad, 0x9b, 0xa4, + 0x01, 0xb3, 0x2a, 0x8e, 0x69, 0x4d, 0x90, 0x79, 0xa8, 0x27, 0x11, 0x36, 0x6b, 0x92, 0x2c, 0xc2, + 0x5c, 0x26, 0xac, 0x64, 0x4d, 0x91, 0x05, 0x80, 0x34, 0x98, 0x61, 0x4d, 0x0b, 0xbc, 0x2c, 0x8b, + 0xb7, 0x66, 0x84, 0x46, 0xfa, 0x1a, 0xc0, 0x9a, 0x15, 0x88, 0x49, 0x92, 0xdf, 0xaa, 0x93, 0x15, + 0x53, 0x9a, 0xdf, 0x02, 0x21, 0x2f, 0xa6, 0xdb, 0xad, 0x39, 0x42, 0xf2, 0x09, 0x77, 0xab, 0x41, + 0xe6, 0x92, 0xec, 0xb9, 0x35, 0x4f, 0xd6, 0x4a, 0x12, 0xe3, 0xd6, 0x02, 0x59, 0xca, 0xe5, 0xb5, + 0xad, 0x45, 0xd2, 0x2c, 0xa6, 0xa9, 0x2d, 0x2b, 0x3b, 0x0a, 0x41, 0x61, 0xac, 0x25, 0x94, 0x24, + 0xa4, 0xc1, 0x22, 0x62, 0x3a, 0x73, 0x29, 0x5b, 0xeb, 0x96, 0x10, 0xe6, 0xee, 0xf0, 0x56, 0x53, + 0x34, 0xab, 0x5d, 0x41, 0xad, 0x65, 0xb2, 0x51, 0x9e, 0x26, 0xb5, 0x56, 0xc4, 0x14, 0x25, 0xe1, + 0x5c, 0x6b, 0x15, 0x5b, 0xca, 0x5e, 0x02, 0x2d, 0x5b, 0x74, 0x28, 0x7b, 0x73, 0xb3, 0xd6, 0xe4, + 0xa7, 0x38, 0x3e, 0xda, 0x7d, 0x7b, 0xc2, 0x8e, 0xdb, 0x1d, 0x6b, 0x1d, 0xcb, 0x4f, 0x8f, 0x0e, + 0x0f, 0x8e, 0x0e, 0x4e, 0xad, 0xdb, 0x62, 0xa8, 0xf9, 0xa3, 0xd8, 0xda, 0x10, 0xd3, 0x65, 0x3c, + 0xa0, 0xad, 0x3b, 0xb2, 0xdf, 0xd9, 0x63, 0xd0, 0x6a, 0xc9, 0xef, 0x7f, 0x9c, 0xb8, 0x57, 0x6b, + 0x53, 0x08, 0x32, 0x0e, 0xcf, 0xda, 0x12, 0x9d, 0xcd, 0xb9, 0x2a, 0xeb, 0xae, 0xf8, 0x98, 0x45, + 0x0f, 0x61, 0x51, 0x31, 0x88, 0xec, 0x0e, 0xb4, 0x3e, 0x20, 0xb7, 0xa5, 0xa7, 0x33, 0x85, 0x98, + 0xad, 0x7b, 0x64, 0x1d, 0x56, 0xcc, 0xc7, 0x8a, 0xf5, 0x21, 0x59, 0x85, 0x5b, 0x86, 0xfd, 0x62, + 0xdd, 0x7f, 0xf8, 0x23, 0x68, 0x9a, 0xee, 0x27, 0x04, 0x84, 0x8b, 0x1f, 0xfa, 0x72, 0x6b, 0xcc, + 0xc2, 0xe4, 0xbe, 0x1b, 0xbe, 0xb3, 0x6a, 0x7b, 0x87, 0x7f, 0xf8, 0xb6, 0x55, 0xfb, 0xe3, 0xb7, + 0xad, 0xda, 0x7f, 0x7f, 0xdb, 0xba, 0xf1, 0xfb, 0xef, 0x5a, 0x37, 0xfe, 0xe5, 0xbb, 0x56, 0xed, + 0x8f, 0xdf, 0xb5, 0x6e, 0xfc, 0xe9, 0xbb, 0xd6, 0x8d, 0xaf, 0xb6, 0x33, 0xff, 0xda, 0x35, 0x74, + 0xa2, 0xc0, 0xbd, 0xf4, 0x03, 0xb7, 0xef, 0x7a, 0xaa, 0xe0, 0xf1, 0x9d, 0xd1, 0xbb, 0xfe, 0xce, + 0xe8, 0x6c, 0x47, 0x5e, 0x8c, 0xce, 0xa6, 0x65, 0x00, 0xf2, 0xc7, 0xff, 0x17, 0x00, 0x00, 0xff, + 0xff, 0x66, 0xe9, 0xfb, 0x0c, 0x6e, 0x36, 0x00, 0x00, } func (m *QueryRequest) Marshal() (dAtA []byte, err error) { @@ -5870,6 +6004,18 @@ func (m *Request) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.MongoDBClientRetireRequest.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0xca { size, err := m.IcebergCacheInvalidateRequest.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -6414,6 +6560,18 @@ func (m *Response) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.MongoDBClientRetireResponse.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0xd2 { size, err := m.IcebergCacheInvalidateResponse.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -7527,12 +7685,12 @@ func (m *TxnInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - n80, err80 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreateAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreateAt):]) - if err80 != nil { - return 0, err80 + n82, err82 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreateAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreateAt):]) + if err82 != nil { + return 0, err82 } - i -= n80 - i = encodeVarintQuery(dAtA, i, uint64(n80)) + i -= n82 + i = encodeVarintQuery(dAtA, i, uint64(n82)) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -9282,6 +9440,77 @@ func (m *MinTimestampResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *MongoDBClientRetireRequest) Marshal() (dAtA []byte, err error) { + size := m.ProtoSize() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MongoDBClientRetireRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.ProtoSize() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MongoDBClientRetireRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.VersionExclusive != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.VersionExclusive)) + i-- + dAtA[i] = 0x18 + } + if m.ConnectionID != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.ConnectionID)) + i-- + dAtA[i] = 0x10 + } + if m.AccountID != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.AccountID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MongoDBClientRetireResponse) Marshal() (dAtA []byte, err error) { + size := m.ProtoSize() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MongoDBClientRetireResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.ProtoSize() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MongoDBClientRetireResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Success { + i-- + if m.Success { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -9619,6 +9848,8 @@ func (m *Request) ProtoSize() (n int) { } l = m.IcebergCacheInvalidateRequest.ProtoSize() n += 2 + l + sovQuery(uint64(l)) + l = m.MongoDBClientRetireRequest.ProtoSize() + n += 2 + l + sovQuery(uint64(l)) return n } @@ -9783,6 +10014,8 @@ func (m *Response) ProtoSize() (n int) { } l = m.IcebergCacheInvalidateResponse.ProtoSize() n += 2 + l + sovQuery(uint64(l)) + l = m.MongoDBClientRetireResponse.ProtoSize() + n += 2 + l + sovQuery(uint64(l)) return n } @@ -10814,6 +11047,36 @@ func (m *MinTimestampResponse) ProtoSize() (n int) { return n } +func (m *MongoDBClientRetireRequest) ProtoSize() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.AccountID != 0 { + n += 1 + sovQuery(uint64(m.AccountID)) + } + if m.ConnectionID != 0 { + n += 1 + sovQuery(uint64(m.ConnectionID)) + } + if m.VersionExclusive != 0 { + n += 1 + sovQuery(uint64(m.VersionExclusive)) + } + return n +} + +func (m *MongoDBClientRetireResponse) ProtoSize() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Success { + n += 2 + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -13334,6 +13597,39 @@ func (m *Request) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 41: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MongoDBClientRetireRequest", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MongoDBClientRetireRequest.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -14845,6 +15141,39 @@ func (m *Response) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 42: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MongoDBClientRetireResponse", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MongoDBClientRetireResponse.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -21182,6 +21511,183 @@ func (m *MinTimestampResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MongoDBClientRetireRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MongoDBClientRetireRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MongoDBClientRetireRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountID", wireType) + } + m.AccountID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.AccountID |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionID", wireType) + } + m.ConnectionID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ConnectionID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field VersionExclusive", wireType) + } + m.VersionExclusive = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.VersionExclusive |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MongoDBClientRetireResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MongoDBClientRetireResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MongoDBClientRetireResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Success", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Success = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/pkg/queryservice/client/query_client.go b/pkg/queryservice/client/query_client.go index ff015e003df31..0591214fd4790 100644 --- a/pkg/queryservice/client/query_client.go +++ b/pkg/queryservice/client/query_client.go @@ -61,6 +61,7 @@ var methodVersions = map[pb.CmdMethod]int64{ pb.CmdMethod_MinTimestamp: defines.MORPCVersion4, pb.CmdMethod_CtlPrefetchOnSubscribed: defines.MORPCVersion4, pb.CmdMethod_IcebergCacheInvalidate: defines.MORPCVersion4, + pb.CmdMethod_MongoDBClientRetire: defines.MORPCVersion5, } type queryClient struct { diff --git a/pkg/queryservice/client/query_client_test.go b/pkg/queryservice/client/query_client_test.go index ede78cbad3c13..b119e07d7ec9c 100644 --- a/pkg/queryservice/client/query_client_test.go +++ b/pkg/queryservice/client/query_client_test.go @@ -19,6 +19,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/common/moerr" "github.com/matrixorigin/matrixone/pkg/common/morpc" + "github.com/matrixorigin/matrixone/pkg/defines" "github.com/matrixorigin/matrixone/pkg/pb/query" "github.com/stretchr/testify/assert" ) @@ -29,6 +30,10 @@ func testCreateQueryClient(t *testing.T) QueryClient { return ct } +func TestMongoDBClientRetireRequiresProtocolVersion5(t *testing.T) { + assert.Equal(t, defines.MORPCVersion5, methodVersions[query.CmdMethod_MongoDBClientRetire]) +} + func TestNewCacheClient(t *testing.T) { ct := testCreateQueryClient(t) assert.NotNil(t, ct) diff --git a/pkg/sql/colexec/aggexec/maxby.go b/pkg/sql/colexec/aggexec/maxby.go new file mode 100644 index 0000000000000..0044e57cc8420 --- /dev/null +++ b/pkg/sql/colexec/aggexec/maxby.go @@ -0,0 +1,314 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package aggexec + +import ( + "bytes" + "math" + "slices" + + "github.com/matrixorigin/matrixone/pkg/common/moerr" + "github.com/matrixorigin/matrixone/pkg/common/mpool" + "github.com/matrixorigin/matrixone/pkg/container/types" + "github.com/matrixorigin/matrixone/pkg/container/vector" +) + +const maxByVarlenaCompactionSlack = 1 << 20 + +// maxByExec keeps value, order and tie in three serialized state vectors. The +// comparison is a total order: order, then tie, then canonical value bytes. +// The final component makes merge commutative even if callers provide duplicate +// tie keys. NULL order rows are ignored and NULL tie sorts below non-NULL tie. +type maxByExec struct { + aggExec + nonNullValue bool +} + +func makeMaxByExec(mp *mpool.MPool, id int64, nonNullValue bool, params []types.Type) AggFuncExec { + if len(params) != 3 { + panic(moerr.NewInternalErrorNoCtx("max_by requires value, order, and tie arguments")) + } + exec := &maxByExec{nonNullValue: nonNullValue} + exec.mp = mp + exec.aggInfo = aggInfo{ + aggId: id, + isDistinct: false, + argTypes: append([]types.Type(nil), params...), + retType: params[0], + stateTypes: append([]types.Type(nil), params...), + emptyNull: true, + } + return exec +} + +func (exec *maxByExec) Fill(groupIndex int, row int, vectors []*vector.Vector) error { + return exec.BatchFill(row, []uint64{uint64(groupIndex + 1)}, vectors) +} + +func (exec *maxByExec) BulkFill(groupIndex int, vectors []*vector.Vector) error { + if len(vectors) != 3 { + return moerr.NewInternalErrorNoCtx("max_by requires three input vectors") + } + return exec.BatchFill(0, slices.Repeat([]uint64{uint64(groupIndex + 1)}, vectors[0].Length()), vectors) +} + +func (exec *maxByExec) BatchFill(offset int, groups []uint64, vectors []*vector.Vector) error { + if len(vectors) != 3 { + return moerr.NewInternalErrorNoCtx("max_by requires three input vectors") + } + for i, group := range groups { + if group == GroupNotMatched { + continue + } + rows := [3]int{offset + i, offset + i, offset + i} + for column := range rows { + if vectors[column].IsConst() { + rows[column] = 0 + } + } + if vectors[1].IsNull(uint64(rows[1])) || exec.nonNullValue && vectors[0].IsNull(uint64(rows[0])) { + continue + } + x, y := exec.getXY(group - 1) + state := &exec.state[x] + if state.vecs[1].IsNull(uint64(y)) || candidateWins(vectors, rows, state.vecs, int(y), exec.argTypes) { + if err := exec.copyWinner(state.vecs, int(y), vectors, rows); err != nil { + return err + } + } + } + return nil +} + +func (exec *maxByExec) Merge(next AggFuncExec, groupIdx1, groupIdx2 int) error { + return exec.BatchMerge(next, groupIdx2, []uint64{uint64(groupIdx1 + 1)}) +} + +func (exec *maxByExec) BatchMerge(next AggFuncExec, offset int, groups []uint64) error { + other, ok := next.(*maxByExec) + if !ok || other.nonNullValue != exec.nonNullValue || !slices.Equal(other.argTypes, exec.argTypes) { + return moerr.NewInternalErrorNoCtx("cannot merge incompatible max_by states") + } + for i, group := range groups { + if group == GroupNotMatched { + continue + } + x1, y1 := exec.getXY(group - 1) + x2, y2 := other.getXY(uint64(offset + i)) + candidate := other.state[x2].vecs + if candidate[1].IsNull(uint64(y2)) { + continue + } + current := exec.state[x1].vecs + rows := [3]int{int(y2), int(y2), int(y2)} + if current[1].IsNull(uint64(y1)) || candidateWins(candidate, rows, current, int(y1), exec.argTypes) { + if err := exec.copyWinner(current, int(y1), candidate, rows); err != nil { + return err + } + } + } + return nil +} + +func candidateWins(candidate []*vector.Vector, candidateRows [3]int, current []*vector.Vector, currentRow int, typs []types.Type) bool { + if cmp := compareVectorValue(candidate[1], candidateRows[1], current[1], currentRow, typs[1]); cmp != 0 { + return cmp > 0 + } + if cmp := compareNullableVectorValue(candidate[2], candidateRows[2], current[2], currentRow, typs[2]); cmp != 0 { + return cmp > 0 + } + // A caller-supplied tie should normally be unique. The value bytes are a + // final deterministic fallback so partial aggregation merge order cannot + // change the result when it is not. + return compareNullableRaw(candidate[0], candidateRows[0], current[0], currentRow) > 0 +} + +func compareNullableVectorValue(a *vector.Vector, ai int, b *vector.Vector, bi int, typ types.Type) int { + an, bn := a.IsNull(uint64(ai)), b.IsNull(uint64(bi)) + if an || bn { + switch { + case an && bn: + return 0 + case an: + return -1 + default: + return 1 + } + } + return compareVectorValue(a, ai, b, bi, typ) +} + +func compareNullableRaw(a *vector.Vector, ai int, b *vector.Vector, bi int) int { + an, bn := a.IsNull(uint64(ai)), b.IsNull(uint64(bi)) + if an || bn { + switch { + case an && bn: + return 0 + case an: + return -1 + default: + return 1 + } + } + return bytes.Compare(a.GetRawBytesAt(ai), b.GetRawBytesAt(bi)) +} + +func compareVectorValue(a *vector.Vector, ai int, b *vector.Vector, bi int, typ types.Type) int { + x, y := a.GetRawBytesAt(ai), b.GetRawBytesAt(bi) + switch typ.Oid { + case types.T_bool: + return types.BoolAscCompare(types.DecodeBool(x), types.DecodeBool(y)) + case types.T_int8: + return types.GenericAscCompare(types.DecodeInt8(x), types.DecodeInt8(y)) + case types.T_int16: + return types.GenericAscCompare(types.DecodeInt16(x), types.DecodeInt16(y)) + case types.T_int32: + return types.GenericAscCompare(types.DecodeInt32(x), types.DecodeInt32(y)) + case types.T_int64: + return types.GenericAscCompare(types.DecodeInt64(x), types.DecodeInt64(y)) + case types.T_uint8: + return types.GenericAscCompare(types.DecodeUint8(x), types.DecodeUint8(y)) + case types.T_uint16: + return types.GenericAscCompare(types.DecodeUint16(x), types.DecodeUint16(y)) + case types.T_uint32: + return types.GenericAscCompare(types.DecodeUint32(x), types.DecodeUint32(y)) + case types.T_uint64, types.T_bit: + return types.GenericAscCompare(types.DecodeUint64(x), types.DecodeUint64(y)) + case types.T_float32: + return compareFloat64(float64(types.DecodeFloat32(x)), float64(types.DecodeFloat32(y))) + case types.T_float64: + return compareFloat64(types.DecodeFloat64(x), types.DecodeFloat64(y)) + case types.T_date: + return types.GenericAscCompare(types.DecodeDate(x), types.DecodeDate(y)) + case types.T_datetime: + return types.GenericAscCompare(types.DecodeDatetime(x), types.DecodeDatetime(y)) + case types.T_timestamp: + return types.GenericAscCompare(types.DecodeTimestamp(x), types.DecodeTimestamp(y)) + case types.T_time: + return types.GenericAscCompare(types.DecodeFixed[types.Time](x), types.DecodeFixed[types.Time](y)) + case types.T_year: + return types.GenericAscCompare(types.DecodeFixed[types.MoYear](x), types.DecodeFixed[types.MoYear](y)) + case types.T_decimal64: + return types.DecodeDecimal64(x).Compare(types.DecodeDecimal64(y)) + case types.T_decimal128: + return types.DecodeDecimal128(x).Compare(types.DecodeDecimal128(y)) + case types.T_decimal256: + return types.DecodeDecimal256(x).Compare(types.DecodeDecimal256(y)) + case types.T_uuid: + return types.DecodeUuid(x).Compare(types.DecodeUuid(y)) + default: + return bytes.Compare(x, y) + } +} + +func compareFloat64(a, b float64) int { + aNaN, bNaN := math.IsNaN(a), math.IsNaN(b) + if aNaN || bNaN { + switch { + case aNaN && bNaN: + return types.GenericAscCompare(math.Float64bits(a), math.Float64bits(b)) + case aNaN: + return 1 + default: + return -1 + } + } + return types.GenericAscCompare(a, b) +} + +func (exec *maxByExec) copyWinner(dst []*vector.Vector, dstRow int, src []*vector.Vector, srcRows [3]int) error { + // Reserve every fallible varlen allocation before mutating any of the three + // correlated state vectors. Without this preflight, an OOM after copying the + // value but before copying order/tie would publish a mixed winner. Growing + // capacity is harmless if a later reservation fails; the logical state stays + // byte-for-byte unchanged and remains safe to serialize or free. + for i := range dst { + if src[i].IsNull(uint64(srcRows[i])) || !dst[i].GetType().IsVarlen() { + continue + } + valueBytes := len(src[i].GetRawBytesAt(srcRows[i])) + if valueBytes <= types.VarlenaInlineSize { + continue + } + if err := dst[i].PreExtendWithArea(0, valueBytes, exec.mp); err != nil { + return err + } + } + for i := range dst { + if src[i].IsNull(uint64(srcRows[i])) { + dst[i].SetNull(uint64(dstRow)) + continue + } + if err := dst[i].SetRawBytesAt(dstRow, src[i].GetRawBytesAt(srcRows[i]), exec.mp); err != nil { + return err + } + dst[i].UnsetNull(uint64(dstRow)) + } + for _, vec := range dst { + // Compaction is an optional bound on stale varlen area. A failed compact + // clone leaves the valid original untouched, so memory pressure must not + // turn a fully copied winner into an aggregate error with ambiguous state. + _ = compactMaxByStateVector(vec, exec.mp) + } + return nil +} + +func compactMaxByStateVector(vec *vector.Vector, mp *mpool.MPool) error { + if vec == nil || !vec.GetType().IsVarlen() { + return nil + } + fixedCapacity := vec.Capacity() * vec.GetType().TypeSize() + areaCapacity := vec.Allocated() - fixedCapacity + if areaCapacity <= maxByVarlenaCompactionSlack { + return nil + } + liveBytes := 0 + for row := 0; row < vec.Length(); row++ { + if vec.IsNull(uint64(row)) { + continue + } + valueBytes := len(vec.GetRawBytesAt(row)) + if valueBytes > types.VarlenaInlineSize { + liveBytes += valueBytes + } + } + if areaCapacity <= 2*liveBytes+maxByVarlenaCompactionSlack { + return nil + } + compact, err := vec.CloneToFlatCompact(mp) + if err != nil { + return err + } + vec.Free(mp) + *vec = *compact + return nil +} + +func (exec *maxByExec) SetExtraInformation(any, int) error { return nil } + +func (exec *maxByExec) Flush() ([]*vector.Vector, error) { + result := make([]*vector.Vector, len(exec.state)) + for i := range exec.state { + result[i] = exec.state[i].vecs[0] + exec.state[i].vecs[0] = nil + for j := 1; j < len(exec.state[i].vecs); j++ { + exec.state[i].vecs[j].Free(exec.mp) + exec.state[i].vecs[j] = nil + } + exec.state[i].length = 0 + exec.state[i].capacity = 0 + } + return result, nil +} diff --git a/pkg/sql/colexec/aggexec/maxby_test.go b/pkg/sql/colexec/aggexec/maxby_test.go new file mode 100644 index 0000000000000..eda3b9a922476 --- /dev/null +++ b/pkg/sql/colexec/aggexec/maxby_test.go @@ -0,0 +1,339 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package aggexec + +import ( + "bytes" + "fmt" + "math" + "strings" + "testing" + + "github.com/matrixorigin/matrixone/pkg/common/mpool" + "github.com/matrixorigin/matrixone/pkg/container/types" + "github.com/matrixorigin/matrixone/pkg/container/vector" + "github.com/stretchr/testify/require" +) + +func assertMaxByFixedCompare[T any](t *testing.T, mp *mpool.MPool, typ types.Type, low, high T) { + t.Helper() + a := vector.NewVec(typ) + b := vector.NewVec(typ) + t.Cleanup(func() { + a.Free(mp) + b.Free(mp) + }) + require.NoError(t, vector.AppendFixed(a, low, false, mp)) + require.NoError(t, vector.AppendFixed(b, high, false, mp)) + require.Less(t, compareVectorValue(a, 0, b, 0, typ), 0) + require.Greater(t, compareVectorValue(b, 0, a, 0, typ), 0) + require.Zero(t, compareVectorValue(a, 0, a, 0, typ)) +} + +func maxByInputs(t *testing.T, mp *mpool.MPool, values []string, nullValue map[int]bool, orders []int64, ties []string) []*vector.Vector { + t.Helper() + valueVec := vector.NewVec(types.T_varchar.ToType()) + orderVec := vector.NewVec(types.T_int64.ToType()) + tieVec := vector.NewVec(types.T_varchar.ToType()) + for i := range values { + require.NoError(t, vector.AppendBytes(valueVec, []byte(values[i]), nullValue[i], mp)) + require.NoError(t, vector.AppendFixed(orderVec, orders[i], false, mp)) + require.NoError(t, vector.AppendBytes(tieVec, []byte(ties[i]), false, mp)) + } + return []*vector.Vector{valueVec, orderVec, tieVec} +} + +func TestMaxByCompactsReplacedVarlenaState(t *testing.T) { + mp := mpool.MustNewZero() + params := []types.Type{types.T_varchar.ToType(), types.T_int64.ToType(), types.T_int64.ToType()} + exec := makeMaxByExec(mp, 7004, false, params).(*maxByExec) + require.NoError(t, exec.GroupGrow(1)) + valueVec := vector.NewVec(types.T_varchar.ToType()) + orderVec := vector.NewVec(types.T_int64.ToType()) + tieVec := vector.NewVec(types.T_int64.ToType()) + defer func() { + valueVec.Free(mp) + orderVec.Free(mp) + tieVec.Free(mp) + exec.Free() + require.Zero(t, mp.CurrNB()) + }() + for i := range 600 { + value := []byte(fmt.Sprintf("%06d:%s", i, strings.Repeat("x", 4096))) + require.NoError(t, vector.AppendBytes(valueVec, value, false, mp)) + require.NoError(t, vector.AppendFixed(orderVec, int64(i), false, mp)) + require.NoError(t, vector.AppendFixed(tieVec, int64(i), false, mp)) + } + require.NoError(t, exec.BulkFill(0, []*vector.Vector{valueVec, orderVec, tieVec})) + state := exec.state[0].vecs[0] + require.Less(t, state.Allocated(), 2<<20, "winner state must be bounded by live groups, not by replaced input rows") +} + +func TestMaxByNullContractAndDeterministicMerge(t *testing.T) { + mp := mpool.MustNewZero() + params := []types.Type{types.T_varchar.ToType(), types.T_int64.ToType(), types.T_varchar.ToType()} + inputs := maxByInputs(t, mp, []string{"ignored", "older"}, map[int]bool{0: true}, []int64{10, 9}, []string{"z", "a"}) + defer func() { + for _, input := range inputs { + input.Free(mp) + } + }() + + keepNull := makeMaxByExec(mp, 7001, false, params).(*maxByExec) + require.NoError(t, keepNull.GroupGrow(1)) + require.NoError(t, keepNull.BulkFill(0, inputs)) + result, err := keepNull.Flush() + require.NoError(t, err) + require.True(t, result[0].IsNull(0), "max_by must retain a winning NULL value") + result[0].Free(mp) + + skipNull := makeMaxByExec(mp, 7002, true, params).(*maxByExec) + require.NoError(t, skipNull.GroupGrow(1)) + require.NoError(t, skipNull.BulkFill(0, inputs)) + result, err = skipNull.Flush() + require.NoError(t, err) + require.Equal(t, "older", string(result[0].GetBytesAt(0))) + result[0].Free(mp) + + leftInput := maxByInputs(t, mp, []string{"alpha"}, nil, []int64{10}, []string{"same"}) + rightInput := maxByInputs(t, mp, []string{"beta"}, nil, []int64{10}, []string{"same"}) + defer func() { + for _, list := range [][]*vector.Vector{leftInput, rightInput} { + for _, input := range list { + input.Free(mp) + } + } + }() + left := makeMaxByExec(mp, 7003, false, params).(*maxByExec) + right := makeMaxByExec(mp, 7003, false, params).(*maxByExec) + require.NoError(t, left.GroupGrow(1)) + require.NoError(t, right.GroupGrow(1)) + require.NoError(t, left.BulkFill(0, leftInput)) + require.NoError(t, right.BulkFill(0, rightInput)) + require.NoError(t, left.Merge(right, 0, 0)) + + var serialized bytes.Buffer + require.NoError(t, left.SaveIntermediateResultOfChunk(0, &serialized)) + restored := makeMaxByExec(mp, 7003, false, params).(*maxByExec) + require.NoError(t, restored.UnmarshalFromReader(&serialized, mp)) + result, err = restored.Flush() + require.NoError(t, err) + require.Equal(t, "beta", string(result[0].GetBytesAt(0))) + result[0].Free(mp) + left.Free() + right.Free() + restored.Free() +} + +func TestMaxByMergeIsCommutativeAndAssociative(t *testing.T) { + mp := mpool.MustNewZero() + params := []types.Type{types.T_varchar.ToType(), types.T_int64.ToType(), types.T_varchar.ToType()} + inputs := []*vector.Vector(nil) + for _, candidate := range []string{"alpha", "gamma", "beta"} { + inputs = append(inputs, maxByInputs(t, mp, []string{candidate}, nil, []int64{10}, []string{"same"})...) + } + defer func() { + for _, input := range inputs { + input.Free(mp) + } + require.Zero(t, mp.CurrNB()) + }() + + run := func(merge func([]*maxByExec) error) string { + states := make([]*maxByExec, 3) + for i := range states { + states[i] = makeMaxByExec(mp, 7005, false, params).(*maxByExec) + require.NoError(t, states[i].GroupGrow(1)) + require.NoError(t, states[i].BulkFill(0, inputs[i*3:i*3+3])) + } + require.NoError(t, merge(states)) + result, err := states[0].Flush() + require.NoError(t, err) + winner := string(result[0].GetBytesAt(0)) + result[0].Free(mp) + for _, state := range states { + state.Free() + } + return winner + } + + leftAssociated := run(func(states []*maxByExec) error { + if err := states[0].Merge(states[1], 0, 0); err != nil { + return err + } + return states[0].Merge(states[2], 0, 0) + }) + rightAssociated := run(func(states []*maxByExec) error { + if err := states[1].Merge(states[2], 0, 0); err != nil { + return err + } + return states[0].Merge(states[1], 0, 0) + }) + reversed := run(func(states []*maxByExec) error { + if err := states[0].Merge(states[2], 0, 0); err != nil { + return err + } + return states[0].Merge(states[1], 0, 0) + }) + require.Equal(t, "gamma", leftAssociated) + require.Equal(t, leftAssociated, rightAssociated) + require.Equal(t, leftAssociated, reversed) +} + +func TestMaxByRejectsIncompatibleMergeAndArity(t *testing.T) { + mp := mpool.MustNewZero() + specialAgg[AggIdOfMaxBy] = true + defer delete(specialAgg, AggIdOfMaxBy) + params := []types.Type{types.T_varchar.ToType(), types.T_int64.ToType(), types.T_varchar.ToType()} + left := makeMaxByExec(mp, 7007, false, params).(*maxByExec) + right := makeMaxByExec(mp, 7008, true, params).(*maxByExec) + require.NoError(t, left.GroupGrow(1)) + require.NoError(t, right.GroupGrow(1)) + require.ErrorContains(t, left.Merge(right, 0, 0), "incompatible") + require.ErrorContains(t, left.BulkFill(0, nil), "three input vectors") + left.Free() + right.Free() + + _, err := MakeAgg(mp, AggIdOfMaxBy, false, types.T_varchar.ToType()) + require.ErrorContains(t, err, "requires value, order, and tie") + require.Zero(t, mp.CurrNB()) +} + +func TestMaxByOOMDoesNotPublishMixedWinner(t *testing.T) { + mp, err := mpool.NewMPool("max-by-oom", 1<<20, mpool.NoFixed) + require.NoError(t, err) + params := []types.Type{types.T_varchar.ToType(), types.T_int64.ToType(), types.T_varchar.ToType()} + exec := makeMaxByExec(mp, 7006, false, params).(*maxByExec) + require.NoError(t, exec.GroupGrow(1)) + old := maxByInputs(t, mp, []string{"old"}, nil, []int64{1}, []string{"old"}) + candidate := maxByInputs(t, mp, + []string{strings.Repeat("v", 400<<10)}, nil, []int64{2}, []string{strings.Repeat("t", 400<<10)}) + defer func() { + for _, list := range [][]*vector.Vector{old, candidate} { + for _, input := range list { + input.Free(mp) + } + } + exec.Free() + require.Zero(t, mp.CurrNB()) + }() + require.NoError(t, exec.BulkFill(0, old)) + require.Error(t, exec.BulkFill(0, candidate)) + + result, err := exec.Flush() + require.NoError(t, err) + require.Equal(t, "old", string(result[0].GetBytesAt(0))) + result[0].Free(mp) +} + +func TestMaxByComparisonCoversSupportedOrderTypes(t *testing.T) { + mp := mpool.MustNewZero() + assertMaxByFixedCompare(t, mp, types.T_bool.ToType(), false, true) + assertMaxByFixedCompare(t, mp, types.T_int8.ToType(), int8(1), int8(2)) + assertMaxByFixedCompare(t, mp, types.T_int16.ToType(), int16(1), int16(2)) + assertMaxByFixedCompare(t, mp, types.T_int32.ToType(), int32(1), int32(2)) + assertMaxByFixedCompare(t, mp, types.T_int64.ToType(), int64(1), int64(2)) + assertMaxByFixedCompare(t, mp, types.T_uint8.ToType(), uint8(1), uint8(2)) + assertMaxByFixedCompare(t, mp, types.T_uint16.ToType(), uint16(1), uint16(2)) + assertMaxByFixedCompare(t, mp, types.T_uint32.ToType(), uint32(1), uint32(2)) + assertMaxByFixedCompare(t, mp, types.T_uint64.ToType(), uint64(1), uint64(2)) + assertMaxByFixedCompare(t, mp, types.T_bit.ToType(), uint64(1), uint64(2)) + assertMaxByFixedCompare(t, mp, types.T_float32.ToType(), float32(1), float32(2)) + assertMaxByFixedCompare(t, mp, types.T_float64.ToType(), float64(1), float64(2)) + assertMaxByFixedCompare(t, mp, types.T_date.ToType(), types.Date(1), types.Date(2)) + assertMaxByFixedCompare(t, mp, types.T_datetime.ToType(), types.Datetime(1), types.Datetime(2)) + assertMaxByFixedCompare(t, mp, types.T_timestamp.ToType(), types.Timestamp(1), types.Timestamp(2)) + assertMaxByFixedCompare(t, mp, types.T_time.ToType(), types.Time(1), types.Time(2)) + assertMaxByFixedCompare(t, mp, types.T_year.ToType(), types.MoYear(1), types.MoYear(2)) + decimal64Low, err := types.ParseDecimal64("1", 18, 0) + require.NoError(t, err) + decimal64High, err := types.ParseDecimal64("2", 18, 0) + require.NoError(t, err) + assertMaxByFixedCompare(t, mp, types.T_decimal64.ToType(), decimal64Low, decimal64High) + decimal128Low, err := types.ParseDecimal128("1", 38, 0) + require.NoError(t, err) + decimal128High, err := types.ParseDecimal128("2", 38, 0) + require.NoError(t, err) + assertMaxByFixedCompare(t, mp, types.T_decimal128.ToType(), decimal128Low, decimal128High) + decimal256Low, err := types.ParseDecimal256("1", 76, 0) + require.NoError(t, err) + decimal256High, err := types.ParseDecimal256("2", 76, 0) + require.NoError(t, err) + assertMaxByFixedCompare(t, mp, types.T_decimal256.ToType(), decimal256Low, decimal256High) + uuidLow, err := types.ParseUuid("00000000-0000-0000-0000-000000000001") + require.NoError(t, err) + uuidHigh, err := types.ParseUuid("00000000-0000-0000-0000-000000000002") + require.NoError(t, err) + assertMaxByFixedCompare(t, mp, types.T_uuid.ToType(), uuidLow, uuidHigh) + + a := vector.NewVec(types.T_varchar.ToType()) + b := vector.NewVec(types.T_varchar.ToType()) + require.NoError(t, vector.AppendBytes(a, []byte("a"), false, mp)) + require.NoError(t, vector.AppendBytes(b, []byte("b"), false, mp)) + require.Less(t, compareVectorValue(a, 0, b, 0, types.T_varchar.ToType()), 0) + a.Free(mp) + b.Free(mp) +} + +func TestMaxByNullableAndNaNComparison(t *testing.T) { + mp := mpool.MustNewZero() + a := vector.NewVec(types.T_varchar.ToType()) + b := vector.NewVec(types.T_varchar.ToType()) + defer func() { + a.Free(mp) + b.Free(mp) + require.Zero(t, mp.CurrNB()) + }() + require.NoError(t, vector.AppendBytes(a, nil, true, mp)) + require.NoError(t, vector.AppendBytes(a, []byte("a"), false, mp)) + require.NoError(t, vector.AppendBytes(b, nil, true, mp)) + require.NoError(t, vector.AppendBytes(b, []byte("b"), false, mp)) + + require.Zero(t, compareNullableVectorValue(a, 0, b, 0, types.T_varchar.ToType())) + require.Less(t, compareNullableVectorValue(a, 0, b, 1, types.T_varchar.ToType()), 0) + require.Greater(t, compareNullableVectorValue(a, 1, b, 0, types.T_varchar.ToType()), 0) + require.Less(t, compareNullableVectorValue(a, 1, b, 1, types.T_varchar.ToType()), 0) + require.Zero(t, compareNullableRaw(a, 0, b, 0)) + require.Less(t, compareNullableRaw(a, 0, b, 1), 0) + require.Greater(t, compareNullableRaw(a, 1, b, 0), 0) + require.Less(t, compareNullableRaw(a, 1, b, 1), 0) + + nan := math.NaN() + require.Zero(t, compareFloat64(nan, nan)) + require.Greater(t, compareFloat64(nan, 1), 0) + require.Less(t, compareFloat64(1, nan), 0) + require.Less(t, compareFloat64(1, 2), 0) +} + +func TestMaxByFillAndMergeSkipBranches(t *testing.T) { + mp := mpool.MustNewZero() + params := []types.Type{types.T_varchar.ToType(), types.T_int64.ToType(), types.T_varchar.ToType()} + exec := makeMaxByExec(mp, 7010, false, params).(*maxByExec) + other := makeMaxByExec(mp, 7010, false, params).(*maxByExec) + require.NoError(t, exec.GroupGrow(1)) + require.NoError(t, other.GroupGrow(1)) + inputs := maxByInputs(t, mp, []string{"value"}, nil, []int64{1}, []string{"tie"}) + require.NoError(t, exec.BatchFill(0, []uint64{GroupNotMatched}, inputs)) + require.NoError(t, exec.Fill(0, 0, inputs)) + require.NoError(t, exec.BatchMerge(other, 0, []uint64{GroupNotMatched})) + require.NoError(t, exec.SetExtraInformation(nil, 0)) + require.ErrorContains(t, exec.BatchFill(0, nil, nil), "three input vectors") + require.Panics(t, func() { makeMaxByExec(mp, 7011, false, nil) }) + for _, input := range inputs { + input.Free(mp) + } + exec.Free() + other.Free() + require.Zero(t, mp.CurrNB()) +} diff --git a/pkg/sql/colexec/aggexec/numeric_contract_test.go b/pkg/sql/colexec/aggexec/numeric_contract_test.go new file mode 100644 index 0000000000000..c91c09fddb64e --- /dev/null +++ b/pkg/sql/colexec/aggexec/numeric_contract_test.go @@ -0,0 +1,102 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package aggexec + +import ( + "testing" + + "github.com/matrixorigin/matrixone/pkg/common/mpool" + "github.com/matrixorigin/matrixone/pkg/container/types" + "github.com/matrixorigin/matrixone/pkg/container/vector" + "github.com/stretchr/testify/require" +) + +// The MongoDB aggregate-v1 contract deliberately keeps AVG(DOUBLE) single-scope: +// partial sums are not associative. DECIMAL is the exact, merge-order-stable +// alternative required before local split can be enabled for that ingestion. +func TestAvgNumericContractMergeOrder(t *testing.T) { + mp := mpool.MustNewZero() + floatInput := vector.NewVec(types.T_float64.ToType()) + require.NoError(t, vector.AppendFixedList(floatInput, []float64{1e16, -1e16, 1}, nil, mp)) + defer floatInput.Free(mp) + + runFloat := func(rightAssociated bool) float64 { + states := make([]AggFuncExec, 3) + for i := range states { + states[i] = makeAvgExec(t, mp, types.T_float64.ToType()) + require.NoError(t, states[i].GroupGrow(1)) + require.NoError(t, states[i].Fill(0, i, []*vector.Vector{floatInput})) + } + if rightAssociated { + require.NoError(t, states[1].Merge(states[2], 0, 0)) + require.NoError(t, states[0].Merge(states[1], 0, 0)) + } else { + require.NoError(t, states[0].Merge(states[1], 0, 0)) + require.NoError(t, states[0].Merge(states[2], 0, 0)) + } + result, err := states[0].Flush() + require.NoError(t, err) + value := vector.GetFixedAtNoTypeCheck[float64](result[0], 0) + result[0].Free(mp) + for _, state := range states { + state.Free() + } + return value + } + + leftFloat := runFloat(false) + rightFloat := runFloat(true) + require.Equal(t, 1.0/3.0, leftFloat) + require.Equal(t, 0.0, rightFloat) + + decimalType := types.New(types.T_decimal64, 18, 2) + decimalInput := vector.NewVec(decimalType) + for _, text := range []string{"9000000000000000.00", "-9000000000000000.00", "1.00"} { + value, err := types.ParseDecimal64(text, decimalType.Width, decimalType.Scale) + require.NoError(t, err) + require.NoError(t, vector.AppendFixed(decimalInput, value, false, mp)) + } + defer decimalInput.Free(mp) + + runDecimal := func(rightAssociated bool) types.Decimal128 { + states := make([]AggFuncExec, 3) + for i := range states { + states[i] = makeAvgExec(t, mp, decimalType) + require.NoError(t, states[i].GroupGrow(1)) + require.NoError(t, states[i].Fill(0, i, []*vector.Vector{decimalInput})) + } + if rightAssociated { + require.NoError(t, states[1].Merge(states[2], 0, 0)) + require.NoError(t, states[0].Merge(states[1], 0, 0)) + } else { + require.NoError(t, states[0].Merge(states[1], 0, 0)) + require.NoError(t, states[0].Merge(states[2], 0, 0)) + } + result, err := states[0].Flush() + require.NoError(t, err) + value := vector.GetFixedAtNoTypeCheck[types.Decimal128](result[0], 0) + result[0].Free(mp) + for _, state := range states { + state.Free() + } + return value + } + + leftDecimal := runDecimal(false) + rightDecimal := runDecimal(true) + require.Equal(t, leftDecimal, rightDecimal) + require.Equal(t, "0.33333333", leftDecimal.Format(8)) + require.Zero(t, mp.CurrNB()) +} diff --git a/pkg/sql/colexec/aggexec/register.go b/pkg/sql/colexec/aggexec/register.go index ed8b7cdfc19f1..904d3f90d520f 100644 --- a/pkg/sql/colexec/aggexec/register.go +++ b/pkg/sql/colexec/aggexec/register.go @@ -83,6 +83,16 @@ func RegisterMax(id int64) { AggIdOfMax = id } +func RegisterMaxBy(id int64) { + specialAgg[id] = true + AggIdOfMaxBy = id +} + +func RegisterMaxByNonNull(id int64) { + specialAgg[id] = true + AggIdOfMaxByNonNull = id +} + func RegisterSum(id int64) { specialAgg[id] = true AggIdOfSum = id @@ -234,6 +244,8 @@ var ( AggIdOfAvgTwResult = int64(-34) AggIdOfHllAdd = int64(-35) AggIdOfHllMerge = int64(-36) + AggIdOfMaxBy = int64(-37) + AggIdOfMaxByNonNull = int64(-38) groupConcatSep = "," getGroupConcatRet = func(args ...types.Type) types.Type { for _, p := range args { diff --git a/pkg/sql/colexec/aggexec/types.go b/pkg/sql/colexec/aggexec/types.go index e84d11498e4e9..051777f67b708 100644 --- a/pkg/sql/colexec/aggexec/types.go +++ b/pkg/sql/colexec/aggexec/types.go @@ -170,6 +170,12 @@ func makeSpecialAggExec( id int64, isDistinct bool, params ...types.Type, ) (AggFuncExec, bool, error) { if _, ok := specialAgg[id]; ok { + if id == AggIdOfMaxBy && len(params) != 3 { + return nil, true, moerr.NewInternalErrorNoCtx("max_by requires value, order, and tie arguments") + } + if id == AggIdOfMaxByNonNull && len(params) != 3 { + return nil, true, moerr.NewInternalErrorNoCtx("max_by_non_null requires value, order, and tie arguments") + } switch id { case AggIdOfBitmapConstruct: return makeBmpConstructExec(mp, id, params[0]), true, nil @@ -195,6 +201,10 @@ func makeSpecialAggExec( return makeMinMaxExec(mp, id, true, params[0]), true, nil case AggIdOfMax: return makeMinMaxExec(mp, id, false, params[0]), true, nil + case AggIdOfMaxBy: + return makeMaxByExec(mp, id, false, params), true, nil + case AggIdOfMaxByNonNull: + return makeMaxByExec(mp, id, true, params), true, nil case AggIdOfSum: return makeSumAvgExec(mp, true, id, isDistinct, params[0]), true, nil case AggIdOfAvg: diff --git a/pkg/sql/colexec/fill/fill.go b/pkg/sql/colexec/fill/fill.go index 6c7f63ae9770f..99540d1dd0960 100644 --- a/pkg/sql/colexec/fill/fill.go +++ b/pkg/sql/colexec/fill/fill.go @@ -17,6 +17,7 @@ package fill import ( "bytes" "fmt" + "io" "github.com/matrixorigin/matrixone/pkg/common/moerr" "github.com/matrixorigin/matrixone/pkg/container/batch" @@ -47,6 +48,7 @@ func (fill *Fill) Prepare(proc *process.Process) (err error) { } ctr := &fill.ctr + ctr.spillThreshold = colexec.ResolveSpillThreshold(fill.SpillThreshold) switch fill.FillType { case plan.Node_VALUE: @@ -75,17 +77,26 @@ func (fill *Fill) Prepare(proc *process.Process) (err error) { case plan.Node_PREV: if len(ctr.prevVecs) == 0 { ctr.prevVecs = make([]*vector.Vector, fill.ColLen) + ctr.prevValid = make([]bool, fill.ColLen) } ctr.process = processPrev case plan.Node_NEXT: - ctr.i = 0 - ctr.idx = 0 - ctr.status = receiveBat - ctr.subStatus = findNull + if len(ctr.nextRun) < fill.ColLen { + ctr.nextRun = make([][]fillCoord, fill.ColLen) + } ctr.process = processNext case plan.Node_LINEAR: - ctr.i = 0 - ctr.idx = 0 + if len(ctr.linRun) < fill.ColLen { + ctr.linRun = make([][]fillCoord, fill.ColLen) + ctr.linPre = make([]fillCoord, fill.ColLen) + ctr.linSeed = make([]*vector.Vector, fill.ColLen) + ctr.linSeedValid = make([]bool, fill.ColLen) + ctr.linEntry = make([]*vector.Vector, fill.ColLen) + ctr.linEntryValid = make([]bool, fill.ColLen) + for i := range ctr.linPre { + ctr.linPre[i] = fillCoord{seq: -1, row: -1} + } + } if len(ctr.exes) == 0 { ctr.valVecs = make([]*vector.Vector, len(fill.FillVal)) for _, v := range fill.FillVal { @@ -166,130 +177,215 @@ func processValue(ctr *container, ap *Fill, proc *process.Process, analyzer proc return result, nil } -func (ctr *container) initIndex() { - ctr.nullIdx = 0 - ctr.nullRow = 0 - ctr.preIdx = 0 - ctr.preRow = 0 - ctr.curIdx = 0 - ctr.curRow = 0 - ctr.status = receiveBat - ctr.subStatus = findNullPre +// partKeyAt reads one partition-key cell, tolerating the constant vectors the +// time window emits when it broadcasts a key across a flushed batch. +func partKeyAt(vec *vector.Vector, row int) (val []byte, isNull bool) { + if vec.IsConstNull() { + return nil, true + } + if vec.IsConst() { + row = 0 + } + if vec.IsNull(uint64(row)) { + return nil, true + } + return vec.GetRawBytesAt(row), false } -func processNextCol(ctr *container, ap *Fill, idx int, proc *process.Process, analyzer process.Analyzer) error { - var err error - ctr.initIndex() - ctr.preIdx = ctr.doneIdx[idx] - ctr.status = findNull - for { - switch ctr.status { - case receiveBat: - if ctr.doneIdx[idx] == len(ctr.bats) || - ctr.endBatch[idx] { - return nil - } +// samePartitionRows reports whether two rows carry the same partition key. +// NULL keys compare equal, matching how GROUP BY folded them into one group. +func samePartitionRows(partIdx []int32, batA *batch.Batch, rowA int, batB *batch.Batch, rowB int) bool { + for _, col := range partIdx { + valA, nullA := partKeyAt(batA.Vecs[col], rowA) + valB, nullB := partKeyAt(batB.Vecs[col], rowB) + if nullA || nullB { + if nullA != nullB { + return false + } + continue + } + if !bytes.Equal(valA, valB) { + return false + } + } + return true +} - result, err := vm.ChildrenCall(ap.GetChildren(0), proc, analyzer) - if err != nil { - return err - } - if result.Batch == nil { - ctr.endBatch[idx] = true - return nil - } else { - if len(ctr.bats) > ctr.i { - if ctr.bats[ctr.i] != nil { - ctr.bats[ctr.i].CleanOnlyData() - } - ctr.bats[ctr.i], err = ctr.bats[ctr.i].AppendWithCopy(proc.Ctx, proc.Mp(), result.Batch) - if err != nil { - return err - } - } else { - appBat, err := result.Batch.Dup(proc.Mp()) - if err != nil { - return err - } - analyzer.Alloc(int64(appBat.Size())) - ctr.bats = append(ctr.bats, appBat) - } - ctr.i++ - } +// snapshotPartKey copies a row's partition key out of the batch, so the next +// batch can detect a boundary after this one has been recycled. +func (ctr *container) snapshotPartKey(partIdx []int32, bat *batch.Batch, row int) { + if cap(ctr.prevPartKey) < len(partIdx) { + ctr.prevPartKey = make([][]byte, len(partIdx)) + ctr.prevPartNull = make([]bool, len(partIdx)) + } + ctr.prevPartKey = ctr.prevPartKey[:len(partIdx)] + ctr.prevPartNull = ctr.prevPartNull[:len(partIdx)] + for i, col := range partIdx { + val, isNull := partKeyAt(bat.Vecs[col], row) + ctr.prevPartNull[i] = isNull + ctr.prevPartKey[i] = append(ctr.prevPartKey[i][:0], val...) + } + ctr.prevPartSet = true +} - if ctr.subStatus == findNull { - ctr.status = findNull - } else { - ctr.status = findValue +// matchesSnapshot compares a row against the saved cross-batch partition key. +func (ctr *container) matchesSnapshot(partIdx []int32, bat *batch.Batch, row int) bool { + if !ctr.prevPartSet { + return true + } + for i, col := range partIdx { + val, isNull := partKeyAt(bat.Vecs[col], row) + if isNull || ctr.prevPartNull[i] { + if isNull != ctr.prevPartNull[i] { + return false } + continue + } + if !bytes.Equal(val, ctr.prevPartKey[i]) { + return false + } + } + return true +} - case findNull: - b := ctr.bats[ctr.preIdx] - hasNull := false - for ; ctr.preRow < b.RowCount(); ctr.preRow++ { - if b.Vecs[idx].IsNull(uint64(ctr.preRow)) { - hasNull = true - break - } - } - ctr.subStatus = findNull - if hasNull { - ctr.status = findValue - } else { - ctr.preIdx++ - ctr.doneIdx[idx] = ctr.preIdx - return nil +// batAt resolves an absolute batch sequence number to its still-pending batch. +func (ctr *container) batAt(seq int) *batch.Batch { + return ctr.bats[seq-ctr.baseSeq] +} + +// pullChild appends the next child batch to the pending FIFO and returns its +// absolute sequence number, or eof when the child is drained. +func (ctr *container) pullChild(ap *Fill, proc *process.Process, analyzer process.Analyzer) (seq int, eof bool, err error) { + result, err := vm.ChildrenCall(ap.GetChildren(0), proc, analyzer) + if err != nil { + return 0, false, err + } + if result.Batch == nil { + return 0, true, nil + } + dup, err := result.Batch.Dup(proc.Mp()) + if err != nil { + return 0, false, err + } + if err = addOriginalNullMarkers(dup, ap.ColLen, proc.Mp()); err != nil { + dup.Clean(proc.Mp()) + return 0, false, err + } + if analyzer != nil { + analyzer.Alloc(int64(dup.Size())) + } + seq = ctr.baseSeq + len(ctr.bats) + ctr.bats = append(ctr.bats, dup) + ctr.pendingBytes += int64(dup.Size()) + ctr.pendingRows += int64(dup.RowCount()) + return seq, false, nil +} + +// emitResolved pops and returns the resolved prefix of the FIFO one batch at a +// time. The popped batch is handed to the caller and freed on the next Call +// (via toFree), because no unresolved coordinate can still reference it. +func (ctr *container) emitResolved(ap *Fill, proc *process.Process) (vm.CallResult, error) { + b := ctr.bats[0] + if ap.FillType == plan.Node_LINEAR && b != nil { + if err := ctr.advanceLinearEntry(ap, b, proc); err != nil { + return vm.NewCallResult(), err + } + } + ctr.bats = ctr.bats[1:] + if b != nil { + ctr.pendingBytes -= int64(b.Size()) + ctr.pendingRows -= int64(b.RowCount()) + } + ctr.baseSeq++ + ctr.flushable-- + ctr.toFree = b + stripOriginalNullMarkers(b, ap.ColLen, proc.Mp()) + result := vm.NewCallResult() + result.Batch = b + result.Status = vm.ExecNext + return result, nil +} + +// advanceLinearEntry moves the endpoint immediately before the pending FIFO +// across one emitted batch. Original-NULL markers are authoritative here: +// interpolated cells are not endpoints, while every original non-NULL cell is. +func (ctr *container) advanceLinearEntry(ap *Fill, bat *batch.Batch, proc *process.Process) error { + for row := 0; row < bat.RowCount(); row++ { + if len(ap.PartitionColIdx) > 0 { + wasSet := ctr.linEntryPart.set + if !ctr.linEntryPart.sameAndSet(ap.PartitionColIdx, bat, row) && wasSet { + clearEndpoints(ctr.linEntryValid) } - case findValue: - ctr.curIdx = ctr.preIdx - ctr.curRow = ctr.preRow - b := ctr.bats[ctr.curIdx] - hasValue := false - for ; ctr.curRow < b.RowCount(); ctr.curRow++ { - if !b.Vecs[idx].IsNull(uint64(ctr.curRow)) { - hasValue = true - break - } + } + for col := 0; col < ap.ColLen; col++ { + if originalNullAt(bat, ap.ColLen, col, row) { + continue } - ctr.subStatus = findValue - if hasValue { - ctr.status = fillValue - } else { - ctr.status = receiveBat + if err := setEndpoint(&ctr.linEntry[col], bat.Vecs[col], row, proc); err != nil { + return err } - case fillValue: - for ; ctr.preIdx < ctr.curIdx-1; ctr.preIdx++ { - for ; ctr.preRow < ctr.bats[ctr.preIdx].RowCount(); ctr.preRow++ { - vec := ctr.bats[ctr.preIdx].Vecs[idx] - if !vec.IsNull(uint64(ctr.preRow)) { - continue - } - err = setValue(vec, ctr.bats[ctr.curIdx].Vecs[idx], ctr.preRow, ctr.curRow, proc) - if err != nil { - return err - } + ctr.linEntryValid[col] = true + } + } + return nil +} - } - if ctr.preRow == ctr.bats[ctr.preRow].RowCount() { - ctr.preRow = 0 - } - } +// isNewSegment reports whether row r of the just-arrived batch opens a new +// partition: row 0 is compared against the key snapshotted from the previous +// batch, later rows against their in-batch predecessor. +func (ctr *container) isNewSegment(ap *Fill, bat *batch.Batch, r int) bool { + if len(ap.PartitionColIdx) == 0 { + return false + } + if r == 0 { + return !ctr.matchesSnapshot(ap.PartitionColIdx, bat, 0) + } + return !samePartitionRows(ap.PartitionColIdx, bat, r-1, bat, r) +} - for ; ctr.preRow < ctr.curRow; ctr.preRow++ { - vec := ctr.bats[ctr.preIdx].Vecs[idx] - if !vec.IsNull(uint64(ctr.preRow)) { - continue - } - err = setValue(vec, ctr.bats[ctr.curIdx].Vecs[idx], ctr.preRow, ctr.curRow, proc) - if err != nil { +// consumeNext folds one freshly pulled batch into the NEXT state: NULLs join +// their column's pending run, a non-NULL back-fills and clears that run, and a +// partition boundary drops the previous partition's pending NULLs (they have no +// next value and stay NULL). +func (ctr *container) consumeNext(ap *Fill, bat *batch.Batch, seq int, proc *process.Process) error { + rows := bat.RowCount() + for r := 0; r < rows; r++ { + if ctr.isNewSegment(ap, bat, r) { + for c := 0; c < ap.ColLen; c++ { + ctr.nextRun[c] = ctr.nextRun[c][:0] + } + } + for c := 0; c < ap.ColLen; c++ { + vec := bat.Vecs[c] + if vec.IsNull(uint64(r)) { + ctr.nextRun[c] = append(ctr.nextRun[c], fillCoord{seq: seq, row: r}) + continue + } + for _, cd := range ctr.nextRun[c] { + if err := setValue(ctr.batAt(cd.seq).Vecs[c], vec, cd.row, r, proc); err != nil { return err } } + ctr.nextRun[c] = ctr.nextRun[c][:0] + } + } + if len(ap.PartitionColIdx) > 0 && rows > 0 { + ctr.snapshotPartKey(ap.PartitionColIdx, bat, rows-1) + } + ctr.recomputeFlushableNext(ap) + return nil +} - ctr.status = findNull - +// recomputeFlushableNext marks every batch before the earliest column still +// awaiting a value as emittable. +func (ctr *container) recomputeFlushableNext(ap *Fill) { + minSeq := ctr.baseSeq + len(ctr.bats) + for c := 0; c < ap.ColLen; c++ { + if len(ctr.nextRun[c]) > 0 && ctr.nextRun[c][0].seq < minSeq { + minSeq = ctr.nextRun[c][0].seq } } + ctr.flushable = minSeq - ctr.baseSeq } func processPrev(ctr *container, ap *Fill, proc *process.Process, analyzer process.Analyzer) (vm.CallResult, error) { @@ -311,10 +407,32 @@ func processPrev(ctr *container, ap *Fill, proc *process.Process, analyzer proce return result, err } + if len(ctr.prevValid) < ap.ColLen { + ctr.prevValid = make([]bool, ap.ColLen) + } + + // A previous value must not leak across a partition boundary, so find + // where new partitions start before filling: row 0 against the key saved + // from the previous batch, later rows against their predecessor. + rowCount := ctr.buf.RowCount() + var newSegment []bool + if len(ap.PartitionColIdx) > 0 && rowCount > 0 { + newSegment = make([]bool, rowCount) + newSegment[0] = !ctr.matchesSnapshot(ap.PartitionColIdx, ctr.buf, 0) + for j := 1; j < rowCount; j++ { + newSegment[j] = !samePartitionRows(ap.PartitionColIdx, ctr.buf, j-1, ctr.buf, j) + } + } + for i := 0; i < ap.ColLen; i++ { for j := 0; j < ctr.buf.Vecs[i].Length(); j++ { + if newSegment != nil && newSegment[j] { + // The new partition has no previous value yet. The vector is + // kept for reuse; only its validity is dropped. + ctr.prevValid[i] = false + } if ctr.buf.Vecs[i].IsNull(uint64(j)) { - if ctr.prevVecs[i] != nil { + if ctr.prevVecs[i] != nil && ctr.prevValid[i] { if err = setValue(ctr.buf.Vecs[i], ctr.prevVecs[i], j, 0, proc); err != nil { return result, err } @@ -331,172 +449,119 @@ func processPrev(ctr *container, ap *Fill, proc *process.Process, analyzer proce return result, err } } - + ctr.prevValid[i] = true } } } + if len(ap.PartitionColIdx) > 0 && rowCount > 0 { + ctr.snapshotPartKey(ap.PartitionColIdx, ctr.buf, rowCount-1) + } result.Batch = ctr.buf return result, nil } -func processLinearCol(ctr *container, ap *Fill, proc *process.Process, idx int, analyzer process.Analyzer) error { - var err error - - ctr.initIndex() - ctr.status = findNullPre - ctr.preIdx = ctr.doneIdx[idx] - - for { - switch ctr.status { - case receiveBat: - if ctr.doneIdx[idx] == len(ctr.bats) || - ctr.endBatch[idx] { - return nil +// consumeLinear folds one freshly pulled batch into the LINEAR state. A NULL +// with a known previous value of the same partition joins that column's run; a +// non-NULL interpolates the pending run against the midpoint of linPre and +// itself, then becomes the new linPre. A run whose neighbour lies across a +// partition boundary stays NULL, because there is nothing to interpolate +// between. +func (ctr *container) consumeLinear(ap *Fill, bat *batch.Batch, seq int, proc *process.Process) error { + rows := bat.RowCount() + for r := 0; r < rows; r++ { + if ctr.isNewSegment(ap, bat, r) { + ctr.clearLinearSeeds(proc.Mp()) + for c := 0; c < ap.ColLen; c++ { + ctr.linRun[c] = ctr.linRun[c][:0] + ctr.linPre[c] = fillCoord{seq: -1, row: -1} } - - result, err := vm.ChildrenCall(ap.GetChildren(0), proc, analyzer) - if err != nil { - return err - } - if result.Batch == nil { - ctr.endBatch[idx] = true - return nil - } else { - if len(ctr.bats) > ctr.i { - if ctr.bats[ctr.i] != nil { - ctr.bats[ctr.i].CleanOnlyData() - } - ctr.bats[ctr.i], err = ctr.bats[ctr.i].AppendWithCopy(proc.Ctx, proc.Mp(), result.Batch) - if err != nil { - return err - } - } else { - appBat, err := result.Batch.Dup(proc.Mp()) - if err != nil { - return err - } - analyzer.Alloc(int64(appBat.Size())) - ctr.bats = append(ctr.bats, appBat) - } - } - - if ctr.subStatus == findNullPre { - ctr.status = findNullPre - } else { - ctr.status = findValue - } - case findNullPre: - b := ctr.bats[ctr.nullIdx] - - if ctr.nullIdx > ctr.preRow { - if b.Vecs[idx].IsNull(uint64(ctr.nullIdx)) { - ctr.status = findValue - continue - } - } - - hasNullPre := false - ctr.preRow = ctr.nullRow - 1 - for ; ctr.nullRow < b.RowCount(); ctr.nullRow++ { - if ctr.preRow >= 0 && b.Vecs[idx].IsNull(uint64(ctr.nullRow)) && !b.Vecs[idx].IsNull(uint64(ctr.preRow)) { - hasNullPre = true - break - } - ctr.preRow++ - } - - ctr.subStatus = findNullPre - if hasNullPre { - ctr.status = findValue - } else { - ctr.nullIdx++ - ctr.nullRow = 0 - ctr.doneIdx[idx] = ctr.nullIdx - if b.Vecs[idx].IsNull(uint64(ctr.preRow)) { - ctr.preIdx++ - ctr.nullRow = 0 - ctr.doneIdx[idx] = ctr.preIdx + } + for c := 0; c < ap.ColLen; c++ { + vec := bat.Vecs[c] + if vec.IsNull(uint64(r)) { + seedValid := c < len(ctr.linSeedValid) && ctr.linSeedValid[c] + if ctr.linPre[c].seq >= 0 || seedValid { + ctr.linRun[c] = append(ctr.linRun[c], fillCoord{seq: seq, row: r}) } - return nil + continue } - case findValue: - ctr.curIdx = ctr.nullIdx - ctr.curRow = ctr.nullRow - b := ctr.bats[ctr.curIdx] - hasValue := false - for ; ctr.curRow < b.RowCount(); ctr.curRow++ { - if !b.Vecs[idx].IsNull(uint64(ctr.curRow)) { - hasValue = true - break + if len(ctr.linRun[c]) > 0 { + if err := ctr.interpolateRun(c, ctr.linPre[c], seq, r, proc); err != nil { + return err } + ctr.linRun[c] = ctr.linRun[c][:0] } - ctr.subStatus = findValue - if hasValue { - ctr.status = fillValue - } else { - ctr.status = receiveBat + if c < len(ctr.linSeed) && ctr.linSeed[c] != nil { + ctr.linSeed[c].Free(proc.Mp()) + ctr.linSeed[c] = nil } - case fillValue: - var valVec *vector.Vector - var owned bool - valVec, owned, err = linearFillValue(ctr, proc, idx) - if err != nil { - return err - } - - ctr.preRow++ - for ; ctr.preIdx < ctr.curIdx-1; ctr.preIdx++ { - for ; ctr.preRow < ctr.bats[ctr.preIdx].RowCount(); ctr.preRow++ { - - vec := ctr.bats[ctr.preIdx].Vecs[idx] - if !vec.IsNull(uint64(ctr.preRow)) { - continue - } - err = setValue(vec, valVec, ctr.preRow, 0, proc) - if err != nil { - if owned { - valVec.Free(proc.Mp()) - } - return err - } - - } - if ctr.preRow == ctr.bats[ctr.preRow].RowCount() { - ctr.preRow = 0 - } + if c < len(ctr.linSeedValid) { + ctr.linSeedValid[c] = false } + ctr.linPre[c] = fillCoord{seq: seq, row: r} + } + } + if len(ap.PartitionColIdx) > 0 && rows > 0 { + ctr.snapshotPartKey(ap.PartitionColIdx, bat, rows-1) + } + ctr.recomputeFlushableLinear(ap) + return nil +} - for ; ctr.preRow < ctr.curRow; ctr.preRow++ { - vec := ctr.bats[ctr.preIdx].Vecs[idx] - if !vec.IsNull(uint64(ctr.preRow)) { - continue - } - err = setValue(vec, valVec, ctr.preRow, 0, proc) - if err != nil { - if owned { - valVec.Free(proc.Mp()) - } - return err - } - } +// interpolateRun writes the midpoint of the pre and cur values into every row +// of column col's pending run. +func (ctr *container) interpolateRun(col int, pre fillCoord, curSeq, curRow int, proc *process.Process) error { + var preBatch *batch.Batch + preRow := pre.row + if pre.seq >= 0 { + preBatch = ctr.batAt(pre.seq) + } else { + preBatch = batch.NewWithSize(col + 1) + preBatch.SetVector(int32(col), ctr.linSeed[col]) + preBatch.SetRowCount(1) + preRow = 0 + } + valVec, owned, err := linearFillValue(ctr, proc, col, preBatch, preRow, ctr.batAt(curSeq), curRow) + if err != nil { + return err + } + for _, cd := range ctr.linRun[col] { + if err = setValue(ctr.batAt(cd.seq).Vecs[col], valVec, cd.row, 0, proc); err != nil { if owned { valVec.Free(proc.Mp()) } + return err + } + } + if owned { + valVec.Free(proc.Mp()) + } + return nil +} - ctr.nullIdx = ctr.preIdx - ctr.nullRow = ctr.preRow - ctr.status = findNullPre +// recomputeFlushableLinear marks batches as emittable up to the earliest one +// still needed: a pending run, or a linPre that a later non-NULL might yet pair +// with. linPre therefore pins its batch until the next non-NULL supersedes it. +func (ctr *container) recomputeFlushableLinear(ap *Fill) { + minSeq := ctr.baseSeq + len(ctr.bats) + for c := 0; c < ap.ColLen; c++ { + if ctr.linPre[c].seq >= 0 && ctr.linPre[c].seq < minSeq { + minSeq = ctr.linPre[c].seq + } + if len(ctr.linRun[c]) > 0 && ctr.linRun[c][0].seq < minSeq { + minSeq = ctr.linRun[c][0].seq } } + ctr.flushable = minSeq - ctr.baseSeq } -func linearFillValue(ctr *container, proc *process.Process, idx int) (*vector.Vector, bool, error) { - preVec := ctr.bats[ctr.preIdx].Vecs[idx] - curVec := ctr.bats[ctr.curIdx].Vecs[idx] +func linearFillValue(ctr *container, proc *process.Process, idx int, preBatch *batch.Batch, preRow int, curBatch *batch.Batch, curRow int) (*vector.Vector, bool, error) { + preVec := preBatch.Vecs[idx] + curVec := curBatch.Vecs[idx] if preVec.GetType().Oid == types.T_decimal128 && curVec.GetType().Oid == types.T_decimal128 { result := vector.NewVec(*preVec.GetType()) - left := vector.GetFixedAtNoTypeCheck[types.Decimal128](preVec, ctr.preRow) - right := vector.GetFixedAtNoTypeCheck[types.Decimal128](curVec, ctr.curRow) + left := vector.GetFixedAtNoTypeCheck[types.Decimal128](preVec, preRow) + right := vector.GetFixedAtNoTypeCheck[types.Decimal128](curVec, curRow) value, err := decimal128LinearMidpoint(left, right, preVec.GetType().Scale) if err != nil { result.Free(proc.Mp()) @@ -511,16 +576,17 @@ func linearFillValue(ctr *container, proc *process.Process, idx int) (*vector.Ve b := batch.NewWithSize(2) b.Vecs[0] = vector.NewVec(*preVec.GetType()) - if err := appendValue(b.Vecs[0], preVec, ctr.preRow, proc); err != nil { + if err := appendValue(b.Vecs[0], preVec, preRow, proc); err != nil { b.Clean(proc.Mp()) return nil, false, err } b.Vecs[1] = vector.NewVec(*curVec.GetType()) - if err := appendValue(b.Vecs[1], curVec, ctr.curRow, proc); err != nil { + if err := appendValue(b.Vecs[1], curVec, curRow, proc); err != nil { b.Clean(proc.Mp()) return nil, false, err } b.SetRowCount(1) + defer b.Clean(proc.Mp()) result, err := ctr.exes[idx].Eval(proc, []*batch.Batch{b}, nil) return result, false, err } @@ -538,123 +604,99 @@ func decimal128LinearMidpoint(left, right types.Decimal128, scale int32) (types. } func processNext(ctr *container, ap *Fill, proc *process.Process, analyzer process.Analyzer) (vm.CallResult, error) { - var err error - result := vm.NewCallResult() - if ctr.done { - if ctr.idx == len(ctr.bats) { - result.Batch = nil - result.Status = vm.ExecStop - return result, nil - } - result.Batch = ctr.bats[ctr.idx] - result.Status = vm.ExecNext - ctr.idx++ - return result, nil - } - for ; ctr.i < 1; ctr.i++ { - result, err = vm.ChildrenCall(ap.GetChildren(0), proc, analyzer) - if err != nil { - return result, err - } - if result.Batch == nil { - break - } - if len(ctr.bats) > ctr.i { - if ctr.bats[ctr.i] != nil { - ctr.bats[ctr.i].CleanOnlyData() - } - ctr.bats[ctr.i], err = ctr.bats[ctr.i].AppendWithCopy(proc.Ctx, proc.Mp(), result.Batch) - if err != nil { - return result, err - } - } else { - appBat, err := result.Batch.Dup(proc.Mp()) - if err != nil { - return result, err - } - analyzer.Alloc(int64(appBat.Size())) - ctr.bats = append(ctr.bats, appBat) - } - ctr.doneIdx = make([]int, ctr.bats[0].VectorCount()) - ctr.endBatch = make([]bool, ctr.bats[0].VectorCount()) - } - if len(ctr.bats) == 0 { - result.Batch = nil - result.Status = vm.ExecStop - return result, nil - } - - for i := range ctr.bats[0].Vecs { - if err = processNextCol(ctr, ap, i, proc, analyzer); err != nil { - return result, err - } - } - ctr.done = true - result.Batch = ctr.bats[ctr.idx] - result.Status = vm.ExecNext - ctr.idx++ - - return result, nil + return ctr.driveFill(ap, proc, analyzer, (*container).consumeNext, (*container).flushPendingRunsNext) } func processLinear(ctr *container, ap *Fill, proc *process.Process, analyzer process.Analyzer) (vm.CallResult, error) { - var err error - result := vm.NewCallResult() - if ctr.done { - if ctr.idx == len(ctr.bats) { - result.Batch = nil - result.Status = vm.ExecStop - return result, nil + return ctr.driveFill(ap, proc, analyzer, (*container).consumeLinear, (*container).flushPendingRunsLinear) +} + +// driveFill is the shared incremental loop for NEXT and LINEAR. It emits the +// resolved batch prefix as soon as it exists — only ever buffering batches that +// still contain a row whose value depends on a not-yet-seen input — and calls +// the child again only when nothing is emittable, so a no-NULL stream flows +// through without ever materializing more than the batch in flight. +func (ctr *container) driveFill( + ap *Fill, proc *process.Process, analyzer process.Analyzer, + consume func(*container, *Fill, *batch.Batch, int, *process.Process) error, + flushPendingRuns func(*container, *Fill), +) (vm.CallResult, error) { + // The batch returned last Call has been consumed by the parent by now. + if ctr.toFree != nil { + ctr.toFree.Clean(proc.Mp()) + ctr.toFree = nil + } + if ctr.spill != nil { + if !ctr.spill.ready { + if err := ctr.collectSpill(ap, proc, analyzer); err != nil { + ctr.cleanupSpill(proc) + return vm.NewCallResult(), err + } + } + bat, err := ctr.spill.replayNext(ctr, ap, proc) + if err == io.EOF { + if err = ctr.finishSpillReplay(ap, proc); err != nil { + return vm.NewCallResult(), err + } + return ctr.driveFill(ap, proc, analyzer, consume, flushPendingRuns) } - result.Batch = ctr.bats[ctr.idx] + if err != nil { + ctr.cleanupSpill(proc) + return vm.NewCallResult(), err + } + result := vm.NewCallResult() + result.Batch = bat result.Status = vm.ExecNext - ctr.idx++ return result, nil } - for ; ctr.i < 1; ctr.i++ { - result, err = vm.ChildrenCall(ap.GetChildren(0), proc, analyzer) + for { + if ctr.flushable > 0 { + return ctr.emitResolved(ap, proc) + } + if ctr.childDone { + if len(ctr.bats) == 0 { + result := vm.NewCallResult() + result.Batch = nil + result.Status = vm.ExecStop + return result, nil + } + // End of input: whatever is still pending has no future value to + // wait for, so it stays NULL and the whole tail becomes emittable. + flushPendingRuns(ctr, ap) + ctr.flushable = len(ctr.bats) + continue + } + seq, eof, err := ctr.pullChild(ap, proc, analyzer) if err != nil { - return result, err + return vm.NewCallResult(), err } - if result.Batch == nil { - break + if eof { + ctr.childDone = true + continue } - - if len(ctr.bats) > ctr.i { - if ctr.bats[ctr.i] != nil { - ctr.bats[ctr.i].CleanOnlyData() - } - ctr.bats[ctr.i], err = ctr.bats[ctr.i].AppendWithCopy(proc.Ctx, proc.Mp(), result.Batch) - if err != nil { - return result, err - } - } else { - appBat, err := result.Batch.Dup(proc.Mp()) - if err != nil { - return result, err + if err = consume(ctr, ap, ctr.batAt(seq), seq, proc); err != nil { + return vm.NewCallResult(), err + } + if ctr.flushable == 0 && ctr.shouldSpillPending() { + if err = ctr.beginSpill(ap, proc); err != nil { + return vm.NewCallResult(), err } - analyzer.Alloc(int64(appBat.Size())) - ctr.bats = append(ctr.bats, appBat) + return ctr.driveFill(ap, proc, analyzer, consume, flushPendingRuns) } - ctr.doneIdx = make([]int, ctr.bats[0].VectorCount()) - ctr.endBatch = make([]bool, ctr.bats[0].VectorCount()) } - if len(ctr.bats) == 0 { - result.Batch = nil - result.Status = vm.ExecStop - return result, nil - } - for i := range ctr.bats[0].Vecs { - if err = processLinearCol(ctr, ap, proc, i, analyzer); err != nil { - return result, err - } +} + +func (ctr *container) flushPendingRunsNext(ap *Fill) { + for c := 0; c < ap.ColLen; c++ { + ctr.nextRun[c] = ctr.nextRun[c][:0] } - ctr.done = true - result.Batch = ctr.bats[ctr.idx] - result.Status = vm.ExecNext - ctr.idx++ +} - return result, nil +func (ctr *container) flushPendingRunsLinear(ap *Fill) { + for c := 0; c < ap.ColLen; c++ { + ctr.linRun[c] = ctr.linRun[c][:0] + ctr.linPre[c] = fillCoord{seq: -1, row: -1} + } } func processDefault(ctr *container, ap *Fill, proc *process.Process, analyzer process.Analyzer) (vm.CallResult, error) { diff --git a/pkg/sql/colexec/fill/fill_test.go b/pkg/sql/colexec/fill/fill_test.go index 28d50f4cd96a6..e0032057b3234 100644 --- a/pkg/sql/colexec/fill/fill_test.go +++ b/pkg/sql/colexec/fill/fill_test.go @@ -18,8 +18,6 @@ import ( "bytes" "testing" - "github.com/matrixorigin/matrixone/pkg/sql/plan/function" - "github.com/matrixorigin/matrixone/pkg/common/mpool" "github.com/matrixorigin/matrixone/pkg/container/batch" "github.com/matrixorigin/matrixone/pkg/container/types" @@ -43,7 +41,6 @@ func makeTestCases(t *testing.T) []fillTestCase { { proc: testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()), arg: &Fill{ - AggIds: []int32{function.MAX}, FillType: plan.Node_VALUE, FillVal: []*plan.Expr{ { @@ -70,7 +67,6 @@ func makeTestCases(t *testing.T) []fillTestCase { { proc: testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()), arg: &Fill{ - AggIds: []int32{function.MAX}, FillType: plan.Node_PREV, FillVal: []*plan.Expr{ { @@ -97,7 +93,6 @@ func makeTestCases(t *testing.T) []fillTestCase { { proc: testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()), arg: &Fill{ - AggIds: []int32{function.MAX}, FillType: plan.Node_NONE, FillVal: []*plan.Expr{ { @@ -125,7 +120,6 @@ func makeTestCases(t *testing.T) []fillTestCase { { proc: testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()), arg: &Fill{ - AggIds: []int32{function.MAX}, FillType: plan.Node_NEXT, FillVal: []*plan.Expr{ { @@ -152,7 +146,6 @@ func makeTestCases(t *testing.T) []fillTestCase { { proc: testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()), arg: &Fill{ - AggIds: []int32{function.MAX}, FillType: plan.Node_LINEAR, FillVal: []*plan.Expr{ { @@ -234,10 +227,10 @@ func TestProcessLinearDecimal128(t *testing.T) { arg := &Fill{ColLen: 1, FillType: plan.Node_LINEAR} ctr := &arg.ctr ctr.bats = []*batch.Batch{bat} - ctr.doneIdx = make([]int, 1) - ctr.endBatch = make([]bool, 1) + ctr.linRun = make([][]fillCoord, 1) + ctr.linPre = []fillCoord{{seq: -1, row: -1}} - require.NoError(t, processLinearCol(ctr, arg, proc, 0, nil)) + require.NoError(t, ctr.consumeLinear(arg, bat, 0, proc)) require.False(t, vec.IsNull(1)) require.Equal(t, types.Decimal128FromInt64(200), vector.GetFixedAtNoTypeCheck[types.Decimal128](vec, 1)) } @@ -1151,17 +1144,13 @@ func TestLinearFillValueUsesExpressionForNonDecimal128(t *testing.T) { defer resultVec.Free(proc.Mp()) ctr := &container{ - bats: []*batch.Batch{input}, - preIdx: 0, - preRow: 0, - curIdx: 0, - curRow: 2, + bats: []*batch.Batch{input}, exes: []colexec.ExpressionExecutor{ &fillStubExpressionExecutor{result: resultVec}, }, } - vec, owned, err := linearFillValue(ctr, proc, 0) + vec, owned, err := linearFillValue(ctr, proc, 0, input, 0, input, 2) require.NoError(t, err) require.False(t, owned) require.Same(t, resultVec, vec) diff --git a/pkg/sql/colexec/fill/partition_test.go b/pkg/sql/colexec/fill/partition_test.go new file mode 100644 index 0000000000000..d84e7669e18d2 --- /dev/null +++ b/pkg/sql/colexec/fill/partition_test.go @@ -0,0 +1,206 @@ +// Copyright 2021 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fill + +import ( + "testing" + + "github.com/matrixorigin/matrixone/pkg/common/mpool" + "github.com/matrixorigin/matrixone/pkg/container/batch" + "github.com/matrixorigin/matrixone/pkg/container/types" + "github.com/matrixorigin/matrixone/pkg/container/vector" + "github.com/matrixorigin/matrixone/pkg/pb/plan" + "github.com/matrixorigin/matrixone/pkg/sql/colexec" + "github.com/matrixorigin/matrixone/pkg/testutil" + "github.com/matrixorigin/matrixone/pkg/vm" + "github.com/matrixorigin/matrixone/pkg/vm/process" + "github.com/stretchr/testify/require" +) + +// partitionedBatch builds one input batch shaped (val int64 nullable, part int64). +// nullRows lists the val rows that are NULL. +func partitionedBatch(mp *mpool.MPool, vals []int64, nullRows []uint64, parts []int64) *batch.Batch { + bat := batch.NewWithSize(2) + bat.SetVector(0, testutil.MakeInt64Vector(vals, nullRows, mp)) + bat.SetVector(1, testutil.MakeInt64Vector(parts, nil, mp)) + bat.SetRowCount(len(vals)) + return bat +} + +// runFill drives the operator to exhaustion and returns the val column as +// (values, isNull) per row across every output batch. +func runFill(t *testing.T, proc *process.Process, fillType plan.Node_FillType, bats []*batch.Batch) (vals []int64, nulls []bool) { + t.Helper() + arg := &Fill{ + ColLen: 1, + FillType: fillType, + PartitionColIdx: []int32{1}, + } + arg.AppendChild(colexec.NewMockOperator().WithBatchs(bats)) + require.NoError(t, arg.Prepare(proc)) + defer arg.Free(proc, false, nil) + + for { + res, err := arg.Call(proc) + require.NoError(t, err) + if res.Batch == nil { + break + } + vec := res.Batch.Vecs[0] + for r := 0; r < res.Batch.RowCount(); r++ { + if vec.IsNull(uint64(r)) { + nulls = append(nulls, true) + vals = append(vals, 0) + } else { + nulls = append(nulls, false) + vals = append(vals, vector.GetFixedAtNoTypeCheck[int64](vec, r)) + } + } + if res.Status == vm.ExecStop { + break + } + } + return +} + +// fill(prev) must not carry the last value of one partition into the next: +// the first window of a new partition has no previous value. +func TestFillPrevStopsAtPartitionBoundary(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + defer proc.Free() + + // batch 1: partition 1 = [10, NULL]; batch 2: partition 2 = [NULL, 30] + bats := []*batch.Batch{ + partitionedBatch(proc.Mp(), []int64{10, 0}, []uint64{1}, []int64{1, 1}), + partitionedBatch(proc.Mp(), []int64{0, 30}, []uint64{0}, []int64{2, 2}), + } + defer func() { + for _, b := range bats { + b.Clean(proc.Mp()) + } + }() + + vals, nulls := runFill(t, proc, plan.Node_PREV, bats) + require.Equal(t, []bool{false, false, true, false}, nulls, + "partition 2's leading NULL has no previous value and must stay NULL") + require.Equal(t, int64(10), vals[1], "within partition 1 the previous value fills") + require.Equal(t, int64(30), vals[3]) +} + +// The boundary must also hold inside a single batch: the non-sliding window +// forwards rows of several partitions in one batch. +func TestFillPrevPartitionBoundaryWithinBatch(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + defer proc.Free() + + bats := []*batch.Batch{ + partitionedBatch(proc.Mp(), []int64{10, 0, 0, 30}, []uint64{1, 2}, []int64{1, 1, 2, 2}), + } + defer bats[0].Clean(proc.Mp()) + + vals, nulls := runFill(t, proc, plan.Node_PREV, bats) + require.Equal(t, []bool{false, false, true, false}, nulls) + require.Equal(t, int64(10), vals[1]) +} + +// fill(next) is the mirror image: the trailing NULLs of a partition have no +// next value, because the following rows belong to another group. +func TestFillNextStopsAtPartitionBoundary(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + defer proc.Free() + + // partition 1 = [NULL, 10, NULL]; partition 2 = [20, NULL] + bats := []*batch.Batch{ + partitionedBatch(proc.Mp(), []int64{0, 10, 0}, []uint64{0, 2}, []int64{1, 1, 1}), + partitionedBatch(proc.Mp(), []int64{20, 0}, []uint64{1}, []int64{2, 2}), + } + defer func() { + for _, b := range bats { + b.Clean(proc.Mp()) + } + }() + + vals, nulls := runFill(t, proc, plan.Node_NEXT, bats) + require.Equal(t, []bool{false, false, true, false, true}, nulls, + "trailing NULLs of each partition must stay NULL") + require.Equal(t, int64(10), vals[0], "within partition 1 the next value fills backwards") +} + +// A batch containing no NULL must not end the scan: batches after it still +// need their NULLs filled. The old streaming state machine dropped them. +func TestFillNextConsumesBatchesAfterNullFreeBatch(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + defer proc.Free() + + bats := []*batch.Batch{ + partitionedBatch(proc.Mp(), []int64{1, 2}, nil, []int64{1, 1}), + partitionedBatch(proc.Mp(), []int64{0, 9}, []uint64{0}, []int64{1, 1}), + } + defer func() { + for _, b := range bats { + b.Clean(proc.Mp()) + } + }() + + vals, nulls := runFill(t, proc, plan.Node_NEXT, bats) + require.Len(t, vals, 4, "every input row must be emitted") + require.Equal(t, []bool{false, false, false, false}, nulls) + require.Equal(t, int64(9), vals[2]) +} + +// fill(linear) needs a neighbour on both sides inside the same partition. +// decimal128 exercises the built-in midpoint path, which needs no expression +// executor. +func TestFillLinearStopsAtPartitionBoundary(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + defer proc.Free() + + // One batch, two partitions: [10, NULL, 30, NULL | NULL, 100]. + // The NULL at the tail of partition 1 has no following value in its + // partition, and partition 2's leading NULL has no previous one: without + // the boundary, linear would interpolate 30 and 100 across the groups. + typ := types.New(types.T_decimal128, 38, 0) + valVec := vector.NewVec(typ) + set := func(v int64, isNull bool) { + require.NoError(t, vector.AppendFixed(valVec, types.Decimal128FromInt64(v), isNull, proc.Mp())) + } + set(10, false) + set(0, true) + set(30, false) + set(0, true) + set(0, true) + set(100, false) + + bat := batch.NewWithSize(2) + bat.SetVector(0, valVec) + bat.SetVector(1, testutil.MakeInt64Vector([]int64{1, 1, 1, 1, 2, 2}, nil, proc.Mp())) + bat.SetRowCount(6) + defer bat.Clean(proc.Mp()) + + arg := &Fill{ColLen: 1, FillType: plan.Node_LINEAR, PartitionColIdx: []int32{1}} + ctr := &arg.ctr + ctr.bats = []*batch.Batch{bat} + ctr.linRun = make([][]fillCoord, 1) + ctr.linPre = []fillCoord{{seq: -1, row: -1}} + + require.NoError(t, ctr.consumeLinear(arg, bat, 0, proc)) + + require.False(t, valVec.IsNull(1)) + require.Equal(t, types.Decimal128FromInt64(20), + vector.GetFixedAtNoTypeCheck[types.Decimal128](valVec, 1), "midpoint of 10 and 30") + require.True(t, valVec.IsNull(3), "partition 1's trailing NULL must stay NULL") + require.True(t, valVec.IsNull(4), "partition 2's leading NULL must stay NULL") + require.False(t, valVec.IsNull(5)) +} diff --git a/pkg/sql/colexec/fill/spill.go b/pkg/sql/colexec/fill/spill.go new file mode 100644 index 0000000000000..9f395a07932ad --- /dev/null +++ b/pkg/sql/colexec/fill/spill.go @@ -0,0 +1,757 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fill + +import ( + "bytes" + "fmt" + "io" + "os" + + "github.com/google/uuid" + "github.com/matrixorigin/matrixone/pkg/common/moerr" + "github.com/matrixorigin/matrixone/pkg/common/mpool" + "github.com/matrixorigin/matrixone/pkg/container/batch" + "github.com/matrixorigin/matrixone/pkg/container/types" + "github.com/matrixorigin/matrixone/pkg/container/vector" + "github.com/matrixorigin/matrixone/pkg/pb/plan" + "github.com/matrixorigin/matrixone/pkg/sql/colexec" + "github.com/matrixorigin/matrixone/pkg/vm" + "github.com/matrixorigin/matrixone/pkg/vm/process" +) + +const fillSpillMagic = uint64(0x46494c4c5350494c) + +type fillSpill struct { + input *os.File + output *os.File + next *os.File + buf bytes.Buffer + + outputReversePos int64 + ready bool + inputRecords int + outputRecords int + replay *batch.Batch + segmentPending []int64 + segmentLeftValid []bool + segmentStart int64 + segmentRows int64 + safeWatermark int64 + safeRows int64 + hasSuffix bool + linearLeft []*vector.Vector + linearLeftValid []bool + forwardPart spillPartitionSnapshot +} + +type spillPartitionSnapshot struct { + keys [][]byte + nulls []bool + set bool +} + +func (s *spillPartitionSnapshot) cloneFrom(src *spillPartitionSnapshot) { + *s = spillPartitionSnapshot{set: src.set} + if len(src.keys) > 0 { + s.keys = make([][]byte, len(src.keys)) + for i := range src.keys { + s.keys[i] = append([]byte(nil), src.keys[i]...) + } + } + s.nulls = append([]bool(nil), src.nulls...) +} + +func addOriginalNullMarkers(bat *batch.Batch, colLen int, mp *mpool.MPool) error { + rows := bat.RowCount() + for c := 0; c < colLen; c++ { + marker := vector.NewVec(types.T_bool.ToType()) + values := make([]bool, rows) + for r := 0; r < rows; r++ { + values[r] = bat.Vecs[c].IsNull(uint64(r)) + } + if err := vector.AppendFixedList(marker, values, nil, mp); err != nil { + marker.Free(mp) + return err + } + bat.Vecs = append(bat.Vecs, marker) + bat.Attrs = append(bat.Attrs, "") + } + return nil +} + +func stripOriginalNullMarkers(bat *batch.Batch, colLen int, mp *mpool.MPool) { + if bat == nil || colLen == 0 || len(bat.Vecs) < colLen { + return + } + start := len(bat.Vecs) - colLen + for _, vec := range bat.Vecs[start:] { + if vec != nil { + vec.Free(mp) + } + } + bat.Vecs = bat.Vecs[:start] + if len(bat.Attrs) >= colLen { + bat.Attrs = bat.Attrs[:len(bat.Attrs)-colLen] + } +} + +func originalNullAt(bat *batch.Batch, colLen, col, row int) bool { + marker := bat.Vecs[len(bat.Vecs)-colLen+col] + return vector.GetFixedAtNoTypeCheck[bool](marker, row) +} + +func newFillSpill(proc *process.Process) (*fillSpill, error) { + fs, err := proc.GetSpillFileService() + if err != nil { + return nil, err + } + input, err := fs.CreateAndRemoveFile(proc.Ctx, fmt.Sprintf("fill_%s_in", uuid.NewString())) + if err != nil { + return nil, err + } + return &fillSpill{input: input}, nil +} + +func (s *fillSpill) ensureOutput(proc *process.Process) error { + if s.output != nil { + return nil + } + fs, err := proc.GetSpillFileService() + if err != nil { + return err + } + s.output, err = fs.CreateAndRemoveFile(proc.Ctx, fmt.Sprintf("fill_%s_out", uuid.NewString())) + return err +} + +func (s *fillSpill) ensureNext(proc *process.Process) error { + if s.next != nil { + return nil + } + fs, err := proc.GetSpillFileService() + if err != nil { + return err + } + s.next, err = fs.CreateAndRemoveFile(proc.Ctx, fmt.Sprintf("fill_%s_next", uuid.NewString())) + return err +} + +func (s *fillSpill) writeRecord(fd *os.File, bat *batch.Batch) error { + s.buf.Reset() + var zero int64 + s.buf.Write(types.EncodeInt64(&zero)) + start := s.buf.Len() + if _, err := bat.MarshalBinaryWithBuffer(&s.buf, false); err != nil { + return err + } + size := int64(s.buf.Len() - start) + copy(s.buf.Bytes()[:8], types.EncodeInt64(&size)) + s.buf.Write(types.EncodeInt64(&size)) + magic := fillSpillMagic + s.buf.Write(types.EncodeUint64(&magic)) + n, err := fd.Write(s.buf.Bytes()) + if err != nil { + return err + } + if n != s.buf.Len() { + return io.ErrShortWrite + } + return nil +} + +func readRecordReverse(fd *os.File, pos *int64, mp *mpool.MPool, reuse *batch.Batch) (*batch.Batch, error) { + if *pos < 0 { + end, err := fd.Seek(0, io.SeekEnd) + if err != nil { + return nil, err + } + *pos = end + } + if *pos == 0 { + return nil, io.EOF + } + if *pos < 24 { + return nil, moerr.NewInternalErrorNoCtx("truncated fill spill record") + } + var tail [16]byte + if _, err := fd.ReadAt(tail[:], *pos-16); err != nil { + return nil, err + } + size := types.DecodeInt64(tail[:8]) + if types.DecodeUint64(tail[8:]) != fillSpillMagic || size < 0 { + return nil, moerr.NewInternalErrorNoCtx("corrupted fill spill record") + } + start := *pos - size - 24 + if start < 0 { + return nil, moerr.NewInternalErrorNoCtx("invalid fill spill record size") + } + var head [8]byte + if _, err := fd.ReadAt(head[:], start); err != nil { + return nil, err + } + if types.DecodeInt64(head[:]) != size { + return nil, moerr.NewInternalErrorNoCtx("fill spill record length mismatch") + } + section := io.NewSectionReader(fd, start+8, size) + allocated := reuse == nil + if reuse == nil { + reuse = batch.NewWithSize(0) + } else { + reuse.CleanOnlyData() + } + if err := reuse.UnmarshalFromReader(section, mp); err != nil { + if allocated { + reuse.Clean(mp) + } + return nil, err + } + consumed, err := section.Seek(0, io.SeekCurrent) + if err != nil { + if allocated { + reuse.Clean(mp) + } + return nil, err + } + if consumed != size { + if allocated { + reuse.Clean(mp) + } + return nil, moerr.NewInternalErrorNoCtx("fill spill record payload length mismatch") + } + *pos = start + return reuse, nil +} + +func (s *fillSpill) close(proc *process.Process) { + if s == nil { + return + } + if s.input != nil { + _ = s.input.Close() + s.input = nil + } + if s.output != nil { + _ = s.output.Close() + s.output = nil + } + if s.next != nil { + _ = s.next.Close() + s.next = nil + } + if s.replay != nil { + s.replay.Clean(proc.Mp()) + s.replay = nil + } + for _, vec := range s.linearLeft { + if vec != nil { + vec.Free(proc.Mp()) + } + } + s.linearLeft = nil + s.linearLeftValid = nil +} + +func (ctr *container) cleanupSpill(proc *process.Process) { + if ctr.spill != nil { + ctr.spill.close(proc) + ctr.spill = nil + } +} + +func (s *spillPartitionSnapshot) sameAndSet(partIdx []int32, bat *batch.Batch, row int) bool { + same := s.set + if cap(s.keys) < len(partIdx) { + s.keys = make([][]byte, len(partIdx)) + s.nulls = make([]bool, len(partIdx)) + } + s.keys = s.keys[:len(partIdx)] + s.nulls = s.nulls[:len(partIdx)] + for i, col := range partIdx { + value, isNull := partKeyAt(bat.Vecs[col], row) + if s.set && (isNull != s.nulls[i] || (!isNull && !bytes.Equal(value, s.keys[i]))) { + same = false + } + s.nulls[i] = isNull + s.keys[i] = append(s.keys[i][:0], value...) + } + s.set = true + return same +} + +func makeEndpoint(vec *vector.Vector, row int, proc *process.Process) (*vector.Vector, error) { + result := vector.NewVec(*vec.GetType()) + if err := appendValue(result, vec, row, proc); err != nil { + result.Free(proc.Mp()) + return nil, err + } + return result, nil +} + +func setEndpoint(dst **vector.Vector, src *vector.Vector, row int, proc *process.Process) error { + if *dst == nil { + var err error + *dst, err = makeEndpoint(src, row, proc) + return err + } + return setValue(*dst, src, 0, row, proc) +} + +func clearEndpoints(valid []bool) { + for i := range valid { + valid[i] = false + } +} + +func cloneBatchWindow(bat *batch.Batch, start, end int, mp *mpool.MPool) (*batch.Batch, error) { + result := batch.NewWithSize(len(bat.Vecs)) + result.Attrs = append(result.Attrs, bat.Attrs...) + for i, vec := range bat.Vecs { + cloned, err := vec.CloneWindow(start, end, mp) + if err != nil { + result.Clean(mp) + return nil, err + } + result.SetVector(int32(i), cloned) + } + result.SetRowCount(end - start) + return result, nil +} + +func (s *fillSpill) transformReverse(ap *Fill, proc *process.Process) error { + if err := s.ensureOutput(proc); err != nil { + return err + } + pos := int64(-1) + var reuse *batch.Batch + next := make([]*vector.Vector, ap.ColLen) + valid := make([]bool, ap.ColLen) + defer func() { + if reuse != nil { + reuse.Clean(proc.Mp()) + } + for _, vec := range next { + if vec != nil { + vec.Free(proc.Mp()) + } + } + }() + var part spillPartitionSnapshot + for { + bat, err := readRecordReverse(s.input, &pos, proc.Mp(), reuse) + if err == io.EOF { + break + } + if err != nil { + return err + } + reuse = bat + for row := bat.RowCount() - 1; row >= 0; row-- { + if len(ap.PartitionColIdx) > 0 && !part.sameAndSet(ap.PartitionColIdx, bat, row) { + clearEndpoints(valid) + } + for col := 0; col < ap.ColLen; col++ { + if originalNullAt(bat, ap.ColLen, col, row) { + if valid[col] { + if err = setValue(bat.Vecs[col], next[col], row, 0, proc); err != nil { + return err + } + } else { + bat.Vecs[col].GetNulls().Add(uint64(row)) + } + continue + } + if err = setEndpoint(&next[col], bat.Vecs[col], row, proc); err != nil { + return err + } + valid[col] = true + } + } + if err = s.writeRecord(s.output, bat); err != nil { + return err + } + s.outputRecords++ + } + if _, err := s.output.Seek(0, io.SeekEnd); err != nil { + return err + } + s.outputReversePos = -1 + if ap.FillType == plan.Node_LINEAR { + if len(s.linearLeft) < ap.ColLen { + s.linearLeft = make([]*vector.Vector, ap.ColLen) + } + if len(s.linearLeftValid) < ap.ColLen { + s.linearLeftValid = make([]bool, ap.ColLen) + } + } + s.ready = true + return nil +} + +func (ctr *container) shouldSpillPending() bool { + return colexec.ShouldSpill(ctr.pendingBytes, ctr.pendingRows, ctr.spillThreshold) +} + +func (s *fillSpill) updateSafeWatermark() { + watermark := s.segmentRows + for _, pending := range s.segmentPending { + if pending >= 0 && pending < watermark { + watermark = pending + } + } + if watermark > s.safeWatermark { + s.safeWatermark = watermark + } +} + +// scanSegment advances the earliest unresolved logical row for every fill +// column. The minimum of those positions is a safe output watermark: later +// rows may still be pending, but they cannot change anything before it. +func (s *fillSpill) scanSegment(ctr *container, ap *Fill, bat *batch.Batch) { + for row := 0; row < bat.RowCount(); row++ { + logicalRow := s.segmentRows + if ctr.isNewSegment(ap, bat, row) { + for col := range s.segmentPending { + s.segmentPending[col] = -1 + s.segmentLeftValid[col] = false + } + } + for col := 0; col < ap.ColLen; col++ { + isNull := originalNullAt(bat, ap.ColLen, col, row) + switch ap.FillType { + case plan.Node_NEXT: + if isNull { + if s.segmentPending[col] < 0 { + s.segmentPending[col] = logicalRow + } + } else { + s.segmentPending[col] = -1 + } + case plan.Node_LINEAR: + if isNull { + if s.segmentLeftValid[col] && s.segmentPending[col] < 0 { + s.segmentPending[col] = logicalRow + } + } else { + s.segmentPending[col] = -1 + s.segmentLeftValid[col] = true + } + } + } + s.segmentRows++ + s.updateSafeWatermark() + } +} + +func (s *fillSpill) finalizeSegment(ctr *container, ap *Fill, proc *process.Process) error { + s.safeRows = s.safeWatermark - s.segmentStart + if err := s.transformReverse(ap, proc); err != nil { + return err + } + if s.input != nil { + _ = s.input.Close() + s.input = nil + } + return nil +} + +func (ctr *container) beginSpill(ap *Fill, proc *process.Process) error { + spill, err := newFillSpill(proc) + if err != nil { + return err + } + spill.segmentPending = make([]int64, ap.ColLen) + spill.segmentLeftValid = make([]bool, ap.ColLen) + for _, bat := range ctr.bats { + spill.segmentRows += int64(bat.RowCount()) + } + coordOffset := func(coord fillCoord) int64 { + var offset int64 + for seq := ctr.baseSeq; seq < coord.seq; seq++ { + offset += int64(ctr.batAt(seq).RowCount()) + } + return offset + int64(coord.row) + } + for col := 0; col < ap.ColLen; col++ { + spill.segmentPending[col] = -1 + if ap.FillType == plan.Node_NEXT { + if len(ctr.nextRun[col]) > 0 { + coord := ctr.nextRun[col][0] + spill.segmentPending[col] = coordOffset(coord) + } + } else { + if len(ctr.linRun[col]) > 0 { + coord := ctr.linRun[col][0] + spill.segmentPending[col] = coordOffset(coord) + } + spill.segmentLeftValid[col] = ctr.linPre[col].seq >= 0 || ctr.linSeedValid[col] + } + } + spill.updateSafeWatermark() + if ap.FillType == plan.Node_LINEAR && len(ctr.linEntry) > 0 { + spill.linearLeft = ctr.linEntry + spill.linearLeftValid = ctr.linEntryValid + spill.forwardPart.cloneFrom(&ctr.linEntryPart) + ctr.linEntry = make([]*vector.Vector, ap.ColLen) + ctr.linEntryValid = make([]bool, ap.ColLen) + ctr.linEntryPart = spillPartitionSnapshot{} + } + for i, bat := range ctr.bats { + if err = spill.writeRecord(spill.input, bat); err != nil { + spill.close(proc) + return err + } + spill.inputRecords++ + bat.Clean(proc.Mp()) + ctr.bats[i] = nil + } + ctr.bats = ctr.bats[:0] + ctr.pendingBytes = 0 + ctr.pendingRows = 0 + ctr.flushable = 0 + ctr.baseSeq = 0 + if ap.FillType == plan.Node_NEXT { + ctr.flushPendingRunsNext(ap) + } else { + ctr.flushPendingRunsLinear(ap) + } + ctr.spill = spill + if spill.safeWatermark > spill.segmentStart { + if err = spill.finalizeSegment(ctr, ap, proc); err != nil { + ctr.cleanupSpill(proc) + return err + } + } + return nil +} + +func (ctr *container) collectSpill(ap *Fill, proc *process.Process, analyzer process.Analyzer) error { + for { + result, err := vm.ChildrenCall(ap.GetChildren(0), proc, analyzer) + if err != nil { + return err + } + if result.Batch == nil { + ctr.childDone = true + ctr.spill.safeWatermark = ctr.spill.segmentRows + return ctr.spill.finalizeSegment(ctr, ap, proc) + } + dup, err := result.Batch.Dup(proc.Mp()) + if err != nil { + return err + } + if err = addOriginalNullMarkers(dup, ap.ColLen, proc.Mp()); err != nil { + dup.Clean(proc.Mp()) + return err + } + ctr.spill.scanSegment(ctr, ap, dup) + if err = ctr.spill.writeRecord(ctr.spill.input, dup); err != nil { + dup.Clean(proc.Mp()) + return err + } + ctr.spill.inputRecords++ + if dup.RowCount() > 0 && len(ap.PartitionColIdx) > 0 { + ctr.snapshotPartKey(ap.PartitionColIdx, dup, dup.RowCount()-1) + } + if analyzer != nil { + analyzer.Spill(int64(ctr.spill.buf.Len())) + analyzer.SpillRows(int64(dup.RowCount())) + } + dup.Clean(proc.Mp()) + if ctr.spill.safeWatermark > ctr.spill.segmentStart { + return ctr.spill.finalizeSegment(ctr, ap, proc) + } + } +} + +func (s *fillSpill) replayNext(ctr *container, ap *Fill, proc *process.Process) (*batch.Batch, error) { + if s.replay != nil { + // The batch returned by the previous Call had its internal marker columns + // stripped. Reusing it for a wider spilled record would make batch + // UnmarshalFromReader clean the batch after setting RowCount, losing the + // decoded count. Release it and keep the replay footprint at one fresh + // batch instead. + s.replay.Clean(proc.Mp()) + s.replay = nil + } + for { + bat, err := readRecordReverse(s.output, &s.outputReversePos, proc.Mp(), nil) + if err != nil { + return nil, err + } + rows := int64(bat.RowCount()) + if s.safeRows <= 0 { + if err = s.writeSuffix(proc, bat); err != nil { + bat.Clean(proc.Mp()) + return nil, err + } + bat.Clean(proc.Mp()) + continue + } + if s.safeRows >= rows { + s.safeRows -= rows + s.replay = bat + if ap.FillType == plan.Node_LINEAR { + if err = s.finishLinearBatch(ctr, ap, proc, bat); err != nil { + return nil, err + } + } + stripOriginalNullMarkers(bat, ap.ColLen, proc.Mp()) + return bat, nil + } + + end := int(s.safeRows) + prefix, err := cloneBatchWindow(bat, 0, end, proc.Mp()) + if err != nil { + bat.Clean(proc.Mp()) + return nil, err + } + suffix, err := cloneBatchWindow(bat, end, bat.RowCount(), proc.Mp()) + if err != nil { + prefix.Clean(proc.Mp()) + bat.Clean(proc.Mp()) + return nil, err + } + bat.Clean(proc.Mp()) + if err = s.writeSuffix(proc, suffix); err != nil { + prefix.Clean(proc.Mp()) + suffix.Clean(proc.Mp()) + return nil, err + } + suffix.Clean(proc.Mp()) + s.safeRows = 0 + s.replay = prefix + if ap.FillType == plan.Node_LINEAR { + if err = s.finishLinearBatch(ctr, ap, proc, prefix); err != nil { + return nil, err + } + } + stripOriginalNullMarkers(prefix, ap.ColLen, proc.Mp()) + return prefix, nil + } +} + +func (s *fillSpill) writeSuffix(proc *process.Process, bat *batch.Batch) error { + if err := s.ensureNext(proc); err != nil { + return err + } + if err := s.writeRecord(s.next, bat); err != nil { + return err + } + s.hasSuffix = true + return nil +} + +func (s *fillSpill) rotateSuffix() { + if s.output != nil { + _ = s.output.Close() + s.output = nil + } + s.input = s.next + s.next = nil + s.outputReversePos = -1 + s.ready = false + s.hasSuffix = false + s.segmentStart = s.safeWatermark + s.safeRows = 0 + s.inputRecords = 0 + s.outputRecords = 0 +} + +func (ctr *container) finishSpillReplay( + ap *Fill, + proc *process.Process, +) error { + spill := ctr.spill + if spill.hasSuffix { + spill.rotateSuffix() + return nil + } + if ap.FillType == plan.Node_LINEAR { + seed := make([]*vector.Vector, ap.ColLen) + seedValid := make([]bool, ap.ColLen) + for col := 0; col < ap.ColLen; col++ { + if !spill.linearLeftValid[col] { + continue + } + var err error + seed[col], err = makeEndpoint(spill.linearLeft[col], 0, proc) + if err != nil { + for _, vec := range seed { + if vec != nil { + vec.Free(proc.Mp()) + } + } + return err + } + seedValid[col] = true + } + ctr.clearLinearSeeds(proc.Mp()) + ctr.clearLinearEntries(proc.Mp()) + ctr.linSeed = seed + ctr.linSeedValid = seedValid + ctr.linEntry = spill.linearLeft + ctr.linEntryValid = spill.linearLeftValid + ctr.linEntryPart.cloneFrom(&spill.forwardPart) + spill.linearLeft = nil + spill.linearLeftValid = nil + } + ctr.cleanupSpill(proc) + return nil +} + +func (s *fillSpill) finishLinearBatch(ctr *container, ap *Fill, proc *process.Process, bat *batch.Batch) error { + for row := 0; row < bat.RowCount(); row++ { + if len(ap.PartitionColIdx) > 0 { + wasSet := s.forwardPart.set + if !s.forwardPart.sameAndSet(ap.PartitionColIdx, bat, row) && wasSet { + clearEndpoints(s.linearLeftValid) + } + } + for col := 0; col < ap.ColLen; col++ { + if !originalNullAt(bat, ap.ColLen, col, row) { + if err := setEndpoint(&s.linearLeft[col], bat.Vecs[col], row, proc); err != nil { + return err + } + s.linearLeftValid[col] = true + continue + } + if bat.Vecs[col].IsNull(uint64(row)) || !s.linearLeftValid[col] { + bat.Vecs[col].GetNulls().Add(uint64(row)) + continue + } + leftBatch := batch.NewWithSize(col + 1) + leftBatch.SetVector(int32(col), s.linearLeft[col]) + leftBatch.SetRowCount(1) + rightBatch := batch.NewWithSize(col + 1) + rightBatch.SetVector(int32(col), bat.Vecs[col]) + rightBatch.SetRowCount(bat.RowCount()) + value, owned, err := linearFillValue(ctr, proc, col, leftBatch, 0, rightBatch, row) + if err != nil { + return err + } + if err = setValue(bat.Vecs[col], value, row, 0, proc); err != nil { + if owned { + value.Free(proc.Mp()) + } + return err + } + if owned { + value.Free(proc.Mp()) + } + } + } + return nil +} diff --git a/pkg/sql/colexec/fill/streaming_test.go b/pkg/sql/colexec/fill/streaming_test.go new file mode 100644 index 0000000000000..e9e640976c658 --- /dev/null +++ b/pkg/sql/colexec/fill/streaming_test.go @@ -0,0 +1,947 @@ +// Copyright 2021 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fill + +import ( + "testing" + + "github.com/matrixorigin/matrixone/pkg/common/mpool" + "github.com/matrixorigin/matrixone/pkg/container/batch" + "github.com/matrixorigin/matrixone/pkg/container/types" + "github.com/matrixorigin/matrixone/pkg/container/vector" + "github.com/matrixorigin/matrixone/pkg/pb/plan" + "github.com/matrixorigin/matrixone/pkg/sql/colexec" + "github.com/matrixorigin/matrixone/pkg/testutil" + "github.com/matrixorigin/matrixone/pkg/vm" + "github.com/matrixorigin/matrixone/pkg/vm/process" + "github.com/stretchr/testify/require" +) + +// countingChild records how many times the operator was pulled, so a test can +// assert that fill emitted a result before draining the whole child. +type countingChild struct { + *colexec.MockOperator + calls int +} + +var _ vm.Operator = (*countingChild)(nil) + +func (c *countingChild) Call(proc *process.Process) (vm.CallResult, error) { + c.calls++ + return c.MockOperator.Call(proc) +} + +type cell struct { + val int64 + null bool +} + +func readCol(bat *batch.Batch, col int) []cell { + vec := bat.Vecs[col] + out := make([]cell, 0, bat.RowCount()) + for r := 0; r < bat.RowCount(); r++ { + if vec.IsNull(uint64(r)) { + out = append(out, cell{null: true}) + } else { + out = append(out, cell{val: vector.GetFixedAtNoTypeCheck[int64](vec, r)}) + } + } + return out +} + +// drainCol keeps calling the operator and concatenates column col of every +// emitted batch. Each batch stays valid until the next Call frees it, so it is +// read before advancing. +func drainCol(t *testing.T, arg *Fill, proc *process.Process, col int) []cell { + t.Helper() + var out []cell + for { + res, err := arg.Call(proc) + require.NoError(t, err) + if res.Batch == nil { + return out + } + out = append(out, readCol(res.Batch, col)...) + } +} + +// A no-NULL NEXT stream must flow straight through: the first batch is emitted +// after a single child pull, never after materializing the whole input. This +// is the regression the reviewer asked for — an outer LIMIT 1 could stop the +// child right here. +func TestFillNextStreamsWithoutBuffering(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + + const n = 5 + bats := make([]*batch.Batch, 0, n) + for i := 0; i < n; i++ { + bats = append(bats, partitionedBatch(proc.Mp(), + []int64{int64(2 * i), int64(2*i + 1)}, nil, []int64{1, 1})) + } + + child := &countingChild{MockOperator: colexec.NewMockOperator().WithBatchs(bats)} + arg := &Fill{ColLen: 1, FillType: plan.Node_NEXT, PartitionColIdx: []int32{1}} + arg.AppendChild(child) + require.NoError(t, arg.Prepare(proc)) + + res, err := arg.Call(proc) + require.NoError(t, err) + require.NotNil(t, res.Batch) + require.Equal(t, 1, child.calls, "first batch must be emitted after exactly one child pull") + require.LessOrEqual(t, len(arg.ctr.bats), 1, "no-NULL NEXT must not buffer the stream") + + all := append(readCol(res.Batch, 0), drainCol(t, arg, proc, 0)...) + require.Len(t, all, 2*n) + for i, c := range all { + require.False(t, c.null) + require.Equal(t, int64(i), c.val) + } + require.Equal(t, n+1, child.calls, "the child is drained exactly once end to end") + + arg.Free(proc, false, nil) + for _, b := range bats { + b.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +// LINEAR keeps at most one batch buffered while streaming a no-NULL input: it +// pins the last non-NULL as a possible left endpoint, so it emits batch k only +// after batch k+1 arrives — bounded, not the whole input. +func TestFillLinearStreamsBounded(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + + const n = 5 + bats := make([]*batch.Batch, 0, n) + for i := 0; i < n; i++ { + bats = append(bats, partitionedBatch(proc.Mp(), + []int64{int64(2 * i), int64(2*i + 1)}, nil, []int64{1, 1})) + } + + child := &countingChild{MockOperator: colexec.NewMockOperator().WithBatchs(bats)} + arg := &Fill{ColLen: 1, FillType: plan.Node_LINEAR, PartitionColIdx: []int32{1}} + arg.AppendChild(child) + require.NoError(t, arg.Prepare(proc)) + + res, err := arg.Call(proc) + require.NoError(t, err) + require.NotNil(t, res.Batch) + require.Equal(t, 2, child.calls, "LINEAR emits its first batch after a one-batch look-ahead") + require.LessOrEqual(t, len(arg.ctr.bats), 1, "LINEAR buffers at most one batch on a no-NULL stream") + + all := append(readCol(res.Batch, 0), drainCol(t, arg, proc, 0)...) + require.Len(t, all, 2*n) + for i, c := range all { + require.False(t, c.null) + require.Equal(t, int64(i), c.val) + } + + arg.Free(proc, false, nil) + for _, b := range bats { + b.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +// A NULL that spans several batches is filled by the value that finally arrives +// downstream, no matter how far away it is. +func TestFillNextLongCrossBatchGap(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + + bats := []*batch.Batch{ + partitionedBatch(proc.Mp(), []int64{10}, nil, []int64{1}), + partitionedBatch(proc.Mp(), []int64{0}, []uint64{0}, []int64{1}), + partitionedBatch(proc.Mp(), []int64{0}, []uint64{0}, []int64{1}), + partitionedBatch(proc.Mp(), []int64{40}, nil, []int64{1}), + } + + vals, nulls := runFill(t, proc, plan.Node_NEXT, bats) + require.Equal(t, []bool{false, false, false, false}, nulls) + require.Equal(t, []int64{10, 40, 40, 40}, vals) + + for _, b := range bats { + b.Clean(proc.Mp()) + } + proc.Free() +} + +func TestFillNextLongGapSpillsPendingSuffix(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + + const nullBatches = 64 + bats := make([]*batch.Batch, 0, nullBatches+2) + bats = append(bats, partitionedBatch(proc.Mp(), []int64{10}, nil, []int64{1})) + for i := 0; i < nullBatches; i++ { + bats = append(bats, partitionedBatch(proc.Mp(), []int64{0}, []uint64{0}, []int64{1})) + } + bats = append(bats, partitionedBatch(proc.Mp(), []int64{90}, nil, []int64{1})) + + child := &countingChild{MockOperator: colexec.NewMockOperator().WithBatchs(bats)} + arg := &Fill{ColLen: 1, FillType: plan.Node_NEXT, PartitionColIdx: []int32{1}, SpillThreshold: 2} + arg.AppendChild(child) + require.NoError(t, arg.Prepare(proc)) + + first, err := arg.Call(proc) + require.NoError(t, err) + require.Equal(t, []cell{{val: 10}}, readCol(first.Batch, 0)) + require.Equal(t, 1, child.calls, "resolved prefix must still stream before spill") + + second, err := arg.Call(proc) + require.NoError(t, err) + require.NotNil(t, second.Batch) + require.NotNil(t, arg.ctr.spill) + require.Equal(t, arg.ctr.spill.inputRecords, arg.ctr.spill.outputRecords) + require.Empty(t, arg.ctr.bats) + require.Zero(t, arg.ctr.pendingBytes) + require.Zero(t, arg.ctr.pendingRows) + + all := append(readCol(second.Batch, 0), drainCol(t, arg, proc, 0)...) + require.Len(t, all, nullBatches+1) + for _, value := range all { + require.Equal(t, cell{val: 90}, value) + } + + arg.Free(proc, false, nil) + for _, bat := range bats { + bat.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +func TestFillNextSpillReplaysClosedSegmentBeforeChildEOF(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + bats := []*batch.Batch{ + partitionedBatch(proc.Mp(), []int64{10}, nil, []int64{1}), + partitionedBatch(proc.Mp(), []int64{0}, []uint64{0}, []int64{1}), + partitionedBatch(proc.Mp(), []int64{0}, []uint64{0}, []int64{1}), + partitionedBatch(proc.Mp(), []int64{40, 50, 60}, nil, []int64{1, 1, 1}), + } + child := &countingChild{MockOperator: colexec.NewMockOperator().WithBatchs(bats)} + arg := &Fill{ColLen: 1, FillType: plan.Node_NEXT, PartitionColIdx: []int32{1}, SpillThreshold: 2} + arg.AppendChild(child) + require.NoError(t, arg.Prepare(proc)) + + first, err := arg.Call(proc) + require.NoError(t, err) + require.Equal(t, []cell{{val: 10}}, readCol(first.Batch, 0)) + require.Equal(t, 1, child.calls) + + second, err := arg.Call(proc) + require.NoError(t, err) + require.Equal(t, []cell{{val: 40}}, readCol(second.Batch, 0)) + require.Equal(t, 4, child.calls, "closed segment must replay before the carry tail or EOF is pulled") + + all := append(readCol(second.Batch, 0), drainCol(t, arg, proc, 0)...) + require.Equal(t, []cell{{val: 40}, {val: 40}, {val: 40}, {val: 50}, {val: 60}}, all) + + arg.Free(proc, false, nil) + for _, bat := range bats { + bat.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +func TestFillNextSpillPartitionBoundaryClosesSegment(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + bats := []*batch.Batch{ + partitionedBatch(proc.Mp(), []int64{10}, nil, []int64{1}), + partitionedBatch(proc.Mp(), []int64{0}, []uint64{0}, []int64{1}), + partitionedBatch(proc.Mp(), []int64{20, 30}, nil, []int64{2, 2}), + } + child := &countingChild{MockOperator: colexec.NewMockOperator().WithBatchs(bats)} + arg := &Fill{ColLen: 1, FillType: plan.Node_NEXT, PartitionColIdx: []int32{1}, SpillThreshold: 1} + arg.AppendChild(child) + require.NoError(t, arg.Prepare(proc)) + + first, err := arg.Call(proc) + require.NoError(t, err) + require.Equal(t, []cell{{val: 10}}, readCol(first.Batch, 0)) + + second, err := arg.Call(proc) + require.NoError(t, err) + require.Equal(t, []cell{{null: true}}, readCol(second.Batch, 0)) + require.Equal(t, 3, child.calls, "partition boundary must close the old segment before its carry rows") + + all := append(readCol(second.Batch, 0), drainCol(t, arg, proc, 0)...) + require.Equal(t, []cell{{null: true}, {val: 20}, {val: 30}}, all) + + arg.Free(proc, false, nil) + for _, bat := range bats { + bat.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +// Trailing NULLs with no following value in the stream stay NULL at EOF rather +// than being dropped or hanging the operator. +func TestFillNextEOFTail(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + + bats := []*batch.Batch{ + partitionedBatch(proc.Mp(), []int64{10}, nil, []int64{1}), + partitionedBatch(proc.Mp(), []int64{0, 0}, []uint64{0, 1}, []int64{1, 1}), + } + + vals, nulls := runFill(t, proc, plan.Node_NEXT, bats) + require.Equal(t, []bool{false, true, true}, nulls) + require.Equal(t, int64(10), vals[0]) + + for _, b := range bats { + b.Clean(proc.Mp()) + } + proc.Free() +} + +func TestFillNextSpillKeepsEOFTailNull(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + bats := []*batch.Batch{ + partitionedBatch(proc.Mp(), []int64{10}, nil, []int64{1}), + partitionedBatch(proc.Mp(), []int64{0}, []uint64{0}, []int64{1}), + partitionedBatch(proc.Mp(), []int64{0}, []uint64{0}, []int64{1}), + } + child := colexec.NewMockOperator().WithBatchs(bats) + arg := &Fill{ColLen: 1, FillType: plan.Node_NEXT, PartitionColIdx: []int32{1}, SpillThreshold: 2} + arg.AppendChild(child) + require.NoError(t, arg.Prepare(proc)) + + got := drainCol(t, arg, proc, 0) + require.Equal(t, []cell{{val: 10}, {null: true}, {null: true}}, got) + + arg.Free(proc, false, nil) + for _, bat := range bats { + bat.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +// Two fill columns resolve independently: a row leaves the operator only once +// every filled column has a value, and each column's gap is closed by its own +// next value. +func TestFillNextMultiColumnGap(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + + // col0: [1, NULL, 3]; col1: [NULL, 20, 30]; part all 1. + bat := batch.NewWithSize(3) + bat.SetVector(0, testutil.MakeInt64Vector([]int64{1, 0, 3}, []uint64{1}, proc.Mp())) + bat.SetVector(1, testutil.MakeInt64Vector([]int64{0, 20, 30}, []uint64{0}, proc.Mp())) + bat.SetVector(2, testutil.MakeInt64Vector([]int64{1, 1, 1}, nil, proc.Mp())) + bat.SetRowCount(3) + + child := colexec.NewMockOperator().WithBatchs([]*batch.Batch{bat}) + arg := &Fill{ColLen: 2, FillType: plan.Node_NEXT, PartitionColIdx: []int32{2}} + arg.AppendChild(child) + require.NoError(t, arg.Prepare(proc)) + + var col0, col1 []cell + for { + res, err := arg.Call(proc) + require.NoError(t, err) + if res.Batch == nil { + break + } + col0 = append(col0, readCol(res.Batch, 0)...) + col1 = append(col1, readCol(res.Batch, 1)...) + } + require.Equal(t, []cell{{val: 1}, {val: 3}, {val: 3}}, col0, "col0 gap filled by its own next value") + require.Equal(t, []cell{{val: 20}, {val: 20}, {val: 30}}, col1, "col1 gap filled independently") + + arg.Free(proc, false, nil) + bat.Clean(proc.Mp()) + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +func TestFillNextSpillMultiColumnAndPartitionBoundary(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + makeBatch := func(col0, col1 []int64, null0, null1 []uint64, parts []int64) *batch.Batch { + bat := batch.NewWithSize(3) + bat.SetVector(0, testutil.MakeInt64Vector(col0, null0, proc.Mp())) + bat.SetVector(1, testutil.MakeInt64Vector(col1, null1, proc.Mp())) + bat.SetVector(2, testutil.MakeInt64Vector(parts, nil, proc.Mp())) + bat.SetRowCount(len(parts)) + return bat + } + bats := []*batch.Batch{ + makeBatch([]int64{1}, []int64{0}, nil, []uint64{0}, []int64{1}), + makeBatch([]int64{0}, []int64{20}, []uint64{0}, nil, []int64{1}), + makeBatch([]int64{3}, []int64{30}, nil, nil, []int64{1}), + // Partition 1's candidates must not fill partition 2's leading NULLs. + makeBatch([]int64{0}, []int64{0}, []uint64{0}, []uint64{0}, []int64{2}), + makeBatch([]int64{8}, []int64{80}, nil, nil, []int64{2}), + } + child := &countingChild{MockOperator: colexec.NewMockOperator().WithBatchs(bats)} + arg := &Fill{ColLen: 2, FillType: plan.Node_NEXT, PartitionColIdx: []int32{2}, SpillThreshold: 1} + arg.AppendChild(child) + require.NoError(t, arg.Prepare(proc)) + + first, err := arg.Call(proc) + require.NoError(t, err) + require.Equal(t, 2, child.calls, "safe watermark must advance before both columns close simultaneously") + col0 := readCol(first.Batch, 0) + col1 := readCol(first.Batch, 1) + for { + res, err := arg.Call(proc) + require.NoError(t, err) + if res.Batch == nil { + break + } + col0 = append(col0, readCol(res.Batch, 0)...) + col1 = append(col1, readCol(res.Batch, 1)...) + } + require.Equal(t, []cell{{val: 1}, {val: 3}, {val: 3}, {val: 8}, {val: 8}}, col0) + require.Equal(t, []cell{{val: 20}, {val: 20}, {val: 30}, {val: 80}, {val: 80}}, col1) + + arg.Free(proc, false, nil) + for _, bat := range bats { + bat.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +func TestFillNextSpillAlternatingColumnsAdvancesWatermark(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + makeBatch := func(col0, col1 int64, null0, null1 bool) *batch.Batch { + bat := batch.NewWithSize(3) + var nulls0, nulls1 []uint64 + if null0 { + nulls0 = []uint64{0} + } + if null1 { + nulls1 = []uint64{0} + } + bat.SetVector(0, testutil.MakeInt64Vector([]int64{col0}, nulls0, proc.Mp())) + bat.SetVector(1, testutil.MakeInt64Vector([]int64{col1}, nulls1, proc.Mp())) + bat.SetVector(2, testutil.MakeInt64Vector([]int64{1}, nil, proc.Mp())) + bat.SetRowCount(1) + return bat + } + bats := []*batch.Batch{ + makeBatch(1, 0, false, true), + makeBatch(0, 20, true, false), + makeBatch(3, 0, false, true), + makeBatch(0, 40, true, false), + makeBatch(5, 50, false, false), + } + child := &countingChild{MockOperator: colexec.NewMockOperator().WithBatchs(bats)} + arg := &Fill{ColLen: 2, FillType: plan.Node_NEXT, PartitionColIdx: []int32{2}, SpillThreshold: 1} + arg.AppendChild(child) + require.NoError(t, arg.Prepare(proc)) + + first, err := arg.Call(proc) + require.NoError(t, err) + require.Equal(t, 2, child.calls, "alternating pending columns must not force an EOF drain") + col0 := readCol(first.Batch, 0) + col1 := readCol(first.Batch, 1) + for { + result, callErr := arg.Call(proc) + require.NoError(t, callErr) + if result.Batch == nil { + break + } + col0 = append(col0, readCol(result.Batch, 0)...) + col1 = append(col1, readCol(result.Batch, 1)...) + } + require.Equal(t, []cell{{val: 1}, {val: 3}, {val: 3}, {val: 5}, {val: 5}}, col0) + require.Equal(t, []cell{{val: 20}, {val: 20}, {val: 40}, {val: 40}, {val: 50}}, col1) + + arg.Free(proc, false, nil) + for _, bat := range bats { + bat.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +func TestFillLinearSpillAlternatingColumnsAdvancesWatermark(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + makeBatch := func(col0, col1 int64, null0, null1 bool) *batch.Batch { + bat := batch.NewWithSize(3) + var nulls0, nulls1 []uint64 + if null0 { + nulls0 = []uint64{0} + } + if null1 { + nulls1 = []uint64{0} + } + bat.SetVector(0, testutil.MakeInt64Vector([]int64{col0}, nulls0, proc.Mp())) + bat.SetVector(1, testutil.MakeInt64Vector([]int64{col1}, nulls1, proc.Mp())) + bat.SetVector(2, testutil.MakeInt64Vector([]int64{1}, nil, proc.Mp())) + bat.SetRowCount(1) + return bat + } + bats := []*batch.Batch{ + makeBatch(10, 0, false, true), + makeBatch(0, 20, true, false), + makeBatch(30, 0, false, true), + makeBatch(0, 40, true, false), + makeBatch(50, 60, false, false), + } + child := &countingChild{MockOperator: colexec.NewMockOperator().WithBatchs(bats)} + arg := &Fill{ColLen: 2, FillType: plan.Node_LINEAR, PartitionColIdx: []int32{2}, SpillThreshold: 1} + arg.AppendChild(child) + require.NoError(t, arg.Prepare(proc)) + midpoint := vector.NewVec(types.T_int64.ToType()) + require.NoError(t, vector.AppendFixed(midpoint, int64(99), false, proc.Mp())) + stub := &fillStubExpressionExecutor{result: midpoint} + arg.ctr.exes = []colexec.ExpressionExecutor{stub, stub} + + first, err := arg.Call(proc) + require.NoError(t, err) + require.Equal(t, 1, child.calls) + col0 := readCol(first.Batch, 0) + col1 := readCol(first.Batch, 1) + second, err := arg.Call(proc) + require.NoError(t, err) + require.Equal(t, 3, child.calls, "alternating LINEAR gaps must advance before child EOF") + col0 = append(col0, readCol(second.Batch, 0)...) + col1 = append(col1, readCol(second.Batch, 1)...) + for { + result, callErr := arg.Call(proc) + require.NoError(t, callErr) + if result.Batch == nil { + break + } + col0 = append(col0, readCol(result.Batch, 0)...) + col1 = append(col1, readCol(result.Batch, 1)...) + } + require.Equal(t, []cell{{val: 10}, {val: 99}, {val: 30}, {val: 99}, {val: 50}}, col0) + require.Equal(t, []cell{{null: true}, {val: 20}, {val: 99}, {val: 40}, {val: 60}}, col1) + + arg.Free(proc, false, nil) + midpoint.Free(proc.Mp()) + for _, bat := range bats { + bat.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +func TestFillSpillWatermarkSplitsBatch(t *testing.T) { + for _, fillType := range []plan.Node_FillType{plan.Node_NEXT, plan.Node_LINEAR} { + t.Run(fillType.String(), func(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + firstInput := batch.NewWithSize(3) + firstInput.SetVector(0, testutil.MakeInt64Vector([]int64{10, 0}, []uint64{1}, proc.Mp())) + firstInput.SetVector(1, testutil.MakeInt64Vector([]int64{0, 20}, []uint64{0}, proc.Mp())) + firstInput.SetVector(2, testutil.MakeInt64Vector([]int64{1, 1}, nil, proc.Mp())) + firstInput.SetRowCount(2) + secondInput := batch.NewWithSize(3) + secondInput.SetVector(0, testutil.MakeInt64Vector([]int64{30}, nil, proc.Mp())) + secondInput.SetVector(1, testutil.MakeInt64Vector([]int64{40}, nil, proc.Mp())) + secondInput.SetVector(2, testutil.MakeInt64Vector([]int64{1}, nil, proc.Mp())) + secondInput.SetRowCount(1) + bats := []*batch.Batch{firstInput, secondInput} + child := &countingChild{MockOperator: colexec.NewMockOperator().WithBatchs(bats)} + arg := &Fill{ColLen: 2, FillType: fillType, PartitionColIdx: []int32{2}, SpillThreshold: 2} + arg.AppendChild(child) + require.NoError(t, arg.Prepare(proc)) + midpoint := vector.NewVec(types.T_int64.ToType()) + if fillType == plan.Node_LINEAR { + require.NoError(t, vector.AppendFixed(midpoint, int64(99), false, proc.Mp())) + stub := &fillStubExpressionExecutor{result: midpoint} + arg.ctr.exes = []colexec.ExpressionExecutor{stub, stub} + } + + first, err := arg.Call(proc) + require.NoError(t, err) + require.Equal(t, 1, child.calls, "batch-local watermark must replay before the next child batch") + col0 := readCol(first.Batch, 0) + col1 := readCol(first.Batch, 1) + for { + result, callErr := arg.Call(proc) + require.NoError(t, callErr) + if result.Batch == nil { + break + } + col0 = append(col0, readCol(result.Batch, 0)...) + col1 = append(col1, readCol(result.Batch, 1)...) + } + if fillType == plan.Node_NEXT { + require.Equal(t, []cell{{val: 10}, {val: 30}, {val: 30}}, col0) + require.Equal(t, []cell{{val: 20}, {val: 20}, {val: 40}}, col1) + } else { + require.Equal(t, []cell{{val: 10}, {val: 99}, {val: 30}}, col0) + require.Equal(t, []cell{{null: true}, {val: 20}, {val: 40}}, col1) + } + + arg.Free(proc, false, nil) + if fillType == plan.Node_LINEAR { + midpoint.Free(proc.Mp()) + } + for _, bat := range bats { + bat.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) + }) + } +} + +// LINEAR interpolates across a batch boundary: the midpoint uses the non-NULL +// values that bracket the gap even when they land in different batches. +func TestFillLinearCrossBatchGap(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + + typ := types.New(types.T_decimal128, 38, 0) + set := func(vec *vector.Vector, v int64, isNull bool) { + require.NoError(t, vector.AppendFixed(vec, types.Decimal128FromInt64(v), isNull, proc.Mp())) + } + // batch 1: [10, NULL]; batch 2: [NULL, 40]; one partition, so the midpoint + // of 10 and 40 (=25) fills both gaps. + v1 := vector.NewVec(typ) + set(v1, 10, false) + set(v1, 0, true) + b1 := batch.NewWithSize(2) + b1.SetVector(0, v1) + b1.SetVector(1, testutil.MakeInt64Vector([]int64{1, 1}, nil, proc.Mp())) + b1.SetRowCount(2) + + v2 := vector.NewVec(typ) + set(v2, 0, true) + set(v2, 40, false) + b2 := batch.NewWithSize(2) + b2.SetVector(0, v2) + b2.SetVector(1, testutil.MakeInt64Vector([]int64{1, 1}, nil, proc.Mp())) + b2.SetRowCount(2) + + bats := []*batch.Batch{b1, b2} + child := colexec.NewMockOperator().WithBatchs(bats) + arg := &Fill{ColLen: 1, FillType: plan.Node_LINEAR, PartitionColIdx: []int32{1}} + arg.AppendChild(child) + require.NoError(t, arg.Prepare(proc)) + + var got []types.Decimal128 + var isNull []bool + for { + res, err := arg.Call(proc) + require.NoError(t, err) + if res.Batch == nil { + break + } + vec := res.Batch.Vecs[0] + for r := 0; r < res.Batch.RowCount(); r++ { + isNull = append(isNull, vec.IsNull(uint64(r))) + got = append(got, vector.GetFixedAtNoTypeCheck[types.Decimal128](vec, r)) + } + } + require.Equal(t, []bool{false, false, false, false}, isNull) + require.Equal(t, types.Decimal128FromInt64(25), got[1], "midpoint of 10 and 40") + require.Equal(t, types.Decimal128FromInt64(25), got[2]) + + arg.Free(proc, false, nil) + for _, b := range bats { + b.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +func TestFillLinearLongGapSpillsPendingSuffix(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + + const nullBatches = 64 + typ := types.New(types.T_decimal128, 38, 0) + makeBatch := func(value int64, isNull bool) *batch.Batch { + vec := vector.NewVec(typ) + require.NoError(t, vector.AppendFixed(vec, types.Decimal128FromInt64(value), isNull, proc.Mp())) + bat := batch.NewWithSize(2) + bat.SetVector(0, vec) + bat.SetVector(1, testutil.MakeInt64Vector([]int64{1}, nil, proc.Mp())) + bat.SetRowCount(1) + return bat + } + bats := make([]*batch.Batch, 0, nullBatches+2) + bats = append(bats, makeBatch(10, false)) + for i := 0; i < nullBatches; i++ { + bats = append(bats, makeBatch(0, true)) + } + bats = append(bats, makeBatch(90, false)) + + child := &countingChild{MockOperator: colexec.NewMockOperator().WithBatchs(bats)} + arg := &Fill{ + ColLen: 1, + FillType: plan.Node_LINEAR, + PartitionColIdx: []int32{1}, + SpillThreshold: 2, + } + arg.AppendChild(child) + require.NoError(t, arg.Prepare(proc)) + + first, err := arg.Call(proc) + require.NoError(t, err) + require.NotNil(t, first.Batch) + require.NotNil(t, arg.ctr.spill) + require.Empty(t, arg.ctr.bats) + require.Zero(t, arg.ctr.pendingBytes) + require.Zero(t, arg.ctr.pendingRows) + + readDecimal := func(bat *batch.Batch) []types.Decimal128 { + return append([]types.Decimal128(nil), vector.MustFixedColNoTypeCheck[types.Decimal128](bat.Vecs[0])...) + } + all := readDecimal(first.Batch) + for { + res, callErr := arg.Call(proc) + require.NoError(t, callErr) + if res.Batch == nil { + break + } + all = append(all, readDecimal(res.Batch)...) + } + require.Len(t, all, nullBatches+2) + require.Equal(t, types.Decimal128FromInt64(10), all[0]) + for _, value := range all[1 : len(all)-1] { + require.Equal(t, types.Decimal128FromInt64(50), value) + } + require.Equal(t, types.Decimal128FromInt64(90), all[len(all)-1]) + + arg.Free(proc, false, nil) + for _, bat := range bats { + bat.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +func TestFillLinearConsecutiveSpillsPreserveSegmentEntry(t *testing.T) { + t.Run("single decimal column", func(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + typ := types.New(types.T_decimal128, 38, 0) + makeBatch := func(values []int64, nulls []uint64, parts []int64) *batch.Batch { + vec := vector.NewVec(typ) + for row, value := range values { + require.NoError(t, vector.AppendFixed( + vec, types.Decimal128FromInt64(value), vec.GetNulls().Contains(uint64(row)), proc.Mp())) + } + for _, row := range nulls { + vec.GetNulls().Add(row) + } + bat := batch.NewWithSize(2) + bat.SetVector(0, vec) + bat.SetVector(1, testutil.MakeInt64Vector(parts, nil, proc.Mp())) + bat.SetRowCount(len(values)) + return bat + } + bats := []*batch.Batch{ + makeBatch([]int64{10}, nil, []int64{1}), + makeBatch([]int64{0, 20}, []uint64{0}, []int64{1, 1}), + } + arg := &Fill{ColLen: 1, FillType: plan.Node_LINEAR, PartitionColIdx: []int32{1}, SpillThreshold: 1} + arg.AppendChild(colexec.NewMockOperator().WithBatchs(bats)) + require.NoError(t, arg.Prepare(proc)) + + var got []types.Decimal128 + var nulls []bool + for { + res, err := arg.Call(proc) + require.NoError(t, err) + if res.Batch == nil { + break + } + for row := 0; row < res.Batch.RowCount(); row++ { + nulls = append(nulls, res.Batch.Vecs[0].IsNull(uint64(row))) + got = append(got, vector.GetFixedAtNoTypeCheck[types.Decimal128](res.Batch.Vecs[0], row)) + } + } + require.Equal(t, []bool{false, false, false}, nulls) + require.Equal(t, types.Decimal128FromInt64(10), got[0]) + require.Equal(t, types.Decimal128FromInt64(15), got[1]) + require.Equal(t, types.Decimal128FromInt64(20), got[2]) + + arg.Free(proc, false, nil) + for _, bat := range bats { + bat.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) + }) + + t.Run("multiple columns and partition boundary", func(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + makeBatch := func(col0, col1 []int64, nulls0, nulls1 []uint64, parts []int64) *batch.Batch { + bat := batch.NewWithSize(3) + bat.SetVector(0, testutil.MakeInt64Vector(col0, nulls0, proc.Mp())) + bat.SetVector(1, testutil.MakeInt64Vector(col1, nulls1, proc.Mp())) + bat.SetVector(2, testutil.MakeInt64Vector(parts, nil, proc.Mp())) + bat.SetRowCount(len(parts)) + return bat + } + bats := []*batch.Batch{ + makeBatch([]int64{10}, []int64{100}, nil, nil, []int64{1}), + makeBatch([]int64{0, 20}, []int64{0, 200}, []uint64{0}, []uint64{0}, []int64{1, 1}), + makeBatch([]int64{0, 40}, []int64{0, 400}, []uint64{0}, []uint64{0}, []int64{2, 2}), + } + arg := &Fill{ColLen: 2, FillType: plan.Node_LINEAR, PartitionColIdx: []int32{2}, SpillThreshold: 1} + arg.AppendChild(colexec.NewMockOperator().WithBatchs(bats)) + require.NoError(t, arg.Prepare(proc)) + midpoint := vector.NewVec(types.T_int64.ToType()) + require.NoError(t, vector.AppendFixed(midpoint, int64(99), false, proc.Mp())) + stub := &fillStubExpressionExecutor{result: midpoint} + arg.ctr.exes = []colexec.ExpressionExecutor{stub, stub} + + var col0, col1 []cell + for { + res, err := arg.Call(proc) + require.NoError(t, err) + if res.Batch == nil { + break + } + col0 = append(col0, readCol(res.Batch, 0)...) + col1 = append(col1, readCol(res.Batch, 1)...) + } + require.Equal(t, []cell{{val: 10}, {val: 99}, {val: 20}, {null: true}, {val: 40}}, col0) + require.Equal(t, []cell{{val: 100}, {val: 99}, {val: 200}, {null: true}, {val: 400}}, col1) + + arg.Free(proc, false, nil) + midpoint.Free(proc.Mp()) + for _, bat := range bats { + bat.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) + }) +} + +func TestFillLinearSpillReplaysClosedSegmentBeforeChildEOF(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + bats := []*batch.Batch{ + partitionedBatch(proc.Mp(), []int64{10}, nil, []int64{1}), + partitionedBatch(proc.Mp(), []int64{0}, []uint64{0}, []int64{1}), + partitionedBatch(proc.Mp(), []int64{0}, []uint64{0}, []int64{1}), + partitionedBatch(proc.Mp(), []int64{40, 50, 60}, nil, []int64{1, 1, 1}), + } + child := &countingChild{MockOperator: colexec.NewMockOperator().WithBatchs(bats)} + arg := &Fill{ + ColLen: 1, + FillType: plan.Node_LINEAR, + PartitionColIdx: []int32{1}, + SpillThreshold: 2, + } + arg.AppendChild(child) + require.NoError(t, arg.Prepare(proc)) + midpoint := vector.NewVec(types.T_int64.ToType()) + require.NoError(t, vector.AppendFixed(midpoint, int64(25), false, proc.Mp())) + arg.ctr.exes = []colexec.ExpressionExecutor{&fillStubExpressionExecutor{result: midpoint}} + + first, err := arg.Call(proc) + require.NoError(t, err) + require.Equal(t, []cell{{val: 10}}, readCol(first.Batch, 0)) + require.Equal(t, 2, child.calls, "safe left endpoint must replay before the right endpoint or EOF") + + all := append(readCol(first.Batch, 0), drainCol(t, arg, proc, 0)...) + require.Equal(t, []cell{{val: 10}, {val: 25}, {val: 25}, {val: 40}, {val: 50}, {val: 60}}, all) + + arg.Free(proc, false, nil) + midpoint.Free(proc.Mp()) + for _, bat := range bats { + bat.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +func TestFillLinearSpillSeedStopsAtPartitionBoundary(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + bats := []*batch.Batch{ + partitionedBatch(proc.Mp(), []int64{10}, nil, []int64{1}), + partitionedBatch(proc.Mp(), []int64{0}, []uint64{0}, []int64{1}), + partitionedBatch(proc.Mp(), []int64{0, 20}, []uint64{0}, []int64{2, 2}), + } + child := &countingChild{MockOperator: colexec.NewMockOperator().WithBatchs(bats)} + arg := &Fill{ColLen: 1, FillType: plan.Node_LINEAR, PartitionColIdx: []int32{1}, SpillThreshold: 1} + arg.AppendChild(child) + require.NoError(t, arg.Prepare(proc)) + + first, err := arg.Call(proc) + require.NoError(t, err) + require.Equal(t, []cell{{val: 10}}, readCol(first.Batch, 0)) + + second, err := arg.Call(proc) + require.NoError(t, err) + require.Equal(t, []cell{{null: true}}, readCol(second.Batch, 0)) + require.Equal(t, 3, child.calls) + + all := append(readCol(second.Batch, 0), drainCol(t, arg, proc, 0)...) + require.Equal(t, []cell{{null: true}, {null: true}, {val: 20}}, all) + + arg.Free(proc, false, nil) + for _, bat := range bats { + bat.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +func TestFillSpillResetReleasesState(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + bats := []*batch.Batch{ + partitionedBatch(proc.Mp(), []int64{0}, []uint64{0}, []int64{1}), + partitionedBatch(proc.Mp(), []int64{0}, []uint64{0}, []int64{1}), + partitionedBatch(proc.Mp(), []int64{90, 100}, nil, []int64{1, 1}), + } + arg := &Fill{ColLen: 1, FillType: plan.Node_NEXT, PartitionColIdx: []int32{1}, SpillThreshold: 2} + arg.AppendChild(colexec.NewMockOperator().WithBatchs(bats)) + require.NoError(t, arg.Prepare(proc)) + + result, err := arg.Call(proc) + require.NoError(t, err) + require.NotNil(t, result.Batch) + require.NotNil(t, arg.ctr.spill) + + arg.Reset(proc, false, nil) + require.Nil(t, arg.ctr.spill) + require.Empty(t, arg.ctr.bats) + require.Zero(t, arg.ctr.pendingBytes) + require.Zero(t, arg.ctr.pendingRows) + + arg.Free(proc, false, nil) + for _, bat := range bats { + bat.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +func TestFillSpillResetReleasesWatermarkSuffix(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + input := batch.NewWithSize(3) + input.SetVector(0, testutil.MakeInt64Vector([]int64{10, 0}, []uint64{1}, proc.Mp())) + input.SetVector(1, testutil.MakeInt64Vector([]int64{0, 20}, []uint64{0}, proc.Mp())) + input.SetVector(2, testutil.MakeInt64Vector([]int64{1, 1}, nil, proc.Mp())) + input.SetRowCount(2) + arg := &Fill{ColLen: 2, FillType: plan.Node_NEXT, PartitionColIdx: []int32{2}, SpillThreshold: 2} + arg.AppendChild(colexec.NewMockOperator().WithBatchs([]*batch.Batch{input})) + require.NoError(t, arg.Prepare(proc)) + + result, err := arg.Call(proc) + require.NoError(t, err) + require.NotNil(t, result.Batch) + require.NotNil(t, arg.ctr.spill) + require.NotNil(t, arg.ctr.spill.next) + require.True(t, arg.ctr.spill.hasSuffix) + + arg.Reset(proc, false, nil) + require.Nil(t, arg.ctr.spill) + arg.Free(proc, false, nil) + input.Clean(proc.Mp()) + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} diff --git a/pkg/sql/colexec/fill/types.go b/pkg/sql/colexec/fill/types.go index ab27a33d3bf7b..a2eb09a000636 100644 --- a/pkg/sql/colexec/fill/types.go +++ b/pkg/sql/colexec/fill/types.go @@ -27,13 +27,12 @@ import ( var _ vm.Operator = new(Fill) -const ( - receiveBat = 0 - findNull = 2 - findValue = 3 - fillValue = 4 - findNullPre = 5 -) +// fillCoord addresses one buffered row by the batch's absolute sequence number +// (stable across FIFO popping) and its row within that batch. +type fillCoord struct { + seq int + row int +} type container struct { @@ -42,26 +41,60 @@ type container struct { // prev prevVecs []*vector.Vector + // prevValid marks which prevVecs hold a value from the current partition. + // A partition boundary invalidates them without freeing the vectors. + prevValid []bool + // prevPartKey / prevPartNull snapshot the partition key of the last row of + // the previous batch, so the first row of the next batch can detect a + // boundary without keeping the old batch alive. + prevPartKey [][]byte + prevPartNull []bool + prevPartSet bool - // next + // next / linear incremental engine. bats is a FIFO of still-pending child + // batches; baseSeq is the absolute sequence number of bats[0], so a + // fillCoord captured as an absolute seq stays valid after the FIFO pops its + // head (local index = seq - baseSeq). toFree holds the batch handed to the + // caller on the previous Call, released at the top of the next one. + // flushable counts the resolved prefix of bats that may be emitted; + // childDone records child EOF. bats []*batch.Batch - preIdx int - preRow int - curIdx int - curRow int - status int - subStatus int - idx int - buf *batch.Batch - i int - doneIdx []int - endBatch []bool + baseSeq int + toFree *batch.Batch + flushable int + childDone bool + // pendingBytes accounts for duplicated batches retained in bats. Once it + // crosses spillThreshold while no prefix is flushable, spill owns the + // unresolved suffix and keeps only one batch resident at a time. + pendingBytes int64 + pendingRows int64 + spillThreshold int64 + spill *fillSpill + // next: per fill-column list of NULL rows still waiting for a following + // value of the same partition. + nextRun [][]fillCoord + // linear: linPre is the last non-NULL row per column (seq < 0 means none in + // the current partition), linRun the NULL run waiting to be interpolated + // between linPre and the next non-NULL. + linPre []fillCoord + linRun [][]fillCoord + // linSeed carries the last original non-NULL value across a completed spill + // segment without pinning the segment's final output batch in memory. + linSeed []*vector.Vector + linSeedValid []bool + // linEntry is the endpoint immediately before bats[0]. Unlike linSeed, + // which follows the currently consumed partition and may be cleared when a + // right endpoint arrives, linEntry advances only when a resolved batch is + // emitted. A spill therefore always starts with the endpoint that belongs + // to the beginning of its persisted suffix. + linEntry []*vector.Vector + linEntryValid []bool + linEntryPart spillPartitionSnapshot + + buf *batch.Batch // linear - nullIdx int - nullRow int - exes []colexec.ExpressionExecutor - done bool + exes []colexec.ExpressionExecutor process func(ctr *container, ap *Fill, proc *process.Process, anal process.Analyzer) (vm.CallResult, error) } @@ -72,7 +105,14 @@ type Fill struct { ColLen int FillType plan.Node_FillType FillVal []*plan.Expr - AggIds []int32 + // SpillThreshold follows the shared colexec convention: zero selects the + // CN-local default, small positive values are row-oriented test thresholds, + // and larger values are bytes. + SpillThreshold int64 + // PartitionColIdx locates the time window's partition keys inside the + // input batch. fill(prev/next/linear) treats a change in these columns as + // a hard boundary: values never cross it in either direction. + PartitionColIdx []int32 vm.OperatorBase colexec.Projection @@ -111,6 +151,9 @@ func (fill *Fill) Release() { func (fill *Fill) Reset(proc *process.Process, pipelineFailed bool, err error) { ctr := &fill.ctr + ctr.cleanupSpill(proc) + ctr.clearLinearSeeds(proc.Mp()) + ctr.clearLinearEntries(proc.Mp()) ctr.resetCtrParma() ctr.resetExes() if ctr.buf != nil { @@ -122,6 +165,11 @@ func (fill *Fill) Reset(proc *process.Process, pipelineFailed bool, err error) { } } ctr.bats = ctr.bats[:0] + // toFree was popped out of bats, so the loop above does not cover it. + if ctr.toFree != nil { + ctr.toFree.Clean(proc.GetMPool()) + ctr.toFree = nil + } if fill.ProjectList != nil { if fill.OpAnalyzer != nil { @@ -133,6 +181,7 @@ func (fill *Fill) Reset(proc *process.Process, pipelineFailed bool, err error) { func (fill *Fill) Free(proc *process.Process, pipelineFailed bool, err error) { ctr := &fill.ctr + ctr.cleanupSpill(proc) ctr.freeBatch(proc.Mp()) ctr.freeExes() ctr.freeVectors(proc.Mp()) @@ -155,6 +204,10 @@ func (ctr *container) freeBatch(mp *mpool.MPool) { b.Clean(mp) } } + if ctr.toFree != nil { + ctr.toFree.Clean(mp) + ctr.toFree = nil + } if ctr.buf != nil { ctr.buf.Clean(mp) ctr.buf = nil @@ -168,6 +221,33 @@ func (ctr *container) freeVectors(mp *mpool.MPool) { } } ctr.prevVecs = nil + ctr.clearLinearSeeds(mp) + ctr.clearLinearEntries(mp) +} + +func (ctr *container) clearLinearSeeds(mp *mpool.MPool) { + for i, vec := range ctr.linSeed { + if vec != nil { + vec.Free(mp) + ctr.linSeed[i] = nil + } + } + for i := range ctr.linSeedValid { + ctr.linSeedValid[i] = false + } +} + +func (ctr *container) clearLinearEntries(mp *mpool.MPool) { + for i, vec := range ctr.linEntry { + if vec != nil { + vec.Free(mp) + ctr.linEntry[i] = nil + } + } + for i := range ctr.linEntryValid { + ctr.linEntryValid[i] = false + } + ctr.linEntryPart = spillPartitionSnapshot{} } func (ctr *container) freeExes() { @@ -188,6 +268,24 @@ func (ctr *container) resetExes() { } func (ctr *container) resetCtrParma() { - ctr.initIndex() - ctr.done = false + ctr.baseSeq = 0 + ctr.flushable = 0 + ctr.childDone = false + ctr.pendingBytes = 0 + ctr.pendingRows = 0 + for i := range ctr.prevValid { + ctr.prevValid[i] = false + } + ctr.prevPartKey = nil + ctr.prevPartNull = nil + ctr.prevPartSet = false + for i := range ctr.nextRun { + ctr.nextRun[i] = ctr.nextRun[i][:0] + } + for i := range ctr.linRun { + ctr.linRun[i] = ctr.linRun[i][:0] + } + for i := range ctr.linPre { + ctr.linPre[i] = fillCoord{seq: -1, row: -1} + } } diff --git a/pkg/sql/colexec/mongoscan/mongoscan.go b/pkg/sql/colexec/mongoscan/mongoscan.go new file mode 100644 index 0000000000000..e895cb5103bf5 --- /dev/null +++ b/pkg/sql/colexec/mongoscan/mongoscan.go @@ -0,0 +1,284 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongoscan + +import ( + "bytes" + "time" + + "github.com/matrixorigin/matrixone/pkg/common/moerr" + moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" + "github.com/matrixorigin/matrixone/pkg/defines" + "github.com/matrixorigin/matrixone/pkg/sql/mongodb" + metric "github.com/matrixorigin/matrixone/pkg/util/metric/v2" + "github.com/matrixorigin/matrixone/pkg/vm" + "github.com/matrixorigin/matrixone/pkg/vm/process" +) + +func (scan *MongoScan) String(buf *bytes.Buffer) { + buf.WriteString("mongoscan: credential-free external source") +} + +func (scan *MongoScan) OpType() vm.OpType { return vm.MongoScan } + +func (scan *MongoScan) Prepare(proc *process.Process) (err error) { + if scan.OpAnalyzer == nil { + scan.OpAnalyzer = process.NewAnalyzer(scan.GetIdx(), scan.IsFirst, scan.IsLast, "mongoscan") + } else { + scan.OpAnalyzer.Reset() + } + if scan.Scan == nil { + return moerr.NewInvalidInput(proc.Ctx, "MongoScan requires a scan specification") + } + if scan.Scan.MaxParallelism != 1 { + return moerr.NewNotSupported(proc.Ctx, "MongoDB MVP requires max_parallelism=1") + } + if scan.Scan.Split != nil { + return moerr.NewNotSupported(proc.Ctx, "MongoDB local split execution is not enabled in the MVP") + } + deps, err := scan.runtimeDependencies(proc) + if err != nil { + return err + } + accountID, err := defines.GetAccountId(proc.Ctx) + if err != nil { + return err + } + if !deps.Config.EnabledFor(accountID) { + return moerr.NewNotSupported(proc.Ctx, "MongoDB external tables are disabled for this account") + } + if deps.Connections == nil || deps.Mappings == nil || deps.Secrets == nil || deps.Pool == nil { + return moerr.NewInternalError(proc.Ctx, "MongoDB runtime dependencies are incomplete") + } + mapping, err := deps.Mappings.ResolveMongoDBMapping( + proc.Ctx, accountID, scan.Scan.MappingId, scan.Scan.MappingVersion) + if err != nil { + return err + } + if !mongodb.MappingSnapshotMatchesPlan(mapping, scan.Scan) { + return moerr.NewInvalidInput(proc.Ctx, "MongoDB table mapping changed after planning; retry the statement") + } + connection, err := deps.Connections.ResolveMongoDBConnection( + proc.Ctx, accountID, scan.Scan.ConnectionId, scan.Scan.ConnectionVersion) + if err != nil { + return err + } + if connection.AccountID != accountID || connection.ConnectionID != scan.Scan.ConnectionId || + connection.Version != scan.Scan.ConnectionVersion || connection.Disabled { + return moerr.NewInvalidInput(proc.Ctx, "MongoDB connection is disabled, stale, or belongs to another account") + } + if deps.Limiter != nil { + scan.ctr.releaseLimit, err = deps.Limiter.Acquire(proc.Ctx, accountID, connection.ConnectionID) + if err != nil { + return err + } + } + defer func() { + if err != nil { + scan.closeResources(proc.Ctx) + } + }() + credentials, err := deps.Secrets.ResolveMongoDBCredentials( + proc.Ctx, accountID, connection.CredentialSecretRef, connection.TLSCASecretRef) + if err != nil { + return moerr.NewInternalError(proc.Ctx, "MongoDB credential resolution failed") + } + lease, err := deps.Pool.Acquire(proc.Ctx, connection, credentials, deps.Config) + if err != nil { + return err + } + scan.ctr.lease = lease + + columns := mongodb.ColumnsFromPlan(scan.Scan.Columns) + scan.ctr.converter, err = mongodb.NewConverter(proc.Ctx, columns, deps.Config.MaxValueBytes) + if err != nil { + return err + } + scan.ctr.converter.SetConversionErrorLimits(deps.Config.MaxConversionErrors, deps.Config.MaxConversionErrorRate) + predicate, err := mongodb.PredicateFromPlan(proc.Ctx, scan.Scan.PushedPredicate) + if err != nil { + return err + } + filter, err := mongodb.PredicateToBSON(proc.Ctx, predicate) + if err != nil { + return err + } + projection := mongodb.ProjectionDocument(columns) + batchRows := deps.Config.BatchRows + if batchRows <= 0 { + batchRows = mongodb.DefaultRuntimeConfig().BatchRows + } + findStarted := time.Now() + scan.ctr.cursor, err = lease.Client().Collection(scan.Scan.Database, scan.Scan.Collection).Find( + proc.Ctx, + mongodb.FindSpec{ + Filter: filter, + Projection: projection, + BatchSize: batchRows, + }, + ) + metric.MongoDBPhaseDurationHistogram.WithLabelValues("find").Observe(time.Since(findStarted).Seconds()) + if err != nil { + metric.MongoDBCursorEventCounter.WithLabelValues("find_error").Inc() + return moerr.NewInternalError(proc.Ctx, "MongoDB find failed") + } + metric.MongoDBCursorEventCounter.WithLabelValues("open").Inc() + scan.ctr.generation++ + scan.ctr.done = false + scan.ctr.rows = 0 + scan.ctr.rawBytes = 0 + scan.ctr.pendingRaw = nil + if scan.ProjectList != nil { + return scan.PrepareProjection(proc) + } + return nil +} + +func (scan *MongoScan) Call(proc *process.Process) (vm.CallResult, error) { + scanStarted := time.Now() + if scan.OpAnalyzer != nil { + defer scan.OpAnalyzer.AddScanTime(scanStarted) + } + result := vm.NewCallResult() + if scan.ctr.done { + result.Status = vm.ExecStop + return result, nil + } + if scan.ctr.cursor == nil || scan.ctr.converter == nil { + result.Status = vm.ExecStop + return result, moerr.NewInternalError(proc.Ctx, "MongoScan is not prepared") + } + if scan.ctr.buf != nil { + scan.ctr.buf.Clean(proc.Mp()) + scan.ctr.buf = nil + } + + deps, err := scan.runtimeDependencies(proc) + if err != nil { + return result, err + } + batchRows := int(deps.Config.BatchRows) + if batchRows <= 0 { + batchRows = int(mongodb.DefaultRuntimeConfig().BatchRows) + } + maxBatchBytes := deps.Config.MaxBatchBytes + if maxBatchBytes <= 0 { + maxBatchBytes = mongodb.DefaultRuntimeConfig().MaxBatchBytes + } + maxRows := firstPositive(scan.Scan.MaxScanRows, deps.Config.MaxScanRows) + maxBytes := firstPositive(scan.Scan.MaxScanBytes, deps.Config.MaxScanBytes) + + bat := scan.ctr.converter.NewBatch() + var currentBatchBytes int64 + for bat.RowCount() < batchRows { + var raw []byte + if scan.ctr.pendingRaw != nil { + raw = scan.ctr.pendingRaw + scan.ctr.pendingRaw = nil + } else { + waitStarted := time.Now() + if !scan.ctr.cursor.Next(proc.Ctx) { + if scan.OpAnalyzer != nil { + scan.OpAnalyzer.WaitStop(waitStarted) + } + metric.MongoDBPhaseDurationHistogram.WithLabelValues("get_more_wait").Observe(time.Since(waitStarted).Seconds()) + if cursorErr := scan.ctr.cursor.Err(); cursorErr != nil { + metric.MongoDBCursorEventCounter.WithLabelValues("error").Inc() + bat.Clean(proc.Mp()) + scan.ctr.done = true + scan.closeResources(proc.Ctx) + return result, moerr.NewInternalError(proc.Ctx, "MongoDB cursor failed") + } + scan.ctr.done = true + scan.closeResources(proc.Ctx) + break + } + if scan.OpAnalyzer != nil { + scan.OpAnalyzer.WaitStop(waitStarted) + } + metric.MongoDBPhaseDurationHistogram.WithLabelValues("get_more_wait").Observe(time.Since(waitStarted).Seconds()) + raw = scan.ctr.cursor.CurrentRaw() + } + if int64(len(raw)) > maxBatchBytes || currentBatchBytes+int64(len(raw)) > maxBatchBytes && bat.RowCount() == 0 { + bat.Clean(proc.Mp()) + scan.ctr.done = true + scan.closeResources(proc.Ctx) + return result, moerr.NewInvalidInput(proc.Ctx, "MongoDB batch byte limit exceeded") + } + if currentBatchBytes+int64(len(raw)) > maxBatchBytes { + // A cursor cannot unread, so retain exactly one bounded document for + // the next Call. Copy because driver-owned Current is reused by Next. + scan.ctr.pendingRaw = append(scan.ctr.pendingRaw[:0], raw...) + break + } + decodeStarted := time.Now() + if err = scan.ctr.converter.AppendDocument(proc.Ctx, bat, raw, proc.Mp()); err != nil { + metric.MongoDBPhaseDurationHistogram.WithLabelValues("decode_append").Observe(time.Since(decodeStarted).Seconds()) + bat.Clean(proc.Mp()) + scan.ctr.done = true + scan.closeResources(proc.Ctx) + return result, err + } + metric.MongoDBPhaseDurationHistogram.WithLabelValues("decode_append").Observe(time.Since(decodeStarted).Seconds()) + metric.MongoDBScanDocumentsCounter.Inc() + metric.MongoDBScanRawBytesCounter.Add(float64(len(raw))) + currentBatchBytes += int64(len(raw)) + scan.ctr.rows++ + scan.ctr.rawBytes += int64(len(raw)) + if maxRows > 0 && scan.ctr.rows > maxRows || maxBytes > 0 && scan.ctr.rawBytes > maxBytes { + bat.Clean(proc.Mp()) + scan.ctr.done = true + scan.closeResources(proc.Ctx) + return result, moerr.NewInvalidInput(proc.Ctx, "MongoDB statement scan limit exceeded") + } + } + if bat.RowCount() == 0 { + bat.Clean(proc.Mp()) + result.Status = vm.ExecStop + return result, nil + } + scan.ctr.buf = bat + scan.OpAnalyzer.Input(bat) + result.Batch, err = scan.ExecProjection(proc, bat) + if err != nil { + scan.ctr.done = true + scan.closeResources(proc.Ctx) + return result, err + } + return result, nil +} + +func (scan *MongoScan) runtimeDependencies(proc *process.Process) (*mongodb.RuntimeDependencies, error) { + if scan.Dependencies != nil { + return scan.Dependencies, nil + } + rt := moruntime.ServiceRuntime(proc.GetService()) + value, ok := rt.GetGlobalVariables(mongodb.RuntimeDependenciesKey) + if !ok && proc.GetService() != "" { + value, ok = moruntime.ServiceRuntime("").GetGlobalVariables(mongodb.RuntimeDependenciesKey) + } + deps, typeOK := value.(*mongodb.RuntimeDependencies) + if !ok || !typeOK || deps == nil { + return nil, moerr.NewInternalError(proc.Ctx, "MongoDB runtime dependencies are not installed on this CN") + } + return deps, nil +} + +func firstPositive(first, fallback int64) int64 { + if first > 0 { + return first + } + return fallback +} diff --git a/pkg/sql/colexec/mongoscan/mongoscan_test.go b/pkg/sql/colexec/mongoscan/mongoscan_test.go new file mode 100644 index 0000000000000..b6f7790845c14 --- /dev/null +++ b/pkg/sql/colexec/mongoscan/mongoscan_test.go @@ -0,0 +1,395 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package mongoscan + +import ( + "context" + "errors" + "sync" + "testing" + + "github.com/matrixorigin/matrixone/pkg/common/mpool" + "github.com/matrixorigin/matrixone/pkg/container/types" + "github.com/matrixorigin/matrixone/pkg/container/vector" + "github.com/matrixorigin/matrixone/pkg/defines" + "github.com/matrixorigin/matrixone/pkg/pb/plan" + "github.com/matrixorigin/matrixone/pkg/sql/mongodb" + "github.com/matrixorigin/matrixone/pkg/testutil" + "github.com/matrixorigin/matrixone/pkg/vm" + "github.com/stretchr/testify/require" + "go.mongodb.org/mongo-driver/v2/bson" +) + +type testConnectionResolver struct{ connection mongodb.Connection } + +func (r testConnectionResolver) ResolveMongoDBConnection(context.Context, uint32, uint64, uint64) (mongodb.Connection, error) { + return r.connection, nil +} + +type testSecretResolver struct{} + +func (testSecretResolver) ResolveMongoDBCredentials(context.Context, uint32, string, string) (mongodb.Credentials, error) { + return mongodb.Credentials{Username: "reader", Password: "not-serialized"}, nil +} + +type testCursor struct { + mu sync.Mutex + docs [][]byte + index int + current []byte + err error + closed int + blocked bool + closeErr error +} + +func (c *testCursor) Next(ctx context.Context) bool { + if c.blocked { + <-ctx.Done() + c.err = context.Cause(ctx) + return false + } + if c.index >= len(c.docs) { + return false + } + c.current = c.docs[c.index] + c.index++ + return true +} +func (c *testCursor) CurrentRaw() []byte { return c.current } +func (c *testCursor) Err() error { return c.err } +func (c *testCursor) Close(ctx context.Context) error { + c.mu.Lock() + c.closed++ + c.closeErr = ctx.Err() + c.mu.Unlock() + return nil +} + +type testCollection struct { + cursor mongodb.Cursor + err error +} + +func (c testCollection) Find(context.Context, mongodb.FindSpec) (mongodb.Cursor, error) { + return c.cursor, c.err +} + +type testClient struct { + collection mongodb.Collection + disconnect int +} + +func (c *testClient) Collection(string, string) mongodb.Collection { return c.collection } +func (*testClient) Ping(context.Context) error { return nil } +func (c *testClient) Disconnect(context.Context) error { c.disconnect++; return nil } + +type testFactory struct{ client mongodb.Client } + +func (f testFactory) Connect(context.Context, mongodb.Connection, mongodb.Credentials, mongodb.RuntimeConfig) (mongodb.Client, error) { + if f.client == nil { + return nil, errors.New("find setup failed") + } + return f.client, nil +} + +type testMappingResolver struct{ mapping mongodb.TableMapping } + +func (r testMappingResolver) ResolveMongoDBMapping(context.Context, uint32, uint64, uint64) (mongodb.TableMapping, error) { + return r.mapping, nil +} + +func testScanDependencies(cursor mongodb.Cursor) (*mongodb.RuntimeDependencies, *testClient) { + connection := mongodb.Connection{AccountID: 7, ConnectionID: 9, Version: 3, CredentialSecretRef: "secret://env/MONGO"} + client := &testClient{collection: testCollection{cursor: cursor}} + cfg := mongodb.DefaultRuntimeConfig() + cfg.Enable = true + cfg.BatchRows = 1 + return &mongodb.RuntimeDependencies{ + Config: cfg, Connections: testConnectionResolver{connection: connection}, Secrets: testSecretResolver{}, + Mappings: testMappingResolver{mapping: mongodb.TableMapping{ + TableID: 7, MappingID: 8, ConnectionID: 9, Database: "db", Collection: "readings", Version: 2, + MaxParallelism: 1, + Columns: []mongodb.ColumnMapping{{Name: "value", Path: "value", TypeID: int32(types.T_int64), Conversion: mongodb.ConversionStrict}}, + }}, + Pool: mongodb.NewClientPool(testFactory{client: client}), Limiter: mongodb.NewSourceLimiter(1), + }, client +} + +func testScanPlan() *plan.MongoScan { + return &plan.MongoScan{ + TableId: 7, MappingId: 8, MappingVersion: 2, ConnectionId: 9, ConnectionVersion: 3, Database: "db", Collection: "readings", MaxParallelism: 1, + Columns: []*plan.MongoColumnMapping{{Name: "value", Path: "value", MoType: plan.Type{Id: int32(types.T_int64)}, ConversionMode: mongodb.ConversionStrict}}, + } +} + +func TestMongoScanMultiBatchLifecycleAndReuse(t *testing.T) { + doc1, err := bson.Marshal(bson.D{{Key: "value", Value: int64(11)}}) + require.NoError(t, err) + doc2, err := bson.Marshal(bson.D{{Key: "value", Value: int64(22)}}) + require.NoError(t, err) + cursor := &testCursor{docs: [][]byte{doc1, doc2}} + deps, client := testScanDependencies(cursor) + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + proc.Ctx = defines.AttachAccountId(proc.Ctx, 7) + scan := NewArgument().WithScan(testScanPlan()) + scan.Dependencies = deps + require.NoError(t, scan.Prepare(proc)) + var values []int64 + for { + result, callErr := scan.Call(proc) + require.NoError(t, callErr) + if result.Batch != nil { + values = append(values, vector.GetFixedAtNoTypeCheck[int64](result.Batch.Vecs[0], 0)) + } + if result.Status == vm.ExecStop { + break + } + } + require.Equal(t, []int64{11, 22}, values) + scan.Reset(proc, false, nil) + scan.Free(proc, false, nil) + scan.Free(proc, false, nil) + require.Equal(t, 1, cursor.closed) + require.NoError(t, deps.Pool.Close(context.Background())) + require.Equal(t, 1, client.disconnect) + proc.Free() + require.Zero(t, proc.Mp().CurrNB()) +} + +func TestMongoScanRejectsMappingSnapshotDriftBeforeConnecting(t *testing.T) { + deps, client := testScanDependencies(&testCursor{}) + resolver := deps.Mappings.(testMappingResolver) + resolver.mapping.Collection = "redirected" + deps.Mappings = resolver + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + proc.Ctx = defines.AttachAccountId(proc.Ctx, 7) + scan := NewArgument().WithScan(testScanPlan()) + scan.Dependencies = deps + require.ErrorContains(t, scan.Prepare(proc), "mapping changed") + scan.Free(proc, true, nil) + require.NoError(t, deps.Pool.Close(t.Context())) + require.Zero(t, client.disconnect, "snapshot drift must fail before opening a MongoDB client") + proc.Free() +} + +func TestMongoScanRejectsUnimplementedSplitBeforeConnecting(t *testing.T) { + deps, client := testScanDependencies(&testCursor{}) + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + proc.Ctx = defines.AttachAccountId(proc.Ctx, 7) + spec := testScanPlan() + spec.Split = &plan.MongoSplit{KeyPath: "ts"} + scan := NewArgument().WithScan(spec) + scan.Dependencies = deps + require.ErrorContains(t, scan.Prepare(proc), "split") + scan.Free(proc, true, nil) + require.NoError(t, deps.Pool.Close(t.Context())) + require.Zero(t, client.disconnect, "unsupported split must fail before opening a MongoDB client") + proc.Free() +} + +func TestMongoScanCancelBlockedGetMore(t *testing.T) { + cursor := &testCursor{blocked: true} + deps, _ := testScanDependencies(cursor) + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + ctx, cancel := context.WithCancel(defines.AttachAccountId(proc.Ctx, 7)) + proc.Ctx = ctx + scan := NewArgument().WithScan(testScanPlan()) + scan.Dependencies = deps + require.NoError(t, scan.Prepare(proc)) + cancel() + _, err := scan.Call(proc) + require.Error(t, err) + scan.Free(proc, true, err) + require.Equal(t, 1, cursor.closed) + require.NoError(t, cursor.closeErr, "cleanup must not inherit the canceled statement context") + require.NoError(t, deps.Pool.Close(context.Background())) + proc.Free() +} + +func TestMongoScanEmptyAndFindFailureReleaseResources(t *testing.T) { + t.Run("empty", func(t *testing.T) { + cursor := &testCursor{} + deps, client := testScanDependencies(cursor) + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + proc.Ctx = defines.AttachAccountId(proc.Ctx, 7) + scan := NewArgument().WithScan(testScanPlan()) + scan.Dependencies = deps + require.NoError(t, scan.Prepare(proc)) + result, err := scan.Call(proc) + require.NoError(t, err) + require.Equal(t, vm.ExecStop, result.Status) + require.Nil(t, result.Batch) + scan.Reset(proc, false, nil) + scan.Free(proc, false, nil) + require.Equal(t, 1, cursor.closed) + require.NoError(t, deps.Pool.Close(context.Background())) + require.Equal(t, 1, client.disconnect) + proc.Free() + require.Zero(t, proc.Mp().CurrNB()) + }) + + t.Run("find-error", func(t *testing.T) { + deps, client := testScanDependencies(nil) + client.collection = testCollection{err: errors.New("injected find error")} + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + proc.Ctx = defines.AttachAccountId(proc.Ctx, 7) + scan := NewArgument().WithScan(testScanPlan()) + scan.Dependencies = deps + require.Error(t, scan.Prepare(proc)) + // Prepare acquired the source semaphore before Find. A second lease can + // succeed only if the error unwind released it. + release, err := deps.Limiter.Acquire(proc.Ctx, 7, 9) + require.NoError(t, err) + release() + scan.Free(proc, true, err) + require.NoError(t, deps.Pool.Close(context.Background())) + require.Equal(t, 1, client.disconnect) + proc.Free() + require.Zero(t, proc.Mp().CurrNB()) + }) +} + +func TestMongoScanCursorErrorAndGenerationReuse(t *testing.T) { + doc1, err := bson.Marshal(bson.D{{Key: "value", Value: int64(11)}}) + require.NoError(t, err) + firstCursor := &testCursor{docs: [][]byte{doc1}, err: errors.New("injected getMore error")} + deps, client := testScanDependencies(firstCursor) + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + proc.Ctx = defines.AttachAccountId(proc.Ctx, 7) + scan := NewArgument().WithScan(testScanPlan()) + scan.Dependencies = deps + require.NoError(t, scan.Prepare(proc)) + result, err := scan.Call(proc) + require.NoError(t, err) + require.Equal(t, int64(11), vector.GetFixedAtNoTypeCheck[int64](result.Batch.Vecs[0], 0)) + _, err = scan.Call(proc) + require.Error(t, err) + require.Equal(t, 1, firstCursor.closed) + + scan.Reset(proc, true, err) + doc2, marshalErr := bson.Marshal(bson.D{{Key: "value", Value: int64(22)}}) + require.NoError(t, marshalErr) + secondCursor := &testCursor{docs: [][]byte{doc2}} + client.collection = testCollection{cursor: secondCursor} + require.NoError(t, scan.Prepare(proc)) + result, err = scan.Call(proc) + require.NoError(t, err) + require.Equal(t, int64(22), vector.GetFixedAtNoTypeCheck[int64](result.Batch.Vecs[0], 0)) + result, err = scan.Call(proc) + require.NoError(t, err) + require.Equal(t, vm.ExecStop, result.Status) + require.Equal(t, 1, secondCursor.closed) + + scan.Free(proc, false, nil) + scan.Free(proc, false, nil) + require.NoError(t, deps.Pool.Close(context.Background())) + require.Equal(t, 1, client.disconnect, "the current client generation is reused across Prepare calls") + proc.Free() + require.Zero(t, proc.Mp().CurrNB()) +} + +func TestMongoScanPartialPrepareFailureReleasesLease(t *testing.T) { + cursor := &testCursor{} + deps, client := testScanDependencies(cursor) + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + proc.Ctx = defines.AttachAccountId(proc.Ctx, 7) + invalid := testScanPlan() + invalid.Columns[0].MoType.Id = int32(types.T_array_float32) + resolver := deps.Mappings.(testMappingResolver) + resolver.mapping.Columns[0].TypeID = int32(types.T_array_float32) + deps.Mappings = resolver + scan := NewArgument().WithScan(invalid) + scan.Dependencies = deps + require.Error(t, scan.Prepare(proc)) + release, err := deps.Limiter.Acquire(proc.Ctx, 7, 9) + require.NoError(t, err) + release() + scan.Free(proc, true, err) + require.Zero(t, cursor.closed, "Find was never reached") + require.NoError(t, deps.Pool.Close(context.Background())) + require.Equal(t, 1, client.disconnect) + proc.Free() + require.Zero(t, proc.Mp().CurrNB()) +} + +func TestMongoScanBatchAndStatementLimits(t *testing.T) { + doc1, err := bson.Marshal(bson.D{{Key: "value", Value: int64(11)}}) + require.NoError(t, err) + doc2, err := bson.Marshal(bson.D{{Key: "value", Value: int64(22)}}) + require.NoError(t, err) + + t.Run("bounded pending document", func(t *testing.T) { + cursor := &testCursor{docs: [][]byte{doc1, doc2}} + deps, _ := testScanDependencies(cursor) + deps.Config.BatchRows = 10 + deps.Config.MaxBatchBytes = int64(len(doc1) + 1) + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + proc.Ctx = defines.AttachAccountId(proc.Ctx, 7) + scan := NewArgument().WithScan(testScanPlan()) + scan.Dependencies = deps + require.NoError(t, scan.Prepare(proc)) + first, err := scan.Call(proc) + require.NoError(t, err) + require.Equal(t, int64(11), vector.GetFixedAtNoTypeCheck[int64](first.Batch.Vecs[0], 0)) + require.LessOrEqual(t, int64(len(scan.ctr.pendingRaw)), deps.Config.MaxBatchBytes) + second, err := scan.Call(proc) + require.NoError(t, err) + require.Equal(t, int64(22), vector.GetFixedAtNoTypeCheck[int64](second.Batch.Vecs[0], 0)) + stop, err := scan.Call(proc) + require.NoError(t, err) + require.Equal(t, vm.ExecStop, stop.Status) + scan.Free(proc, false, nil) + require.NoError(t, deps.Pool.Close(t.Context())) + proc.Free() + require.Zero(t, proc.Mp().CurrNB()) + }) + + t.Run("single document exceeds batch", func(t *testing.T) { + cursor := &testCursor{docs: [][]byte{doc1}} + deps, _ := testScanDependencies(cursor) + deps.Config.MaxBatchBytes = int64(len(doc1) - 1) + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + proc.Ctx = defines.AttachAccountId(proc.Ctx, 7) + scan := NewArgument().WithScan(testScanPlan()) + scan.Dependencies = deps + require.NoError(t, scan.Prepare(proc)) + _, err := scan.Call(proc) + require.ErrorContains(t, err, "batch byte limit") + require.Equal(t, 1, cursor.closed) + scan.Free(proc, true, err) + require.NoError(t, deps.Pool.Close(t.Context())) + proc.Free() + require.Zero(t, proc.Mp().CurrNB()) + }) + + t.Run("statement row limit", func(t *testing.T) { + cursor := &testCursor{docs: [][]byte{doc1, doc2}} + deps, _ := testScanDependencies(cursor) + deps.Config.BatchRows = 10 + deps.Config.MaxScanRows = 1 + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + proc.Ctx = defines.AttachAccountId(proc.Ctx, 7) + scan := NewArgument().WithScan(testScanPlan()) + scan.Dependencies = deps + require.NoError(t, scan.Prepare(proc)) + _, err := scan.Call(proc) + require.ErrorContains(t, err, "statement scan limit") + require.Equal(t, 1, cursor.closed) + scan.Free(proc, true, err) + require.NoError(t, deps.Pool.Close(t.Context())) + proc.Free() + require.Zero(t, proc.Mp().CurrNB()) + }) +} diff --git a/pkg/sql/colexec/mongoscan/types.go b/pkg/sql/colexec/mongoscan/types.go new file mode 100644 index 0000000000000..6ae142a75abb6 --- /dev/null +++ b/pkg/sql/colexec/mongoscan/types.go @@ -0,0 +1,145 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongoscan + +import ( + "context" + "time" + + "github.com/matrixorigin/matrixone/pkg/common/reuse" + "github.com/matrixorigin/matrixone/pkg/container/batch" + "github.com/matrixorigin/matrixone/pkg/pb/plan" + "github.com/matrixorigin/matrixone/pkg/sql/colexec" + "github.com/matrixorigin/matrixone/pkg/sql/mongodb" + metric "github.com/matrixorigin/matrixone/pkg/util/metric/v2" + "github.com/matrixorigin/matrixone/pkg/vm" + "github.com/matrixorigin/matrixone/pkg/vm/process" +) + +const mongoCleanupTimeout = 10 * time.Second + +var _ vm.Operator = new(MongoScan) + +type container struct { + cursor mongodb.Cursor + lease *mongodb.ClientLease + converter *mongodb.Converter + buf *batch.Batch + done bool + rows int64 + rawBytes int64 + generation uint64 + pendingRaw []byte + releaseLimit func() +} + +// MongoScan only performs source I/O and BSON-to-vector conversion. All SQL +// filtering, grouping, time-window aggregation, and writes remain ordinary MO +// operators downstream. +type MongoScan struct { + Scan *plan.MongoScan + + // Dependencies is set only by unit tests and embedded deployments. Normal + // CN execution obtains the same object from the service runtime. + Dependencies *mongodb.RuntimeDependencies + + ctr container + vm.OperatorBase + colexec.Projection +} + +func init() { + reuse.CreatePool[MongoScan]( + func() *MongoScan { return &MongoScan{} }, + func(scan *MongoScan) { *scan = MongoScan{} }, + reuse.DefaultOptions[MongoScan]().WithEnableChecker(), + ) +} + +func NewArgument() *MongoScan { return reuse.Alloc[MongoScan](nil) } + +func (scan *MongoScan) WithScan(spec *plan.MongoScan) *MongoScan { + scan.Scan = spec + return scan +} + +func (scan *MongoScan) GetOperatorBase() *vm.OperatorBase { return &scan.OperatorBase } +func (scan MongoScan) TypeName() string { return "mongoscan" } + +func (scan *MongoScan) Release() { + if scan != nil { + reuse.Free[MongoScan](scan, nil) + } +} + +func (scan *MongoScan) Reset(proc *process.Process, _ bool, _ error) { + scan.closeResources(proc.Ctx) + if scan.ctr.buf != nil { + scan.ctr.buf.Clean(proc.Mp()) + scan.ctr.buf = nil + } + scan.ctr.converter = nil + scan.ctr.done = false + scan.ctr.rows = 0 + scan.ctr.rawBytes = 0 + scan.ctr.pendingRaw = nil + if scan.ProjectList != nil { + if scan.OpAnalyzer != nil { + scan.OpAnalyzer.Alloc(scan.ProjectAllocSize) + } + scan.ResetProjection(proc) + } +} + +func (scan *MongoScan) Free(proc *process.Process, _ bool, _ error) { + scan.closeResources(proc.Ctx) + if scan.ctr.buf != nil { + scan.ctr.buf.Clean(proc.Mp()) + scan.ctr.buf = nil + } + scan.ctr.converter = nil + scan.ctr.pendingRaw = nil + scan.FreeProjection(proc) +} + +func (scan *MongoScan) closeResources(_ context.Context) { + // Reset/Free and cursor-error cleanup frequently run after the statement + // context has been canceled. Give the driver a separate bounded window to + // send killCursors and retire a stale client generation; using the canceled + // statement context would turn cleanup into a no-op, while an unbounded + // background context could stall pipeline teardown indefinitely. + cleanupCtx, cancel := context.WithTimeout(context.Background(), mongoCleanupTimeout) + defer cancel() + if scan.ctr.cursor != nil { + _ = scan.ctr.cursor.Close(cleanupCtx) + metric.MongoDBCursorEventCounter.WithLabelValues("close").Inc() + scan.ctr.cursor = nil + } + if scan.ctr.lease != nil { + _ = scan.ctr.lease.Release(cleanupCtx) + scan.ctr.lease = nil + } + if scan.ctr.releaseLimit != nil { + scan.ctr.releaseLimit() + scan.ctr.releaseLimit = nil + } +} + +func (scan *MongoScan) ExecProjection(proc *process.Process, input *batch.Batch) (*batch.Batch, error) { + if scan.ProjectList == nil { + return input, nil + } + return scan.EvalProjection(input, proc) +} diff --git a/pkg/sql/colexec/timewin/partition_test.go b/pkg/sql/colexec/timewin/partition_test.go new file mode 100644 index 0000000000000..dd347ba048cbe --- /dev/null +++ b/pkg/sql/colexec/timewin/partition_test.go @@ -0,0 +1,670 @@ +// Copyright 2021 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package timewin + +import ( + "testing" + + "github.com/matrixorigin/matrixone/pkg/common/mpool" + "github.com/matrixorigin/matrixone/pkg/container/batch" + "github.com/matrixorigin/matrixone/pkg/container/types" + "github.com/matrixorigin/matrixone/pkg/container/vector" + "github.com/matrixorigin/matrixone/pkg/pb/plan" + "github.com/matrixorigin/matrixone/pkg/sql/colexec" + "github.com/matrixorigin/matrixone/pkg/sql/colexec/aggexec" + "github.com/matrixorigin/matrixone/pkg/sql/plan/function" + "github.com/matrixorigin/matrixone/pkg/testutil" + "github.com/matrixorigin/matrixone/pkg/vm" + "github.com/matrixorigin/matrixone/pkg/vm/process" + "github.com/stretchr/testify/require" +) + +// nullPart stands in for a NULL partition key in the decoded output. +const nullPart = int64(-9999) + +// row is one input tuple: a timestamp, the value to aggregate, and the +// partition key. Input must already be ordered by (part, ts), which is what +// the planner's ORDER BY guarantees. +type row struct { + ts string + val int32 + part int64 +} + +func mustDatetime(t *testing.T, s string) types.Datetime { + t.Helper() + d, err := types.ParseDatetime(s, 0) + require.NoError(t, err) + return d +} + +// makePartInput builds a batch shaped (ts datetime, val int32, part int64). +func makePartInput(t *testing.T, mp *mpool.MPool, rows []row) *batch.Batch { + t.Helper() + ts := make([]string, 0, len(rows)) + vals := make([]int32, 0, len(rows)) + parts := make([]int64, 0, len(rows)) + for _, r := range rows { + ts = append(ts, r.ts) + vals = append(vals, r.val) + parts = append(parts, r.part) + } + + bat := batch.New([]string{"ts", "val", "part"}) + bat.Vecs[0] = testutil.NewVector(len(rows), types.T_datetime.ToType(), mp, false, ts) + bat.Vecs[1] = testutil.NewVector(len(rows), types.T_int32.ToType(), mp, false, vals) + bat.Vecs[2] = testutil.NewVector(len(rows), types.T_int64.ToType(), mp, false, parts) + bat.SetRowCount(len(rows)) + return bat +} + +func newPartArg(t *testing.T, proc *process.Process, sliding types.Datetime, withPartition bool) *TimeWin { + t.Helper() + arg := &TimeWin{ + WStart: true, + WEnd: false, + Types: []types.Type{types.T_int32.ToType()}, + Aggs: []aggexec.AggFuncExecExpression{ + aggexec.MakeAggFunctionExpression( + function.AggSumOverloadID, false, []*plan.Expr{newExpression(1)}, nil), + }, + TsType: plan.Type{Id: int32(types.T_datetime)}, + Ts: newExpression(0), + Interval: makeInterval(), + Sliding: sliding, + } + if withPartition { + partExpr := newExpression(2) + partExpr.Typ = plan.Type{Id: int32(types.T_int64)} + arg.PartitionBy = []*plan.Expr{partExpr} + } + return arg +} + +// runPartArg drives the operator to exhaustion and returns (wstart, max, part) +// per output row. +func runPartArg(t *testing.T, arg *TimeWin, proc *process.Process, in *batch.Batch) (starts []types.Datetime, sums []int64, parts []int64) { + t.Helper() + op := colexec.NewMockOperator().WithBatchs([]*batch.Batch{in}) + arg.Children = nil + arg.AppendChild(op) + require.NoError(t, arg.Prepare(proc)) + + for { + res, err := vm.Exec(arg, proc) + require.NoError(t, err) + if res.Batch == nil || res.Status == vm.ExecStop { + if res.Batch == nil { + break + } + } + bat := res.Batch + n := bat.Vecs[0].Length() + // Layout: [max, _wstart, part...] + sums = append(sums, vector.MustFixedColNoTypeCheck[int64](bat.Vecs[0])[:n]...) + starts = append(starts, vector.MustFixedColNoTypeCheck[types.Datetime](bat.Vecs[1])[:n]...) + if len(arg.PartitionBy) > 0 { + pv := bat.Vecs[2] + for i := 0; i < n; i++ { + switch { + case pv.IsConstNull(): + // A null partition key broadcasts as a const-null vector, + // which carries no data to index. + parts = append(parts, nullPart) + case pv.IsConst(): + parts = append(parts, vector.MustFixedColNoTypeCheck[int64](pv)[0]) + default: + parts = append(parts, vector.MustFixedColNoTypeCheck[int64](pv)[i]) + } + } + } + if res.Status == vm.ExecStop { + break + } + } + return +} + +func TestTimeWinSlidingKeepsDatetimeEpoch(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + sliding, err := calcDatetime(5, types.Second) + require.NoError(t, err) + + in := makePartInput(t, proc.Mp(), []row{ + {"0001-01-01 00:00:00", 10, 1}, + {"0001-01-01 00:00:04", 20, 1}, + {"0001-01-01 00:00:05", 30, 1}, + }) + arg := newPartArg(t, proc, sliding, false) + starts, sums, _ := runPartArg(t, arg, proc, in) + + require.Equal(t, []types.Datetime{ + mustDatetime(t, "0001-01-01 00:00:00"), + mustDatetime(t, "0001-01-01 00:00:05"), + }, starts) + require.Equal(t, []int64{30, 30}, sums) + + arg.Free(proc, false, nil) + in.Clean(proc.Mp()) + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +// Sliding windows carry state across rows, so a partition boundary has to +// restart that state. Each partition must produce exactly the windows it would +// have produced on its own. +func TestTimeWinSlidingPartitionResetsWindowState(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + sliding, err := calcDatetime(5, 2) // 5 seconds, interval is 5s => tumbling-by-slide + require.NoError(t, err) + + in := makePartInput(t, proc.Mp(), []row{ + {"2023-08-01 00:00:00", 10, 1}, + {"2023-08-01 00:00:01", 20, 1}, + {"2023-08-01 00:00:06", 30, 1}, + {"2023-08-01 00:00:00", 100, 2}, + {"2023-08-01 00:00:07", 400, 2}, + }) + + arg := newPartArg(t, proc, sliding, true) + starts, sums, parts := runPartArg(t, arg, proc, in) + + require.Equal(t, []types.Datetime{ + mustDatetime(t, "2023-08-01 00:00:00"), + mustDatetime(t, "2023-08-01 00:00:05"), + mustDatetime(t, "2023-08-01 00:00:00"), + mustDatetime(t, "2023-08-01 00:00:05"), + }, starts) + // Partition 1's sum must never absorb partition 2's rows: a leak of + // partition 2's first row would make the first window 130 instead of 30. + require.Equal(t, []int64{30, 30, 100, 400}, sums) + require.Equal(t, []int64{1, 1, 2, 2}, parts) + + arg.Free(proc, false, nil) + in.Clean(proc.Mp()) + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +// A partition whose last windows are still pending when the boundary arrives +// must emit them before the next partition starts; dropping them silently +// loses rows. +func TestTimeWinPartitionEmitsTrailingWindows(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + sliding, err := calcDatetime(5, 2) + require.NoError(t, err) + + in := makePartInput(t, proc.Mp(), []row{ + // partition 1 spans three windows + {"2023-08-01 00:00:00", 1, 1}, + {"2023-08-01 00:00:06", 2, 1}, + {"2023-08-01 00:00:12", 3, 1}, + // partition 2 has a single row + {"2023-08-01 00:00:00", 9, 2}, + }) + + arg := newPartArg(t, proc, sliding, true) + starts, sums, parts := runPartArg(t, arg, proc, in) + + require.Equal(t, []int64{1, 1, 1, 2}, parts, "partition 1 must not lose its trailing windows") + require.Equal(t, []int64{1, 2, 3, 9}, sums) + require.Len(t, starts, 4) + + arg.Free(proc, false, nil) + in.Clean(proc.Mp()) + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +func TestGapFillGeneratesOnlyInteriorBuckets(t *testing.T) { + for _, tc := range []struct { + name string + gapFill bool + wantStarts []string + wantNull []bool + }{ + {name: "legacy", wantStarts: []string{"2023-08-01 00:00:00", "2023-08-01 00:00:10"}, wantNull: []bool{false, false}}, + {name: "gapfill", gapFill: true, wantStarts: []string{"2023-08-01 00:00:00", "2023-08-01 00:00:05", "2023-08-01 00:00:10"}, wantNull: []bool{false, true, false}}, + } { + t.Run(tc.name, func(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + sliding, err := calcDatetime(5, types.Second) + require.NoError(t, err) + in := makePartInput(t, proc.Mp(), []row{ + {"2023-08-01 00:00:00", 1, 1}, + {"2023-08-01 00:00:12", 3, 1}, + }) + arg := newPartArg(t, proc, sliding, false) + arg.GapFill = tc.gapFill + op := colexec.NewMockOperator().WithBatchs([]*batch.Batch{in}) + arg.AppendChild(op) + require.NoError(t, arg.Prepare(proc)) + var starts []types.Datetime + var nulls []bool + for { + res, callErr := vm.Exec(arg, proc) + require.NoError(t, callErr) + if res.Batch == nil { + break + } + for i := 0; i < res.Batch.RowCount(); i++ { + starts = append(starts, vector.GetFixedAtNoTypeCheck[types.Datetime](res.Batch.Vecs[1], i)) + nulls = append(nulls, res.Batch.Vecs[0].IsNull(uint64(i))) + } + } + want := make([]types.Datetime, len(tc.wantStarts)) + for i := range want { + want[i] = mustDatetime(t, tc.wantStarts[i]) + } + require.Equal(t, want, starts) + require.Equal(t, tc.wantNull, nulls) + arg.Free(proc, false, nil) + in.Clean(proc.Mp()) + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) + }) + } +} + +func TestGapFillResourceAccountingLimits(t *testing.T) { + arg := &TimeWin{GapFill: true} + ctr := container{partitionWindows: maxGapFillRowsPerPartition + 1} + require.ErrorContains(t, ctr.accountGapFillWindow(arg), "partition") + + ctr = container{gapFillWindows: maxGapFillRowsTotal} + require.ErrorContains(t, ctr.accountGapFillWindow(arg), "total") + + ctr = container{partitionWindows: maxGapFillRowsPerPartition - 1, gapFillWindows: maxGapFillRowsTotal - 1} + require.NoError(t, ctr.accountGapFillWindow(arg)) +} + +// A single partition must behave exactly like the unpartitioned operator. +func TestTimeWinSinglePartitionMatchesNoPartition(t *testing.T) { + rows := []row{ + {"2023-08-01 00:00:00", 10, 7}, + {"2023-08-01 00:00:01", 20, 7}, + {"2023-08-01 00:00:06", 30, 7}, + } + sliding, err := calcDatetime(5, 2) + require.NoError(t, err) + + procA := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + inA := makePartInput(t, procA.Mp(), rows) + argA := newPartArg(t, procA, sliding, true) + startsA, sumsA, partsA := runPartArg(t, argA, procA, inA) + + procB := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + inB := makePartInput(t, procB.Mp(), rows) + argB := newPartArg(t, procB, sliding, false) + startsB, sumsB, partsB := runPartArg(t, argB, procB, inB) + + require.Equal(t, startsB, startsA) + require.Equal(t, sumsB, sumsA) + require.Empty(t, partsB) + require.Equal(t, []int64{7, 7}, partsA) + + argA.Free(procA, false, nil) + inA.Clean(procA.Mp()) + procA.Free() + require.Equal(t, int64(0), procA.Mp().CurrNB()) + + argB.Free(procB, false, nil) + inB.Clean(procB.Mp()) + procB.Free() + require.Equal(t, int64(0), procB.Mp().CurrNB()) +} + +// GROUP BY folds NULL keys into one group, so the window must treat two NULL +// keys as the same partition rather than as a boundary. +func TestTimeWinPartitionNullKeysGroupTogether(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + + bat := batch.New([]string{"ts", "val", "part"}) + bat.Vecs[0] = testutil.NewVector(2, types.T_datetime.ToType(), proc.Mp(), false, + []string{"2023-08-01 00:00:00", "2023-08-01 00:00:01"}) + bat.Vecs[1] = testutil.NewVector(2, types.T_int32.ToType(), proc.Mp(), false, []int32{10, 20}) + partVec := testutil.NewVector(2, types.T_int64.ToType(), proc.Mp(), false, []int64{0, 0}) + partVec.GetNulls().Add(0) + partVec.GetNulls().Add(1) + bat.Vecs[2] = partVec + bat.SetRowCount(2) + + sliding, err := calcDatetime(5, 2) + require.NoError(t, err) + arg := newPartArg(t, proc, sliding, true) + _, sums, _ := runPartArg(t, arg, proc, bat) + + // One partition, one window: both rows aggregate together. + require.Equal(t, []int64{30}, sums) + + arg.Free(proc, false, nil) + bat.Clean(proc.Mp()) + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +func TestTimeWinAnyNullPartitionKey(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + rows := []row{ + {"2023-08-01 00:00:00", 10, 0}, + {"2023-08-01 00:00:01", 20, 0}, + {"2023-08-01 00:00:06", 30, 0}, + } + in := makePartInput(t, proc.Mp(), rows) + in.Vecs[2].Free(proc.Mp()) + in.Vecs[2] = vector.NewConstNull(types.T_any.ToType(), len(rows), proc.Mp()) + + sliding, err := calcDatetime(5, 2) + require.NoError(t, err) + arg := newPartArg(t, proc, sliding, true) + arg.PartitionBy[0].Typ = plan.Type{Id: int32(types.T_any)} + + _, sums, parts := runPartArg(t, arg, proc, in) + require.Equal(t, []int64{30, 30}, sums) + require.Equal(t, []int64{nullPart, nullPart}, parts) + + arg.Free(proc, false, nil) + in.Clean(proc.Mp()) + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +func TestAnyPartitionKeyRejectsNonNullValue(t *testing.T) { + mp := mpool.MustNewZero() + typ := types.T_any.ToType() + src := vector.NewVec(typ) + src.SetLength(1) + dst := vector.NewVec(typ) + + err := getPartitionSetFunction(typ, mp)(dst, src, 0, 1) + require.ErrorContains(t, err, "non-NULL T_any partition key") + + src.Free(mp) + dst.Free(mp) + require.Equal(t, int64(0), mp.CurrNB()) +} + +func TestSamePartition(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + ctr := &container{} + ctr.partExe = make([]colexec.ExpressionExecutor, 1) + + v := testutil.NewVector(3, types.T_int64.ToType(), proc.Mp(), false, []int64{5, 5, 9}) + v.GetNulls().Add(2) + ctr.partVec = [][]*vector.Vector{{v}} + + require.True(t, ctr.samePartition(0, 0, 0, 1), "equal keys are one partition") + require.False(t, ctr.samePartition(0, 0, 0, 2), "a null key differs from a non-null one") + require.True(t, ctr.samePartition(0, 2, 0, 2), "a null key equals itself") + + v.Free(proc.Mp()) + proc.Free() +} + +// Without sliding the operator takes the `interval` path, where the child +// aggregate has already reduced each (partition, window) to a single row and +// the operator only decorates it. The partition key must pass straight through +// rather than be broadcast per window. +func TestTimeWinIntervalPathForwardsPartitionKeys(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + + in := makePartInput(t, proc.Mp(), []row{ + {"2023-08-01 00:00:00", 10, 1}, + {"2023-08-01 00:00:06", 30, 1}, + {"2023-08-01 00:00:00", 100, 2}, + }) + + arg := newPartArg(t, proc, 0, true) + // A non-nil EndExpr is what selects the pass-through path. + arg.EndExpr = newExpression(0) + arg.WEnd = true + + op := colexec.NewMockOperator().WithBatchs([]*batch.Batch{in}) + arg.Children = nil + arg.AppendChild(op) + require.NoError(t, arg.Prepare(proc)) + + res, err := vm.Exec(arg, proc) + require.NoError(t, err) + require.NotNil(t, res.Batch) + + // Layout: [sum, _wstart, _wend, part] + require.Len(t, res.Batch.Vecs, 4) + parts := vector.MustFixedColNoTypeCheck[int64](res.Batch.Vecs[3]) + require.Equal(t, []int64{1, 1, 2}, parts[:res.Batch.Vecs[0].Length()], + "each input row keeps its own key on the pass-through path") + + arg.Free(proc, false, nil) + in.Clean(proc.Mp()) + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +// A Reset/Prepare cycle must be a full generation boundary: the second run +// gets the same output a fresh operator would produce, from cursors and +// buffers restarted at zero, and Free still returns every byte. Before the +// fix, the second run resumed through nextWindow with flushed-out aggregate +// state and crashed in GroupGrow. +func TestTimeWinReuseAfterReset(t *testing.T) { + rows := []row{ + {"2023-08-01 00:00:00", 10, 1}, + {"2023-08-01 00:00:01", 20, 1}, + {"2023-08-01 00:00:06", 30, 1}, + {"2023-08-01 00:00:00", 100, 2}, + {"2023-08-01 00:00:07", 400, 2}, + } + sliding, err := calcDatetime(5, 2) + require.NoError(t, err) + + cases := []struct { + name string + withPartition bool + }{ + {"partitioned sliding", true}, + {"sliding without partitions", false}, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + + arg := newPartArg(t, proc, sliding, tc.withPartition) + + // The first generation reads two child batches so its buffers hold + // two entries; the second reads one, which must land in entry 0 + // rather than continue after the stale pair. + bats1 := []*batch.Batch{ + makePartInput(t, proc.Mp(), rows[:3]), + makePartInput(t, proc.Mp(), rows[3:]), + } + starts1, sums1, parts1 := runPartArgBats(t, arg, proc, bats1) + require.NotEmpty(t, sums1) + + arg.Reset(proc, false, nil) + + in2 := makePartInput(t, proc.Mp(), rows) + starts2, sums2, parts2 := runPartArg(t, arg, proc, in2) + + require.Equal(t, starts1, starts2) + require.Equal(t, sums1, sums2) + require.Equal(t, parts1, parts2) + + arg.Free(proc, false, nil) + for _, b := range bats1 { + b.Clean(proc.Mp()) + } + in2.Clean(proc.Mp()) + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) + }) + } +} + +// The interval pass-through path buffers one vector set per child batch, +// indexed by the same cursor; reuse must restart it at zero as well. +func TestTimeWinIntervalPathReuseAfterReset(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + + rows := []row{ + {"2023-08-01 00:00:00", 10, 1}, + {"2023-08-01 00:00:06", 30, 1}, + {"2023-08-01 00:00:00", 100, 2}, + } + + arg := newPartArg(t, proc, 0, true) + // A non-nil EndExpr selects the pass-through path. + arg.EndExpr = newExpression(0) + arg.WEnd = true + + // Layout: [val, _wstart, _wend, part]; the values pass through unreduced. + run := func(in *batch.Batch) (vals []int32, parts []int64) { + op := colexec.NewMockOperator().WithBatchs([]*batch.Batch{in}) + arg.Children = nil + arg.AppendChild(op) + require.NoError(t, arg.Prepare(proc)) + for { + res, err := vm.Exec(arg, proc) + require.NoError(t, err) + if res.Batch == nil { + break + } + n := res.Batch.Vecs[0].Length() + vals = append(vals, vector.MustFixedColNoTypeCheck[int32](res.Batch.Vecs[0])[:n]...) + parts = append(parts, vector.MustFixedColNoTypeCheck[int64](res.Batch.Vecs[3])[:n]...) + if res.Status == vm.ExecStop { + break + } + } + return + } + + in1 := makePartInput(t, proc.Mp(), rows) + vals1, parts1 := run(in1) + require.Equal(t, []int32{10, 30, 100}, vals1) + + arg.Reset(proc, false, nil) + + in2 := makePartInput(t, proc.Mp(), rows) + vals2, parts2 := run(in2) + require.Equal(t, vals1, vals2) + require.Equal(t, parts1, parts2) + + arg.Free(proc, false, nil) + in1.Clean(proc.Mp()) + in2.Clean(proc.Mp()) + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) +} + +// runPartArgBats drives the operator over several child batches; the +// partition state machine must behave identically no matter where the +// batch boundaries fall. +func runPartArgBats(t *testing.T, arg *TimeWin, proc *process.Process, bats []*batch.Batch) (starts []types.Datetime, sums []int64, parts []int64) { + t.Helper() + op := colexec.NewMockOperator().WithBatchs(bats) + arg.Children = nil + arg.AppendChild(op) + require.NoError(t, arg.Prepare(proc)) + + for { + res, err := vm.Exec(arg, proc) + require.NoError(t, err) + if res.Batch == nil { + break + } + bat := res.Batch + n := bat.Vecs[0].Length() + sums = append(sums, vector.MustFixedColNoTypeCheck[int64](bat.Vecs[0])[:n]...) + starts = append(starts, vector.MustFixedColNoTypeCheck[types.Datetime](bat.Vecs[1])[:n]...) + if len(arg.PartitionBy) > 0 { + pv := bat.Vecs[2] + for i := 0; i < n; i++ { + if pv.IsConst() { + parts = append(parts, vector.MustFixedColNoTypeCheck[int64](pv)[0]) + } else { + parts = append(parts, vector.MustFixedColNoTypeCheck[int64](pv)[i]) + } + } + } + if res.Status == vm.ExecStop { + break + } + } + return +} + +// The same rows produce the same windows regardless of how the child chops +// them into batches: one partition spanning two batches, a partition starting +// exactly on a batch's first row, and a boundary in the middle of the second +// batch must all match the single-batch run. +func TestTimeWinPartitionAcrossChildBatches(t *testing.T) { + rows := []row{ + {"2023-08-01 00:00:00", 10, 1}, + {"2023-08-01 00:00:01", 20, 1}, + {"2023-08-01 00:00:06", 30, 1}, + {"2023-08-01 00:00:00", 100, 2}, + {"2023-08-01 00:00:07", 400, 2}, + {"2023-08-01 00:00:02", 7, 3}, + } + splits := []struct { + name string + sizes []int + }{ + {"single batch", []int{6}}, + {"partition 1 spans two batches", []int{2, 4}}, + {"partition 2 starts a new batch", []int{3, 3}}, + {"boundary inside the second batch", []int{3, 2, 1}}, + } + + sliding, err := calcDatetime(5, 2) + require.NoError(t, err) + + var wantStarts []types.Datetime + var wantSums, wantParts []int64 + for _, split := range splits { + sizes := split.sizes + t.Run(split.name, func(t *testing.T) { + proc := testutil.NewProcessWithMPool(t, "", mpool.MustNewZero()) + + var bats []*batch.Batch + offset := 0 + for _, size := range sizes { + bats = append(bats, makePartInput(t, proc.Mp(), rows[offset:offset+size])) + offset += size + } + require.Equal(t, len(rows), offset) + + arg := newPartArg(t, proc, sliding, true) + starts, sums, parts := runPartArgBats(t, arg, proc, bats) + + if wantSums == nil { + // The single-batch run is the reference every split must match. + wantStarts, wantSums, wantParts = starts, sums, parts + require.Equal(t, []int64{30, 30, 100, 400, 7}, sums) + require.Equal(t, []int64{1, 1, 2, 2, 3}, parts) + } else { + require.Equal(t, wantStarts, starts) + require.Equal(t, wantSums, sums) + require.Equal(t, wantParts, parts) + } + + arg.Free(proc, false, nil) + for _, b := range bats { + b.Clean(proc.Mp()) + } + proc.Free() + require.Equal(t, int64(0), proc.Mp().CurrNB()) + }) + } +} diff --git a/pkg/sql/colexec/timewin/timewin.go b/pkg/sql/colexec/timewin/timewin.go index fc4ce8b815f2e..219fe7f501ea0 100644 --- a/pkg/sql/colexec/timewin/timewin.go +++ b/pkg/sql/colexec/timewin/timewin.go @@ -18,6 +18,8 @@ import ( "bytes" "context" + "github.com/matrixorigin/matrixone/pkg/common/moerr" + "github.com/matrixorigin/matrixone/pkg/common/mpool" "github.com/matrixorigin/matrixone/pkg/container/batch" "github.com/matrixorigin/matrixone/pkg/container/types" "github.com/matrixorigin/matrixone/pkg/container/vector" @@ -29,6 +31,12 @@ import ( "github.com/matrixorigin/matrixone/pkg/vm/process" ) +// Some branches encode MySQL's zero datetime as a negative sentinel, distinct +// from the valid 0001-01-01 epoch. Older encodings use zero for that epoch and +// do not support a distinct zero-date value, so they must use normal window +// arithmetic for it. +const hasDistinctZeroDatetimeSentinel = types.ZeroDatetime < types.Datetime(0) + const opName = "time_window" func (timeWin *TimeWin) String(buf *bytes.Buffer) { @@ -49,21 +57,38 @@ func (timeWin *TimeWin) Prepare(proc *process.Process) (err error) { } if len(ctr.aggExe) == 0 { - ctr.aggExe = make([]colexec.ExpressionExecutor, len(timeWin.Aggs)) + ctr.aggExe = make([]colexec.ExprEvalVector, len(timeWin.Aggs)) for i, ag := range timeWin.Aggs { - if expressions := ag.GetArgExpressions(); len(expressions) > 0 { - ctr.aggExe[i], err = colexec.NewExpressionExecutor(proc, expressions[0]) - if err != nil { - return err - } + ctr.aggExe[i], err = colexec.MakeEvalVector(proc, ag.GetArgExpressions()) + if err != nil { + return err } } + } + + // Gated separately from the expression executors: Reset discards the + // aggregate state (it cannot survive a Flush) while keeping the executors, + // so a reused operator arrives here with executors but no aggregates. + if len(ctr.aggs) == 0 { ctr.aggs, err = makeAggExecutors(timeWin, proc, false) if err != nil { return err } } + if len(ctr.partExe) == 0 && len(timeWin.PartitionBy) > 0 { + ctr.partExe = make([]colexec.ExpressionExecutor, len(timeWin.PartitionBy)) + ctr.partSet = make([]func(v, w *vector.Vector, sel int64, length int) error, len(timeWin.PartitionBy)) + for i, expr := range timeWin.PartitionBy { + ctr.partExe[i], err = colexec.NewExpressionExecutor(proc, expr) + if err != nil { + return err + } + ctr.partSet[i] = getPartitionSetFunction( + types.New(types.T(expr.Typ.Id), expr.Typ.Width, expr.Typ.Scale), proc.Mp()) + } + } + if ctr.tsExe == nil { ctr.tsExe, err = colexec.NewExpressionExecutor(proc, timeWin.Ts) if err != nil { @@ -99,6 +124,8 @@ func (timeWin *TimeWin) Prepare(proc *process.Process) (err error) { ctr.tsOid = types.T(timeWin.TsType.Id) ctr.resetParam(timeWin) + // Must match plan.BuildTimeWindowLayout: aggregates, then the boundaries, + // then the partition keys. ctr.colCnt = len(timeWin.Aggs) if timeWin.WStart { ctr.colCnt++ @@ -106,9 +133,29 @@ func (timeWin *TimeWin) Prepare(proc *process.Process) (err error) { if timeWin.WEnd { ctr.colCnt++ } + ctr.colCnt += len(timeWin.PartitionBy) return nil } +func getPartitionSetFunction( + typ types.Type, + mp *mpool.MPool, +) func(v, w *vector.Vector, sel int64, length int) error { + if typ.Oid != types.T_any { + return vector.GetConstSetFunction(typ, mp) + } + + // T_any is the physical type of an untyped NULL literal. It has no value + // representation for GetConstSetFunction to copy, but GROUP BY NULL is a + // valid single partition and its key still occupies an output-layout slot. + return func(v, w *vector.Vector, sel int64, length int) error { + if !w.IsConstNull() && !w.IsNull(uint64(sel)) { + return moerr.NewInternalErrorNoCtx("time window received a non-NULL T_any partition key") + } + return vector.SetConstNull(v, length, mp) + } +} + func (timeWin *TimeWin) Call(proc *process.Process) (vm.CallResult, error) { ctr := &timeWin.ctr var err error @@ -186,6 +233,15 @@ func (timeWin *TimeWin) Call(proc *process.Process) (vm.CallResult, error) { } if ctr.end { + if ctr.zeroWindow { + ctr.last = true + if !ctr.withoutFill { + ctr.wStart = append(ctr.wStart, types.ZeroDatetime) + ctr.wEnd = append(ctr.wEnd, types.ZeroDatetime) + } + ctr.status = flush + break + } if ctr.preVecIdx == ctr.i-1 && ctr.preRowIdx == ctr.tsVec[ctr.preVecIdx].Length()-1 { ctr.last = true @@ -230,9 +286,32 @@ func (timeWin *TimeWin) Call(proc *process.Process) (vm.CallResult, error) { return result, err } - if ctr.last { + switch { + case ctr.last: ctr.status = end - } else { + case ctr.partitionBreak: + // The previous partition is fully emitted. Resume at its first + // foreign row and rebuild the window state from scratch, so + // the new partition's windows are anchored on its own data + // rather than sliding the old partition's state forward. + replacements, err := makeAggExecutors(timeWin, proc, false) + if err != nil { + return result, err + } + ctr.freeAgg() + ctr.aggs = replacements + ctr.curVecIdx = ctr.breakVecIdx + ctr.curRowIdx = ctr.breakRowIdx + ctr.preVecIdx = ctr.breakVecIdx + ctr.preRowIdx = ctr.breakRowIdx + ctr.partIdx = -1 + ctr.group = -1 + ctr.withoutFill = true + ctr.partEnd = false + ctr.partitionBreak = false + ctr.partitionWindows = 0 + ctr.status = firstWindow + default: replacements, err := makeAggExecutors(timeWin, proc, true) if err != nil { return result, err @@ -276,8 +355,17 @@ func makeAggExecutors(timeWin *TimeWin, proc *process.Process, growFirstGroup bo }() for i, expression := range timeWin.Aggs { + params := make([]types.Type, len(expression.GetArgExpressions())) + for j, argument := range expression.GetArgExpressions() { + params[j] = types.New(types.T(argument.Typ.Id), argument.Typ.Width, argument.Typ.Scale) + if j == 0 && params[j].Oid == types.T_any && i < len(timeWin.Types) { + // Older manually-constructed plans/tests keep the physical first + // argument type in TimeWin.Types rather than the expression. + params[j] = timeWin.Types[i] + } + } aggs[i], err = aggexec.MakeAgg( - proc.Mp(), expression.GetAggID(), expression.IsDistinct(), timeWin.Types[i]) + proc.Mp(), expression.GetAggID(), expression.IsDistinct(), params...) if err != nil { return nil, err } @@ -334,7 +422,8 @@ func newTsExpr(typ plan.Type, ctx context.Context) (*plan.Expr, error) { } func (ctr *container) nextWindow(t *TimeWin) error { - if !ctr.withoutFill { + emit := !ctr.withoutFill || t.GapFill + if emit { ctr.wStart = append(ctr.wStart, ctr.left) ctr.wEnd = append(ctr.wEnd, ctr.right) } @@ -348,24 +437,59 @@ func (ctr *container) nextWindow(t *TimeWin) error { ctr.curVecIdx = ctr.preVecIdx ctr.curRowIdx = ctr.preRowIdx - if !ctr.withoutFill { + if emit { for _, ag := range ctr.aggs { if err := ag.GroupGrow(1); err != nil { return err } } ctr.group++ + ctr.partitionWindows++ + if err := ctr.accountGapFillWindow(t); err != nil { + return err + } } + // See firstWindow: the new window is empty until a row lands in it. + ctr.withoutFill = true return nil } func (ctr *container) firstWindow(t *TimeWin) error { + if ctr.partIdx < 0 { + ctr.partitionCount++ + if t.GapFill && ctr.partitionCount > maxGapFillPartitions { + return moerr.NewInvalidInputNoCtx("GAPFILL partition limit exceeded") + } + ctr.partitionWindows = 1 + } else { + ctr.partitionWindows++ + } + if err := ctr.accountGapFillWindow(t); err != nil { + return err + } val := vector.MustFixedColWithTypeCheck[types.Datetime](ctr.tsVec[ctr.curVecIdx])[ctr.curRowIdx] - ctr.left = val - val%t.Interval - ctr.right = ctr.left + t.Interval + if hasDistinctZeroDatetimeSentinel && val == types.ZeroDatetime { + // A zero temporal has no chronological position, but it is a storable + // non-NULL key. Keep it in its own sentinel window instead of letting + // -1 % interval turn it into the valid epoch (0). + ctr.left = types.ZeroDatetime + ctr.right = types.ZeroDatetime + ctr.nextLeft = types.ZeroDatetime + ctr.nextRight = types.ZeroDatetime + ctr.zeroWindow = true + } else { + ctr.left = val - val%t.Interval + ctr.right = ctr.left + t.Interval - ctr.nextLeft = ctr.left + t.Sliding - ctr.nextRight = ctr.nextLeft + t.Interval + ctr.nextLeft = ctr.left + t.Sliding + ctr.nextRight = ctr.nextLeft + t.Interval + ctr.zeroWindow = false + } + + // This row opens the partition every window until the next boundary + // belongs to; fillRows compares against it to spot the change. + ctr.partIdx = ctr.curVecIdx + ctr.partRow = ctr.curRowIdx for _, ag := range ctr.aggs { if err := ag.GroupGrow(1); err != nil { @@ -373,6 +497,11 @@ func (ctr *container) firstWindow(t *TimeWin) error { } } ctr.group++ + // The window is empty until fillRows lands a row in it. This must live at + // window switches, not at the top of fillRows: a window's rows can arrive + // in one batch and its closing row in the next, and resetting the flag + // per batch made such a window look empty and drop from the output. + ctr.withoutFill = true return nil } @@ -381,8 +510,59 @@ func (ctr *container) fillRows() error { vals := vector.MustFixedColNoTypeCheck[types.Datetime](ctr.tsVec[ctr.curVecIdx]) outRange := false - ctr.withoutFill = true + partBreak := false for ; ctr.curRowIdx < cnt; ctr.curRowIdx++ { + if ctr.zeroWindow { + if len(ctr.partExe) > 0 && !ctr.samePartition(ctr.curVecIdx, ctr.curRowIdx, ctr.partIdx, ctr.partRow) { + if !ctr.withoutFill { + ctr.wStart = append(ctr.wStart, types.ZeroDatetime) + ctr.wEnd = append(ctr.wEnd, types.ZeroDatetime) + } + ctr.breakVecIdx = ctr.curVecIdx + ctr.breakRowIdx = ctr.curRowIdx + ctr.partitionBreak = true + ctr.zeroWindow = false + ctr.status = flush + return nil + } + if vals[ctr.curRowIdx] == types.ZeroDatetime { + for j, agg := range ctr.aggs { + if err := agg.Fill(ctr.group, ctr.curRowIdx, ctr.aggVec[ctr.curVecIdx][j]); err != nil { + return err + } + } + ctr.withoutFill = false + ctr.partLastVal = vals[ctr.curRowIdx] + ctr.partLastVecIdx = ctr.curVecIdx + ctr.partLastRowIdx = ctr.curRowIdx + continue + } + + if !ctr.withoutFill { + ctr.wStart = append(ctr.wStart, types.ZeroDatetime) + ctr.wEnd = append(ctr.wEnd, types.ZeroDatetime) + } + ctr.zeroWindow = false + ctr.status = firstWindow + return nil + } + + // Input arrives ordered by partition key, so the first row that + // disagrees with the key this window opened on ends the partition's + // data. Its remaining windows still have to be produced, so record + // where to resume and fall through to the same slide-to-exhaustion + // logic that end-of-stream uses. + if len(ctr.partExe) > 0 && !ctr.samePartition(ctr.curVecIdx, ctr.curRowIdx, ctr.partIdx, ctr.partRow) { + ctr.partEnd = true + ctr.breakVecIdx = ctr.curVecIdx + ctr.breakRowIdx = ctr.curRowIdx + partBreak = true + break + } + ctr.partLastVal = vals[ctr.curRowIdx] + ctr.partLastVecIdx = ctr.curVecIdx + ctr.partLastRowIdx = ctr.curRowIdx + if vals[ctr.curRowIdx] <= ctr.nextLeft { ctr.preVecIdx = ctr.curVecIdx ctr.preRowIdx = ctr.curRowIdx @@ -390,7 +570,7 @@ func (ctr *container) fillRows() error { if vals[ctr.curRowIdx] >= ctr.left && vals[ctr.curRowIdx] < ctr.right { for j, agg := range ctr.aggs { - if err := agg.Fill(ctr.group, ctr.curRowIdx, []*vector.Vector{ctr.aggVec[ctr.curVecIdx][j]}); err != nil { + if err := agg.Fill(ctr.group, ctr.curRowIdx, ctr.aggVec[ctr.curVecIdx][j]); err != nil { return err } } @@ -401,7 +581,21 @@ func (ctr *container) fillRows() error { } } - if outRange { + switch { + case partBreak: + // Same shape as the end-of-stream check in nextBatch, scoped to the + // partition: once the rewind point has reached the partition's last + // row and the next window would start past it, the partition is done. + if ctr.preVecIdx == ctr.partLastVecIdx && ctr.preRowIdx == ctr.partLastRowIdx && + ctr.partLastVal < ctr.nextLeft { + ctr.partitionBreak = true + ctr.wStart = append(ctr.wStart, ctr.left) + ctr.wEnd = append(ctr.wEnd, ctr.right) + ctr.status = flush + } else { + ctr.status = nextWindow + } + case outRange: if ctr.group > maxTimeWindowRows { ctr.wStart = append(ctr.wStart, ctr.left) ctr.wEnd = append(ctr.wEnd, ctr.right) @@ -409,7 +603,7 @@ func (ctr *container) fillRows() error { } else { ctr.status = nextWindow } - } else { + default: ctr.lastVal = vals[cnt-1] ctr.status = nextBatch } @@ -418,13 +612,28 @@ func (ctr *container) fillRows() error { const maxTimeWindowRows = 8192 -func (ctr *container) calRes(ap *TimeWin, proc *process.Process) (err error) { - // The output batch remains owned by TimeWin and is valid until the next - // Call. Once the downstream asks for another result, the previous batch has - // been consumed and must be released before ctr.bat is replaced. - if ctr.bat != nil { - ctr.bat.Clean(proc.Mp()) +const ( + maxGapFillRowsPerPartition = 1_000_000 + maxGapFillPartitions = 100_000 + maxGapFillRowsTotal = 10_000_000 +) + +func (ctr *container) accountGapFillWindow(timeWin *TimeWin) error { + if !timeWin.GapFill { + return nil } + if ctr.partitionWindows > maxGapFillRowsPerPartition { + return moerr.NewInvalidInputNoCtx("GAPFILL generated row limit exceeded for a partition") + } + ctr.gapFillWindows++ + if ctr.gapFillWindows > maxGapFillRowsTotal { + return moerr.NewInvalidInputNoCtx("GAPFILL generated total row limit exceeded") + } + return nil +} + +func (ctr *container) calRes(ap *TimeWin, proc *process.Process) (err error) { + ctr.freeFlushedAggVecs(proc.Mp()) ctr.bat = batch.NewWithSize(ctr.colCnt) i := 0 for _, agg := range ctr.aggs { @@ -442,7 +651,16 @@ func (ctr *container) calRes(ap *TimeWin, proc *process.Process) (err error) { } if !ap.WStart && !ap.WEnd { + if err = ctr.setPartVecsForWindows(i, ctr.bat.Vecs[0].Length(), proc); err != nil { + return err + } batch.SetLength(ctr.bat, ctr.bat.Vecs[0].Length()) + // Sliding execution records boundaries while building groups even when + // pruning removed both boundary columns from the output. A flush closes + // that generation of groups, so retaining the unused bounds here would + // grow these slices for the lifetime of the query. + ctr.wStart = nil + ctr.wEnd = nil return nil } bat := batch.NewWithSize(1) @@ -483,6 +701,11 @@ func (ctr *container) calRes(ap *TimeWin, proc *process.Process) (err error) { if err != nil { return err } + i++ + } + + if err = ctr.setPartVecsForWindows(i, ctr.bat.Vecs[0].Length(), proc); err != nil { + return err } batch.SetLength(ctr.bat, ctr.bat.Vecs[0].Length()) @@ -494,12 +717,15 @@ func (ctr *container) calRes(ap *TimeWin, proc *process.Process) (err error) { func (ctr *container) calResForInterval(ap *TimeWin, proc *process.Process) (err error) { ctr.bat = batch.NewWithSize(ctr.colCnt) i := 0 - for _, vec := range ctr.aggVec[ctr.i-1] { - ctr.bat.SetVector(int32(i), vec) + for _, vecs := range ctr.aggVec[ctr.i-1] { + ctr.bat.SetVector(int32(i), vecs[0]) i++ } if !ap.WStart && !ap.WEnd { + // The partition keys still have to land in their slots, and they sit + // after the (absent) boundaries. + ctr.setPartVecsForInterval(i) batch.SetLength(ctr.bat, ctr.bat.Vecs[0].Length()) return nil } @@ -521,14 +747,78 @@ func (ctr *container) calResForInterval(ap *TimeWin, proc *process.Process) (err if err != nil { return err } + i++ } + ctr.setPartVecsForInterval(i) + batch.SetLength(ctr.bat, ctr.bat.Vecs[0].Length()) ctr.wStart = nil ctr.wEnd = nil return nil } +// setPartVecsForInterval forwards the partition keys row-for-row. Without +// sliding the child aggregate has already reduced each (partition, window) to +// one row, so this path never merges rows and the key passes straight through. +func (ctr *container) setPartVecsForInterval(slot int) { + if len(ctr.partExe) == 0 { + // Without partition keys evalPartVector buffers nothing, so partVec + // has no entry for this batch to read. + return + } + for _, vec := range ctr.partVec[ctr.i-1] { + ctr.bat.SetVector(int32(slot), vec) + slot++ + } +} + +// freeFlushedAggVecs releases the aggregate vectors of the previously flushed +// result. Each flush replaces ctr.bat, and the Flush() results are the only +// vectors that batch owns outright -- the boundaries belong to their expression +// executors and the partition keys to ctr.partOut. Without this, every flush +// after the first orphans a set of aggregate vectors, which partitioning makes +// routine rather than rare. +func (ctr *container) freeFlushedAggVecs(mp *mpool.MPool) { + if ctr.bat == nil { + return + } + for i := 0; i < len(ctr.aggs) && i < len(ctr.bat.Vecs); i++ { + if vec := ctr.bat.Vecs[i]; vec != nil { + vec.Free(mp) + ctr.bat.SetVector(int32(i), nil) + } + } +} + +// setPartVecsForWindows broadcasts the current partition's key across the rows +// being flushed. Sliding windows collapse many input rows into one row per +// window, but a flush never spans partitions, so one key covers the batch. +func (ctr *container) setPartVecsForWindows(slot, length int, proc *process.Process) error { + if len(ctr.partExe) == 0 { + return nil + } + if ctr.partIdx < 0 { + return moerr.NewInternalErrorNoCtx("time window flushed a result before any partition key was seen") + } + if len(ctr.partOut) == 0 { + ctr.partOut = make([]*vector.Vector, len(ctr.partExe)) + } + for p, src := range ctr.partVec[ctr.partIdx] { + if ctr.partOut[p] == nil { + ctr.partOut[p] = vector.NewVec(*src.GetType()) + } else { + ctr.partOut[p].CleanOnlyData() + } + if err := ctr.partSet[p](ctr.partOut[p], src, int64(ctr.partRow), length); err != nil { + return err + } + ctr.bat.SetVector(int32(slot), ctr.partOut[p]) + slot++ + } + return nil +} + func (ctr *container) evalVector(bat *batch.Batch, proc *process.Process) error { if err := ctr.evalTsVector(bat, proc); err != nil { return err @@ -536,10 +826,60 @@ func (ctr *container) evalVector(bat *batch.Batch, proc *process.Process) error if err := ctr.evalAggVector(bat, proc); err != nil { return err } + if err := ctr.evalPartVector(bat, proc); err != nil { + return err + } ctr.i++ return nil } +func (ctr *container) evalPartVector(bat *batch.Batch, proc *process.Process) error { + if len(ctr.partExe) == 0 { + return nil + } + f := len(ctr.partVec) > ctr.i + if !f { + ctr.partVec = append(ctr.partVec, make([]*vector.Vector, len(ctr.partExe))) + } + for i := range ctr.partExe { + vec, err := ctr.partExe[i].Eval(proc, []*batch.Batch{bat}, nil) + if err != nil { + return err + } + if f { + ctr.partVec[ctr.i][i].CleanOnlyData() + if err = ctr.partVec[ctr.i][i].UnionBatch(vec, 0, vec.Length(), nil, proc.Mp()); err != nil { + return err + } + } else { + ctr.partVec[ctr.i][i], err = vec.Dup(proc.Mp()) + if err != nil { + return err + } + } + } + return nil +} + +// samePartition reports whether two buffered rows carry the same partition key. +func (ctr *container) samePartition(vecIdx1, rowIdx1, vecIdx2, rowIdx2 int) bool { + for i := range ctr.partExe { + v1, v2 := ctr.partVec[vecIdx1][i], ctr.partVec[vecIdx2][i] + null1, null2 := v1.IsNull(uint64(rowIdx1)), v2.IsNull(uint64(rowIdx2)) + if null1 || null2 { + // GROUP BY folds NULLs together, so the window must too. + if null1 != null2 { + return false + } + continue + } + if !bytes.Equal(v1.GetRawBytesAt(rowIdx1), v2.GetRawBytesAt(rowIdx2)) { + return false + } + } + return true +} + func (ctr *container) evalTsVector(bat *batch.Batch, proc *process.Process) error { vec, err := ctr.tsExe.Eval(proc, []*batch.Batch{bat}, nil) if err != nil { @@ -565,21 +905,24 @@ func (ctr *container) evalTsVector(bat *batch.Batch, proc *process.Process) erro func (ctr *container) evalAggVector(bat *batch.Batch, proc *process.Process) error { f := len(ctr.aggVec) > ctr.i if !f { - ctr.aggVec = append(ctr.aggVec, make([]*vector.Vector, len(ctr.aggExe))) + ctr.aggVec = append(ctr.aggVec, make([][]*vector.Vector, len(ctr.aggExe))) } for i := range ctr.aggExe { - if ctr.aggExe[i] != nil { - vec, err := ctr.aggExe[i].Eval(proc, []*batch.Batch{bat}, nil) + if !f { + ctr.aggVec[ctr.i][i] = make([]*vector.Vector, len(ctr.aggExe[i].Executor)) + } + for j := range ctr.aggExe[i].Executor { + vec, err := ctr.aggExe[i].Executor[j].Eval(proc, []*batch.Batch{bat}, nil) if err != nil { return err } if f { - ctr.aggVec[ctr.i][i].CleanOnlyData() - if err = ctr.aggVec[ctr.i][i].UnionBatch(vec, 0, vec.Length(), nil, proc.Mp()); err != nil { + ctr.aggVec[ctr.i][i][j].CleanOnlyData() + if err = ctr.aggVec[ctr.i][i][j].UnionBatch(vec, 0, vec.Length(), nil, proc.Mp()); err != nil { return err } } else { - ctr.aggVec[ctr.i][i], err = vec.Dup(proc.Mp()) + ctr.aggVec[ctr.i][i][j], err = vec.Dup(proc.Mp()) if err != nil { return err } diff --git a/pkg/sql/colexec/timewin/timewin_test.go b/pkg/sql/colexec/timewin/timewin_test.go index 20b085ce311b3..c0441443f69a2 100644 --- a/pkg/sql/colexec/timewin/timewin_test.go +++ b/pkg/sql/colexec/timewin/timewin_test.go @@ -191,9 +191,13 @@ func TestTimeWinSplitDistinctResultAndReplace(t *testing.T) { arg.ctr.status = flush arg.ctr.colCnt = 1 arg.ctr.aggs = []aggexec.AggFuncExec{agg} + arg.ctr.wStart = make([]types.Datetime, rows) + arg.ctr.wEnd = make([]types.Datetime, rows) result, err := arg.Call(proc) require.NoError(t, err) require.NotNil(t, result.Batch) + require.Empty(t, arg.ctr.wStart) + require.Empty(t, arg.ctr.wEnd) resultValues := vector.MustFixedColWithTypeCheck[int64](result.Batch.Vecs[0]) require.Len(t, resultValues, rows) for _, idx := range []int{0, aggexec.AggBatchSize - 1, aggexec.AggBatchSize, rows - 1} { @@ -209,10 +213,14 @@ func TestTimeWinSplitDistinctResultAndReplace(t *testing.T) { // released when the second replacement is installed. require.NoError(t, arg.ctr.aggs[0].Fill(0, 0, []*vector.Vector{input})) arg.ctr.status = flush + arg.ctr.wStart = make([]types.Datetime, maxTimeWindowRows+1) + arg.ctr.wEnd = make([]types.Datetime, maxTimeWindowRows+1) secondResult, err := arg.Call(proc) require.NoError(t, err) require.NotNil(t, secondResult.Batch) require.Equal(t, []int64{1}, vector.MustFixedColWithTypeCheck[int64](secondResult.Batch.Vecs[0])) + require.Empty(t, arg.ctr.wStart) + require.Empty(t, arg.ctr.wEnd) arg.Free(proc, false, nil) input.Free(proc.Mp()) diff --git a/pkg/sql/colexec/timewin/types.go b/pkg/sql/colexec/timewin/types.go index fa24a378c15cd..e8b579275f70e 100644 --- a/pkg/sql/colexec/timewin/types.go +++ b/pkg/sql/colexec/timewin/types.go @@ -46,8 +46,16 @@ type container struct { colCnt int i int - aggExe []colexec.ExpressionExecutor - aggVec [][]*vector.Vector + aggExe []colexec.ExprEvalVector + aggVec [][][]*vector.Vector + + partExe []colexec.ExpressionExecutor + partVec [][]*vector.Vector + // partSet broadcasts one input row's partition key across a whole flushed + // batch: every window in a flush belongs to a single partition, because + // the operator flushes at each boundary. + partSet []func(v, w *vector.Vector, sel int64, length int) error + partOut []*vector.Vector tsExe colexec.ExpressionExecutor tsVec []*vector.Vector @@ -78,11 +86,37 @@ type container struct { nextLeft types.Datetime nextRight types.Datetime + // zeroWindow marks the dedicated bucket when MySQL's 0000-00-00 temporal + // has an encoding distinct from the valid 0001-01-01 epoch. + zeroWindow bool withoutFill bool last bool lastVal types.Datetime + + // partIdx / partRow locate the row whose partition key the window + // currently being accumulated belongs to; -1 before the first window. + partIdx int + partRow int + // partEnd mirrors `end` but for one partition: its rows are exhausted, so + // windows keep sliding until they pass the partition's last value. + partEnd bool + // breakVecIdx / breakRowIdx hold the first row of the next partition, the + // row the restart re-anchors on. + breakVecIdx int + breakRowIdx int + // partLast* track the last row seen inside the current partition, playing + // the role `lastVal` and the final buffered row play for the whole stream. + partLastVal types.Datetime + partLastVecIdx int + partLastRowIdx int + // partitionBreak marks that the pending flush ends a partition, so the + // next window must restart rather than slide. + partitionBreak bool + partitionWindows int64 + partitionCount int64 + gapFillWindows int64 } type TimeWin struct { @@ -91,6 +125,11 @@ type TimeWin struct { Types []types.Type Aggs []aggexec.AggFuncExecExpression + // PartitionBy holds the GROUP BY keys other than the window's timestamp. + // Each distinct key value gets its own window sequence, so input must + // arrive ordered by these keys first. + PartitionBy []*plan.Expr + TsType plan.Type Ts *plan.Expr EndExpr *plan.Expr @@ -98,8 +137,9 @@ type TimeWin struct { Interval types.Datetime Sliding types.Datetime - WStart bool - WEnd bool + WStart bool + WEnd bool + GapFill bool vm.OperatorBase } @@ -138,6 +178,20 @@ func (timeWin *TimeWin) Release() { func (timeWin *TimeWin) Reset(proc *process.Process, pipelineFailed bool, err error) { ctr := &timeWin.ctr ctr.resetExes() + // The last flushed batch and the aggregate executors belong to the finished + // generation. In the sliding path the batch owns its aggregate prefix (the + // boundaries belong to their expression executors and the partition keys to + // partOut); in the interval path every vector is a buffer that outlives the + // batch, so only the reference is dropped. Aggregates cannot be rewound + // once Flush has run (see makeAggExecutors), so they are discarded here and + // rebuilt by Prepare. The tsVec/aggVec/partVec buffers stay allocated: with + // the cursors back at zero the next generation reuses them from index 0. + if timeWin.EndExpr == nil { + ctr.freeFlushedAggVecs(proc.Mp()) + } + ctr.bat = nil + ctr.freeAgg() + ctr.aggs = nil ctr.resetParam(timeWin) } @@ -204,6 +258,14 @@ func (timeWin *TimeWin) ExecProjection(proc *process.Process, input *batch.Batch func (ctr *container) resetExes() { for _, exe := range ctr.aggExe { + exe.ResetForNextQuery() + } + for _, exe := range ctr.partExe { + if exe != nil { + exe.ResetForNextQuery() + } + } + for _, exe := range ctr.partExe { if exe != nil { exe.ResetForNextQuery() } @@ -219,20 +281,54 @@ func (ctr *container) resetExes() { } } +// resetParam rewinds every piece of per-generation state, so a Reset/Prepare +// cycle starts from the same blank slate as a fresh operator. Any cursor left +// over from the previous run would either read stale buffered rows or, worse, +// route receive into nextWindow with window bounds that no longer exist. func (ctr *container) resetParam(timeWin *TimeWin) { if timeWin.EndExpr != nil { ctr.status = interval } else { ctr.status = receive } + ctr.i = 0 ctr.end = false ctr.group = -1 ctr.wStart = nil ctr.wEnd = nil + + ctr.curVecIdx = 0 + ctr.curRowIdx = 0 + ctr.preVecIdx = 0 + ctr.preRowIdx = 0 + ctr.left = 0 + ctr.right = 0 + ctr.nextLeft = 0 + ctr.nextRight = 0 + ctr.zeroWindow = false + ctr.withoutFill = false + ctr.last = false + ctr.lastVal = 0 + + ctr.partIdx = -1 + ctr.partRow = 0 + ctr.partEnd = false + ctr.breakVecIdx = 0 + ctr.breakRowIdx = 0 + ctr.partLastVal = 0 + ctr.partLastVecIdx = 0 + ctr.partLastRowIdx = 0 + ctr.partitionBreak = false + ctr.partitionWindows = 0 + ctr.partitionCount = 0 + ctr.gapFillWindows = 0 } func (ctr *container) freeExes() { for _, exe := range ctr.aggExe { + exe.Free() + } + for _, exe := range ctr.partExe { if exe != nil { exe.Free() } @@ -270,12 +366,46 @@ func (ctr *container) freeVector(mp *mpool.MPool) { } ctr.tsVec = nil - for _, vecs := range ctr.aggVec { + for _, aggregateVecs := range ctr.aggVec { + for _, vecs := range aggregateVecs { + for _, vec := range vecs { + if vec != nil { + vec.Free(mp) + } + } + } + } + ctr.aggVec = nil + + for _, vecs := range ctr.partVec { for _, vec := range vecs { if vec != nil { vec.Free(mp) } } } - ctr.aggVec = nil + ctr.partVec = nil + + ctr.freePartOut(mp) + + // calRes only ever hands the *cast results* of these two to the output + // batch; the datetime staging vectors themselves are owned here and were + // never released before. + if ctr.startVec != nil { + ctr.startVec.Free(mp) + ctr.startVec = nil + } + if ctr.endVec != nil { + ctr.endVec.Free(mp) + ctr.endVec = nil + } +} + +func (ctr *container) freePartOut(mp *mpool.MPool) { + for _, vec := range ctr.partOut { + if vec != nil { + vec.Free(mp) + } + } + ctr.partOut = nil } diff --git a/pkg/sql/compile/compile.go b/pkg/sql/compile/compile.go index 03998eb732311..ce99471700813 100644 --- a/pkg/sql/compile/compile.go +++ b/pkg/sql/compile/compile.go @@ -66,6 +66,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/sql/colexec/mergedelete" "github.com/matrixorigin/matrixone/pkg/sql/colexec/mergerecursive" "github.com/matrixorigin/matrixone/pkg/sql/colexec/minus" + "github.com/matrixorigin/matrixone/pkg/sql/colexec/mongoscan" "github.com/matrixorigin/matrixone/pkg/sql/colexec/multi_update" "github.com/matrixorigin/matrixone/pkg/sql/colexec/output" "github.com/matrixorigin/matrixone/pkg/sql/colexec/sample" @@ -73,6 +74,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/sql/colexec/table_scan" "github.com/matrixorigin/matrixone/pkg/sql/colexec/value_scan" "github.com/matrixorigin/matrixone/pkg/sql/crt" + sqlmongodb "github.com/matrixorigin/matrixone/pkg/sql/mongodb" "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" plan2 "github.com/matrixorigin/matrixone/pkg/sql/plan" "github.com/matrixorigin/matrixone/pkg/sql/plan/function" @@ -1836,6 +1838,19 @@ func (c *Compile) compileExternScanWithPlanNodeID(node *plan.Node, planNodeID in } }() + if node.ExternScan != nil && node.ExternScan.Type == int32(plan.ExternType_MONGODB_TB) { + if err := c.hydrateMongoScan(node); err != nil { + return nil, err + } + scope := c.constructScopeForExternal(c.addr, false) + currentFirstFlag := c.anal.isFirst + op := mongoscan.NewArgument().WithScan(node.ExternScan.MongodbScan) + op.SetAnalyzeControl(c.anal.curNodeIdx, currentFirstFlag) + scope.setRootOperator(op) + c.anal.isFirst = false + return []*Scope{scope}, nil + } + err, strictSqlMode := StrictSqlMode(c.proc) if err != nil { return nil, err @@ -1915,6 +1930,116 @@ func (c *Compile) compileExternScanWithPlanNodeID(node *plan.Node, planNodeID in } } +func (c *Compile) hydrateMongoScan(node *plan.Node) error { + if node == nil || node.ExternScan == nil || node.ExternScan.MongodbScan == nil { + return moerr.NewInvalidInput(c.proc.Ctx, "MongoDB external table is missing scan metadata") + } + scan := node.ExternScan.MongodbScan + accountID, err := defines.GetAccountId(c.proc.Ctx) + if err != nil { + return err + } + res, err := c.runSqlWithResultAndOptions( + sqlmongodb.GetMappingByTableIDSQL(accountID, scan.TableId), + NoAccountId, + executor.StatementOption{}.WithDisableLog(), + ) + if err != nil { + return err + } + defer res.Close() + found := false + var parseErr error + res.ReadRows(func(rows int, cols []*vector.Vector) bool { + if rows == 0 || len(cols) < 9 { + return true + } + mappingIDs := executor.GetFixedRows[uint64](cols[0]) + connectionIDs := executor.GetFixedRows[uint64](cols[1]) + versions := executor.GetFixedRows[uint64](cols[2]) + parallelism := executor.GetFixedRows[int32](cols[6]) + disabled := executor.GetFixedRows[uint64](cols[7]) + mappingVersions := executor.GetFixedRows[uint64](cols[8]) + if len(mappingIDs) == 0 || len(connectionIDs) == 0 || len(versions) == 0 || len(parallelism) == 0 || len(disabled) == 0 || len(mappingVersions) == 0 { + parseErr = moerr.NewInternalError(c.proc.Ctx, "MongoDB catalog mapping row has invalid types") + return false + } + if disabled[0] != 0 { + parseErr = moerr.NewInvalidInput(c.proc.Ctx, "MongoDB connection is disabled") + return false + } + var columns []sqlmongodb.ColumnMapping + if err := json.Unmarshal(cols[5].GetBytesAt(0), &columns); err != nil { + parseErr = moerr.NewInternalError(c.proc.Ctx, "MongoDB catalog column mapping is invalid") + return false + } + catalogMapping := sqlmongodb.TableMapping{ + TableID: scan.TableId, MappingID: mappingIDs[0], ConnectionID: connectionIDs[0], + Database: string(cols[3].GetBytesAt(0)), Collection: string(cols[4].GetBytesAt(0)), + Columns: columns, MaxParallelism: parallelism[0], Version: mappingVersions[0], + } + if !sqlmongodb.MappingDefinitionMatchesPlan(catalogMapping, scan) { + parseErr = moerr.NewInvalidInput(c.proc.Ctx, "MongoDB table mapping changed during planning; retry the statement") + return false + } + columns, parseErr = projectedMongoColumns(c.proc.Ctx, columns, node.TableDef) + if parseErr != nil { + return false + } + scan.MappingId = mappingIDs[0] + scan.MappingVersion = mappingVersions[0] + scan.ConnectionId = connectionIDs[0] + scan.ConnectionVersion = versions[0] + scan.Database = string(cols[3].GetBytesAt(0)) + scan.Collection = string(cols[4].GetBytesAt(0)) + scan.Columns = sqlmongodb.ColumnsToPlan(columns) + scan.ProjectedPaths = projectedMongoPlanPaths(columns) + scan.MaxParallelism = parallelism[0] + found = true + return false + }) + if parseErr != nil { + return parseErr + } + if !found { + return moerr.NewInvalidInput(c.proc.Ctx, "MongoDB table mapping does not exist for this account") + } + if scan.MaxParallelism != 1 { + return moerr.NewNotSupported(c.proc.Ctx, "MongoDB MVP requires max_parallelism=1") + } + scan.PushedPredicate, scan.ResidualFilterDigest = sqlmongodb.PushdownPlanFilters(c.proc.Ctx, node.FilterList, scan.Columns) + return nil +} + +func projectedMongoColumns(ctx context.Context, columns []sqlmongodb.ColumnMapping, tableDef *plan.TableDef) ([]sqlmongodb.ColumnMapping, error) { + if tableDef == nil { + return nil, moerr.NewInternalError(ctx, "MongoDB external scan is missing its table definition") + } + names := make([]string, 0, len(tableDef.Cols)) + for _, column := range tableDef.Cols { + if column != nil && !column.Hidden { + names = append(names, column.Name) + } + } + if len(names) == 0 { + return nil, moerr.NewInternalError(ctx, "MongoDB external scan has no retained mapped columns") + } + return sqlmongodb.ProjectColumnsByName(ctx, columns, names) +} + +func projectedMongoPlanPaths(columns []sqlmongodb.ColumnMapping) []string { + result := make([]string, 0, len(columns)) + seen := make(map[string]struct{}, len(columns)) + for _, column := range columns { + if _, ok := seen[column.Path]; ok { + continue + } + seen[column.Path] = struct{}{} + result = append(result, column.Path) + } + return result +} + func (c *Compile) getParallelSizeForExternalScan(node *plan.Node, cpuNum int) int { if node.Stats == nil { return cpuNum @@ -3443,6 +3568,12 @@ func (c *Compile) compileProjection(node *plan.Node, ss []*Scope) []*Scope { } else { c.setProjection(node, ss[i]) } + case *mongoscan.MongoScan: + if op.ProjectList == nil { + op.ProjectList = node.ProjectList + } else { + c.setProjection(node, ss[i]) + } case *group.Group: if op.ProjectList == nil { op.ProjectList = node.ProjectList diff --git a/pkg/sql/compile/ddl.go b/pkg/sql/compile/ddl.go index 9c81258c294ab..812dde2c4ee34 100644 --- a/pkg/sql/compile/ddl.go +++ b/pkg/sql/compile/ddl.go @@ -56,6 +56,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/sql/colexec/lockop" "github.com/matrixorigin/matrixone/pkg/sql/features" sqliceberg "github.com/matrixorigin/matrixone/pkg/sql/iceberg" + sqlmongodb "github.com/matrixorigin/matrixone/pkg/sql/mongodb" "github.com/matrixorigin/matrixone/pkg/sql/parsers" "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect" "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" @@ -1716,6 +1717,9 @@ func (s *Scope) CreateTable(c *Compile) error { ) return err } + if err := c.maybeInsertMongoDBTableMapping(dbSource, main, qry); err != nil { + return err + } var indexExtra *api.SchemaExtra for i, def := range qry.IndexTables { @@ -2084,6 +2088,92 @@ func icebergCreateSQLFromPlanTableDef(tableDef *plan.TableDef) string { return "" } +func (c *Compile) maybeInsertMongoDBTableMapping(dbSource engine.Database, rel engine.Relation, qry *plan.CreateTable) error { + createSQL := icebergCreateSQLFromPlanTableDef(qry.GetTableDef()) + env, found, err := sqlmongodb.ParseCreateSQLEnvelope(c.proc.Ctx, createSQL) + if err != nil || !found { + return err + } + accountID, err := defines.GetAccountId(c.proc.Ctx) + if err != nil { + return err + } + dbIDText := dbSource.GetDatabaseId(c.proc.Ctx) + dbID, err := strconv.ParseUint(dbIDText, 10, 64) + if err != nil || dbID == 0 { + return moerr.NewInternalErrorf(c.proc.Ctx, "invalid database id for MongoDB mapping: %s", dbIDText) + } + connectionID, err := c.lookupMongoDBConnectionID(accountID, env.Connection) + if err != nil { + return err + } + mapping := sqlmongodb.TableMapping{ + AccountID: accountID, DatabaseID: dbID, TableID: rel.GetTableID(c.proc.Ctx), + ConnectionID: connectionID, Connection: env.Connection, + Database: env.Database, Collection: env.Collection, + SchemaMode: env.SchemaMode, Conversion: env.ConversionMode, + SplitKey: env.SplitKey, MaxParallelism: env.MaxParallelism, + Columns: env.Columns, Version: 1, + } + return c.runSqlWithOptions( + sqlmongodb.InsertTableMappingSQL(mapping), + executor.StatementOption{}.WithDisableLog(), + ) +} + +func (c *Compile) lookupMongoDBConnectionID(accountID uint32, name string) (uint64, error) { + res, err := c.runSqlWithResultAndOptions( + sqlmongodb.GetConnectionByNameForUpdateSQL(accountID, name), + NoAccountId, + executor.StatementOption{}.WithDisableLog(), + ) + if err != nil { + return 0, err + } + defer res.Close() + var connectionID uint64 + var disabled bool + res.ReadRows(func(rows int, cols []*vector.Vector) bool { + if rows == 0 || len(cols) < 18 { + return true + } + ids := executor.GetFixedRows[uint64](cols[1]) + disabledValues := executor.GetFixedRows[uint64](cols[17]) + if len(ids) > 0 { + connectionID = ids[0] + } + if len(disabledValues) > 0 { + disabled = disabledValues[0] != 0 + } + return false + }) + if connectionID == 0 || disabled { + return 0, moerr.NewInvalidInputf(c.proc.Ctx, "MongoDB connection %s does not exist or is disabled", name) + } + return connectionID, nil +} + +func (c *Compile) maybeDeleteMongoDBTableMapping(dbSource engine.Database, rel engine.Relation, tableDef *plan.TableDef) error { + createSQL := icebergCreateSQLFromPlanTableDef(tableDef) + _, found, err := sqlmongodb.ParseCreateSQLEnvelope(c.proc.Ctx, createSQL) + if err != nil || !found { + return err + } + accountID, err := defines.GetAccountId(c.proc.Ctx) + if err != nil { + return err + } + dbIDText := dbSource.GetDatabaseId(c.proc.Ctx) + dbID, err := strconv.ParseUint(dbIDText, 10, 64) + if err != nil || dbID == 0 { + return moerr.NewInternalErrorf(c.proc.Ctx, "invalid database id for MongoDB mapping delete: %s", dbIDText) + } + return c.runSqlWithOptions( + sqlmongodb.DeleteTableMappingSQL(accountID, dbID, rel.GetTableID(c.proc.Ctx)), + executor.StatementOption{}.WithDisableLog(), + ) +} + func (c *Compile) runSqlWithSystemTenant(sql string) error { oldCtx := c.proc.Ctx c.proc.Ctx = context.WithValue(oldCtx, defines.TenantIDKey{}, uint32(0)) @@ -3360,6 +3450,9 @@ func (s *Scope) dropTableSingle(c *Compile, qry *plan.DropTable) error { if err := c.maybeDeleteIcebergTableMapping(dbSource, rel, qry.GetTableDef()); err != nil { return err } + if err := c.maybeDeleteMongoDBTableMapping(dbSource, rel, qry.GetTableDef()); err != nil { + return err + } if err := dbSource.Delete(c.proc.Ctx, tblName); err != nil { return err diff --git a/pkg/sql/compile/debugTools.go b/pkg/sql/compile/debugTools.go index 13eea90f36b3c..a530638c39064 100644 --- a/pkg/sql/compile/debugTools.go +++ b/pkg/sql/compile/debugTools.go @@ -58,6 +58,7 @@ var debugInstructionNames = map[vm.OpType]string{ vm.PreInsertUnique: "pre insert uk", vm.PreInsertSecondaryIndex: "pre insert 2nd", vm.External: "external", + vm.MongoScan: "mongodb scan", vm.Source: "source", vm.Minus: "minus", vm.Intersect: "intersect", diff --git a/pkg/sql/compile/operator.go b/pkg/sql/compile/operator.go index 7b43bfdc766e0..bdf2da93ff0a4 100644 --- a/pkg/sql/compile/operator.go +++ b/pkg/sql/compile/operator.go @@ -22,6 +22,7 @@ import ( "strings" "time" + "github.com/gogo/protobuf/proto" "github.com/google/uuid" "github.com/matrixorigin/matrixone/pkg/catalog" "github.com/matrixorigin/matrixone/pkg/common/bitmap" @@ -65,6 +66,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/sql/colexec/mergerecursive" "github.com/matrixorigin/matrixone/pkg/sql/colexec/mergetop" "github.com/matrixorigin/matrixone/pkg/sql/colexec/minus" + "github.com/matrixorigin/matrixone/pkg/sql/colexec/mongoscan" "github.com/matrixorigin/matrixone/pkg/sql/colexec/multi_update" "github.com/matrixorigin/matrixone/pkg/sql/colexec/offset" "github.com/matrixorigin/matrixone/pkg/sql/colexec/order" @@ -395,6 +397,12 @@ func dupOperator(sourceOp vm.Operator, index int, maxParallel int) vm.Operator { op.ProjectList = t.ProjectList op.SetInfo(&info) return op + case vm.MongoScan: + t := sourceOp.(*mongoscan.MongoScan) + op := mongoscan.NewArgument().WithScan(proto.Clone(t.Scan).(*plan.MongoScan)) + op.ProjectList = t.ProjectList + op.SetInfo(&info) + return op case vm.Source: t := sourceOp.(*source.Source) op := source.NewArgument() @@ -1488,48 +1496,36 @@ func constructUnionAll(_ *plan.Node) *unionall.UnionAll { } func constructFill(node *plan.Node) *fill.Fill { - aggIdx := make([]int32, len(node.AggList)) - for i, expr := range node.AggList { - f := expr.Expr.(*plan.Expr_F) - obj := int64(uint64(f.F.Func.Obj) & function.DistinctMask) - aggIdx[i], _ = function.DecodeOverloadID(obj) - } arg := fill.NewArgument() + // AggList is pruned in lockstep with the child TIME_WINDOW's aggregates, + // so this stays aligned with the prefix that child projects. arg.ColLen = len(node.AggList) arg.FillType = node.FillType arg.FillVal = node.FillVal - arg.AggIds = aggIdx + arg.PartitionColIdx = node.TimeWindowPartitionColPos return arg } func constructTimeWindow(_ context.Context, node *plan.Node, proc *process.Process) *timewin.TimeWin { - var aggregationExpressions []aggexec.AggFuncExecExpression = nil - var typs []types.Type - var wStart, wEnd bool - i := 0 - for _, expr := range node.AggList { - if e, ok := expr.Expr.(*plan.Expr_Col); ok { - if e.Col.Name == plan2.TimeWindowStart { - wStart = true - } - if e.Col.Name == plan2.TimeWindowEnd { - wEnd = true - } - continue - } - f := expr.Expr.(*plan.Expr_F) + // The planner addresses this operator's output through the same layout, + // so derive both from BuildTimeWindowLayout rather than re-deriving here. + layout := plan2.BuildTimeWindowLayout(node) + aggregationExpressions := make([]aggexec.AggFuncExecExpression, 0, len(layout.AggIdx)) + typs := make([]types.Type, 0, len(layout.AggIdx)) + for _, aggIdx := range layout.AggIdx { + f := node.AggList[aggIdx].Expr.(*plan.Expr_F) isDistinct := (uint64(f.F.Func.Obj) & function.Distinct) != 0 functionID := int64(uint64(f.F.Func.Obj) & function.DistinctMask) + // Every slot the layout hands out must get an aggregate, or the + // operator's columns stop matching the positions the planner projects. e := f.F.Args[0] - if e != nil { - aggregationExpressions = append( - aggregationExpressions, - aggexec.MakeAggFunctionExpression(functionID, isDistinct, f.F.Args, nil)) - - typs = append(typs, types.New(types.T(e.Typ.Id), e.Typ.Width, e.Typ.Scale)) - } - i++ + aggregationExpressions = append( + aggregationExpressions, + aggexec.MakeAggFunctionExpression(functionID, isDistinct, f.F.Args, nil)) + typs = append(typs, types.New(types.T(e.Typ.Id), e.Typ.Width, e.Typ.Scale)) } + wStart := layout.WStartSlot != plan2.TimeWindowSlotNone + wEnd := layout.WEndSlot != plan2.TimeWindowSlotNone arg := timewin.NewArgument() err := arg.MakeIntervalAndSliding(node.Interval, node.Sliding) @@ -1539,13 +1535,52 @@ func constructTimeWindow(_ context.Context, node *plan.Node, proc *process.Proce arg.Types = typs arg.Aggs = aggregationExpressions arg.Ts = node.GroupBy[0] + arg.PartitionBy = node.TimeWindowPartitionBy + arg.GapFill = node.GapFillMode == plan.Node_GAP_FILL_PARTITION + // A tumbling window normally uses the interval fast path (EndExpr != nil), + // which forwards only groups already produced by the child aggregate. That + // path cannot synthesize absent buckets. GAPFILL therefore uses the general + // sliding-window state machine with a slide equal to the interval; its + // explicit left/right bounds still produce the same tumbling windows. + if arg.GapFill && node.Sliding == nil { + arg.Sliding = arg.Interval + } arg.WStart = wStart arg.WEnd = wEnd - arg.EndExpr = node.WEnd + // The operator evaluates the window-end expression against a batch holding + // only the timestamp, so its column reference has to name slot 0. The + // planner leaves it pointing at the timestamp's GROUP BY position, which is + // 0 only while the window key is the sole grouping key. Copy before + // rewriting: the plan may be reused. + if node.WEnd != nil && !arg.GapFill { + endExpr := plan2.DeepCopyExpr(node.WEnd) + resetTimeWindowTsColRef(endExpr) + arg.EndExpr = endExpr + } arg.TsType = node.Timestamp.Typ return arg } +// resetTimeWindowTsColRef points every column reference in a time-window +// helper expression at slot 0, the single timestamp column the operator feeds +// it. The expression is derived from the window's timestamp, so it can hold no +// other column. +func resetTimeWindowTsColRef(expr *plan.Expr) { + switch e := expr.Expr.(type) { + case *plan.Expr_Col: + e.Col.RelPos = 0 + e.Col.ColPos = 0 + case *plan.Expr_F: + for _, arg := range e.F.Args { + resetTimeWindowTsColRef(arg) + } + case *plan.Expr_List: + for _, item := range e.List.List { + resetTimeWindowTsColRef(item) + } + } +} + func constructWindow(_ context.Context, node *plan.Node, proc *process.Process) *window.Window { aggregationExpressions := make([]aggexec.AggFuncExecExpression, len(node.WinSpecList)) diff --git a/pkg/sql/compile/operator_test.go b/pkg/sql/compile/operator_test.go index 3995dd5c99285..598f1ec5e1269 100644 --- a/pkg/sql/compile/operator_test.go +++ b/pkg/sql/compile/operator_test.go @@ -30,6 +30,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/sql/colexec/multi_update" "github.com/matrixorigin/matrixone/pkg/sql/colexec/shuffle" "github.com/matrixorigin/matrixone/pkg/sql/colexec/shuffleV2" + sqlmongodb "github.com/matrixorigin/matrixone/pkg/sql/mongodb" plan2 "github.com/matrixorigin/matrixone/pkg/sql/plan" "github.com/matrixorigin/matrixone/pkg/sql/plan/function" "github.com/stretchr/testify/require" @@ -220,6 +221,48 @@ func TestConstructTimeWindowUsesRegularSumForPartialSum(t *testing.T) { require.Equal(t, types.T_decimal128, timeWin.Types[0].Oid) } +func TestConstructGapFillDisablesTumblingFastPath(t *testing.T) { + node := &plan.Node{ + NodeType: plan.Node_TIME_WINDOW, + Interval: makeTimeWindowIntervalExpr(1, "minute"), + GroupBy: []*plan.Expr{{Typ: plan.Type{Id: int32(types.T_datetime)}, Expr: &plan.Expr_Col{Col: &plan.ColRef{ColPos: 0}}}}, + Timestamp: &plan.Expr{Typ: plan.Type{Id: int32(types.T_datetime)}}, + WEnd: &plan.Expr{Typ: plan.Type{Id: int32(types.T_datetime)}, Expr: &plan.Expr_Col{Col: &plan.ColRef{ColPos: 0}}}, + GapFillMode: plan.Node_GAP_FILL_PARTITION, + ProjectList: []*plan.Expr{}, + BindingTags: []int32{}, + AggList: []*plan.Expr{}, + } + arg := constructTimeWindow(context.Background(), node, nil) + require.True(t, arg.GapFill) + require.Equal(t, arg.Interval, arg.Sliding) + require.Nil(t, arg.EndExpr, "GAPFILL must not use the existing-window-only interval fast path") + arg.Release() +} + +func TestProjectedMongoColumnsUsesExternalScanLayout(t *testing.T) { + columns := []sqlmongodb.ColumnMapping{ + {Name: "id", Path: "_id"}, + {Name: "pump", Path: "pump"}, + {Name: "value", Path: "value"}, + } + tableDef := &plan.TableDef{Cols: []*plan.ColDef{ + {Name: "value"}, + {Name: "pump"}, + {Name: "__mo_hidden", Hidden: true}, + }} + projected, err := projectedMongoColumns(t.Context(), columns, tableDef) + require.NoError(t, err) + require.Equal(t, []sqlmongodb.ColumnMapping{columns[2], columns[1]}, projected) + + _, err = projectedMongoColumns(t.Context(), columns, &plan.TableDef{Cols: []*plan.ColDef{{Name: "missing"}}}) + require.Error(t, err) + _, err = projectedMongoColumns(t.Context(), columns, nil) + require.Error(t, err) + _, err = projectedMongoColumns(t.Context(), columns, &plan.TableDef{Cols: []*plan.ColDef{{Name: "hidden", Hidden: true}}}) + require.Error(t, err) +} + func TestDupOperatorLoopJoinMarkPos(t *testing.T) { op := loopjoin.NewArgument() op.MarkPos = 3 diff --git a/pkg/sql/compile/remoterun.go b/pkg/sql/compile/remoterun.go index 9e9d86a2fe0c7..6f1aa559ef10c 100644 --- a/pkg/sql/compile/remoterun.go +++ b/pkg/sql/compile/remoterun.go @@ -55,6 +55,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/sql/colexec/mergerecursive" "github.com/matrixorigin/matrixone/pkg/sql/colexec/mergetop" "github.com/matrixorigin/matrixone/pkg/sql/colexec/minus" + "github.com/matrixorigin/matrixone/pkg/sql/colexec/mongoscan" "github.com/matrixorigin/matrixone/pkg/sql/colexec/multi_update" "github.com/matrixorigin/matrixone/pkg/sql/colexec/offset" "github.com/matrixorigin/matrixone/pkg/sql/colexec/order" @@ -737,6 +738,9 @@ func convertToPipelineInstruction(op vm.Operator, proc *process.Process, ctx *sc IcebergDeleteSpillEnabled: t.Es.IcebergDeleteSpillEnabled, } in.ProjectList = t.ProjectList + case *mongoscan.MongoScan: + in.MongodbScan = t.Scan + in.ProjectList = t.ProjectList case *source.Source: in.StreamScan = &pipeline.StreamScan{ TblDef: t.TblDef, @@ -1240,6 +1244,9 @@ func convertToVmOperator(opr *pipeline.Instruction, ctx *scopeContext, eng engin }, ) op.(*external.External).ProjectList = opr.ProjectList + case vm.MongoScan: + op = mongoscan.NewArgument().WithScan(opr.GetMongodbScan()) + op.(*mongoscan.MongoScan).ProjectList = opr.ProjectList case vm.Source: t := opr.GetStreamScan() arg := source.NewArgument() diff --git a/pkg/sql/compile/remoterun_test.go b/pkg/sql/compile/remoterun_test.go index 79d3a3e4e2d8c..dc32a71c5128f 100644 --- a/pkg/sql/compile/remoterun_test.go +++ b/pkg/sql/compile/remoterun_test.go @@ -15,6 +15,7 @@ package compile import ( + "bytes" "context" "errors" "reflect" @@ -64,6 +65,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/sql/colexec/mergerecursive" "github.com/matrixorigin/matrixone/pkg/sql/colexec/mergetop" "github.com/matrixorigin/matrixone/pkg/sql/colexec/minus" + "github.com/matrixorigin/matrixone/pkg/sql/colexec/mongoscan" "github.com/matrixorigin/matrixone/pkg/sql/colexec/multi_update" "github.com/matrixorigin/matrixone/pkg/sql/colexec/offset" "github.com/matrixorigin/matrixone/pkg/sql/colexec/order" @@ -3193,6 +3195,41 @@ func TestDeletionCanTruncateSerializationRoundtrip(t *testing.T) { require.True(t, restored.DeleteCtx.AddAffectedRows) } +func TestMongoScanPipelineRoundTripContainsNoCredential(t *testing.T) { + ctx := &scopeContext{ + id: 0, + plan: &planpb.Plan{}, + scope: &Scope{}, + root: &scopeContext{}, + regs: make(map[*process.WaitRegister]int32), + } + ctx.root = ctx + spec := &planpb.MongoScan{ + TableId: 33, MappingId: 11, MappingVersion: 4, ConnectionId: 22, ConnectionVersion: 3, + Database: "telemetry", Collection: "raw", MaxParallelism: 1, + Columns: []*planpb.MongoColumnMapping{{Name: "pump", Path: "meta.pump", MoType: planpb.Type{Id: int32(types.T_varchar)}}}, + PushedPredicate: &planpb.MongoPredicate{Op: planpb.MongoPredicateOp_MONGO_PREDICATE_EQUAL, Path: "meta.pump", ValueBson: []byte{3, 0, 0, 0, 10, 0}}, + } + original := mongoscan.NewArgument().WithScan(spec) + defer original.Release() + + _, instruction, err := convertToPipelineInstruction(original, nil, ctx, 0) + require.NoError(t, err) + wire, err := instruction.Marshal() + require.NoError(t, err) + for _, forbidden := range []string{"mongodb://", "secret://", "username", "password", "credential", "token"} { + require.False(t, bytes.Contains(bytes.ToLower(wire), []byte(forbidden))) + } + + decoded := new(pipeline.Instruction) + require.NoError(t, decoded.Unmarshal(wire)) + restoredOperator, err := convertToVmOperator(decoded, ctx, nil) + require.NoError(t, err) + restored := restoredOperator.(*mongoscan.MongoScan) + defer restored.Release() + require.Equal(t, spec, restored.Scan) +} + // newDispatchSrcScopeForTest builds a cross-CN shuffle dispatch source scope: // its dispatch sends to localBuckets via LocalRegs (same CN) and to remoteBuckets // via RemoteRegs (other CN), exactly like constructDispatchLocalAndRemote does. diff --git a/pkg/sql/mongodb/catalog_resolver.go b/pkg/sql/mongodb/catalog_resolver.go new file mode 100644 index 0000000000000..ef7069058d97c --- /dev/null +++ b/pkg/sql/mongodb/catalog_resolver.go @@ -0,0 +1,143 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "context" + "encoding/json" + + "github.com/matrixorigin/matrixone/pkg/common/moerr" + "github.com/matrixorigin/matrixone/pkg/container/vector" + "github.com/matrixorigin/matrixone/pkg/util/executor" +) + +type CatalogConnectionResolver struct { + Executor executor.SQLExecutor +} + +type CatalogMappingResolver struct { + Executor executor.SQLExecutor +} + +func (resolver CatalogMappingResolver) ResolveMongoDBMapping( + ctx context.Context, + accountID uint32, + mappingID uint64, + version uint64, +) (TableMapping, error) { + if resolver.Executor == nil { + return TableMapping{}, moerr.NewInternalError(ctx, "MongoDB catalog mapping resolver has no SQL executor") + } + result, err := resolver.Executor.Exec( + ctx, + GetMappingByIDSQL(accountID, mappingID, version), + executor.Options{}. + WithAccountID(accountID). + WithStatementOption(executor.StatementOption{}.WithDisableLog()), + ) + if err != nil { + return TableMapping{}, err + } + defer result.Close() + for _, bat := range result.Batches { + if bat == nil || bat.RowCount() == 0 || len(bat.Vecs) < 14 { + continue + } + row := 0 + mapping := TableMapping{ + AccountID: vector.GetFixedAtWithTypeCheck[uint32](bat.Vecs[0], row), + DatabaseID: vector.GetFixedAtWithTypeCheck[uint64](bat.Vecs[1], row), + TableID: vector.GetFixedAtWithTypeCheck[uint64](bat.Vecs[2], row), + MappingID: vector.GetFixedAtWithTypeCheck[uint64](bat.Vecs[3], row), + ConnectionID: vector.GetFixedAtWithTypeCheck[uint64](bat.Vecs[4], row), + Database: nullableString(bat.Vecs[5], row), + Collection: nullableString(bat.Vecs[6], row), + SchemaMode: nullableString(bat.Vecs[7], row), + Conversion: nullableString(bat.Vecs[8], row), + SplitKey: nullableString(bat.Vecs[9], row), + MaxParallelism: vector.GetFixedAtWithTypeCheck[int32](bat.Vecs[10], row), + OptionsJSON: nullableString(bat.Vecs[12], row), + Version: vector.GetFixedAtWithTypeCheck[uint64](bat.Vecs[13], row), + } + if err := json.Unmarshal(bat.Vecs[11].GetBytesAt(row), &mapping.Columns); err != nil { + return TableMapping{}, moerr.NewInternalError(ctx, "MongoDB catalog column mapping is invalid") + } + if mapping.AccountID != accountID || mapping.MappingID != mappingID || mapping.Version != version { + return TableMapping{}, moerr.NewInvalidInput(ctx, "MongoDB table mapping is stale or belongs to another account") + } + return mapping, nil + } + return TableMapping{}, moerr.NewInvalidInput(ctx, "MongoDB table mapping does not exist at the planned version") +} + +func (resolver CatalogConnectionResolver) ResolveMongoDBConnection( + ctx context.Context, + accountID uint32, + connectionID uint64, + version uint64, +) (Connection, error) { + if resolver.Executor == nil { + return Connection{}, moerr.NewInternalError(ctx, "MongoDB catalog resolver has no SQL executor") + } + result, err := resolver.Executor.Exec( + ctx, + GetConnectionByIDSQL(accountID, connectionID, version), + executor.Options{}. + WithAccountID(accountID). + WithStatementOption(executor.StatementOption{}.WithDisableLog()), + ) + if err != nil { + return Connection{}, err + } + defer result.Close() + for _, bat := range result.Batches { + if bat == nil || bat.RowCount() == 0 || len(bat.Vecs) < 18 { + continue + } + row := 0 + connection := Connection{ + AccountID: vector.GetFixedAtWithTypeCheck[uint32](bat.Vecs[0], row), + ConnectionID: vector.GetFixedAtWithTypeCheck[uint64](bat.Vecs[1], row), + Name: nullableString(bat.Vecs[2], row), + DiscoveryMode: nullableString(bat.Vecs[3], row), + Hosts: nullableString(bat.Vecs[4], row), + SRVHost: nullableString(bat.Vecs[5], row), + ReplicaSet: nullableString(bat.Vecs[6], row), + AuthSource: nullableString(bat.Vecs[7], row), + AuthMechanism: nullableString(bat.Vecs[8], row), + CredentialSecretRef: nullableString(bat.Vecs[9], row), + TLSMode: nullableString(bat.Vecs[10], row), + TLSCASecretRef: nullableString(bat.Vecs[11], row), + ReadPreference: nullableString(bat.Vecs[12], row), + ReadConcern: nullableString(bat.Vecs[13], row), + MaxStalenessSeconds: vector.GetFixedAtWithTypeCheck[int64](bat.Vecs[14], row), + OptionsJSON: nullableString(bat.Vecs[15], row), + Version: vector.GetFixedAtWithTypeCheck[uint64](bat.Vecs[16], row), + Disabled: vector.GetFixedAtWithTypeCheck[uint64](bat.Vecs[17], row) != 0, + } + if connection.AccountID != accountID || connection.ConnectionID != connectionID || connection.Version != version || connection.Disabled { + return Connection{}, moerr.NewInvalidInput(ctx, "MongoDB connection is stale, disabled, or belongs to another account") + } + return connection, nil + } + return Connection{}, moerr.NewInvalidInput(ctx, "MongoDB connection does not exist at the planned version") +} + +func nullableString(vec *vector.Vector, row int) string { + if vec == nil || vec.IsNull(uint64(row)) { + return "" + } + return string(vec.GetBytesAt(row)) +} diff --git a/pkg/sql/mongodb/catalog_resolver_test.go b/pkg/sql/mongodb/catalog_resolver_test.go new file mode 100644 index 0000000000000..15d246df585fb --- /dev/null +++ b/pkg/sql/mongodb/catalog_resolver_test.go @@ -0,0 +1,227 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "errors" + "strings" + "testing" + + "github.com/matrixorigin/matrixone/pkg/common/mpool" + "github.com/matrixorigin/matrixone/pkg/container/types" + "github.com/matrixorigin/matrixone/pkg/container/vector" + "github.com/matrixorigin/matrixone/pkg/util/executor" + "github.com/stretchr/testify/require" +) + +func TestCatalogMappingResolverValidatesSnapshot(t *testing.T) { + ctx := t.Context() + _, err := (CatalogMappingResolver{}).ResolveMongoDBMapping(ctx, 7, 11, 3) + require.ErrorContains(t, err, "no SQL executor") + + wantErr := errors.New("catalog unavailable") + resolver := CatalogMappingResolver{Executor: executor.NewMemExecutor(func(string) (executor.Result, error) { + return executor.Result{}, wantErr + })} + _, err = resolver.ResolveMongoDBMapping(ctx, 7, 11, 3) + require.ErrorIs(t, err, wantErr) + + for _, tc := range []struct { + name string + result func(*testing.T) executor.Result + wantErr string + }{ + {name: "not found", result: func(*testing.T) executor.Result { return executor.Result{} }, wantErr: "does not exist"}, + {name: "short batch", result: newShortCatalogResult, wantErr: "does not exist"}, + {name: "invalid columns", result: func(t *testing.T) executor.Result { + return newMappingCatalogResult(t, 7, 11, 3, "not-json") + }, wantErr: "column mapping is invalid"}, + {name: "stale tenant", result: func(t *testing.T) executor.Result { + return newMappingCatalogResult(t, 8, 11, 3, `[]`) + }, wantErr: "stale or belongs"}, + } { + t.Run(tc.name, func(t *testing.T) { + resolver := CatalogMappingResolver{Executor: executor.NewMemExecutor(func(sql string) (executor.Result, error) { + require.Contains(t, sql, "mapping_id = 11") + return tc.result(t), nil + })} + _, err := resolver.ResolveMongoDBMapping(t.Context(), 7, 11, 3) + require.ErrorContains(t, err, tc.wantErr) + }) + } + + resolver = CatalogMappingResolver{Executor: executor.NewMemExecutor(func(sql string) (executor.Result, error) { + require.Contains(t, sql, "version = 3") + return newMappingCatalogResult(t, 7, 11, 3, `[{"name":"device_id","path":"meta.device_id","type_id":25,"not_nullable":true}]`), nil + })} + mapping, err := resolver.ResolveMongoDBMapping(ctx, 7, 11, 3) + require.NoError(t, err) + require.Equal(t, uint64(101), mapping.DatabaseID) + require.Equal(t, uint64(102), mapping.TableID) + require.Equal(t, uint64(12), mapping.ConnectionID) + require.Equal(t, "telemetry", mapping.Database) + require.Equal(t, "events", mapping.Collection) + require.Equal(t, "strict", mapping.Conversion) + require.Equal(t, int32(1), mapping.MaxParallelism) + require.Equal(t, "device_id", mapping.Columns[0].Name) + require.True(t, mapping.Columns[0].NotNullable) +} + +func TestCatalogConnectionResolverValidatesGeneration(t *testing.T) { + ctx := t.Context() + _, err := (CatalogConnectionResolver{}).ResolveMongoDBConnection(ctx, 7, 12, 3) + require.ErrorContains(t, err, "no SQL executor") + + wantErr := errors.New("catalog unavailable") + resolver := CatalogConnectionResolver{Executor: executor.NewMemExecutor(func(string) (executor.Result, error) { + return executor.Result{}, wantErr + })} + _, err = resolver.ResolveMongoDBConnection(ctx, 7, 12, 3) + require.ErrorIs(t, err, wantErr) + + for _, tc := range []struct { + name string + result func(*testing.T) executor.Result + wantErr string + }{ + {name: "not found", result: func(*testing.T) executor.Result { return executor.Result{} }, wantErr: "does not exist"}, + {name: "short batch", result: newShortCatalogResult, wantErr: "does not exist"}, + {name: "wrong tenant", result: func(t *testing.T) executor.Result { + return newConnectionCatalogResult(t, 8, 12, 3, false) + }, wantErr: "stale, disabled"}, + {name: "disabled", result: func(t *testing.T) executor.Result { + return newConnectionCatalogResult(t, 7, 12, 3, true) + }, wantErr: "stale, disabled"}, + } { + t.Run(tc.name, func(t *testing.T) { + resolver := CatalogConnectionResolver{Executor: executor.NewMemExecutor(func(sql string) (executor.Result, error) { + require.Contains(t, sql, "connection_id = 12") + return tc.result(t), nil + })} + _, err := resolver.ResolveMongoDBConnection(t.Context(), 7, 12, 3) + require.ErrorContains(t, err, tc.wantErr) + }) + } + + resolver = CatalogConnectionResolver{Executor: executor.NewMemExecutor(func(sql string) (executor.Result, error) { + require.Contains(t, sql, "version = 3") + return newConnectionCatalogResult(t, 7, 12, 3, false), nil + })} + connection, err := resolver.ResolveMongoDBConnection(ctx, 7, 12, 3) + require.NoError(t, err) + require.Equal(t, "source", connection.Name) + require.Equal(t, "127.0.0.1:27017", connection.Hosts) + require.Equal(t, "SCRAM-SHA-256", connection.AuthMechanism) + require.Equal(t, int64(120), connection.MaxStalenessSeconds) + require.False(t, connection.Disabled) +} + +func TestCatalogSQLGeneratorsCoverLifecycle(t *testing.T) { + connection := Connection{ + AccountID: 7, ConnectionID: 12, Name: `source\'one`, DiscoveryMode: DiscoverySeeds, + Hosts: "mongo:27017", CredentialSecretRef: "secret://env/MO_MONGODB_SOURCE", + } + mapping := TableMapping{ + AccountID: 7, DatabaseID: 101, TableID: 102, ConnectionID: 12, + Database: "telemetry", Collection: "events", Columns: []ColumnMapping{{Name: "device_id", Path: "meta.device_id", NotNullable: true}}, + } + queries := []string{ + GetConnectionByNameSQL(7, connection.Name), + GetConnectionByNameForUpdateSQL(7, connection.Name), + GetConnectionByIDSQL(7, 12, 3), + GetMappingByTableIDSQL(7, 102), + GetMappingByIDSQL(7, 11, 3), + InsertTableMappingSQL(mapping), + DeleteTableMappingSQL(7, 101, 102), + InsertConnectionSQL(connection), + UpdateConnectionSQL(connection), + DisableConnectionSQL(7, connection.Name), + EnableConnectionSQL(7, connection.Name), + DeleteConnectionSQL(7, 12), + ConnectionDependencyCountSQL(7, 12), + } + for _, query := range queries { + require.NotEmpty(t, query) + require.NotContains(t, query, `source\'one`) + } + require.True(t, strings.HasSuffix(queries[1], " for update")) + require.Contains(t, queries[5], "max_parallelism") + require.Contains(t, queries[5], `"not_nullable":true`) + require.Contains(t, queries[7], "SCRAM-SHA-256") + require.Equal(t, uint64(1), defaultVersion(0)) + require.Equal(t, uint64(4), defaultVersion(4)) +} + +func newShortCatalogResult(t *testing.T) executor.Result { + t.Helper() + mem := executor.NewMemResult([]types.Type{types.T_uint32.ToType()}, mpool.MustNewZero()) + mem.NewBatchWithRowCount(1) + require.NoError(t, executor.AppendFixedRows(mem, 0, []uint32{7})) + return mem.GetResult() +} + +func newMappingCatalogResult(t *testing.T, accountID uint32, mappingID, version uint64, columns string) executor.Result { + t.Helper() + mem := executor.NewMemResult([]types.Type{ + types.T_uint32.ToType(), types.T_uint64.ToType(), types.T_uint64.ToType(), types.T_uint64.ToType(), types.T_uint64.ToType(), + types.T_varchar.ToType(), types.T_varchar.ToType(), types.T_varchar.ToType(), types.T_varchar.ToType(), types.T_varchar.ToType(), + types.T_int32.ToType(), types.T_varchar.ToType(), types.T_varchar.ToType(), types.T_uint64.ToType(), + }, mpool.MustNewZero()) + mem.NewBatchWithRowCount(1) + require.NoError(t, executor.AppendFixedRows(mem, 0, []uint32{accountID})) + for column, value := range map[int]uint64{1: 101, 2: 102, 3: mappingID, 4: 12, 13: version} { + require.NoError(t, executor.AppendFixedRows(mem, column, []uint64{value})) + } + for column, value := range map[int]string{5: "telemetry", 6: "events", 7: "explicit", 8: "strict", 9: "", 11: columns, 12: "{}"} { + require.NoError(t, executor.AppendStringRows(mem, column, []string{value})) + } + require.NoError(t, executor.AppendFixedRows(mem, 10, []int32{1})) + return mem.GetResult() +} + +func newConnectionCatalogResult(t *testing.T, accountID uint32, connectionID, version uint64, disabled bool) executor.Result { + t.Helper() + columnTypes := []types.Type{types.T_uint32.ToType(), types.T_uint64.ToType()} + for range 12 { + columnTypes = append(columnTypes, types.T_varchar.ToType()) + } + columnTypes = append(columnTypes, types.T_int64.ToType(), types.T_varchar.ToType(), types.T_uint64.ToType(), types.T_uint64.ToType()) + mem := executor.NewMemResult(columnTypes, mpool.MustNewZero()) + mem.NewBatchWithRowCount(1) + require.NoError(t, executor.AppendFixedRows(mem, 0, []uint32{accountID})) + require.NoError(t, executor.AppendFixedRows(mem, 1, []uint64{connectionID})) + values := []string{"source", "seeds", "127.0.0.1:27017", "", "rs0", "admin", "SCRAM-SHA-256", "secret://env/MO_MONGODB_SOURCE", "disabled", "", "secondaryPreferred", "majority"} + for index, value := range values { + require.NoError(t, executor.AppendStringRows(mem, index+2, []string{value})) + } + require.NoError(t, executor.AppendFixedRows(mem, 14, []int64{120})) + require.NoError(t, executor.AppendStringRows(mem, 15, []string{"{}"})) + require.NoError(t, executor.AppendFixedRows(mem, 16, []uint64{version})) + flag := uint64(0) + if disabled { + flag = 1 + } + require.NoError(t, executor.AppendFixedRows(mem, 17, []uint64{flag})) + return mem.GetResult() +} + +func TestNullableCatalogString(t *testing.T) { + require.Empty(t, nullableString(nil, 0)) + mp := mpool.MustNewZero() + vec := vector.NewVec(types.T_varchar.ToType()) + require.NoError(t, vector.AppendBytes(vec, nil, true, mp)) + require.Empty(t, nullableString(vec, 0)) + vec.Free(mp) +} diff --git a/pkg/sql/mongodb/catalog_sql.go b/pkg/sql/mongodb/catalog_sql.go new file mode 100644 index 0000000000000..aa82fdca1788f --- /dev/null +++ b/pkg/sql/mongodb/catalog_sql.go @@ -0,0 +1,144 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "encoding/json" + "fmt" + "strings" +) + +func quoteSQLString(value string) string { + // BackgroundExec parses these generated statements with backslash escapes + // enabled. Escape backslashes before quote doubling so a user-controlled + // backslash cannot consume either quote and terminate the SQL literal. + value = strings.ReplaceAll(value, `\`, `\\`) + value = strings.ReplaceAll(value, "'", "''") + return "'" + value + "'" +} + +func nullOrSQLString(value string) string { + if strings.TrimSpace(value) == "" { + return "null" + } + return quoteSQLString(value) +} + +func GetConnectionByNameSQL(accountID uint32, name string) string { + return fmt.Sprintf( + "select account_id,connection_id,name,discovery_mode,hosts,srv_host,replica_set,auth_source,auth_mechanism,credential_secret_ref,tls_mode,tls_ca_secret_ref,read_preference,read_concern,max_staleness_seconds,coalesce(cast(options_json as char),''),version,cast(disabled_at is not null as unsigned) from mo_catalog.%s where account_id = %d and name = %s", + TableConnections, accountID, quoteSQLString(name), + ) +} + +func GetConnectionByNameForUpdateSQL(accountID uint32, name string) string { + return GetConnectionByNameSQL(accountID, name) + " for update" +} + +func GetConnectionByIDSQL(accountID uint32, connectionID, version uint64) string { + return fmt.Sprintf( + "select account_id,connection_id,name,discovery_mode,hosts,srv_host,replica_set,auth_source,auth_mechanism,credential_secret_ref,tls_mode,tls_ca_secret_ref,read_preference,read_concern,max_staleness_seconds,coalesce(cast(options_json as char),''),version,cast(disabled_at is not null as unsigned) from mo_catalog.%s where account_id = %d and connection_id = %d and version = %d", + TableConnections, accountID, connectionID, version, + ) +} + +func GetMappingByTableIDSQL(accountID uint32, tableID uint64) string { + return fmt.Sprintf( + "select m.mapping_id,m.connection_id,c.version,m.database_name,m.collection_name,cast(m.columns_json as char),m.max_parallelism,cast(c.disabled_at is not null as unsigned),m.version from mo_catalog.%s m join mo_catalog.%s c on c.account_id = m.account_id and c.connection_id = m.connection_id where m.account_id = %d and m.table_id = %d", + TableMappings, TableConnections, accountID, tableID, + ) +} + +func GetMappingByIDSQL(accountID uint32, mappingID, version uint64) string { + return fmt.Sprintf( + "select account_id,db_id,table_id,mapping_id,connection_id,database_name,collection_name,schema_mode,conversion_mode,coalesce(split_key,''),max_parallelism,cast(columns_json as char),coalesce(cast(options_json as char),''),version from mo_catalog.%s where account_id = %d and mapping_id = %d and version = %d", + TableMappings, accountID, mappingID, version, + ) +} + +func InsertTableMappingSQL(mapping TableMapping) string { + columns, _ := json.Marshal(mapping.Columns) + return fmt.Sprintf( + "insert into mo_catalog.%s(account_id,db_id,table_id,connection_id,database_name,collection_name,schema_mode,conversion_mode,split_key,max_parallelism,columns_json,options_json,version) values (%d,%d,%d,%d,%s,%s,%s,%s,%s,%d,%s,%s,%d)", + TableMappings, + mapping.AccountID, mapping.DatabaseID, mapping.TableID, mapping.ConnectionID, + quoteSQLString(mapping.Database), quoteSQLString(mapping.Collection), + quoteSQLString(defaultString(mapping.SchemaMode, SchemaExplicit)), + quoteSQLString(defaultString(mapping.Conversion, ConversionStrict)), + nullOrSQLString(mapping.SplitKey), defaultParallelism(mapping.MaxParallelism), + quoteSQLString(string(columns)), nullOrSQLString(mapping.OptionsJSON), + defaultVersion(mapping.Version), + ) +} + +func DeleteTableMappingSQL(accountID uint32, databaseID, tableID uint64) string { + return fmt.Sprintf( + "delete from mo_catalog.%s where account_id = %d and db_id = %d and table_id = %d", + TableMappings, accountID, databaseID, tableID, + ) +} + +func InsertConnectionSQL(connection Connection) string { + return fmt.Sprintf( + "insert into mo_catalog.%s(account_id,name,discovery_mode,hosts,srv_host,replica_set,auth_source,auth_mechanism,credential_secret_ref,tls_mode,tls_ca_secret_ref,read_preference,read_concern,max_staleness_seconds,options_json,version) values (%d,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%d,%s,%d)", + TableConnections, connection.AccountID, quoteSQLString(connection.Name), + quoteSQLString(connection.DiscoveryMode), nullOrSQLString(connection.Hosts), nullOrSQLString(connection.SRVHost), + nullOrSQLString(connection.ReplicaSet), quoteSQLString(defaultString(connection.AuthSource, "admin")), + quoteSQLString(defaultString(connection.AuthMechanism, "SCRAM-SHA-256")), quoteSQLString(connection.CredentialSecretRef), + quoteSQLString(defaultString(connection.TLSMode, "required")), nullOrSQLString(connection.TLSCASecretRef), + quoteSQLString(defaultString(connection.ReadPreference, "secondaryPreferred")), quoteSQLString(defaultString(connection.ReadConcern, "majority")), + connection.MaxStalenessSeconds, nullOrSQLString(connection.OptionsJSON), defaultVersion(connection.Version), + ) +} + +func UpdateConnectionSQL(connection Connection) string { + return fmt.Sprintf( + "update mo_catalog.%s set discovery_mode=%s,hosts=%s,srv_host=%s,replica_set=%s,auth_source=%s,auth_mechanism=%s,credential_secret_ref=%s,tls_mode=%s,tls_ca_secret_ref=%s,read_preference=%s,read_concern=%s,max_staleness_seconds=%d,options_json=%s,updated_at=utc_timestamp,version=version+1 where account_id=%d and name=%s", + TableConnections, quoteSQLString(connection.DiscoveryMode), nullOrSQLString(connection.Hosts), nullOrSQLString(connection.SRVHost), nullOrSQLString(connection.ReplicaSet), + quoteSQLString(defaultString(connection.AuthSource, "admin")), quoteSQLString(defaultString(connection.AuthMechanism, "SCRAM-SHA-256")), + quoteSQLString(connection.CredentialSecretRef), quoteSQLString(defaultString(connection.TLSMode, "required")), nullOrSQLString(connection.TLSCASecretRef), + quoteSQLString(defaultString(connection.ReadPreference, "secondaryPreferred")), quoteSQLString(defaultString(connection.ReadConcern, "majority")), + connection.MaxStalenessSeconds, nullOrSQLString(connection.OptionsJSON), connection.AccountID, quoteSQLString(connection.Name), + ) +} + +func DisableConnectionSQL(accountID uint32, name string) string { + return fmt.Sprintf( + "update mo_catalog.%s set disabled_at=utc_timestamp,updated_at=utc_timestamp,version=version+1 where account_id=%d and name=%s", + TableConnections, accountID, quoteSQLString(name), + ) +} + +func EnableConnectionSQL(accountID uint32, name string) string { + return fmt.Sprintf( + "update mo_catalog.%s set disabled_at=null,updated_at=utc_timestamp,version=version+1 where account_id=%d and name=%s", + TableConnections, accountID, quoteSQLString(name), + ) +} + +func DeleteConnectionSQL(accountID uint32, connectionID uint64) string { + return fmt.Sprintf("delete from mo_catalog.%s where account_id=%d and connection_id=%d", TableConnections, accountID, connectionID) +} + +func ConnectionDependencyCountSQL(accountID uint32, connectionID uint64) string { + return fmt.Sprintf("select count(*) from mo_catalog.%s where account_id=%d and connection_id=%d", TableMappings, accountID, connectionID) +} + +func defaultVersion(version uint64) uint64 { + if version == 0 { + return 1 + } + return version +} diff --git a/pkg/sql/mongodb/converter.go b/pkg/sql/mongodb/converter.go new file mode 100644 index 0000000000000..2178454106ec7 --- /dev/null +++ b/pkg/sql/mongodb/converter.go @@ -0,0 +1,447 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "context" + "errors" + "math" + "strconv" + "strings" + "time" + "unicode/utf8" + + "github.com/matrixorigin/matrixone/pkg/common/moerr" + "github.com/matrixorigin/matrixone/pkg/common/mpool" + "github.com/matrixorigin/matrixone/pkg/container/batch" + "github.com/matrixorigin/matrixone/pkg/container/types" + "github.com/matrixorigin/matrixone/pkg/container/vector" + metric "github.com/matrixorigin/matrixone/pkg/util/metric/v2" + "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore" +) + +const conversionErrorRateMinAttempts = 100 + +type Converter struct { + columns []ColumnMapping + maxValueBytes int64 + maxConversionErrors int64 + maxConversionErrorRate float64 + conversionAttempts int64 + conversionErrors int64 +} + +func NewConverter(ctx context.Context, columns []ColumnMapping, maxValueBytes int64) (*Converter, error) { + if len(columns) == 0 { + return nil, moerr.NewInvalidInput(ctx, "MongoDB scan requires explicit column mappings") + } + seen := make(map[string]struct{}, len(columns)) + for i := range columns { + if columns[i].Name == "" { + return nil, moerr.NewInvalidInput(ctx, "MongoDB mapped column name cannot be empty") + } + if _, ok := seen[strings.ToLower(columns[i].Name)]; ok { + return nil, moerr.NewInvalidInput(ctx, "MongoDB mapped column names must be unique") + } + seen[strings.ToLower(columns[i].Name)] = struct{}{} + if columns[i].Path == "" { + columns[i].Path = columns[i].Name + } + if err := ValidateBSONPath(ctx, columns[i].Path); err != nil { + return nil, err + } + if columns[i].Conversion == "" { + columns[i].Conversion = ConversionStrict + } + if columns[i].Conversion != ConversionStrict && columns[i].Conversion != ConversionTryNull { + return nil, moerr.NewInvalidInput(ctx, "MongoDB conversion mode must be strict or try_null") + } + if !supportedMOType(types.T(columns[i].TypeID)) { + return nil, moerr.NewNotSupportedf(ctx, "MongoDB mapping target type %s", types.T(columns[i].TypeID).String()) + } + } + if maxValueBytes <= 0 { + maxValueBytes = DefaultRuntimeConfig().MaxValueBytes + } + defaults := DefaultRuntimeConfig() + return &Converter{ + columns: columns, maxValueBytes: maxValueBytes, + maxConversionErrors: defaults.MaxConversionErrors, + maxConversionErrorRate: defaults.MaxConversionErrorRate, + }, nil +} + +// SetConversionErrorLimits configures statement-local try_null protection. +// The converter itself is statement-scoped, so Reset/Prepare starts fresh +// counters without sharing mutable state across operators. +func (c *Converter) SetConversionErrorLimits(maxErrors int64, maxRate float64) { + defaults := DefaultRuntimeConfig() + if maxErrors <= 0 { + maxErrors = defaults.MaxConversionErrors + } + if maxRate <= 0 || maxRate > 1 { + maxRate = defaults.MaxConversionErrorRate + } + c.maxConversionErrors = maxErrors + c.maxConversionErrorRate = maxRate +} + +func (c *Converter) ConversionErrors() int64 { return c.conversionErrors } + +func (c *Converter) Columns() []ColumnMapping { + return append([]ColumnMapping(nil), c.columns...) +} + +func (c *Converter) NewBatch() *batch.Batch { + attrs := make([]string, len(c.columns)) + bat := batch.NewWithSize(len(c.columns)) + for i, column := range c.columns { + attrs[i] = column.Name + bat.Vecs[i] = vector.NewVec(types.New(types.T(column.TypeID), column.Width, column.Scale)) + } + bat.Attrs = attrs + return bat +} + +func (c *Converter) AppendDocument(ctx context.Context, bat *batch.Batch, raw []byte, mp *mpool.MPool) error { + if int64(len(raw)) > c.maxValueBytes { + return moerr.NewInvalidInput(ctx, "MongoDB BSON document exceeds max-value-bytes") + } + doc := bson.Raw(raw) + if err := doc.Validate(); err != nil { + return moerr.NewInvalidInput(ctx, "MongoDB returned invalid BSON") + } + startRows := bat.RowCount() + committed := false + defer func() { + if !committed { + for _, vec := range bat.Vecs { + vec.SetLength(startRows) + } + bat.SetRowCount(startRows) + } + }() + for i, column := range c.columns { + value, found, lookupErr := lookupScalarPath(doc, column.Path) + if !found || lookupErr == nil && (value.Type == bson.TypeNull || value.Type == bson.TypeUndefined) { + if column.NotNullable { + return mongoDBNotNullError(ctx, column) + } + if appendErr := vector.AppendNull(bat.Vecs[i], mp); appendErr != nil { + return appendErr + } + continue + } + if column.Conversion == ConversionTryNull { + c.conversionAttempts++ + } + appendErr := lookupErr + if appendErr == nil { + appendErr = c.appendValue(bat.Vecs[i], value, column, mp) + } + if err := appendErr; err != nil { + if errors.Is(err, errConversion) && column.Conversion == ConversionTryNull { + c.conversionErrors++ + metric.MongoDBConversionErrorCounter.Inc() + if column.NotNullable { + return mongoDBNotNullError(ctx, column) + } + if c.conversionErrors > c.maxConversionErrors || + c.conversionAttempts >= conversionErrorRateMinAttempts && + float64(c.conversionErrors)/float64(c.conversionAttempts) > c.maxConversionErrorRate { + return moerr.NewInvalidInput(ctx, "MongoDB try_null conversion error limit exceeded") + } + if appendErr := vector.AppendNull(bat.Vecs[i], mp); appendErr != nil { + return appendErr + } + continue + } + if errors.Is(err, errConversion) { + return moerr.NewInvalidInputf(ctx, "MongoDB value at path %s cannot be converted to %s", column.Path, types.T(column.TypeID).String()) + } + return err + } + } + bat.SetRowCount(startRows + 1) + committed = true + return nil +} + +func mongoDBNotNullError(ctx context.Context, column ColumnMapping) error { + return moerr.NewInvalidInputf(ctx, "MongoDB NOT NULL column %s at path %s produced NULL", column.Name, column.Path) +} + +func lookupScalarPath(doc bson.Raw, path string) (bson.RawValue, bool, error) { + parts := strings.Split(path, ".") + current := doc + for i, part := range parts { + value, err := current.LookupErr(part) + if err != nil { + if errors.Is(err, bsoncore.ErrElementNotFound) { + return bson.RawValue{}, false, nil + } + return bson.RawValue{}, true, errConversion + } + if i == len(parts)-1 { + return value, true, nil + } + nested, ok := value.DocumentOK() + if !ok { + // Arrays and polymorphic scalar parents are not silently interpreted as + // dotted documents. They follow the mapping's strict/try_null policy. + return bson.RawValue{}, true, errConversion + } + current = nested + } + return bson.RawValue{}, false, nil +} + +func (c *Converter) appendValue(vec *vector.Vector, value bson.RawValue, column ColumnMapping, mp *mpool.MPool) error { + target := types.T(column.TypeID) + switch target { + case types.T_bool: + v, ok := value.BooleanOK() + if !ok { + return errConversion + } + return vector.AppendFixed(vec, v, false, mp) + case types.T_int8: + v, ok := bsonInt64(value) + if !ok || v < math.MinInt8 || v > math.MaxInt8 { + return errConversion + } + return vector.AppendFixed(vec, int8(v), false, mp) + case types.T_int16: + v, ok := bsonInt64(value) + if !ok || v < math.MinInt16 || v > math.MaxInt16 { + return errConversion + } + return vector.AppendFixed(vec, int16(v), false, mp) + case types.T_int32: + v, ok := bsonInt64(value) + if !ok || v < math.MinInt32 || v > math.MaxInt32 { + return errConversion + } + return vector.AppendFixed(vec, int32(v), false, mp) + case types.T_int64: + v, ok := bsonInt64(value) + if !ok { + return errConversion + } + return vector.AppendFixed(vec, v, false, mp) + case types.T_uint8, types.T_uint16, types.T_uint32, types.T_uint64: + v, ok := bsonInt64(value) + if !ok || v < 0 { + return errConversion + } + u := uint64(v) + switch target { + case types.T_uint8: + if u > math.MaxUint8 { + return errConversion + } + return vector.AppendFixed(vec, uint8(u), false, mp) + case types.T_uint16: + if u > math.MaxUint16 { + return errConversion + } + return vector.AppendFixed(vec, uint16(u), false, mp) + case types.T_uint32: + if u > math.MaxUint32 { + return errConversion + } + return vector.AppendFixed(vec, uint32(u), false, mp) + default: + return vector.AppendFixed(vec, u, false, mp) + } + case types.T_float32, types.T_float64: + v, ok := value.AsFloat64OK() + if !ok { + return errConversion + } + if target == types.T_float32 { + if !math.IsInf(v, 0) && (v > math.MaxFloat32 || v < -math.MaxFloat32) { + return errConversion + } + return vector.AppendFixed(vec, float32(v), false, mp) + } + return vector.AppendFixed(vec, v, false, mp) + case types.T_decimal64, types.T_decimal128, types.T_decimal256: + text, ok := bsonNumberString(value) + if !ok { + return errConversion + } + switch target { + case types.T_decimal64: + v, err := types.ParseDecimal64(text, column.Width, column.Scale) + if err != nil { + return errConversion + } + return vector.AppendFixed(vec, v, false, mp) + case types.T_decimal128: + v, err := types.ParseDecimal128(text, column.Width, column.Scale) + if err != nil { + return errConversion + } + return vector.AppendFixed(vec, v, false, mp) + default: + v, err := types.ParseDecimal256(text, column.Width, column.Scale) + if err != nil { + return errConversion + } + return vector.AppendFixed(vec, v, false, mp) + } + case types.T_date, types.T_datetime, types.T_timestamp: + millis, ok := value.DateTimeOK() + if !ok { + return errConversion + } + dt := types.DatetimeFromUnixWithNsec(time.UTC, millis/1000, (millis%1000)*int64(time.Millisecond)) + switch target { + case types.T_date: + return vector.AppendFixed(vec, dt.ToDate(), false, mp) + case types.T_datetime: + return vector.AppendFixed(vec, dt.TruncateToScale(column.Scale), false, mp) + default: + return vector.AppendFixed(vec, dt.ToTimestamp(time.UTC), false, mp) + } + case types.T_char, types.T_varchar, types.T_text: + var data []byte + if s, ok := value.StringValueOK(); ok { + data = []byte(s) + } else if objectID, ok := value.ObjectIDOK(); ok { + data = []byte(objectID.Hex()) + } else { + return errConversion + } + return c.appendString(vec, data, column.Width, mp) + case types.T_binary, types.T_varbinary, types.T_blob: + var data []byte + if _, bytes, ok := value.BinaryOK(); ok { + data = bytes + } else if objectID, ok := value.ObjectIDOK(); ok { + data = objectID[:] + } else { + return errConversion + } + return c.appendBytes(vec, data, column.Width, mp) + case types.T_json: + var decoded any + if err := value.Unmarshal(&decoded); err != nil { + return errConversion + } + // Canonical Extended JSON preserves BSON distinctions such as int32 vs + // int64, Decimal128, Date and Binary instead of silently relaxing them + // into a lossy generic JSON number/string representation. + text, err := bson.MarshalExtJSON(decoded, true, false) + if err != nil { + return errConversion + } + jsonValue, err := types.ParseStringToByteJson(string(text)) + if err != nil { + return errConversion + } + data, err := types.EncodeJson(jsonValue) + if err != nil { + return errConversion + } + return c.appendBytes(vec, data, column.Width, mp) + default: + return errConversion + } +} + +func (c *Converter) appendBytes(vec *vector.Vector, value []byte, width int32, mp *mpool.MPool) error { + if int64(len(value)) > c.maxValueBytes || width > 0 && int32(len(value)) > width { + return errConversion + } + return vector.AppendBytes(vec, value, false, mp) +} + +func (c *Converter) appendString(vec *vector.Vector, value []byte, width int32, mp *mpool.MPool) error { + // MO CHAR/VARCHAR width is measured in Unicode code points, while the + // memory-protection limit remains a byte limit. This matches the existing + // external reader and avoids rejecting valid multi-byte strings early. + if int64(len(value)) > c.maxValueBytes || width > 0 && utf8.RuneCount(value) > int(width) { + return errConversion + } + return vector.AppendBytes(vec, value, false, mp) +} + +func bsonInt64(value bson.RawValue) (int64, bool) { + switch value.Type { + case bson.TypeInt32: + v, ok := value.Int32OK() + return int64(v), ok + case bson.TypeInt64: + return value.Int64OK() + case bson.TypeDouble: + v, ok := value.DoubleOK() + // float64(math.MaxInt64) rounds to 2^63, so a conventional + // v > math.MaxInt64 check accidentally accepts exactly 2^63 and Go's + // conversion produces MinInt64. The upper bound must be exclusive. + if !ok || math.IsNaN(v) || math.IsInf(v, 0) || math.Trunc(v) != v || + v < -9223372036854775808.0 || v >= 9223372036854775808.0 { + return 0, false + } + return int64(v), true + default: + return 0, false + } +} + +func bsonNumberString(value bson.RawValue) (string, bool) { + switch value.Type { + case bson.TypeInt32: + v, ok := value.Int32OK() + return strconv.FormatInt(int64(v), 10), ok + case bson.TypeInt64: + v, ok := value.Int64OK() + return strconv.FormatInt(v, 10), ok + case bson.TypeDouble: + v, ok := value.DoubleOK() + if !ok || math.IsNaN(v) || math.IsInf(v, 0) { + return "", false + } + return strconv.FormatFloat(v, 'g', -1, 64), true + case bson.TypeDecimal128: + v, ok := value.Decimal128OK() + if !ok || v.IsNaN() || v.IsInf() != 0 { + return "", false + } + return v.String(), true + default: + return "", false + } +} + +func supportedMOType(t types.T) bool { + switch t { + case types.T_bool, + types.T_int8, types.T_int16, types.T_int32, types.T_int64, + types.T_uint8, types.T_uint16, types.T_uint32, types.T_uint64, + types.T_float32, types.T_float64, + types.T_decimal64, types.T_decimal128, types.T_decimal256, + types.T_date, types.T_datetime, types.T_timestamp, + types.T_char, types.T_varchar, types.T_text, + types.T_binary, types.T_varbinary, types.T_blob, types.T_json: + return true + default: + return false + } +} + +var errConversion = moerr.NewInvalidInputNoCtx("MongoDB BSON conversion failed") diff --git a/pkg/sql/mongodb/ddl.go b/pkg/sql/mongodb/ddl.go new file mode 100644 index 0000000000000..642418d8c64e9 --- /dev/null +++ b/pkg/sql/mongodb/ddl.go @@ -0,0 +1,74 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import "github.com/matrixorigin/matrixone/pkg/catalog" + +const ConnectionsDDL = `create table mo_catalog.mo_mongodb_connections ( + account_id int unsigned not null, + connection_id bigint unsigned not null auto_increment, + name varchar(300) not null, + discovery_mode varchar(16) not null, + hosts text, + srv_host varchar(1024), + replica_set varchar(256), + auth_source varchar(256) not null default 'admin', + auth_mechanism varchar(64) not null default 'SCRAM-SHA-256', + credential_secret_ref text not null, + tls_mode varchar(32) not null default 'required', + tls_ca_secret_ref text, + read_preference varchar(64) not null default 'secondaryPreferred', + read_concern varchar(64) not null default 'majority', + max_staleness_seconds bigint not null default 0, + options_json json, + created_at timestamp not null default utc_timestamp, + updated_at timestamp not null default utc_timestamp, + disabled_at timestamp default null, + version bigint unsigned not null default 1, + primary key(account_id, connection_id), + unique key(account_id, name) +)` + +const MappingsDDL = `create table mo_catalog.mo_mongodb_tables ( + account_id int unsigned not null, + db_id bigint unsigned not null, + table_id bigint unsigned not null, + mapping_id bigint unsigned not null auto_increment, + connection_id bigint unsigned not null, + database_name varchar(1024) not null, + collection_name varchar(1024) not null, + schema_mode varchar(32) not null default 'explicit', + conversion_mode varchar(32) not null default 'strict', + split_key varchar(1024), + max_parallelism int not null default 1, + columns_json json not null, + options_json json, + created_at timestamp not null default utc_timestamp, + updated_at timestamp not null default utc_timestamp, + version bigint unsigned not null default 1, + primary key(account_id, db_id, table_id), + unique key(account_id, mapping_id) +)` + +type SystemTableDDL struct { + Schema string + Name string + DDL string +} + +var SystemTableDDLs = []SystemTableDDL{ + {Schema: catalog.MO_CATALOG, Name: TableConnections, DDL: ConnectionsDDL}, + {Schema: catalog.MO_CATALOG, Name: TableMappings, DDL: MappingsDDL}, +} diff --git a/pkg/sql/mongodb/driver.go b/pkg/sql/mongodb/driver.go new file mode 100644 index 0000000000000..8d717b245d34b --- /dev/null +++ b/pkg/sql/mongodb/driver.go @@ -0,0 +1,297 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/json" + "io" + "strings" + "time" + + "github.com/matrixorigin/matrixone/pkg/common/moerr" + "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/mongo/options" + "go.mongodb.org/mongo-driver/v2/mongo/readconcern" + "go.mongodb.org/mongo-driver/v2/mongo/readpref" +) + +// FindSpec is deliberately driver-neutral at the operator boundary. +type FindSpec struct { + Filter any + Projection any + Sort any + BatchSize int32 + Limit int64 +} + +type Cursor interface { + Next(context.Context) bool + CurrentRaw() []byte + Err() error + Close(context.Context) error +} + +type Collection interface { + Find(context.Context, FindSpec) (Cursor, error) +} + +type Client interface { + Collection(database, collection string) Collection + Ping(context.Context) error + Disconnect(context.Context) error +} + +type ClientFactory interface { + Connect(context.Context, Connection, Credentials, RuntimeConfig) (Client, error) +} + +type OfficialClientFactory struct{} + +type connectorOptions struct { + Direct bool `json:"direct"` +} + +func decodeConnectorOptions(ctx context.Context, raw string) (connectorOptions, error) { + var decoded connectorOptions + raw = strings.TrimSpace(raw) + if raw == "" { + return decoded, nil + } + if !strings.HasPrefix(raw, "{") { + return decoded, moerr.NewInvalidInput(ctx, "MongoDB options_json must be a JSON object") + } + decoder := json.NewDecoder(strings.NewReader(raw)) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&decoded); err != nil { + return connectorOptions{}, moerr.NewInvalidInput(ctx, "MongoDB options_json is invalid or contains an unsupported option") + } + var trailing any + if err := decoder.Decode(&trailing); err != io.EOF { + return connectorOptions{}, moerr.NewInvalidInput(ctx, "MongoDB options_json must contain exactly one JSON object") + } + return decoded, nil +} + +func (OfficialClientFactory) Connect(ctx context.Context, connection Connection, credentials Credentials, cfg RuntimeConfig) (Client, error) { + if err := ValidateConnection(ctx, connection, cfg); err != nil { + return nil, err + } + clientOptions, err := buildClientOptions(ctx, connection, credentials, cfg) + if err != nil { + return nil, err + } + if err := ValidateResolvedEndpoints(ctx, connection, cfg, nil); err != nil { + return nil, err + } + client, err := mongo.Connect(clientOptions) + if err != nil { + return nil, moerr.NewInternalError(ctx, "MongoDB client configuration failed") + } + wrapper := &officialClient{client: client, readPreference: clientOptions.ReadPreference} + if err := wrapper.Ping(ctx); err != nil { + _ = disconnectClients([]Client{wrapper}) + return nil, moerr.NewInternalError(ctx, "MongoDB server selection or authentication failed") + } + return wrapper, nil +} + +func buildClientOptions(ctx context.Context, connection Connection, credentials Credentials, cfg RuntimeConfig) (*options.ClientOptions, error) { + if credentials.Username == "" || credentials.Password == "" { + return nil, moerr.NewInvalidInput(ctx, "MongoDB credential secret resolved to an incomplete identity") + } + if connection.TLSCASecretRef != "" && len(credentials.TLSCA) == 0 { + return nil, moerr.NewInvalidInput(ctx, "MongoDB TLS CA secret resolved to empty material") + } + commandMonitor, poolMonitor, serverMonitor := newDriverMonitors() + clientOptions := options.Client(). + SetAppName("MatrixOne MongoScan"). + SetMonitor(commandMonitor). + SetPoolMonitor(poolMonitor). + SetServerMonitor(serverMonitor). + SetDialer(newPolicyDialer(cfg, nil)). + SetConnectTimeout(cfg.ConnectTimeout). + SetServerSelectionTimeout(cfg.ServerSelectionTimeout). + SetTimeout(cfg.SocketTimeout). + SetMaxPoolSize(cfg.MaxPoolSize). + SetMinPoolSize(cfg.MinPoolSize). + SetMaxConnecting(cfg.MaxConnecting). + // The initial find remains a retryable read, but an in-progress + // cursor must never hide a getMore failure behind an adaptive retry. + // MongoScan fails the statement and replays from the committed + // watermark instead of risking an ambiguous partial cursor. + SetMaxAdaptiveRetries(0). + SetRetryReads(true). + SetRetryWrites(false) + connectorOptions, err := decodeConnectorOptions(ctx, connection.OptionsJSON) + if err != nil { + return nil, err + } + if strings.TrimSpace(connection.OptionsJSON) != "" { + clientOptions.SetDirect(connectorOptions.Direct) + } + + if strings.TrimSpace(connection.SRVHost) != "" { + clientOptions.ApplyURI("mongodb+srv://" + strings.TrimSpace(connection.SRVHost)) + } else { + clientOptions.SetHosts(splitSeeds(connection.Hosts)) + if connection.ReplicaSet != "" { + clientOptions.SetReplicaSet(connection.ReplicaSet) + } + } + if credentials.Username != "" { + clientOptions.SetAuth(options.Credential{ + AuthMechanism: connection.AuthMechanism, + AuthSource: defaultString(connection.AuthSource, "admin"), + Username: credentials.Username, + Password: credentials.Password, + PasswordSet: true, + }) + } + + rp, err := parseReadPreference(connection.ReadPreference, connection.MaxStalenessSeconds) + if err != nil { + return nil, moerr.NewInvalidInput(ctx, "unsupported MongoDB read preference") + } + clientOptions.SetReadPreference(rp) + switch strings.ToLower(connection.ReadConcern) { + case "", "majority": + clientOptions.SetReadConcern(readconcern.Majority()) + case "local": + clientOptions.SetReadConcern(readconcern.Local()) + default: + return nil, moerr.NewInvalidInput(ctx, "unsupported MongoDB read concern") + } + + tlsMode := strings.ToLower(strings.TrimSpace(connection.TLSMode)) + if err := configureTLS(ctx, clientOptions, tlsMode, credentials.TLSCA); err != nil { + return nil, err + } + if err := clientOptions.Validate(); err != nil { + return nil, moerr.NewInvalidInput(ctx, "invalid MongoDB client configuration") + } + return clientOptions, nil +} + +func configureTLS(ctx context.Context, clientOptions *options.ClientOptions, tlsMode string, caPEM []byte) error { + if tlsMode == "disabled" { + // mongodb+srv enables TLS implicitly. The catalog surface makes the TLS + // mode explicit, so override that URI default instead of silently + // connecting with behavior different from SHOW CREATE. + clientOptions.SetTLSConfig(nil) + } else if tlsMode != "" { + tlsConfig := &tls.Config{MinVersion: tls.VersionTLS12} + if len(caPEM) > 0 { + roots, err := x509.SystemCertPool() + if err != nil || roots == nil { + roots = x509.NewCertPool() + } + if !roots.AppendCertsFromPEM(caPEM) { + return moerr.NewInvalidInput(ctx, "MongoDB TLS CA secret does not contain a valid certificate") + } + tlsConfig.RootCAs = roots + } + clientOptions.SetTLSConfig(tlsConfig) + } + return nil +} + +func splitSeeds(hosts string) []string { + parts := strings.Split(hosts, ",") + seeds := make([]string, 0, len(parts)) + for _, host := range parts { + if host = strings.TrimSpace(host); host != "" { + seeds = append(seeds, host) + } + } + return seeds +} + +func parseReadPreference(value string, maxStalenessSeconds int64) (*readpref.ReadPref, error) { + modeValue := strings.ToLower(strings.TrimSpace(value)) + if modeValue == "" { + modeValue = "secondarypreferred" + } + mode, err := readpref.ModeFromString(modeValue) + if err != nil { + return nil, moerr.NewInvalidInputNoCtx("unsupported MongoDB read preference") + } + options := make([]readpref.Option, 0, 1) + if maxStalenessSeconds > 0 { + options = append(options, readpref.WithMaxStaleness(time.Duration(maxStalenessSeconds)*time.Second)) + } + return readpref.New(mode, options...) +} + +type officialClient struct { + client *mongo.Client + readPreference *readpref.ReadPref +} + +func (c *officialClient) Collection(database, collection string) Collection { + return officialCollection{collection: c.client.Database(database).Collection(collection)} +} + +func (c *officialClient) Ping(ctx context.Context) error { + return c.client.Ping(ctx, c.readPreference) +} + +func (c *officialClient) Disconnect(ctx context.Context) error { + return c.client.Disconnect(ctx) +} + +type officialCollection struct { + collection *mongo.Collection +} + +func (c officialCollection) Find(ctx context.Context, spec FindSpec) (Cursor, error) { + filter := spec.Filter + if filter == nil { + filter = bson.D{} + } + findOptions := options.Find() + if spec.Projection != nil { + findOptions.SetProjection(spec.Projection) + } + if spec.Sort != nil { + findOptions.SetSort(spec.Sort) + } + if spec.BatchSize > 0 { + findOptions.SetBatchSize(spec.BatchSize) + } + if spec.Limit > 0 { + findOptions.SetLimit(spec.Limit) + } + // Driver v2 intentionally removed the cursor-operation maxTimeMS option. + // The client operation timeout and this statement context bound both the + // initial find and every getMore without creating a second timeout source. + cursor, err := c.collection.Find(ctx, filter, findOptions) + if err != nil { + return nil, err + } + return &officialCursor{cursor: cursor}, nil +} + +type officialCursor struct { + cursor *mongo.Cursor +} + +func (c *officialCursor) Next(ctx context.Context) bool { return c.cursor.Next(ctx) } +func (c *officialCursor) CurrentRaw() []byte { return c.cursor.Current } +func (c *officialCursor) Err() error { return c.cursor.Err() } +func (c *officialCursor) Close(ctx context.Context) error { return c.cursor.Close(ctx) } diff --git a/pkg/sql/mongodb/driver_monitor.go b/pkg/sql/mongodb/driver_monitor.go new file mode 100644 index 0000000000000..080519991b0d3 --- /dev/null +++ b/pkg/sql/mongodb/driver_monitor.go @@ -0,0 +1,186 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "context" + "strings" + "sync" + + metric "github.com/matrixorigin/matrixone/pkg/util/metric/v2" + "go.mongodb.org/mongo-driver/v2/event" + "go.mongodb.org/mongo-driver/v2/mongo" +) + +// driverMonitorState retains endpoint identity only inside one driver client +// so command events can be reduced to a bounded server-role label. Endpoint, +// namespace, command document, reply, and errors are never logged or exported. +type driverMonitorState struct { + mu sync.RWMutex + roles map[string]string +} + +func newDriverMonitors() (*event.CommandMonitor, *event.PoolMonitor, *event.ServerMonitor) { + state := &driverMonitorState{roles: make(map[string]string)} + commandMonitor := &event.CommandMonitor{ + Started: func(_ context.Context, command *event.CommandStartedEvent) { + name := boundedCommandLabel(command.CommandName) + metric.MongoDBDriverCommandCounter.WithLabelValues(name, "started").Inc() + metric.MongoDBSelectedServerRoleCounter.WithLabelValues(state.roleForConnection(command.ConnectionID)).Inc() + }, + Succeeded: func(_ context.Context, command *event.CommandSucceededEvent) { + name := boundedCommandLabel(command.CommandName) + metric.MongoDBDriverCommandCounter.WithLabelValues(name, "succeeded").Inc() + metric.MongoDBDriverCommandDurationHistogram.WithLabelValues(name, "succeeded").Observe(command.Duration.Seconds()) + }, + Failed: func(_ context.Context, command *event.CommandFailedEvent) { + name := boundedCommandLabel(command.CommandName) + metric.MongoDBDriverCommandCounter.WithLabelValues(name, "failed").Inc() + metric.MongoDBDriverCommandDurationHistogram.WithLabelValues(name, "failed").Observe(command.Duration.Seconds()) + if name == "find" && mongo.IsNetworkError(command.Failure) { + metric.MongoDBRetryableFindCounter.Inc() + } + }, + } + poolMonitor := &event.PoolMonitor{Event: func(poolEvent *event.PoolEvent) { + typeLabel := boundedPoolEventLabel(poolEvent.Type) + metric.MongoDBPoolEventCounter.WithLabelValues(typeLabel, boundedPoolReasonLabel(poolEvent.Reason)).Inc() + if poolEvent.Duration > 0 { + metric.MongoDBPoolEventDurationHistogram.WithLabelValues(typeLabel).Observe(poolEvent.Duration.Seconds()) + } + switch poolEvent.Type { + case event.ConnectionCheckedOut: + metric.MongoDBPoolCheckedOutGauge.Inc() + case event.ConnectionCheckedIn: + metric.MongoDBPoolCheckedOutGauge.Dec() + } + }} + serverMonitor := &event.ServerMonitor{ + ServerDescriptionChanged: func(serverEvent *event.ServerDescriptionChangedEvent) { + role := boundedServerRole(serverEvent.NewDescription.Kind) + state.mu.Lock() + state.roles[serverEvent.Address.String()] = role + state.mu.Unlock() + }, + ServerClosed: func(serverEvent *event.ServerClosedEvent) { + state.mu.Lock() + delete(state.roles, serverEvent.Address.String()) + state.mu.Unlock() + }, + ServerHeartbeatSucceeded: func(serverEvent *event.ServerHeartbeatSucceededEvent) { + metric.MongoDBServerHeartbeatDurationHistogram.WithLabelValues("succeeded").Observe(serverEvent.Duration.Seconds()) + }, + ServerHeartbeatFailed: func(serverEvent *event.ServerHeartbeatFailedEvent) { + metric.MongoDBServerHeartbeatDurationHistogram.WithLabelValues("failed").Observe(serverEvent.Duration.Seconds()) + }, + } + return commandMonitor, poolMonitor, serverMonitor +} + +func (state *driverMonitorState) roleForConnection(connectionID string) string { + address := connectionID + if suffix := strings.LastIndex(address, "[-"); suffix >= 0 { + address = address[:suffix] + } + state.mu.RLock() + role := state.roles[address] + state.mu.RUnlock() + if role == "" { + return "unknown" + } + return role +} + +func boundedCommandLabel(name string) string { + switch strings.ToLower(name) { + case "find": + return "find" + case "getmore": + return "get_more" + case "killcursors": + return "kill_cursors" + default: + return "other" + } +} + +func boundedPoolEventLabel(name string) string { + switch name { + case event.ConnectionPoolCreated: + return "pool_created" + case event.ConnectionPoolReady: + return "pool_ready" + case event.ConnectionPoolCleared: + return "pool_cleared" + case event.ConnectionPoolClosed: + return "pool_closed" + case event.ConnectionCreated: + return "connection_created" + case event.ConnectionReady: + return "connection_ready" + case event.ConnectionClosed: + return "connection_closed" + case event.ConnectionCheckOutStarted: + return "checkout_started" + case event.ConnectionCheckOutFailed: + return "checkout_failed" + case event.ConnectionCheckedOut: + return "checked_out" + case event.ConnectionCheckedIn: + return "checked_in" + default: + return "other" + } +} + +func boundedPoolReasonLabel(reason string) string { + switch reason { + case "": + return "none" + case event.ReasonIdle: + return "idle" + case event.ReasonPoolClosed: + return "pool_closed" + case event.ReasonStale: + return "stale" + case event.ReasonConnectionErrored: + return "connection_error" + case event.ReasonTimedOut: + return "timeout" + case event.ReasonError: + return "error" + default: + return "other" + } +} + +func boundedServerRole(kind string) string { + switch strings.ToLower(kind) { + case "rsprimary": + return "primary" + case "rssecondary": + return "secondary" + case "standalone": + return "standalone" + case "mongos": + return "mongos" + case "loadbalancer": + return "load_balancer" + case "unknown", "": + return "unknown" + default: + return "other" + } +} diff --git a/pkg/sql/mongodb/driver_monitor_test.go b/pkg/sql/mongodb/driver_monitor_test.go new file mode 100644 index 0000000000000..da11a834a184b --- /dev/null +++ b/pkg/sql/mongodb/driver_monitor_test.go @@ -0,0 +1,37 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestDriverMonitorLabelsAreBoundedAndRedacted(t *testing.T) { + require.Equal(t, "find", boundedCommandLabel("find")) + require.Equal(t, "get_more", boundedCommandLabel("getMore")) + require.Equal(t, "other", boundedCommandLabel("secret-database-command")) + require.Equal(t, "other", boundedPoolEventLabel("mongodb.internal:27017")) + require.Equal(t, "other", boundedPoolReasonLabel("password=secret")) + require.Equal(t, "primary", boundedServerRole("RSPrimary")) + require.Equal(t, "other", boundedServerRole("mongodb.internal:27017")) +} + +func TestDriverMonitorResolvesRoleWithoutExportingEndpoint(t *testing.T) { + state := &driverMonitorState{roles: map[string]string{"mongodb.internal:27017": "secondary"}} + require.Equal(t, "secondary", state.roleForConnection("mongodb.internal:27017[-42]")) + require.Equal(t, "unknown", state.roleForConnection("other.internal:27017[-1]")) +} diff --git a/pkg/sql/mongodb/env_secret.go b/pkg/sql/mongodb/env_secret.go new file mode 100644 index 0000000000000..b57aa7be72f7f --- /dev/null +++ b/pkg/sql/mongodb/env_secret.go @@ -0,0 +1,93 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "context" + "encoding/json" + "fmt" + "io" + "os" + "strings" + + "github.com/matrixorigin/matrixone/pkg/common/moerr" +) + +// EnvSecretResolver is a minimal resolver for local deployments and CI. The +// credential environment value is JSON with username/password fields; the TLS +// environment value is PEM. Production deployments can replace this runtime +// dependency with their KMS/secret-manager resolver. +type EnvSecretResolver struct{} + +func (EnvSecretResolver) ResolveMongoDBCredentials( + ctx context.Context, + accountID uint32, + credentialRef string, + tlsCARef string, +) (Credentials, error) { + credentialKey, err := envSecretKey(ctx, accountID, credentialRef) + if err != nil { + return Credentials{}, err + } + raw, ok := os.LookupEnv(credentialKey) + if !ok { + return Credentials{}, moerr.NewInternalError(ctx, "MongoDB credential secret is unavailable") + } + var payload struct { + Username string `json:"username"` + Password string `json:"password"` + } + decoder := json.NewDecoder(strings.NewReader(raw)) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&payload); err != nil || payload.Username == "" || payload.Password == "" { + return Credentials{}, moerr.NewInternalError(ctx, "MongoDB credential secret has an invalid format") + } + var trailing any + if err := decoder.Decode(&trailing); err != io.EOF { + return Credentials{}, moerr.NewInternalError(ctx, "MongoDB credential secret has an invalid format") + } + credentials := Credentials{Username: payload.Username, Password: payload.Password} + if strings.TrimSpace(tlsCARef) != "" { + caKey, err := envSecretKey(ctx, accountID, tlsCARef) + if err != nil { + return Credentials{}, err + } + ca, ok := os.LookupEnv(caKey) + if !ok { + return Credentials{}, moerr.NewInternalError(ctx, "MongoDB TLS CA secret is unavailable") + } + credentials.TLSCA = []byte(ca) + } + return credentials, nil +} + +func envSecretKey(ctx context.Context, accountID uint32, ref string) (string, error) { + const prefix = "secret://env/" + if !strings.HasPrefix(ref, prefix) || len(ref) == len(prefix) { + return "", moerr.NewNotSupported(ctx, "default MongoDB resolver only supports secret://env references") + } + key := strings.TrimPrefix(ref, prefix) + if strings.ContainsAny(key, "/\\\x00=") { + return "", moerr.NewInvalidInput(ctx, "MongoDB environment secret reference is invalid") + } + allowedPrefix := "MO_MONGODB_" + if accountID != 0 { + allowedPrefix = fmt.Sprintf("MO_MONGODB_ACCOUNT_%d_", accountID) + } + if !strings.HasPrefix(key, allowedPrefix) { + return "", moerr.NewInvalidInput(ctx, "MongoDB environment secret reference is outside the account-scoped namespace") + } + return key, nil +} diff --git a/pkg/sql/mongodb/envelope.go b/pkg/sql/mongodb/envelope.go new file mode 100644 index 0000000000000..4c08dd0e0dcce --- /dev/null +++ b/pkg/sql/mongodb/envelope.go @@ -0,0 +1,125 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "context" + "encoding/json" + "fmt" + "net/url" + "strconv" + "strings" + + "github.com/matrixorigin/matrixone/pkg/common/moerr" +) + +const CreateSQLEnvelopePrefix = "MO_MONGODB:" + +type CreateSQLEnvelope struct { + Version int + Connection string + Database string + Collection string + SchemaMode string + ConversionMode string + SplitKey string + MaxParallelism int32 + Columns []ColumnMapping +} + +func BuildCreateSQLEnvelope(mapping TableMapping) string { + columns, _ := json.Marshal(mapping.Columns) + return fmt.Sprintf( + "/* %s version=1; connection=%s; database=%s; collection=%s; schema_mode=%s; conversion_mode=%s; split_key=%s; max_parallelism=%d; columns=%s */", + CreateSQLEnvelopePrefix, + url.QueryEscape(mapping.Connection), + url.QueryEscape(mapping.Database), + url.QueryEscape(mapping.Collection), + url.QueryEscape(defaultString(mapping.SchemaMode, SchemaExplicit)), + url.QueryEscape(defaultString(mapping.Conversion, ConversionStrict)), + url.QueryEscape(mapping.SplitKey), + defaultParallelism(mapping.MaxParallelism), + url.QueryEscape(string(columns)), + ) +} + +func ParseCreateSQLEnvelope(ctx context.Context, createSQL string) (CreateSQLEnvelope, bool, error) { + idx := strings.Index(createSQL, CreateSQLEnvelopePrefix) + if idx < 0 { + return CreateSQLEnvelope{}, false, nil + } + start := idx + len(CreateSQLEnvelopePrefix) + end := strings.Index(createSQL[start:], "*/") + if end < 0 { + return CreateSQLEnvelope{}, true, moerr.NewInvalidInput(ctx, "MongoDB rel_createsql envelope is not closed") + } + fields := make(map[string]string) + for _, part := range strings.Split(createSQL[start:start+end], ";") { + part = strings.TrimSpace(part) + if part == "" { + continue + } + key, value, ok := strings.Cut(part, "=") + if !ok { + return CreateSQLEnvelope{}, true, moerr.NewInvalidInput(ctx, "MongoDB rel_createsql envelope field must be key=value") + } + decoded, err := url.QueryUnescape(strings.TrimSpace(value)) + if err != nil { + return CreateSQLEnvelope{}, true, moerr.NewInvalidInput(ctx, "MongoDB rel_createsql envelope field is not url-escaped") + } + fields[strings.ToLower(strings.TrimSpace(key))] = decoded + } + version, err := strconv.Atoi(fields["version"]) + if err != nil || version != 1 { + return CreateSQLEnvelope{}, true, moerr.NewInvalidInput(ctx, "MongoDB rel_createsql envelope version must be 1") + } + parallelism, err := strconv.ParseInt(fields["max_parallelism"], 10, 32) + if err != nil || parallelism != 1 { + return CreateSQLEnvelope{}, true, moerr.NewInvalidInput(ctx, "MongoDB MVP max_parallelism must be 1") + } + var columns []ColumnMapping + if err := json.Unmarshal([]byte(fields["columns"]), &columns); err != nil || len(columns) == 0 { + return CreateSQLEnvelope{}, true, moerr.NewInvalidInput(ctx, "MongoDB rel_createsql envelope requires explicit columns") + } + env := CreateSQLEnvelope{ + Version: version, + Connection: fields["connection"], + Database: fields["database"], + Collection: fields["collection"], + SchemaMode: defaultString(fields["schema_mode"], SchemaExplicit), + ConversionMode: defaultString(fields["conversion_mode"], ConversionStrict), + SplitKey: fields["split_key"], + MaxParallelism: int32(parallelism), + Columns: columns, + } + if env.Connection == "" || env.Database == "" || env.Collection == "" { + return CreateSQLEnvelope{}, true, moerr.NewInvalidInput(ctx, "MongoDB rel_createsql envelope missing connection, database, or collection") + } + return env, true, nil +} + +func defaultString(value, fallback string) string { + if strings.TrimSpace(value) == "" { + return fallback + } + return value +} + +func defaultParallelism(value int32) int32 { + if value == 0 { + return 1 + } + return value +} diff --git a/pkg/sql/mongodb/limiter.go b/pkg/sql/mongodb/limiter.go new file mode 100644 index 0000000000000..9996ac26dfdd7 --- /dev/null +++ b/pkg/sql/mongodb/limiter.go @@ -0,0 +1,79 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package mongodb + +import ( + "context" + "sync" +) + +type sourceLimitKey struct { + accountID uint32 + connectionID uint64 +} + +// SourceLimiter bounds concurrent statements per tenant/source. Waiting is +// cancellation-aware, so a saturated source cannot pin a CN pipeline forever. +type SourceLimiter struct { + mu sync.Mutex + limit int + sources map[sourceLimitKey]*sourceSemaphore +} + +type sourceSemaphore struct { + ch chan struct{} + users int +} + +func NewSourceLimiter(limit int) *SourceLimiter { + if limit <= 0 { + limit = DefaultRuntimeConfig().MaxSourceConcurrency + } + return &SourceLimiter{limit: limit, sources: make(map[sourceLimitKey]*sourceSemaphore)} +} + +func (l *SourceLimiter) Acquire(ctx context.Context, accountID uint32, connectionID uint64) (func(), error) { + if l == nil { + return func() {}, nil + } + key := sourceLimitKey{accountID: accountID, connectionID: connectionID} + l.mu.Lock() + semaphore := l.sources[key] + if semaphore == nil { + semaphore = &sourceSemaphore{ch: make(chan struct{}, l.limit)} + l.sources[key] = semaphore + } + semaphore.users++ + l.mu.Unlock() + select { + case semaphore.ch <- struct{}{}: + var once sync.Once + return func() { once.Do(func() { l.release(key, semaphore, true) }) }, nil + case <-ctx.Done(): + l.release(key, semaphore, false) + return nil, context.Cause(ctx) + } +} + +func (l *SourceLimiter) release(key sourceLimitKey, semaphore *sourceSemaphore, held bool) { + if held { + <-semaphore.ch + } + l.mu.Lock() + semaphore.users-- + if semaphore.users == 0 && len(semaphore.ch) == 0 && l.sources[key] == semaphore { + delete(l.sources, key) + } + l.mu.Unlock() +} diff --git a/pkg/sql/mongodb/mapping.go b/pkg/sql/mongodb/mapping.go new file mode 100644 index 0000000000000..25bee110d2b3f --- /dev/null +++ b/pkg/sql/mongodb/mapping.go @@ -0,0 +1,158 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "context" + "strconv" + "strings" + + "github.com/matrixorigin/matrixone/pkg/common/moerr" + "github.com/matrixorigin/matrixone/pkg/pb/plan" + "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" +) + +type TableMappingSpec struct { + Mapping TableMapping +} + +func ParseTableMappingSpec( + ctx context.Context, + param *tree.MongoDBTableParam, + defs tree.TableDefs, + tableDef *plan.TableDef, +) (TableMappingSpec, error) { + if param == nil || tableDef == nil { + return TableMappingSpec{}, moerr.NewInvalidInput(ctx, "MongoDB external table mapping is missing") + } + options := make(map[string]string, len(param.Options)) + for _, option := range param.Options { + if option == nil { + continue + } + key := strings.ToLower(strings.TrimSpace(string(option.Key))) + if key == "" || strings.TrimSpace(option.Val) == "" { + return TableMappingSpec{}, moerr.NewInvalidInput(ctx, "MongoDB table option key and value cannot be empty") + } + if _, exists := options[key]; exists { + return TableMappingSpec{}, moerr.NewInvalidInputf(ctx, "duplicate MongoDB table option %s", key) + } + switch key { + case "connection", "database", "collection", "schema_mode", "conversion_mode", "split_key", "max_parallelism": + default: + return TableMappingSpec{}, moerr.NewInvalidInputf(ctx, "unsupported MongoDB table option %s", key) + } + options[key] = strings.TrimSpace(option.Val) + } + mapping := TableMapping{ + Connection: options["connection"], + Database: options["database"], + Collection: options["collection"], + SchemaMode: defaultString(options["schema_mode"], SchemaExplicit), + Conversion: defaultString(options["conversion_mode"], ConversionStrict), + SplitKey: options["split_key"], + MaxParallelism: 1, + } + if mapping.Connection == "" || mapping.Database == "" || mapping.Collection == "" { + return TableMappingSpec{}, moerr.NewInvalidInput(ctx, "MongoDB external table requires connection, database, and collection options") + } + if strings.ContainsAny(mapping.Database+mapping.Collection, "\x00") { + return TableMappingSpec{}, moerr.NewInvalidInput(ctx, "MongoDB namespace contains an invalid character") + } + if mapping.SchemaMode != SchemaExplicit { + return TableMappingSpec{}, moerr.NewNotSupported(ctx, "MongoDB MVP requires schema_mode=explicit") + } + if mapping.Conversion != ConversionStrict && mapping.Conversion != ConversionTryNull { + return TableMappingSpec{}, moerr.NewInvalidInput(ctx, "MongoDB conversion_mode must be strict or try_null") + } + if value := options["max_parallelism"]; value != "" { + parsed, err := strconv.ParseInt(value, 10, 32) + if err != nil || parsed != 1 { + return TableMappingSpec{}, moerr.NewNotSupported(ctx, "MongoDB MVP requires max_parallelism=1") + } + } + + columnDefs := make([]*tree.ColumnTableDef, 0, len(defs)) + for _, def := range defs { + if column, ok := def.(*tree.ColumnTableDef); ok { + columnDefs = append(columnDefs, column) + } + } + // buildTableDefs may append MO-internal hidden columns before the external + // engine is attached to the TableDef. They are storage metadata, not BSON + // mappings, and MongoScan must neither require nor emit them. + plannedColumns := make([]*plan.ColDef, 0, len(tableDef.Cols)) + for _, column := range tableDef.Cols { + if column != nil && !column.Hidden { + plannedColumns = append(plannedColumns, column) + } + } + if len(columnDefs) == 0 || len(columnDefs) != len(plannedColumns) { + return TableMappingSpec{}, moerr.NewInvalidInput(ctx, "MongoDB external table requires an explicit scalar column schema") + } + mapping.Columns = make([]ColumnMapping, 0, len(columnDefs)) + for i, column := range columnDefs { + planned := plannedColumns[i] + if !strings.EqualFold(column.Name.ColName(), planned.Name) { + return TableMappingSpec{}, moerr.NewInternalError(ctx, "MongoDB parsed and planned column order diverged") + } + path := planned.Name + conversion := mapping.Conversion + seenPath := false + seenConversion := false + for _, attribute := range column.Attributes { + switch typed := attribute.(type) { + case *tree.AttributeMongoDBPath: + if seenPath { + return TableMappingSpec{}, moerr.NewInvalidInputf(ctx, "duplicate MONGODB_PATH for column %s", planned.Name) + } + seenPath = true + path = typed.Path + case *tree.AttributeMongoDBConvert: + if seenConversion { + return TableMappingSpec{}, moerr.NewInvalidInputf(ctx, "duplicate MONGODB_CONVERT for column %s", planned.Name) + } + seenConversion = true + conversion = strings.ToLower(strings.TrimSpace(typed.Mode)) + } + } + if conversion != ConversionStrict && conversion != ConversionTryNull { + return TableMappingSpec{}, moerr.NewInvalidInputf(ctx, "invalid MONGODB_CONVERT for column %s", planned.Name) + } + if err := ValidateBSONPath(ctx, path); err != nil { + return TableMappingSpec{}, err + } + notNullable := planned.Typ.NotNullable + // CREATE TABLE records declared nullability in Default.NullAbility, + // while resolved catalog TableDefs also expose it on Typ.NotNullable. + // Honor both representations so the mapping cannot weaken the schema. + if planned.Default != nil && !planned.Default.NullAbility { + notNullable = true + } + mapping.Columns = append(mapping.Columns, ColumnMapping{ + Name: planned.Name, + Path: path, + TypeID: planned.Typ.Id, + Width: planned.Typ.Width, + Scale: planned.Typ.Scale, + NotNullable: notNullable, + Conversion: conversion, + }) + } + if _, err := NewConverter(ctx, mapping.Columns, DefaultRuntimeConfig().MaxValueBytes); err != nil { + return TableMappingSpec{}, err + } + return TableMappingSpec{Mapping: mapping}, nil +} diff --git a/pkg/sql/mongodb/model.go b/pkg/sql/mongodb/model.go new file mode 100644 index 0000000000000..12cf1af1a0cef --- /dev/null +++ b/pkg/sql/mongodb/model.go @@ -0,0 +1,148 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import "time" + +const ( + TableConnections = "mo_mongodb_connections" + TableMappings = "mo_mongodb_tables" + + DiscoverySeeds = "seeds" + DiscoverySRV = "srv" + + ConversionStrict = "strict" + ConversionTryNull = "try_null" + + SchemaExplicit = "explicit" +) + +// Connection is the non-secret, tenant-scoped configuration persisted in the +// MO catalog. Credentials and CA material are deliberately represented only by +// opaque secret references. +type Connection struct { + AccountID uint32 + ConnectionID uint64 + Name string + DiscoveryMode string + Hosts string + SRVHost string + ReplicaSet string + AuthSource string + AuthMechanism string + CredentialSecretRef string + TLSMode string + TLSCASecretRef string + ReadPreference string + ReadConcern string + MaxStalenessSeconds int64 + OptionsJSON string + Version uint64 + Disabled bool +} + +// ColumnMapping maps one MO output column to a scalar BSON dotted path. +type ColumnMapping struct { + Name string `json:"name"` + Path string `json:"path"` + TypeID int32 `json:"type_id"` + Width int32 `json:"width,omitempty"` + Scale int32 `json:"scale,omitempty"` + NotNullable bool `json:"not_nullable,omitempty"` + Conversion string `json:"conversion,omitempty"` +} + +// TableMapping is the catalog authority for one MongoDB external table. +type TableMapping struct { + AccountID uint32 + DatabaseID uint64 + TableID uint64 + MappingID uint64 + ConnectionID uint64 + Connection string + Database string + Collection string + SchemaMode string + Conversion string + SplitKey string + MaxParallelism int32 + Columns []ColumnMapping + OptionsJSON string + Version uint64 +} + +// RuntimeConfig contains process-local limits. It is never serialized into a +// logical plan or pipeline message. +type RuntimeConfig struct { + Enable bool + EnablePerAccount bool + AllowedAccounts map[uint32]struct{} + AllowLoopback bool + AllowedHostSuffixes []string + AllowedCIDRs []string + ConnectTimeout time.Duration + ServerSelectionTimeout time.Duration + SocketTimeout time.Duration + MaxPoolSize uint64 + MinPoolSize uint64 + MaxConnecting uint64 + MaxCachedClients int + BatchRows int32 + MaxBatchBytes int64 + MaxValueBytes int64 + MaxScanRows int64 + MaxScanBytes int64 + MaxConversionErrors int64 + MaxConversionErrorRate float64 + MaxSourceConcurrency int +} + +func (c RuntimeConfig) EnabledFor(accountID uint32) bool { + if !c.Enable { + return false + } + if !c.EnablePerAccount || accountID == 0 { + return true + } + _, ok := c.AllowedAccounts[accountID] + return ok +} + +func DefaultRuntimeConfig() RuntimeConfig { + return RuntimeConfig{ + ConnectTimeout: 10 * time.Second, + ServerSelectionTimeout: 10 * time.Second, + SocketTimeout: 30 * time.Second, + MaxPoolSize: 32, + MaxConnecting: 2, + MaxCachedClients: 64, + BatchRows: 8192, + MaxBatchBytes: 64 << 20, + MaxValueBytes: 16 << 20, + MaxScanRows: 50_000_000, + MaxScanBytes: 32 << 30, + MaxConversionErrors: 1_000, + MaxConversionErrorRate: 0.10, + MaxSourceConcurrency: 4, + } +} + +// Credentials is returned by a CN-local resolver. It must never be formatted, +// logged, stored in catalog metadata, or encoded into protobuf messages. +type Credentials struct { + Username string + Password string + TLSCA []byte +} diff --git a/pkg/sql/mongodb/mongodb_test.go b/pkg/sql/mongodb/mongodb_test.go new file mode 100644 index 0000000000000..d1aeb7764da1c --- /dev/null +++ b/pkg/sql/mongodb/mongodb_test.go @@ -0,0 +1,1588 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "context" + "crypto/tls" + "errors" + "math" + "net" + "strings" + "sync" + "testing" + "time" + + "github.com/matrixorigin/matrixone/pkg/common/moerr" + "github.com/matrixorigin/matrixone/pkg/common/mpool" + "github.com/matrixorigin/matrixone/pkg/container/types" + "github.com/matrixorigin/matrixone/pkg/container/vector" + planpb "github.com/matrixorigin/matrixone/pkg/pb/plan" + "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect/mysql" + "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" + "github.com/stretchr/testify/require" + "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/mongo/options" +) + +func TestQuoteSQLStringRoundTrip(t *testing.T) { + for _, value := range []string{ + "plain", + `path\segment`, + `trailing\`, + "single'quote", + `raw\'); select 1; -- `, + `backslash\nsequence`, + } { + t.Run(value, func(t *testing.T) { + stmt, err := mysql.ParseOne(t.Context(), "select "+quoteSQLString(value), 1) + require.NoError(t, err) + defer stmt.Free() + + selectStmt, ok := stmt.(*tree.Select) + require.True(t, ok) + clause, ok := selectStmt.Select.(*tree.SelectClause) + require.True(t, ok) + require.Len(t, clause.Exprs, 1) + literal, ok := clause.Exprs[0].Expr.(*tree.NumVal) + require.True(t, ok) + require.Equal(t, value, literal.String()) + }) + } +} + +func TestCreateSQLEnvelopeRoundTripAndRejectsParallelMVP(t *testing.T) { + ctx := context.Background() + mapping := TableMapping{ + Connection: "telemetry production", + Database: "telemetry", + Collection: "measurements/hour", + Columns: []ColumnMapping{{Name: "device_id", Path: "meta.device_id", TypeID: int32(types.T_varchar)}}, + } + raw := BuildCreateSQLEnvelope(mapping) + require.NotContains(t, raw, "password") + env, found, err := ParseCreateSQLEnvelope(ctx, raw) + require.NoError(t, err) + require.True(t, found) + require.Equal(t, mapping.Connection, env.Connection) + require.Equal(t, int32(1), env.MaxParallelism) + require.Equal(t, mapping.Columns, env.Columns) + + _, found, err = ParseCreateSQLEnvelope(ctx, "create external table x (a int)") + require.NoError(t, err) + require.False(t, found) + + bad := BuildCreateSQLEnvelope(TableMapping{ + Connection: "c", Database: "d", Collection: "x", MaxParallelism: 2, + Columns: mapping.Columns, + }) + _, found, err = ParseCreateSQLEnvelope(ctx, bad) + require.True(t, found) + require.Error(t, err) +} + +func TestMappingSnapshotMatchesPlan(t *testing.T) { + mapping := TableMapping{ + TableID: 10, MappingID: 11, ConnectionID: 22, Version: 3, + Database: "telemetry", Collection: "raw", MaxParallelism: 1, + Columns: []ColumnMapping{{Name: "value", Path: "reading.value", TypeID: int32(types.T_float64), Conversion: ConversionStrict}}, + } + scan := &planpb.MongoScan{ + TableId: 10, MappingId: 11, MappingVersion: 3, ConnectionId: 22, + Database: "telemetry", Collection: "raw", MaxParallelism: 1, + Columns: ColumnsToPlan(mapping.Columns), + } + require.True(t, MappingDefinitionMatchesPlan(mapping, scan)) + require.True(t, MappingSnapshotMatchesPlan(mapping, scan)) + mapping.Columns = append(mapping.Columns, ColumnMapping{Name: "quality", Path: "quality", TypeID: int32(types.T_varchar), Conversion: ConversionStrict}) + require.False(t, MappingDefinitionMatchesPlan(mapping, scan), "compile compares the full rel_createsql definition") + require.True(t, MappingSnapshotMatchesPlan(mapping, scan), "execution accepts a verified projected subset") + + drifted := mapping + drifted.Collection = "redirected" + require.False(t, MappingDefinitionMatchesPlan(drifted, scan)) + require.False(t, MappingSnapshotMatchesPlan(drifted, scan)) + + drifted = mapping + drifted.Columns = drifted.Columns[:1] + drifted.Version++ + require.True(t, MappingDefinitionMatchesPlan(drifted, scan)) + require.False(t, MappingSnapshotMatchesPlan(drifted, scan)) +} + +func TestParseTableMappingSpecIgnoresInternalHiddenColumns(t *testing.T) { + ctx := context.Background() + defs := tree.TableDefs{ + &tree.ColumnTableDef{ + Name: tree.NewUnresolvedColName("value"), + Attributes: []tree.ColumnAttribute{ + tree.NewAttributeMongoDBPath("reading.value"), + }, + }, + } + param := tree.NewMongoDBTableParam(tree.MongoDBOptions{ + tree.NewMongoDBOption("connection", "source"), + tree.NewMongoDBOption("database", "telemetry"), + tree.NewMongoDBOption("collection", "raw"), + }) + tableDef := &planpb.TableDef{Cols: []*planpb.ColDef{ + {Name: "value", Typ: planpb.Type{Id: int32(types.T_float64), NotNullable: true}}, + {Name: "__mo_fake_pk_col", Hidden: true, Typ: planpb.Type{Id: int32(types.T_uint64)}}, + }} + spec, err := ParseTableMappingSpec(ctx, param, defs, tableDef) + require.NoError(t, err) + require.Equal(t, []ColumnMapping{{ + Name: "value", Path: "reading.value", TypeID: int32(types.T_float64), NotNullable: true, Conversion: ConversionStrict, + }}, spec.Mapping.Columns) +} + +func TestPredicateTranslationAndProjection(t *testing.T) { + ctx := context.Background() + p := &Predicate{Op: PredicateAnd, Children: []*Predicate{ + {Op: PredicateGreaterEqual, Path: "meta.ts", Value: int64(10)}, + {Op: PredicateIsNull, Path: "reading.value"}, + }} + filter, err := PredicateToBSON(ctx, p) + require.NoError(t, err) + encoded, err := bson.MarshalExtJSON(filter, false, false) + require.NoError(t, err) + require.JSONEq(t, `{"$and":[{"meta.ts":{"$gte":10}},{"reading.value":null}]}`, string(encoded)) + + notNull, err := PredicateToBSON(ctx, &Predicate{Op: PredicateIsNotNull, Path: "x"}) + require.NoError(t, err) + encoded, err = bson.MarshalExtJSON(notNull, false, false) + require.NoError(t, err) + require.JSONEq(t, `{"$and":[{"x":{"$exists":true}},{"x":{"$ne":null}}]}`, string(encoded)) + + projection := ProjectionDocument([]ColumnMapping{{Path: "a"}, {Path: "a"}, {Path: "nested.b"}}) + require.Equal(t, bson.D{{Key: "a", Value: 1}, {Key: "nested.b", Value: 1}, {Key: "_id", Value: 0}}, projection) + require.Error(t, (&Predicate{Op: PredicateEqual, Path: "$where", Value: 1}).Validate(ctx)) +} + +func TestPredicateOperatorsValidationAndProjectionParents(t *testing.T) { + ctx := t.Context() + require.NoError(t, (*Predicate)(nil).Validate(ctx)) + empty, err := PredicateToBSON(ctx, nil) + require.NoError(t, err) + require.Empty(t, empty) + require.ErrorContains(t, (&Predicate{Op: PredicateAnd}).Validate(ctx), "requires children") + require.Error(t, (&Predicate{Op: PredicateAnd, Children: []*Predicate{{Op: PredicateInvalid, Path: "x"}}}).Validate(ctx)) + require.ErrorContains(t, (&Predicate{Op: PredicateIn, Path: "x"}).Validate(ctx), "cannot be empty") + require.ErrorContains(t, (&Predicate{Op: PredicateInvalid, Path: "x"}).Validate(ctx), "unsupported") + + for _, tc := range []struct { + name string + op PredicateOp + }{ + {name: "equal", op: PredicateEqual}, + {name: "not equal", op: PredicateNotEqual}, + {name: "less", op: PredicateLess}, + {name: "less equal", op: PredicateLessEqual}, + {name: "greater", op: PredicateGreater}, + {name: "greater equal", op: PredicateGreaterEqual}, + {name: "is null", op: PredicateIsNull}, + {name: "is not null", op: PredicateIsNotNull}, + } { + t.Run(tc.name, func(t *testing.T) { + document, err := PredicateToBSON(t.Context(), &Predicate{Op: tc.op, Path: "reading.value", Value: int64(10)}) + require.NoError(t, err) + require.NotEmpty(t, document) + }) + } + in, err := PredicateToBSON(ctx, &Predicate{Op: PredicateIn, Path: "reading.value", Values: []any{int64(1), int64(2)}}) + require.NoError(t, err) + require.NotEmpty(t, in) + + for _, path := range []string{"", ".value", "value.", "a..b", "$value", "a.*", "a[0]", "a\x00b"} { + require.Error(t, ValidateBSONPath(ctx, path), path) + } + require.NoError(t, ValidateBSONPath(ctx, "metadata.reading.value")) + + projection := ProjectionDocument([]ColumnMapping{ + {Path: "payload.value"}, {Path: "payload.quality"}, {Path: "payload"}, {Path: "_id.hex"}, + }) + require.Equal(t, bson.D{{Key: "payload", Value: 1}, {Key: "_id.hex", Value: 1}}, projection) +} + +func TestParseTableMappingSpecRejectsInvalidOptionsAndColumnContracts(t *testing.T) { + ctx := t.Context() + validOptions := func(extra ...*tree.MongoDBOption) *tree.MongoDBTableParam { + options := tree.MongoDBOptions{ + tree.NewMongoDBOption("connection", "source"), + tree.NewMongoDBOption("database", "telemetry"), + tree.NewMongoDBOption("collection", "raw"), + } + options = append(options, extra...) + return tree.NewMongoDBTableParam(options) + } + validDefs := func(attributes ...tree.ColumnAttribute) tree.TableDefs { + return tree.TableDefs{&tree.ColumnTableDef{Name: tree.NewUnresolvedColName("value"), Attributes: attributes}} + } + validTable := func() *planpb.TableDef { + return &planpb.TableDef{Cols: []*planpb.ColDef{{Name: "value", Typ: planpb.Type{Id: int32(types.T_int64)}}}} + } + + for _, tc := range []struct { + name string + param *tree.MongoDBTableParam + defs tree.TableDefs + table *planpb.TableDef + }{ + {name: "missing param", defs: validDefs(), table: validTable()}, + {name: "missing table", param: validOptions(), defs: validDefs()}, + {name: "empty option", param: tree.NewMongoDBTableParam(tree.MongoDBOptions{tree.NewMongoDBOption("", "value")}), defs: validDefs(), table: validTable()}, + {name: "duplicate option", param: validOptions(tree.NewMongoDBOption("DATABASE", "other")), defs: validDefs(), table: validTable()}, + {name: "unsupported option", param: validOptions(tree.NewMongoDBOption("password", "secret")), defs: validDefs(), table: validTable()}, + {name: "missing required", param: tree.NewMongoDBTableParam(tree.MongoDBOptions{tree.NewMongoDBOption("connection", "source")}), defs: validDefs(), table: validTable()}, + {name: "invalid namespace", param: tree.NewMongoDBTableParam(tree.MongoDBOptions{ + tree.NewMongoDBOption("connection", "source"), + tree.NewMongoDBOption("database", "telemetry"), + tree.NewMongoDBOption("collection", "bad\x00name"), + }), defs: validDefs(), table: validTable()}, + {name: "schema mode", param: validOptions(tree.NewMongoDBOption("schema_mode", "infer")), defs: validDefs(), table: validTable()}, + {name: "conversion mode", param: validOptions(tree.NewMongoDBOption("conversion_mode", "lossy")), defs: validDefs(), table: validTable()}, + {name: "parallel parse", param: validOptions(tree.NewMongoDBOption("max_parallelism", "many")), defs: validDefs(), table: validTable()}, + {name: "parallel unsupported", param: validOptions(tree.NewMongoDBOption("max_parallelism", "2")), defs: validDefs(), table: validTable()}, + {name: "missing columns", param: validOptions(), table: validTable()}, + {name: "column count", param: validOptions(), defs: validDefs(), table: &planpb.TableDef{Cols: []*planpb.ColDef{{Name: "value", Typ: planpb.Type{Id: int32(types.T_int64)}}, {Name: "other", Typ: planpb.Type{Id: int32(types.T_int64)}}}}}, + {name: "column order", param: validOptions(), defs: validDefs(), table: &planpb.TableDef{Cols: []*planpb.ColDef{{Name: "other", Typ: planpb.Type{Id: int32(types.T_int64)}}}}}, + {name: "duplicate path", param: validOptions(), defs: validDefs(tree.NewAttributeMongoDBPath("a"), tree.NewAttributeMongoDBPath("b")), table: validTable()}, + {name: "duplicate conversion", param: validOptions(), defs: validDefs(tree.NewAttributeMongoDBConvert("strict"), tree.NewAttributeMongoDBConvert("try_null")), table: validTable()}, + {name: "invalid column conversion", param: validOptions(), defs: validDefs(tree.NewAttributeMongoDBConvert("lossy")), table: validTable()}, + {name: "invalid column path", param: validOptions(), defs: validDefs(tree.NewAttributeMongoDBPath("$where")), table: validTable()}, + {name: "unsupported type", param: validOptions(), defs: validDefs(), table: &planpb.TableDef{Cols: []*planpb.ColDef{{Name: "value", Typ: planpb.Type{Id: int32(types.T_array_float32)}}}}}, + } { + t.Run(tc.name, func(t *testing.T) { + _, err := ParseTableMappingSpec(ctx, tc.param, tc.defs, tc.table) + require.Error(t, err) + }) + } + + spec, err := ParseTableMappingSpec(ctx, validOptions(tree.NewMongoDBOption("max_parallelism", "1")), validDefs( + tree.NewAttributeMongoDBPath("reading.value"), tree.NewAttributeMongoDBConvert(" TRY_NULL "), + ), validTable()) + require.NoError(t, err) + require.Equal(t, ConversionTryNull, spec.Mapping.Columns[0].Conversion) +} + +func TestProjectColumnsByNameKeepsCompactResidualLayout(t *testing.T) { + columns := []ColumnMapping{ + {Name: "device_id", Path: "metadata.device_id"}, + {Name: "site_id", Path: "metadata.site_id"}, + {Name: "ts", Path: "event.ts"}, + } + projected, err := ProjectColumnsByName(t.Context(), columns, []string{"ts", "device_id"}) + require.NoError(t, err) + require.Equal(t, []ColumnMapping{columns[2], columns[0]}, projected) + + _, err = ProjectColumnsByName(t.Context(), columns, []string{"missing"}) + require.ErrorContains(t, err, "has no mapping") + _, err = ProjectColumnsByName(t.Context(), append(columns, columns[0]), []string{"device_id"}) + require.ErrorContains(t, err, "duplicate") +} + +func TestPlanPredicatePushdownKeepsResidualAndStrictFallback(t *testing.T) { + columnExpr := &planpb.Expr{Expr: &planpb.Expr_Col{Col: &planpb.ColRef{ColPos: 0}}} + literalExpr := &planpb.Expr{Expr: &planpb.Expr_Lit{Lit: &planpb.Literal{Value: &planpb.Literal_I64Val{I64Val: 42}}}} + filter := &planpb.Expr{Expr: &planpb.Expr_F{F: &planpb.Function{ + Func: &planpb.ObjectRef{ObjName: ">="}, Args: []*planpb.Expr{columnExpr, literalExpr}, + }}} + tryColumns := []*planpb.MongoColumnMapping{{Path: "reading.value", ConversionMode: ConversionTryNull, MoType: planpb.Type{Id: int32(types.T_int64)}}} + pushed, residual := PushdownPlanFilters(context.Background(), []*planpb.Expr{filter}, tryColumns) + require.NotNil(t, pushed) + require.Equal(t, planpb.MongoPredicateOp_MONGO_PREDICATE_GREATER_EQUAL, pushed.Op) + require.Equal(t, "reading.value", pushed.Path) + require.NotEmpty(t, residual) + + strictColumns := []*planpb.MongoColumnMapping{{Path: "reading.value", ConversionMode: ConversionStrict, MoType: planpb.Type{Id: int32(types.T_float64)}}} + pushed, residual = PushdownPlanFilters(context.Background(), []*planpb.Expr{filter}, strictColumns) + require.Nil(t, pushed, "strict conversion must not hide malformed source values") + require.NotEmpty(t, residual) + + isNull := &planpb.Expr{Expr: &planpb.Expr_F{F: &planpb.Function{ + Func: &planpb.ObjectRef{ObjName: "is_null"}, Args: []*planpb.Expr{columnExpr}, + }}} + pushed, residual = PushdownPlanFilters(context.Background(), []*planpb.Expr{isNull}, tryColumns) + require.Nil(t, pushed, "IS NULL must retain malformed try_null values as candidates") + require.NotEmpty(t, residual) + + isNotNull := &planpb.Expr{Expr: &planpb.Expr_F{F: &planpb.Function{ + Func: &planpb.ObjectRef{ObjName: "is_not_null"}, Args: []*planpb.Expr{columnExpr}, + }}} + pushed, residual = PushdownPlanFilters(context.Background(), []*planpb.Expr{isNotNull}, tryColumns) + require.NotNil(t, pushed) + require.Equal(t, planpb.MongoPredicateOp_MONGO_PREDICATE_IS_NOT_NULL, pushed.Op) + require.NotEmpty(t, residual) + + pushed, residual = PushdownPlanFilters(context.Background(), []*planpb.Expr{isNotNull}, strictColumns) + require.Nil(t, pushed, "strict IS NOT NULL must not hide malformed nested values") + require.NotEmpty(t, residual) + + stringColumns := []*planpb.MongoColumnMapping{{Path: "reading.value", ConversionMode: ConversionTryNull, MoType: planpb.Type{Id: int32(types.T_varchar)}}} + pushed, residual = PushdownPlanFilters(context.Background(), []*planpb.Expr{filter}, stringColumns) + require.Nil(t, pushed, "string comparison collation has not been proven equivalent") + require.NotEmpty(t, residual) + + floatColumns := []*planpb.MongoColumnMapping{{Path: "reading.value", ConversionMode: ConversionTryNull, MoType: planpb.Type{Id: int32(types.T_float32)}}} + pushed, residual = PushdownPlanFilters(context.Background(), []*planpb.Expr{filter}, floatColumns) + require.Nil(t, pushed, "lossy BSON-to-float conversion can make a raw-value predicate narrower than the SQL residual") + require.NotEmpty(t, residual) +} + +func TestStrictNestedIsNotNullKeepsMalformedIntermediateCandidate(t *testing.T) { + columnExpr := &planpb.Expr{Expr: &planpb.Expr_Col{Col: &planpb.ColRef{ColPos: 0}}} + filter := &planpb.Expr{Expr: &planpb.Expr_F{F: &planpb.Function{ + Func: &planpb.ObjectRef{ObjName: "is_not_null"}, Args: []*planpb.Expr{columnExpr}, + }}} + columns := []*planpb.MongoColumnMapping{{ + Path: "payload.value", ConversionMode: ConversionStrict, + MoType: planpb.Type{Id: int32(types.T_int64)}, + }} + + pushed, residual := PushdownPlanFilters(t.Context(), []*planpb.Expr{filter}, columns) + require.Nil(t, pushed) + require.NotEmpty(t, residual) + + converter, err := NewConverter(t.Context(), []ColumnMapping{{ + Name: "value", Path: "payload.value", TypeID: int32(types.T_int64), Conversion: ConversionStrict, + }}, 1024) + require.NoError(t, err) + mp := mpool.MustNewZero() + bat := converter.NewBatch() + defer bat.Clean(mp) + + malformed, err := bson.Marshal(bson.D{{Key: "payload", Value: "not-a-document"}}) + require.NoError(t, err) + require.ErrorContains(t, converter.AppendDocument(t.Context(), bat, malformed, mp), "cannot be converted") + require.Zero(t, bat.RowCount()) +} + +func TestPlanPredicatePushesTryNullBSONDateTimeWithSafeRounding(t *testing.T) { + columnExpr := &planpb.Expr{Expr: &planpb.Expr_Col{Col: &planpb.ColRef{ColPos: 0}}} + columns := []*planpb.MongoColumnMapping{{ + Path: "ts", ConversionMode: ConversionTryNull, + MoType: planpb.Type{Id: int32(types.T_datetime), Scale: 6}, + }} + literalDatetime := types.DatetimeFromUnixWithNsec(time.UTC, 10, 123456000) + literalExpr := &planpb.Expr{ + Typ: planpb.Type{Id: int32(types.T_datetime), Scale: 6}, + Expr: &planpb.Expr_Lit{Lit: &planpb.Literal{Value: &planpb.Literal_I64Val{I64Val: int64(literalDatetime)}}}, + } + filter := &planpb.Expr{Expr: &planpb.Expr_F{F: &planpb.Function{ + Func: &planpb.ObjectRef{ObjName: ">="}, Args: []*planpb.Expr{columnExpr, literalExpr}, + }}} + pushed, residual := PushdownPlanFilters(t.Context(), []*planpb.Expr{filter}, columns) + require.NotNil(t, pushed) + require.NotEmpty(t, residual) + predicate, err := PredicateFromPlan(t.Context(), pushed) + require.NoError(t, err) + require.Equal(t, bson.DateTime(10124), predicate.Value, + ">= must round its BSON millisecond candidate outward") + + castLiteral := &planpb.Expr{ + Typ: planpb.Type{Id: int32(types.T_datetime), Scale: 3}, + Expr: &planpb.Expr_F{F: &planpb.Function{ + Func: &planpb.ObjectRef{ObjName: "cast"}, + Args: []*planpb.Expr{{ + Typ: planpb.Type{Id: int32(types.T_varchar)}, + Expr: &planpb.Expr_Lit{Lit: &planpb.Literal{Value: &planpb.Literal_Sval{Sval: "2026-07-27 10:55:00.123"}}}, + }}, + }}, + } + filter.GetF().Args[1] = castLiteral + pushed, _ = PushdownPlanFilters(t.Context(), []*planpb.Expr{filter}, columns) + require.NotNil(t, pushed, "a deterministic DATETIME string cast is a safe BSON candidate") + + timestampColumns := ColumnsToPlan([]ColumnMapping{{ + Path: "ts", TypeID: int32(types.T_timestamp), Scale: 3, Conversion: ConversionTryNull, + }}) + castLiteral.Typ.Id = int32(types.T_timestamp) + pushed, _ = PushdownPlanFilters(t.Context(), []*planpb.Expr{filter}, timestampColumns) + require.Nil(t, pushed, "a TIMESTAMP string cast depends on the session time zone") + castLiteral.Typ.Id = int32(types.T_datetime) + + filter.GetF().Func.ObjName = "=" + filter.GetF().Args[1] = literalExpr + pushed, _ = PushdownPlanFilters(t.Context(), []*planpb.Expr{filter}, columns) + require.Nil(t, pushed, "a sub-millisecond equality has no exact BSON DateTime candidate") + + strictColumns := ColumnsToPlan([]ColumnMapping{{ + Path: "ts", TypeID: int32(types.T_datetime), Scale: 6, Conversion: ConversionStrict, + }}) + filter.GetF().Func.ObjName = ">=" + pushed, _ = PushdownPlanFilters(t.Context(), []*planpb.Expr{filter}, strictColumns) + require.Nil(t, pushed, "strict temporal conversion must not hide malformed values") +} + +func TestTemporalCandidateRoundingBeforeUnixEpoch(t *testing.T) { + require.Equal(t, int64(-2), floorDiv(-1001, 1000)) + require.Equal(t, int64(-1), ceilDiv(-1001, 1000)) + require.Equal(t, int64(-1), floorDiv(-999, 1000)) + require.Equal(t, int64(0), ceilDiv(-999, 1000)) +} + +func TestPlanPredicateHelperVariants(t *testing.T) { + for _, tc := range []struct { + name string + op PredicateOp + want PredicateOp + }{ + {name: "less", op: PredicateLess, want: PredicateGreater}, + {name: "less equal", op: PredicateLessEqual, want: PredicateGreaterEqual}, + {name: "greater", op: PredicateGreater, want: PredicateLess}, + {name: "greater equal", op: PredicateGreaterEqual, want: PredicateLessEqual}, + {name: "equal", op: PredicateEqual, want: PredicateEqual}, + } { + t.Run(tc.name, func(t *testing.T) { require.Equal(t, tc.want, reversePredicateOp(tc.op)) }) + } + + for _, tc := range []struct { + name string + want PredicateOp + ok bool + }{ + {name: "=", want: PredicateEqual, ok: true}, + {name: "!=", want: PredicateNotEqual, ok: true}, + {name: "<>", want: PredicateNotEqual, ok: true}, + {name: "<", want: PredicateLess, ok: true}, + {name: "<=", want: PredicateLessEqual, ok: true}, + {name: ">", want: PredicateGreater, ok: true}, + {name: ">=", want: PredicateGreaterEqual, ok: true}, + {name: "like", want: PredicateInvalid}, + } { + t.Run("operator "+tc.name, func(t *testing.T) { + got, ok := comparisonPredicateOp(tc.name) + require.Equal(t, tc.ok, ok) + require.Equal(t, tc.want, got) + }) + } + + literals := []struct { + name string + literal *planpb.Literal + want any + ok bool + }{ + {name: "nil"}, + {name: "null", literal: &planpb.Literal{Isnull: true}, ok: true}, + {name: "bool", literal: &planpb.Literal{Value: &planpb.Literal_Bval{Bval: true}}, want: true, ok: true}, + {name: "int8", literal: &planpb.Literal{Value: &planpb.Literal_I8Val{I8Val: 8}}, want: int32(8), ok: true}, + {name: "int16", literal: &planpb.Literal{Value: &planpb.Literal_I16Val{I16Val: 16}}, want: int32(16), ok: true}, + {name: "int32", literal: &planpb.Literal{Value: &planpb.Literal_I32Val{I32Val: 32}}, want: int32(32), ok: true}, + {name: "int64", literal: &planpb.Literal{Value: &planpb.Literal_I64Val{I64Val: 64}}, want: int64(64), ok: true}, + {name: "uint8", literal: &planpb.Literal{Value: &planpb.Literal_U8Val{U8Val: 8}}, want: int32(8), ok: true}, + {name: "uint16", literal: &planpb.Literal{Value: &planpb.Literal_U16Val{U16Val: 16}}, want: int32(16), ok: true}, + {name: "uint32", literal: &planpb.Literal{Value: &planpb.Literal_U32Val{U32Val: 32}}, want: int64(32), ok: true}, + {name: "uint64", literal: &planpb.Literal{Value: &planpb.Literal_U64Val{U64Val: 64}}, want: int64(64), ok: true}, + {name: "uint64 overflow", literal: &planpb.Literal{Value: &planpb.Literal_U64Val{U64Val: math.MaxUint64}}}, + {name: "float32", literal: &planpb.Literal{Value: &planpb.Literal_Fval{Fval: 1.5}}, want: float32(1.5), ok: true}, + {name: "float64", literal: &planpb.Literal{Value: &planpb.Literal_Dval{Dval: 2.5}}, want: 2.5, ok: true}, + {name: "string", literal: &planpb.Literal{Value: &planpb.Literal_Sval{Sval: "value"}}, want: "value", ok: true}, + {name: "unsupported", literal: &planpb.Literal{Value: &planpb.Literal_Dateval{Dateval: 1}}}, + } + for _, tc := range literals { + t.Run("literal "+tc.name, func(t *testing.T) { + expr := &planpb.Expr{} + if tc.literal != nil { + expr.Expr = &planpb.Expr_Lit{Lit: tc.literal} + } + got, ok := scalarPlanLiteral(expr) + require.Equal(t, tc.ok, ok) + require.Equal(t, tc.want, got) + }) + } + + for _, tc := range []struct { + op PredicateOp + micro int64 + want int64 + ok bool + }{ + {op: PredicateEqual, micro: 2000, want: 2, ok: true}, + {op: PredicateNotEqual, micro: 2001}, + {op: PredicateGreaterEqual, micro: 2001, want: 3, ok: true}, + {op: PredicateLess, micro: 2001, want: 3, ok: true}, + {op: PredicateGreater, micro: 2001, want: 2, ok: true}, + {op: PredicateLessEqual, micro: 2001, want: 2, ok: true}, + {op: PredicateIn, micro: 2000}, + } { + got, ok := temporalCandidateMilliseconds(tc.micro, tc.op) + require.Equal(t, tc.ok, ok) + require.Equal(t, tc.want, got) + } +} + +func TestPlanPredicateCompoundInAndReversedComparisons(t *testing.T) { + column := &planpb.Expr{Expr: &planpb.Expr_Col{Col: &planpb.ColRef{ColPos: 0}}} + badColumn := &planpb.Expr{Expr: &planpb.Expr_Col{Col: &planpb.ColRef{ColPos: 9}}} + literal := func(value int64) *planpb.Expr { + return &planpb.Expr{Expr: &planpb.Expr_Lit{Lit: &planpb.Literal{Value: &planpb.Literal_I64Val{I64Val: value}}}} + } + fn := func(name string, args ...*planpb.Expr) *planpb.Expr { + return &planpb.Expr{Expr: &planpb.Expr_F{F: &planpb.Function{Func: &planpb.ObjectRef{ObjName: name}, Args: args}}} + } + columns := []*planpb.MongoColumnMapping{{ + Path: "reading.value", ConversionMode: ConversionTryNull, MoType: planpb.Type{Id: int32(types.T_int64)}, + }} + + reversed, ok := planExprToPredicate(fn("<", literal(10), column), columns) + require.True(t, ok) + require.Equal(t, PredicateGreater, reversed.Op) + require.Equal(t, int64(10), reversed.Value) + + and, ok := planExprToPredicate(fn("and", fn(">", column, literal(1)), fn("<=", column, literal(9))), columns) + require.True(t, ok) + require.Equal(t, PredicateAnd, and.Op) + require.Len(t, and.Children, 2) + _, ok = planExprToPredicate(fn("and", fn(">", column, literal(1)), fn("=", badColumn, literal(9))), columns) + require.False(t, ok) + + inList := &planpb.Expr{Expr: &planpb.Expr_List{List: &planpb.ExprList{List: []*planpb.Expr{literal(1), literal(2)}}}} + in, ok := planExprToPredicate(fn("in", column, inList), columns) + require.True(t, ok) + require.Equal(t, []any{int64(1), int64(2)}, in.Values) + for _, invalid := range []*planpb.Expr{ + fn("in", badColumn, inList), + fn("in", column, &planpb.Expr{Expr: &planpb.Expr_List{List: &planpb.ExprList{}}}), + fn("in", column, &planpb.Expr{Expr: &planpb.Expr_List{List: &planpb.ExprList{List: []*planpb.Expr{{Expr: &planpb.Expr_Lit{Lit: &planpb.Literal{Isnull: true}}}}}}}), + fn("unknown", column, literal(1)), + fn("=", column), + {}, + } { + _, ok = planExprToPredicate(invalid, columns) + require.False(t, ok) + } + + isNotNull, ok := planExprToPredicate(fn("isnotnull", column), columns) + require.True(t, ok) + require.Equal(t, PredicateIsNotNull, isNotNull.Op) + _, ok = planExprToPredicate(fn("isnull", column), columns) + require.False(t, ok) + _, ok = planExprToPredicate(fn("is_not_null", badColumn), columns) + require.False(t, ok) + + pushed, residual := PushdownPlanFilters(t.Context(), []*planpb.Expr{fn(">", column, literal(1)), fn("unknown")}, columns) + require.NotNil(t, pushed) + require.Equal(t, "mo-residual:ff", residual) + require.Equal(t, "", residualDigest(nil)) +} + +func TestSourceLimiterCancellationReleaseAndKeyRecycling(t *testing.T) { + limiter := NewSourceLimiter(1) + release, err := limiter.Acquire(context.Background(), 7, 9) + require.NoError(t, err) + ctx, cancel := context.WithCancel(context.Background()) + cancel() + _, err = limiter.Acquire(ctx, 7, 9) + require.ErrorIs(t, err, context.Canceled) + release() + release() + limiter.mu.Lock() + require.Empty(t, limiter.sources) + limiter.mu.Unlock() + + // Recreating a previously idle key must still enforce the same limit. + release, err = limiter.Acquire(context.Background(), 7, 9) + require.NoError(t, err) + release() + limiter.mu.Lock() + require.Empty(t, limiter.sources) + limiter.mu.Unlock() +} + +func TestConverterTypesMissingTryNullAndRollback(t *testing.T) { + ctx := context.Background() + mp, err := mpool.NewMPool("mongodb-converter-test", 0, mpool.NoFixed) + require.NoError(t, err) + columns := []ColumnMapping{ + {Name: "id", Path: "_id", TypeID: int32(types.T_varchar), Width: 24}, + {Name: "device_id", Path: "meta.device_id", TypeID: int32(types.T_varchar), Width: 32}, + {Name: "count", Path: "count", TypeID: int32(types.T_int32)}, + {Name: "value", Path: "value", TypeID: int32(types.T_float64)}, + {Name: "when", Path: "when", TypeID: int32(types.T_datetime), Scale: 3}, + {Name: "optional", Path: "optional", TypeID: int32(types.T_int64)}, + {Name: "try_value", Path: "bad", TypeID: int32(types.T_int64), Conversion: ConversionTryNull}, + } + converter, err := NewConverter(ctx, columns, 1024) + require.NoError(t, err) + bat := converter.NewBatch() + t.Cleanup(func() { + bat.Clean(mp) + require.Zero(t, mp.CurrNB()) + }) + + objectID := bson.NewObjectID() + raw, err := bson.Marshal(bson.D{ + {Key: "_id", Value: objectID}, + {Key: "meta", Value: bson.D{{Key: "device_id", Value: "device-001"}}}, + {Key: "count", Value: int64(7)}, + {Key: "value", Value: 2.675}, + {Key: "when", Value: time.Date(2026, 7, 27, 8, 9, 10, 123000000, time.UTC)}, + {Key: "optional", Value: nil}, + {Key: "bad", Value: "not-an-int"}, + }) + require.NoError(t, err) + require.NoError(t, converter.AppendDocument(ctx, bat, raw, mp)) + require.Equal(t, 1, bat.RowCount()) + require.Equal(t, objectID.Hex(), string(bat.Vecs[0].GetBytesAt(0))) + require.Equal(t, "device-001", string(bat.Vecs[1].GetBytesAt(0))) + require.Equal(t, int32(7), vector.GetFixedAtWithTypeCheck[int32](bat.Vecs[2], 0)) + require.Equal(t, 2.675, vector.GetFixedAtWithTypeCheck[float64](bat.Vecs[3], 0)) + require.True(t, bat.Vecs[5].GetNulls().Contains(0)) + require.True(t, bat.Vecs[6].GetNulls().Contains(0)) + + // A strict error after earlier columns were appended must not leave a + // half-row in any vector. + badRaw, err := bson.Marshal(bson.D{ + {Key: "_id", Value: objectID}, + {Key: "meta", Value: bson.D{{Key: "device_id", Value: "device-002"}}}, + {Key: "count", Value: int64(1) << 40}, + }) + require.NoError(t, err) + require.Error(t, converter.AppendDocument(ctx, bat, badRaw, mp)) + require.Equal(t, 1, bat.RowCount()) + for _, vec := range bat.Vecs { + require.Equal(t, 1, vec.Length()) + } +} + +func TestConverterRejectsNullForNotNullMapping(t *testing.T) { + columns := []ColumnMapping{{ + Name: "value", Path: "payload.value", TypeID: int32(types.T_int64), + NotNullable: true, Conversion: ConversionTryNull, + }} + require.Equal(t, columns, ColumnsFromPlan(ColumnsToPlan(columns))) + + converter, err := NewConverter(t.Context(), columns, 1024) + require.NoError(t, err) + mp := mpool.MustNewZero() + bat := converter.NewBatch() + t.Cleanup(func() { + bat.Clean(mp) + require.Zero(t, mp.CurrNB()) + }) + + for _, tc := range []struct { + name string + doc bson.D + }{ + {name: "missing", doc: bson.D{}}, + {name: "explicit BSON null", doc: bson.D{{Key: "payload", Value: bson.D{{Key: "value", Value: nil}}}}}, + {name: "BSON undefined", doc: bson.D{{Key: "payload", Value: bson.D{{Key: "value", Value: bson.Undefined{}}}}}}, + {name: "try_null conversion failure", doc: bson.D{{Key: "payload", Value: bson.D{{Key: "value", Value: "not-an-int"}}}}}, + } { + t.Run(tc.name, func(t *testing.T) { + raw, marshalErr := bson.Marshal(tc.doc) + require.NoError(t, marshalErr) + require.ErrorContains(t, converter.AppendDocument(t.Context(), bat, raw, mp), "NOT NULL column value") + require.Zero(t, bat.RowCount()) + require.Zero(t, bat.Vecs[0].Length()) + }) + } +} + +func TestConverterRejectsOversizeAndUnsupportedType(t *testing.T) { + ctx := context.Background() + _, err := NewConverter(ctx, []ColumnMapping{{Name: "x", Path: "x", TypeID: int32(types.T_array_float32)}}, 1) + require.Error(t, err) + converter, err := NewConverter(ctx, []ColumnMapping{{Name: "x", Path: "x", TypeID: int32(types.T_varchar)}}, 8) + require.NoError(t, err) + mp, err := mpool.NewMPool("mongodb-oversize-test", 0, mpool.NoFixed) + require.NoError(t, err) + bat := converter.NewBatch() + raw, err := bson.Marshal(bson.D{{Key: "x", Value: "larger-than-eight"}}) + require.NoError(t, err) + require.Error(t, converter.AppendDocument(ctx, bat, raw, mp)) + require.Zero(t, bat.RowCount()) + bat.Clean(mp) + require.Zero(t, mp.CurrNB()) +} + +func TestConverterVarcharWidthCountsUnicodeCharacters(t *testing.T) { + converter, err := NewConverter(t.Context(), []ColumnMapping{ + {Name: "value", Path: "value", TypeID: int32(types.T_varchar), Width: 2}, + }, 1024) + require.NoError(t, err) + mp := mpool.MustNewZero() + bat := converter.NewBatch() + + raw, err := bson.Marshal(bson.D{{Key: "value", Value: "你好"}}) + require.NoError(t, err) + require.NoError(t, converter.AppendDocument(t.Context(), bat, raw, mp)) + require.Equal(t, "你好", string(bat.Vecs[0].GetBytesAt(0))) + + raw, err = bson.Marshal(bson.D{{Key: "value", Value: "你好世"}}) + require.NoError(t, err) + require.Error(t, converter.AppendDocument(t.Context(), bat, raw, mp)) + require.Equal(t, 1, bat.RowCount()) + bat.Clean(mp) + require.Zero(t, mp.CurrNB()) +} + +func TestConverterNestedPathDistinguishesMissingAndInvalidTraversal(t *testing.T) { + mp := mpool.MustNewZero() + strict, err := NewConverter(t.Context(), []ColumnMapping{ + {Name: "value", Path: "reading.value", TypeID: int32(types.T_int64), Conversion: ConversionStrict}, + }, 1024) + require.NoError(t, err) + bat := strict.NewBatch() + + missing, err := bson.Marshal(bson.D{{Key: "other", Value: 1}}) + require.NoError(t, err) + require.NoError(t, strict.AppendDocument(t.Context(), bat, missing, mp)) + require.True(t, bat.Vecs[0].IsNull(0)) + + for _, malformed := range []any{"scalar-parent", bson.A{bson.D{{Key: "value", Value: 1}}}} { + raw, marshalErr := bson.Marshal(bson.D{{Key: "reading", Value: malformed}}) + require.NoError(t, marshalErr) + require.Error(t, strict.AppendDocument(t.Context(), bat, raw, mp)) + require.Equal(t, 1, bat.RowCount()) + } + bat.Clean(mp) + require.Zero(t, mp.CurrNB()) + + tryNull, err := NewConverter(t.Context(), []ColumnMapping{ + {Name: "value", Path: "reading.value", TypeID: int32(types.T_int64), Conversion: ConversionTryNull}, + }, 1024) + require.NoError(t, err) + bat = tryNull.NewBatch() + raw, err := bson.Marshal(bson.D{{Key: "reading", Value: "scalar-parent"}}) + require.NoError(t, err) + require.NoError(t, tryNull.AppendDocument(t.Context(), bat, raw, mp)) + require.True(t, bat.Vecs[0].IsNull(0)) + require.Equal(t, int64(1), tryNull.ConversionErrors()) + bat.Clean(mp) + require.Zero(t, mp.CurrNB()) +} + +func TestConverterMpoolFailureLeavesNoPartialRow(t *testing.T) { + ctx := context.Background() + converter, err := NewConverter(ctx, []ColumnMapping{ + {Name: "first", Path: "first", TypeID: int32(types.T_varchar)}, + {Name: "second", Path: "second", TypeID: int32(types.T_varchar)}, + }, 2<<20) + require.NoError(t, err) + mp, err := mpool.NewMPool("mongodb-oom-test", 1<<20, mpool.NoFixed) + require.NoError(t, err) + bat := converter.NewBatch() + for _, vec := range bat.Vecs { + vec.SetOffHeap(true) + } + raw, err := bson.Marshal(bson.D{ + {Key: "first", Value: strings.Repeat("a", 700<<10)}, + {Key: "second", Value: strings.Repeat("b", 700<<10)}, + }) + require.NoError(t, err) + require.Error(t, converter.AppendDocument(ctx, bat, raw, mp)) + require.Zero(t, bat.RowCount()) + for _, vec := range bat.Vecs { + require.Zero(t, vec.Length()) + } + bat.Clean(mp) + require.Zero(t, mp.CurrNB()) +} + +func TestConverterTryNullDoesNotSwallowMpoolFailure(t *testing.T) { + ctx := context.Background() + converter, err := NewConverter(ctx, []ColumnMapping{ + {Name: "value", Path: "value", TypeID: int32(types.T_varchar), Conversion: ConversionTryNull}, + }, 2<<20) + require.NoError(t, err) + mp, err := mpool.NewMPool("mongodb-try-null-oom-test", 1<<20, mpool.NoFixed) + require.NoError(t, err) + bat := converter.NewBatch() + bat.Vecs[0].SetOffHeap(true) + raw, err := bson.Marshal(bson.D{{Key: "value", Value: strings.Repeat("x", 1100<<10)}}) + require.NoError(t, err) + + require.Error(t, converter.AppendDocument(ctx, bat, raw, mp)) + require.Zero(t, bat.RowCount()) + require.Zero(t, bat.Vecs[0].Length()) + bat.Clean(mp) + require.Zero(t, mp.CurrNB()) +} + +func TestConverterTryNullStatementErrorLimits(t *testing.T) { + columns := []ColumnMapping{ + {Name: "value", Path: "value", TypeID: int32(types.T_int64), Conversion: ConversionTryNull}, + } + converter, err := NewConverter(t.Context(), columns, 1024) + require.NoError(t, err) + converter.SetConversionErrorLimits(1, 1) + mp := mpool.MustNewZero() + bat := converter.NewBatch() + bad, err := bson.Marshal(bson.D{{Key: "value", Value: "not-an-int"}}) + require.NoError(t, err) + require.NoError(t, converter.AppendDocument(t.Context(), bat, bad, mp)) + require.True(t, bat.Vecs[0].IsNull(0)) + require.Equal(t, int64(1), converter.ConversionErrors()) + require.ErrorContains(t, converter.AppendDocument(t.Context(), bat, bad, mp), "error limit") + require.Equal(t, 1, bat.RowCount(), "the threshold-crossing row must be rolled back") + bat.Clean(mp) + require.Zero(t, mp.CurrNB()) + + converter, err = NewConverter(t.Context(), columns, 1024) + require.NoError(t, err) + converter.SetConversionErrorLimits(1_000, 0.05) + bat = converter.NewBatch() + for range conversionErrorRateMinAttempts - 1 { + require.NoError(t, converter.AppendDocument(t.Context(), bat, bad, mp)) + } + require.ErrorContains(t, converter.AppendDocument(t.Context(), bat, bad, mp), "error limit") + require.Equal(t, conversionErrorRateMinAttempts-1, bat.RowCount()) + bat.Clean(mp) + require.Zero(t, mp.CurrNB()) +} + +func TestBSONDoubleToInt64RejectsTwoToThe63rd(t *testing.T) { + raw, err := bson.Marshal(bson.D{{Key: "value", Value: float64(9223372036854775808)}}) + require.NoError(t, err) + value := bson.Raw(raw).Lookup("value") + converted, ok := bsonInt64(value) + require.False(t, ok) + require.Zero(t, converted) +} + +func TestConverterDecimalBinaryAndInternalJSONEncoding(t *testing.T) { + ctx := context.Background() + mp := mpool.MustNewZero() + decimal, err := bson.ParseDecimal128("123.456") + require.NoError(t, err) + converter, err := NewConverter(ctx, []ColumnMapping{ + {Name: "decimal", Path: "decimal", TypeID: int32(types.T_decimal128), Width: 18, Scale: 3}, + {Name: "binary", Path: "binary", TypeID: int32(types.T_varbinary), Width: 16}, + {Name: "document", Path: "document", TypeID: int32(types.T_json)}, + }, 1024) + require.NoError(t, err) + raw, err := bson.Marshal(bson.D{ + {Key: "decimal", Value: decimal}, + {Key: "binary", Value: bson.Binary{Subtype: 0, Data: []byte{1, 2, 3}}}, + {Key: "document", Value: bson.D{{Key: "nested", Value: bson.A{1, "two"}}}}, + }) + require.NoError(t, err) + bat := converter.NewBatch() + require.NoError(t, converter.AppendDocument(ctx, bat, raw, mp)) + require.Equal(t, "123.456", vector.GetFixedAtNoTypeCheck[types.Decimal128](bat.Vecs[0], 0).Format(3)) + require.Equal(t, []byte{1, 2, 3}, bat.Vecs[1].GetBytesAt(0)) + require.JSONEq(t, `{"nested":[{"$numberInt":"1"},"two"]}`, types.DecodeJson(bat.Vecs[2].GetBytesAt(0)).String()) + bat.Clean(mp) + require.Zero(t, mp.CurrNB()) +} + +func TestConverterCoversSupportedScalarFamilies(t *testing.T) { + mp := mpool.MustNewZero() + decimal, err := bson.ParseDecimal128("12.345") + require.NoError(t, err) + objectID := bson.NewObjectID() + when := time.Date(2026, 7, 29, 10, 11, 12, 345000000, time.UTC) + columns := []ColumnMapping{ + {Name: "bool", TypeID: int32(types.T_bool)}, + {Name: "int8", TypeID: int32(types.T_int8)}, + {Name: "int16", TypeID: int32(types.T_int16)}, + {Name: "int64", TypeID: int32(types.T_int64)}, + {Name: "uint8", TypeID: int32(types.T_uint8)}, + {Name: "uint16", TypeID: int32(types.T_uint16)}, + {Name: "uint32", TypeID: int32(types.T_uint32)}, + {Name: "uint64", TypeID: int32(types.T_uint64)}, + {Name: "float32", TypeID: int32(types.T_float32)}, + {Name: "decimal64", TypeID: int32(types.T_decimal64), Width: 18, Scale: 2}, + {Name: "decimal128", TypeID: int32(types.T_decimal128), Width: 20, Scale: 3}, + {Name: "decimal256", TypeID: int32(types.T_decimal256), Width: 38, Scale: 3}, + {Name: "date", TypeID: int32(types.T_date)}, + {Name: "timestamp", TypeID: int32(types.T_timestamp)}, + {Name: "char", TypeID: int32(types.T_char), Width: 8}, + {Name: "text", TypeID: int32(types.T_text)}, + {Name: "binary", TypeID: int32(types.T_binary), Width: 8}, + {Name: "varbinary", TypeID: int32(types.T_varbinary), Width: 12}, + {Name: "blob", TypeID: int32(types.T_blob)}, + } + converter, err := NewConverter(t.Context(), columns, 0) + require.NoError(t, err) + require.Equal(t, columns, converter.Columns()) + copyOfColumns := converter.Columns() + copyOfColumns[0].Name = "changed" + require.Equal(t, "bool", converter.Columns()[0].Name) + converter.SetConversionErrorLimits(3, 0.25) + require.Equal(t, int64(3), converter.maxConversionErrors) + require.Equal(t, 0.25, converter.maxConversionErrorRate) + converter.SetConversionErrorLimits(0, 2) + require.Equal(t, DefaultRuntimeConfig().MaxConversionErrors, converter.maxConversionErrors) + require.Equal(t, DefaultRuntimeConfig().MaxConversionErrorRate, converter.maxConversionErrorRate) + + raw, err := bson.Marshal(bson.D{ + {Key: "bool", Value: true}, + {Key: "int8", Value: int32(8)}, + {Key: "int16", Value: int32(16)}, + {Key: "int64", Value: float64(64)}, + {Key: "uint8", Value: int32(8)}, + {Key: "uint16", Value: int32(16)}, + {Key: "uint32", Value: int64(32)}, + {Key: "uint64", Value: int64(64)}, + {Key: "float32", Value: 1.5}, + {Key: "decimal64", Value: int32(12)}, + {Key: "decimal128", Value: int64(12345)}, + {Key: "decimal256", Value: decimal}, + {Key: "date", Value: when}, + {Key: "timestamp", Value: when}, + {Key: "char", Value: "text"}, + {Key: "text", Value: objectID}, + {Key: "binary", Value: bson.Binary{Data: []byte{1, 2}}}, + {Key: "varbinary", Value: objectID}, + {Key: "blob", Value: bson.Binary{Data: []byte{3, 4}}}, + }) + require.NoError(t, err) + bat := converter.NewBatch() + require.NoError(t, converter.AppendDocument(t.Context(), bat, raw, mp)) + require.Equal(t, 1, bat.RowCount()) + require.True(t, vector.GetFixedAtNoTypeCheck[bool](bat.Vecs[0], 0)) + require.Equal(t, int8(8), vector.GetFixedAtNoTypeCheck[int8](bat.Vecs[1], 0)) + require.Equal(t, uint64(64), vector.GetFixedAtNoTypeCheck[uint64](bat.Vecs[7], 0)) + require.Equal(t, objectID.Hex(), string(bat.Vecs[15].GetBytesAt(0))) + require.Equal(t, objectID[:], bat.Vecs[17].GetBytesAt(0)) + bat.Clean(mp) + require.Zero(t, mp.CurrNB()) +} + +func TestConverterRejectsInvalidMappingsAndScalarBounds(t *testing.T) { + for _, tc := range []struct { + name string + columns []ColumnMapping + }{ + {name: "empty"}, + {name: "empty name", columns: []ColumnMapping{{TypeID: int32(types.T_int64)}}}, + {name: "duplicate", columns: []ColumnMapping{{Name: "Value", TypeID: int32(types.T_int64)}, {Name: "value", TypeID: int32(types.T_int64)}}}, + {name: "invalid path", columns: []ColumnMapping{{Name: "value", Path: "$where", TypeID: int32(types.T_int64)}}}, + {name: "invalid conversion", columns: []ColumnMapping{{Name: "value", TypeID: int32(types.T_int64), Conversion: "lossy"}}}, + } { + t.Run(tc.name, func(t *testing.T) { + _, err := NewConverter(t.Context(), tc.columns, 1024) + require.Error(t, err) + }) + } + + mp := mpool.MustNewZero() + tooWideDecimal, err := bson.ParseDecimal128("123456789") + require.NoError(t, err) + for _, tc := range []struct { + name string + target types.T + width int32 + scale int32 + value any + }{ + {name: "bool", target: types.T_bool, value: "true"}, + {name: "int8", target: types.T_int8, value: int32(math.MaxInt8 + 1)}, + {name: "int16", target: types.T_int16, value: int32(math.MaxInt16 + 1)}, + {name: "int64 fraction", target: types.T_int64, value: 1.5}, + {name: "uint negative", target: types.T_uint64, value: int32(-1)}, + {name: "uint8", target: types.T_uint8, value: int32(math.MaxUint8 + 1)}, + {name: "uint16", target: types.T_uint16, value: int64(math.MaxUint16 + 1)}, + {name: "uint32", target: types.T_uint32, value: int64(math.MaxUint32 + 1)}, + {name: "float32", target: types.T_float32, value: math.MaxFloat64}, + {name: "decimal type", target: types.T_decimal64, width: 18, scale: 2, value: "12.3"}, + {name: "decimal width", target: types.T_decimal64, width: 4, scale: 0, value: tooWideDecimal}, + {name: "date", target: types.T_date, value: "2026-07-29"}, + {name: "char", target: types.T_char, width: 8, value: int32(1)}, + {name: "binary", target: types.T_binary, width: 8, value: "bytes"}, + } { + t.Run(tc.name, func(t *testing.T) { + converter, err := NewConverter(t.Context(), []ColumnMapping{{ + Name: "value", TypeID: int32(tc.target), Width: tc.width, Scale: tc.scale, + }}, 1024) + require.NoError(t, err) + raw, err := bson.Marshal(bson.D{{Key: "value", Value: tc.value}}) + require.NoError(t, err) + bat := converter.NewBatch() + require.Error(t, converter.AppendDocument(t.Context(), bat, raw, mp)) + require.Zero(t, bat.RowCount()) + bat.Clean(mp) + }) + } + require.Zero(t, mp.CurrNB()) + + for _, value := range []any{math.NaN(), math.Inf(1), math.Inf(-1), float64(9223372036854775808)} { + raw, err := bson.Marshal(bson.D{{Key: "value", Value: value}}) + require.NoError(t, err) + _, ok := bsonInt64(bson.Raw(raw).Lookup("value")) + require.False(t, ok) + } +} + +func TestConnectionValidationAndRedaction(t *testing.T) { + ctx := context.Background() + base := Connection{ + Name: "c", Hosts: "db.mongo.example:27017", CredentialSecretRef: "secret://mongodb/reader", + AuthMechanism: "SCRAM-SHA-256", TLSMode: "required", ReadPreference: "secondaryPreferred", ReadConcern: "majority", + } + cfg := DefaultRuntimeConfig() + cfg.AllowedHostSuffixes = []string{"mongo.example"} + require.NoError(t, ValidateConnection(ctx, base, cfg)) + bad := base + bad.Hosts = "mongodb://user:password@db:27017" + require.Error(t, ValidateConnection(ctx, bad, cfg)) + bad = base + bad.Hosts = "127.0.0.1:27017" + require.Error(t, ValidateConnection(ctx, bad, cfg)) + bad = base + bad.CredentialSecretRef = "reader:plaintext" + require.Error(t, ValidateConnection(ctx, bad, cfg)) + bad = base + bad.OptionsJSON = `{"password":"must-not-be-smuggled"}` + require.Error(t, ValidateConnection(ctx, bad, cfg)) + bad.OptionsJSON = `{"direct":true} trailing` + require.Error(t, ValidateConnection(ctx, bad, cfg)) + good := base + good.OptionsJSON = `{"direct":true}` + require.NoError(t, ValidateConnection(ctx, good, cfg)) + + noAllowlist := base + require.ErrorContains(t, ValidateConnection(ctx, noAllowlist, DefaultRuntimeConfig()), "suffix allowlist") + ipLiteral := base + ipLiteral.Hosts = "10.10.1.5:27017" + require.ErrorContains(t, ValidateConnection(ctx, ipLiteral, DefaultRuntimeConfig()), "CIDR allowlist") + loopback := base + loopback.Hosts = "127.0.0.1:27017" + loopbackConfig := DefaultRuntimeConfig() + loopbackConfig.AllowLoopback = true + require.NoError(t, ValidateConnection(ctx, loopback, loopbackConfig)) + unspecified := base + unspecified.Hosts = "0.0.0.0:27017" + require.ErrorContains(t, ValidateConnection(ctx, unspecified, loopbackConfig), "unspecified") + + redacted := Redact("mongodb://alice:very-secret@db.example:27017/x") + require.NotContains(t, redacted, "alice") + require.NotContains(t, redacted, "very-secret") + require.Equal(t, "mongodb://db.example:27017/x", redacted) + redacted = Redact("mongodb://alice:very-secret@db.example:27017/x?password=one&token=two&password=three") + for _, forbidden := range []string{"alice", "very-secret", "one", "two", "three"} { + require.NotContains(t, redacted, forbidden) + } + require.Equal(t, "mongodb://db.example:27017/x?password=******&token=******&password=******", redacted) + redacted = Redact("server selection failed for mongodb+srv://bob:p%40ss@db.example/x token=raw-token") + require.Equal(t, "server selection failed for mongodb+srv://db.example/x token=******", redacted) +} + +func TestDriverOptionsFailClosedOnIncompleteResolvedSecrets(t *testing.T) { + connection := Connection{ + Name: "c", Hosts: "127.0.0.1:27017", CredentialSecretRef: "secret://env/MONGO", + AuthMechanism: "SCRAM-SHA-256", TLSMode: "disabled", ReadPreference: "primary", ReadConcern: "majority", + } + cfg := DefaultRuntimeConfig() + cfg.AllowLoopback = true + _, err := buildClientOptions(t.Context(), connection, Credentials{}, cfg) + require.ErrorContains(t, err, "incomplete identity") + + connection.TLSMode = "required" + connection.TLSCASecretRef = "secret://env/MONGO_CA" + _, err = buildClientOptions(t.Context(), connection, Credentials{Username: "reader", Password: "secret"}, cfg) + require.ErrorContains(t, err, "empty material") +} + +func TestDriverDisablesAdaptiveCursorRetries(t *testing.T) { + connection := Connection{ + Name: "c", Hosts: "127.0.0.1:27017", CredentialSecretRef: "secret://env/MONGO", + AuthMechanism: "SCRAM-SHA-256", TLSMode: "disabled", ReadPreference: "primary", ReadConcern: "majority", + } + cfg := DefaultRuntimeConfig() + cfg.AllowLoopback = true + clientOptions, err := buildClientOptions( + t.Context(), connection, Credentials{Username: "reader", Password: "secret"}, cfg) + require.NoError(t, err) + require.NotNil(t, clientOptions.MaxAdaptiveRetries) + require.Zero(t, *clientOptions.MaxAdaptiveRetries) + require.NotNil(t, clientOptions.RetryReads) + require.True(t, *clientOptions.RetryReads, "the initial find remains retryable") +} + +func TestDriverSRVTLSModeIsExplicit(t *testing.T) { + clientOptions := options.Client().SetTLSConfig(&tls.Config{MinVersion: tls.VersionTLS12}) + err := configureTLS(t.Context(), clientOptions, "disabled", nil) + require.NoError(t, err) + require.Nil(t, clientOptions.TLSConfig, "tls_mode=disabled must override mongodb+srv's implicit TLS") + + err = configureTLS(t.Context(), clientOptions, "required", nil) + require.NoError(t, err) + require.NotNil(t, clientOptions.TLSConfig) + require.Equal(t, uint16(tls.VersionTLS12), clientOptions.TLSConfig.MinVersion) +} + +func TestEnvSecretResolverRejectsMalformedCredentials(t *testing.T) { + ctx := context.Background() + resolver := EnvSecretResolver{} + t.Setenv("MO_MONGODB_ACCOUNT_1_TEST_CREDENTIAL", `{"username":"reader","password":"secret"}`) + t.Setenv("MO_MONGODB_ACCOUNT_1_TEST_CA", "test-ca") + credentials, err := resolver.ResolveMongoDBCredentials( + ctx, 1, "secret://env/MO_MONGODB_ACCOUNT_1_TEST_CREDENTIAL", "secret://env/MO_MONGODB_ACCOUNT_1_TEST_CA") + require.NoError(t, err) + require.Equal(t, "reader", credentials.Username) + require.Equal(t, "secret", credentials.Password) + require.Equal(t, []byte("test-ca"), credentials.TLSCA) + + for name, raw := range map[string]string{ + "missing-password": `{"username":"reader"}`, + "unknown-field": `{"username":"reader","password":"secret","token":"leak"}`, + "trailing-json": `{"username":"reader","password":"secret"}{}`, + } { + t.Run(name, func(t *testing.T) { + t.Setenv("MO_MONGODB_ACCOUNT_1_TEST_BAD_CREDENTIAL", raw) + _, err := resolver.ResolveMongoDBCredentials( + ctx, 1, "secret://env/MO_MONGODB_ACCOUNT_1_TEST_BAD_CREDENTIAL", "") + require.Error(t, err) + }) + } + _, err = resolver.ResolveMongoDBCredentials(ctx, 1, "env://PLAINTEXT", "") + require.Error(t, err) + t.Setenv("MO_MONGODB_ACCOUNT_2_TEST_CREDENTIAL", `{"username":"other","password":"secret"}`) + _, err = resolver.ResolveMongoDBCredentials(ctx, 1, "secret://env/MO_MONGODB_ACCOUNT_2_TEST_CREDENTIAL", "") + require.Error(t, err, "one tenant must not resolve another tenant's environment-secret namespace") +} + +type fakeHostResolver struct { + addresses map[string][]net.IPAddr + srv []*net.SRV +} + +type recordingDialer struct { + addresses []string +} + +func (d *recordingDialer) DialContext(_ context.Context, _, address string) (net.Conn, error) { + d.addresses = append(d.addresses, address) + return nil, nil +} + +func (r fakeHostResolver) LookupIPAddr(_ context.Context, host string) ([]net.IPAddr, error) { + return r.addresses[host], nil +} + +func (r fakeHostResolver) LookupSRV(context.Context, string, string, string) (string, []*net.SRV, error) { + return "", r.srv, nil +} + +func TestResolvedEndpointPolicyRejectsDNSRebinding(t *testing.T) { + ctx := context.Background() + connection := Connection{ + Name: "c", Hosts: "db.mongo.example:27017", CredentialSecretRef: "secret://env/MONGO", + AuthMechanism: "SCRAM-SHA-256", TLSMode: "required", ReadPreference: "secondaryPreferred", ReadConcern: "majority", + } + cfg := DefaultRuntimeConfig() + cfg.AllowedHostSuffixes = []string{"mongo.example"} + resolver := fakeHostResolver{addresses: map[string][]net.IPAddr{"db.mongo.example": {{IP: net.ParseIP("127.0.0.1")}}}} + require.Error(t, ValidateResolvedEndpoints(ctx, connection, cfg, resolver)) + resolver.addresses["db.mongo.example"] = []net.IPAddr{{IP: net.ParseIP("10.10.1.5")}} + cfg.AllowedCIDRs = []string{"10.10.0.0/16"} + require.NoError(t, ValidateResolvedEndpoints(ctx, connection, cfg, resolver)) + + srvConnection := connection + srvConnection.Hosts = "" + srvConnection.SRVHost = "cluster.mongo.example" + resolver.srv = []*net.SRV{{Target: "attacker.invalid.", Port: 27017}} + resolver.addresses["attacker.invalid"] = []net.IPAddr{{IP: net.ParseIP("10.10.1.5")}} + require.ErrorContains(t, ValidateResolvedEndpoints(ctx, srvConnection, cfg, resolver), "hostname allowlist") +} + +func TestEndpointPolicyRejectsCloudMetadataAddresses(t *testing.T) { + ctx := context.Background() + cfg := DefaultRuntimeConfig() + cfg.AllowLoopback = true + for _, address := range []string{ + "169.254.169.254", + "100.100.100.200", + "fd00:ec2::254", + "fd20:ce::254", + } { + t.Run(address, func(t *testing.T) { + require.Error(t, validateHost(ctx, address, cfg)) + }) + } +} + +func TestPolicyDialerValidatesDiscoveredMembersAndDialsResolvedIP(t *testing.T) { + ctx := context.Background() + cfg := DefaultRuntimeConfig() + cfg.AllowedHostSuffixes = []string{"mongo.example"} + cfg.AllowedCIDRs = []string{"10.20.0.0/16"} + resolver := fakeHostResolver{addresses: map[string][]net.IPAddr{ + "member.mongo.example": {{IP: net.ParseIP("10.20.1.7")}}, + }} + base := &recordingDialer{} + dialer := newPolicyDialer(cfg, resolver) + dialer.base = base + _, err := dialer.DialContext(ctx, "tcp", "member.mongo.example:27017") + require.NoError(t, err) + require.Equal(t, []string{"10.20.1.7:27017"}, base.addresses) + + resolver.addresses["member.mongo.example"] = []net.IPAddr{{IP: net.ParseIP("127.0.0.1")}} + _, err = dialer.DialContext(ctx, "tcp", "member.mongo.example:27017") + require.Error(t, err) + require.Len(t, base.addresses, 1, "an out-of-policy rebinding must fail before socket creation") + + _, err = dialer.DialContext(ctx, "tcp", "attacker.invalid:27017") + require.Error(t, err, "a discovered member must also satisfy the hostname allowlist") +} + +func TestProjectionDocumentCollapsesParentChildPaths(t *testing.T) { + projection := ProjectionDocument([]ColumnMapping{ + {Path: "payload.value"}, + {Path: "other"}, + {Path: "payload"}, + {Path: "payload.unit"}, + }) + require.Equal(t, bson.D{ + {Key: "other", Value: 1}, + {Key: "payload", Value: 1}, + {Key: "_id", Value: 0}, + }, projection) + + projection = ProjectionDocument([]ColumnMapping{{Path: "_id"}, {Path: "value"}}) + require.Equal(t, bson.D{{Key: "_id", Value: 1}, {Key: "value", Value: 1}}, projection) +} + +type fakeFactory struct { + mu sync.Mutex + clients []*fakeClient +} + +type connectionResolverFunc func(context.Context, uint32, uint64, uint64) (Connection, error) + +func (f connectionResolverFunc) ResolveMongoDBConnection( + ctx context.Context, accountID uint32, connectionID uint64, version uint64, +) (Connection, error) { + return f(ctx, accountID, connectionID, version) +} + +func (f *fakeFactory) Connect(context.Context, Connection, Credentials, RuntimeConfig) (Client, error) { + f.mu.Lock() + defer f.mu.Unlock() + c := &fakeClient{} + f.clients = append(f.clients, c) + return c, nil +} + +type fakeClient struct { + mu sync.Mutex + disconnects int + disconnectContextErr error +} + +func (*fakeClient) Collection(string, string) Collection { return nil } +func (*fakeClient) Ping(context.Context) error { return nil } +func (c *fakeClient) Disconnect(ctx context.Context) error { + c.mu.Lock() + c.disconnects++ + c.disconnectContextErr = ctx.Err() + c.mu.Unlock() + return nil +} +func (c *fakeClient) count() int { + c.mu.Lock() + defer c.mu.Unlock() + return c.disconnects +} + +func TestClientPoolTenantIsolationRotationAndIdempotentRelease(t *testing.T) { + ctx := context.Background() + factory := &fakeFactory{} + pool := NewClientPool(factory) + base := Connection{AccountID: 1, ConnectionID: 9, Version: 1, CredentialSecretRef: "secret://v1"} + l1, err := pool.Acquire(ctx, base, Credentials{}, RuntimeConfig{}) + require.NoError(t, err) + l2, err := pool.Acquire(ctx, base, Credentials{}, RuntimeConfig{}) + require.NoError(t, err) + require.Same(t, l1.Client(), l2.Client()) + + tenant2 := base + tenant2.AccountID = 2 + lTenant, err := pool.Acquire(ctx, tenant2, Credentials{}, RuntimeConfig{}) + require.NoError(t, err) + require.NotSame(t, l1.Client(), lTenant.Client()) + + rotated := base + rotated.Version = 2 + rotated.CredentialSecretRef = "secret://v2" + l3, err := pool.Acquire(ctx, rotated, Credentials{}, RuntimeConfig{}) + require.NoError(t, err) + require.NotSame(t, l1.Client(), l3.Client()) + old := l1.Client().(*fakeClient) + require.Zero(t, old.count()) + require.NoError(t, l1.Release(ctx)) + require.NoError(t, l1.Release(ctx)) + require.Zero(t, old.count()) + require.NoError(t, l2.Release(ctx)) + require.Equal(t, 1, old.count()) + require.NoError(t, l3.Release(ctx)) + require.NoError(t, lTenant.Release(ctx)) + // A released current generation stays reusable until rotation, eviction, + // or CN shutdown, so the driver's socket pool survives statement boundaries. + l4, err := pool.Acquire(ctx, rotated, Credentials{}, RuntimeConfig{}) + require.NoError(t, err) + require.Same(t, l3.Client(), l4.Client()) + require.NoError(t, l4.Release(ctx)) + require.NoError(t, pool.Close(ctx)) +} + +func TestClientPoolDetectsInPlaceSecretRotation(t *testing.T) { + factory := &fakeFactory{} + pool := NewClientPool(factory) + connection := Connection{AccountID: 1, ConnectionID: 9, Version: 1, CredentialSecretRef: "secret://stable"} + oldLease, err := pool.Acquire(t.Context(), connection, Credentials{Username: "reader", Password: "old"}, RuntimeConfig{}) + require.NoError(t, err) + newLease, err := pool.Acquire(t.Context(), connection, Credentials{Username: "reader", Password: "new"}, RuntimeConfig{}) + require.NoError(t, err) + require.NotSame(t, oldLease.Client(), newLease.Client()) + for key := range pool.entries { + require.NotContains(t, key.identity, "old") + require.NotContains(t, key.identity, "new") + require.NotContains(t, key.identity, "reader") + } + require.NoError(t, oldLease.Release(t.Context())) + require.Equal(t, 1, oldLease.Client().(*fakeClient).count()) + require.NoError(t, newLease.Release(t.Context())) + reused, err := pool.Acquire(t.Context(), connection, Credentials{Username: "reader", Password: "new"}, RuntimeConfig{}) + require.NoError(t, err) + require.Same(t, newLease.Client(), reused.Client()) + require.NoError(t, reused.Release(t.Context())) + require.NoError(t, pool.Close(t.Context())) +} + +func TestClientPoolBoundsIdleEntries(t *testing.T) { + ctx := context.Background() + factory := &fakeFactory{} + pool := NewClientPool(factory, 1) + first := Connection{AccountID: 1, ConnectionID: 1, Version: 1} + lease1, err := pool.Acquire(ctx, first, Credentials{}, RuntimeConfig{}) + require.NoError(t, err) + client1 := lease1.Client().(*fakeClient) + require.NoError(t, lease1.Release(ctx)) + require.Zero(t, client1.count()) + + second := first + second.ConnectionID = 2 + lease2, err := pool.Acquire(ctx, second, Credentials{}, RuntimeConfig{}) + require.NoError(t, err) + require.Equal(t, 1, client1.count()) + require.Len(t, pool.entries, 1) + require.NoError(t, lease2.Release(ctx)) + require.Len(t, pool.entries, 1) + require.NoError(t, pool.Close(ctx)) +} + +func TestClientPoolRetiresCommittedOldGeneration(t *testing.T) { + factory := &fakeFactory{} + pool := NewClientPool(factory) + connection := Connection{AccountID: 1, ConnectionID: 9, Version: 3} + + idle, err := pool.Acquire(t.Context(), connection, Credentials{}, RuntimeConfig{}) + require.NoError(t, err) + idleClient := idle.Client().(*fakeClient) + require.NoError(t, idle.Release(t.Context())) + require.NoError(t, pool.RetireBefore(1, 9, 4)) + require.Equal(t, 1, idleClient.count(), "an idle replaced generation must disconnect immediately") + + connection.Version = 4 + active, err := pool.Acquire(t.Context(), connection, Credentials{}, RuntimeConfig{}) + require.NoError(t, err) + activeClient := active.Client().(*fakeClient) + require.NoError(t, pool.RetireBefore(1, 9, 5)) + require.Zero(t, activeClient.count(), "an active generation must remain valid until its lease releases") + require.NoError(t, active.Release(t.Context())) + require.Equal(t, 1, activeClient.count()) + + connection.Version = 5 + dropped, err := pool.Acquire(t.Context(), connection, Credentials{}, RuntimeConfig{}) + require.NoError(t, err) + droppedClient := dropped.Client().(*fakeClient) + require.NoError(t, dropped.Release(t.Context())) + require.NoError(t, pool.RetireConnection(1, 9)) + require.Equal(t, 1, droppedClient.count()) + require.NoError(t, pool.Close(t.Context())) +} + +func TestClientPoolLateGenerationObservesRetirementTombstone(t *testing.T) { + for _, tc := range []struct { + name string + retire func(*ClientPool) error + version uint64 + connID uint64 + }{ + { + name: "alter", + retire: func(pool *ClientPool) error { + return pool.RetireBefore(4, 8, 2) + }, + version: 1, + connID: 8, + }, + { + name: "drop", + retire: func(pool *ClientPool) error { + return pool.RetireConnection(4, 9) + }, + version: 1, + connID: 9, + }, + { + name: "drop account", + retire: func(pool *ClientPool) error { + return pool.RetireAccount(4) + }, + version: 1, + connID: 10, + }, + } { + t.Run(tc.name, func(t *testing.T) { + allow := make(chan struct{}) + factory := &blockingFactory{ + started: make(chan uint64, 1), + allow: map[uint64]chan struct{}{tc.version: allow}, + } + pool := NewClientPool(factory) + type acquireResult struct { + lease *ClientLease + err error + } + result := make(chan acquireResult, 1) + go func() { + lease, err := pool.Acquire(t.Context(), Connection{ + AccountID: 4, ConnectionID: tc.connID, Version: tc.version, + }, Credentials{}, RuntimeConfig{}) + result <- acquireResult{lease: lease, err: err} + }() + require.Equal(t, tc.version, <-factory.started) + require.NoError(t, tc.retire(pool)) + close(allow) + acquired := <-result + require.NoError(t, acquired.err) + require.NotNil(t, acquired.lease) + client := acquired.lease.Client().(*fakeClient) + require.Zero(t, client.count(), "an already resolved statement may finish its lease") + require.NoError(t, acquired.lease.Release(t.Context())) + require.Equal(t, 1, client.count(), "a late retired client must not remain idle or reusable") + pool.mu.Lock() + require.Empty(t, pool.retirements, "retirement tombstones must be reclaimed after the race drains") + require.Empty(t, pool.connecting) + pool.mu.Unlock() + require.NoError(t, pool.Close(t.Context())) + }) + } +} + +func TestValidatedClientPoolClosesPreAcquireGenerationRace(t *testing.T) { + factory := &fakeFactory{} + validator := connectionResolverFunc(func(ctx context.Context, _ uint32, _ uint64, _ uint64) (Connection, error) { + return Connection{}, moerr.NewInvalidInput(ctx, "stale generation") + }) + pool := NewValidatedClientPool(factory, validator) + + // With no pool Acquire in flight, retirement metadata can be reclaimed. + // A statement that resolved v1 before this point but reaches Acquire only + // afterward is still rejected by the second catalog validation, before any + // socket pool is created. + require.NoError(t, pool.RetireBefore(4, 8, 2)) + require.Empty(t, pool.retirements) + _, err := pool.Acquire(t.Context(), Connection{ + AccountID: 4, ConnectionID: 8, Version: 1, + }, Credentials{}, RuntimeConfig{}) + require.ErrorContains(t, err, "stale generation") + require.Empty(t, factory.clients) + require.Empty(t, pool.connecting) + require.NoError(t, pool.Close(t.Context())) +} + +func TestClientPoolCleanupDoesNotInheritCanceledCaller(t *testing.T) { + factory := &fakeFactory{} + pool := NewClientPool(factory) + lease, err := pool.Acquire(context.Background(), Connection{AccountID: 1, ConnectionID: 1, Version: 1}, Credentials{}, RuntimeConfig{}) + require.NoError(t, err) + require.NoError(t, lease.Release(context.Background())) + client := lease.Client().(*fakeClient) + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + require.NoError(t, pool.Close(ctx)) + client.mu.Lock() + defer client.mu.Unlock() + require.Equal(t, 1, client.disconnects) + require.NoError(t, client.disconnectContextErr) +} + +type failingFactory struct{} + +func (failingFactory) Connect(context.Context, Connection, Credentials, RuntimeConfig) (Client, error) { + return nil, errors.New("connect failed") +} + +func TestClientPoolAcquireFailureDoesNotPublishEntry(t *testing.T) { + pool := NewClientPool(failingFactory{}) + _, err := pool.Acquire(context.Background(), Connection{}, Credentials{}, RuntimeConfig{}) + require.Error(t, err) + require.Empty(t, pool.entries) +} + +type blockingFactory struct { + started chan uint64 + allow map[uint64]chan struct{} +} + +func (f *blockingFactory) Connect(_ context.Context, connection Connection, _ Credentials, _ RuntimeConfig) (Client, error) { + f.started <- connection.Version + <-f.allow[connection.Version] + return &fakeClient{}, nil +} + +func TestClientPoolLateOldGenerationCannotDrainNewGeneration(t *testing.T) { + allowV1 := make(chan struct{}) + defer func() { + select { + case <-allowV1: + default: + close(allowV1) + } + }() + allowV2 := make(chan struct{}) + close(allowV2) + factory := &blockingFactory{ + started: make(chan uint64, 2), + allow: map[uint64]chan struct{}{1: allowV1, 2: allowV2}, + } + pool := NewClientPool(factory) + type result struct { + lease *ClientLease + err error + } + oldResult := make(chan result, 1) + go func() { + lease, err := pool.Acquire(t.Context(), Connection{AccountID: 1, ConnectionID: 9, Version: 1}, Credentials{}, RuntimeConfig{}) + oldResult <- result{lease: lease, err: err} + }() + require.Equal(t, uint64(1), <-factory.started) + + newLease, err := pool.Acquire(t.Context(), Connection{AccountID: 1, ConnectionID: 9, Version: 2}, Credentials{}, RuntimeConfig{}) + require.NoError(t, err) + require.Equal(t, uint64(2), <-factory.started) + close(allowV1) + old := <-oldResult + require.NoError(t, old.err) + require.NotSame(t, old.lease.Client(), newLease.Client()) + + reusedNew, err := pool.Acquire(t.Context(), Connection{AccountID: 1, ConnectionID: 9, Version: 2}, Credentials{}, RuntimeConfig{}) + require.NoError(t, err) + require.Same(t, newLease.Client(), reusedNew.Client(), "a late old Connect must not retire the current generation") + require.NoError(t, old.lease.Release(t.Context())) + require.Equal(t, 1, old.lease.Client().(*fakeClient).count()) + require.NoError(t, newLease.Release(t.Context())) + require.NoError(t, reusedNew.Release(t.Context())) + require.NoError(t, pool.Close(t.Context())) +} diff --git a/pkg/sql/mongodb/plan_bridge.go b/pkg/sql/mongodb/plan_bridge.go new file mode 100644 index 0000000000000..80ae66dbcf0ab --- /dev/null +++ b/pkg/sql/mongodb/plan_bridge.go @@ -0,0 +1,218 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "context" + "slices" + "strings" + + "github.com/matrixorigin/matrixone/pkg/common/moerr" + "github.com/matrixorigin/matrixone/pkg/pb/plan" + "go.mongodb.org/mongo-driver/v2/bson" +) + +// ProjectColumnsByName returns mappings in the compact MO scan-column order. +// Column pruning rewrites filter ColPos values against that compact order, so +// a connector must convert every retained scan column (including residual-only +// filter columns), not only the columns projected to its parent operator. +func ProjectColumnsByName(ctx context.Context, columns []ColumnMapping, names []string) ([]ColumnMapping, error) { + byName := make(map[string]ColumnMapping, len(columns)) + for _, column := range columns { + key := strings.ToLower(column.Name) + if _, exists := byName[key]; exists { + return nil, moerr.NewInternalErrorf(ctx, "duplicate MongoDB mapping column %s", column.Name) + } + byName[key] = column + } + projected := make([]ColumnMapping, 0, len(names)) + for _, name := range names { + column, ok := byName[strings.ToLower(name)] + if !ok { + return nil, moerr.NewInternalErrorf(ctx, "MongoDB scan column %s has no mapping", name) + } + projected = append(projected, column) + } + return projected, nil +} + +// MappingDefinitionMatchesPlan validates the non-secret definition captured +// from rel_createsql against the authoritative mapping row during compile. +func MappingDefinitionMatchesPlan(mapping TableMapping, scan *plan.MongoScan) bool { + if scan == nil || mapping.Database != scan.Database || mapping.Collection != scan.Collection || + mapping.MaxParallelism != scan.MaxParallelism { + return false + } + return slices.Equal(mapping.Columns, ColumnsFromPlan(scan.Columns)) +} + +// MappingSnapshotMatchesPlan additionally pins catalog identity and version; +// execution CNs use this after resolving the exact mapping generation. +func MappingSnapshotMatchesPlan(mapping TableMapping, scan *plan.MongoScan) bool { + if scan == nil || mapping.Database != scan.Database || mapping.Collection != scan.Collection || + mapping.MaxParallelism != scan.MaxParallelism || + mapping.TableID != scan.TableId || + mapping.MappingID != scan.MappingId || + mapping.Version != scan.MappingVersion || + mapping.ConnectionID != scan.ConnectionId { + return false + } + planned := ColumnsFromPlan(scan.Columns) + if len(planned) == 0 { + return false + } + for _, projected := range planned { + matched := false + for _, catalogColumn := range mapping.Columns { + if projected == catalogColumn { + matched = true + break + } + } + if !matched { + return false + } + } + return true +} + +func ColumnsFromPlan(columns []*plan.MongoColumnMapping) []ColumnMapping { + result := make([]ColumnMapping, 0, len(columns)) + for _, column := range columns { + if column == nil { + continue + } + result = append(result, ColumnMapping{ + Name: column.Name, + Path: column.Path, + TypeID: column.MoType.Id, + Width: column.MoType.Width, + Scale: column.MoType.Scale, + NotNullable: column.MoType.NotNullable, + Conversion: column.ConversionMode, + }) + } + return result +} + +func ColumnsToPlan(columns []ColumnMapping) []*plan.MongoColumnMapping { + result := make([]*plan.MongoColumnMapping, 0, len(columns)) + for _, column := range columns { + result = append(result, &plan.MongoColumnMapping{ + Name: column.Name, + Path: column.Path, + MoType: plan.Type{ + Id: column.TypeID, + Width: column.Width, + Scale: column.Scale, + NotNullable: column.NotNullable, + }, + ConversionMode: column.Conversion, + }) + } + return result +} + +// MarshalPredicateValue encodes a scalar in a one-field BSON document. BSON +// has no standalone-value wire format, so the stable field name is part of the +// connector protocol. +func MarshalPredicateValue(value any) ([]byte, error) { + return bson.Marshal(bson.D{{Key: "v", Value: value}}) +} + +func predicateValue(ctx context.Context, data []byte) (any, error) { + if len(data) == 0 { + return nil, nil + } + raw := bson.Raw(data) + if err := raw.Validate(); err != nil { + return nil, moerr.NewInvalidInput(ctx, "MongoDB predicate contains invalid BSON") + } + value, err := raw.LookupErr("v") + if err != nil { + return nil, moerr.NewInvalidInput(ctx, "MongoDB predicate BSON is missing its scalar value") + } + var decoded any + if err := value.Unmarshal(&decoded); err != nil { + return nil, moerr.NewInvalidInput(ctx, "MongoDB predicate BSON scalar cannot be decoded") + } + return decoded, nil +} + +func PredicateFromPlan(ctx context.Context, input *plan.MongoPredicate) (*Predicate, error) { + if input == nil { + return nil, nil + } + result := &Predicate{Op: PredicateOp(input.Op), Path: input.Path} + var err error + if len(input.ValueBson) > 0 { + result.Value, err = predicateValue(ctx, input.ValueBson) + if err != nil { + return nil, err + } + } + result.Values = make([]any, 0, len(input.ValuesBson)) + for _, raw := range input.ValuesBson { + value, valueErr := predicateValue(ctx, raw) + if valueErr != nil { + return nil, valueErr + } + result.Values = append(result.Values, value) + } + result.Children = make([]*Predicate, 0, len(input.Children)) + for _, child := range input.Children { + converted, childErr := PredicateFromPlan(ctx, child) + if childErr != nil { + return nil, childErr + } + result.Children = append(result.Children, converted) + } + if err = result.Validate(ctx); err != nil { + return nil, err + } + return result, nil +} + +func PredicateToPlan(ctx context.Context, input *Predicate) (*plan.MongoPredicate, error) { + if input == nil { + return nil, nil + } + if err := input.Validate(ctx); err != nil { + return nil, err + } + result := &plan.MongoPredicate{Op: plan.MongoPredicateOp(input.Op), Path: input.Path} + var err error + if input.Op != PredicateAnd && input.Op != PredicateIsNull && input.Op != PredicateIsNotNull { + result.ValueBson, err = MarshalPredicateValue(input.Value) + if err != nil { + return nil, err + } + } + for _, value := range input.Values { + encoded, encodeErr := MarshalPredicateValue(value) + if encodeErr != nil { + return nil, encodeErr + } + result.ValuesBson = append(result.ValuesBson, encoded) + } + for _, child := range input.Children { + converted, childErr := PredicateToPlan(ctx, child) + if childErr != nil { + return nil, childErr + } + result.Children = append(result.Children, converted) + } + return result, nil +} diff --git a/pkg/sql/mongodb/plan_predicate.go b/pkg/sql/mongodb/plan_predicate.go new file mode 100644 index 0000000000000..ffff82bffc1d3 --- /dev/null +++ b/pkg/sql/mongodb/plan_predicate.go @@ -0,0 +1,349 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "context" + "strings" + "time" + + "github.com/matrixorigin/matrixone/pkg/container/types" + "github.com/matrixorigin/matrixone/pkg/pb/plan" + "go.mongodb.org/mongo-driver/v2/bson" +) + +// PushdownPlanFilters translates the conservative, driver-neutral subset of +// scan filters. Callers must retain every original expression as an MO +// residual. In strict conversion mode a source value with an unexpected BSON +// type must still reach the converter and fail, so comparison pushdown is +// disabled; try_null mappings are eligible for IS NOT NULL, and try_null +// numeric mappings are eligible for comparisons, because malformed values +// become SQL NULL and cannot satisfy either residual. String/collation +// predicates and IS NULL remain residual-only until their full candidate-set +// semantics are proven. +func PushdownPlanFilters(ctx context.Context, filters []*plan.Expr, columns []*plan.MongoColumnMapping) (*plan.MongoPredicate, string) { + children := make([]*Predicate, 0, len(filters)) + for _, filter := range filters { + if predicate, ok := planExprToPredicate(filter, columns); ok { + children = append(children, predicate) + } + } + if len(children) == 0 { + return nil, residualDigest(filters) + } + var predicate *Predicate + if len(children) == 1 { + predicate = children[0] + } else { + predicate = &Predicate{Op: PredicateAnd, Children: children} + } + converted, err := PredicateToPlan(ctx, predicate) + if err != nil { + return nil, residualDigest(filters) + } + return converted, residualDigest(filters) +} + +func planExprToPredicate(expr *plan.Expr, columns []*plan.MongoColumnMapping) (*Predicate, bool) { + fn := expr.GetF() + if fn == nil || fn.Func == nil { + return nil, false + } + name := strings.ToLower(fn.Func.ObjName) + if name == "and" && len(fn.Args) == 2 { + left, leftOK := planExprToPredicate(fn.Args[0], columns) + right, rightOK := planExprToPredicate(fn.Args[1], columns) + if !leftOK || !rightOK { + return nil, false + } + return &Predicate{Op: PredicateAnd, Children: []*Predicate{left, right}}, true + } + if (name == "is_null" || name == "isnull" || name == "is_not_null" || name == "isnotnull") && len(fn.Args) == 1 { + column, ok := mappedColumn(fn.Args[0], columns) + if !ok { + return nil, false + } + if name == "is_null" || name == "isnull" { + // {field:null} excludes present-but-malformed values. That would + // hide a strict conversion error and is also a false negative for + // try_null, where malformed becomes SQL NULL. + return nil, false + } + if !strings.EqualFold(column.ConversionMode, ConversionTryNull) { + // A strict dotted mapping must inspect malformed intermediate + // values. MongoDB's $exists/$ne candidate would discard scalar or + // null parents before conversion and silently hide that error. + return nil, false + } + return &Predicate{Op: PredicateIsNotNull, Path: column.Path}, true + } + if name == "in" && len(fn.Args) == 2 { + column, ok := mappedColumn(fn.Args[0], columns) + if !ok || !eligibleComparisonColumn(column) { + return nil, false + } + list := fn.Args[1].GetList() + if list == nil || len(list.List) == 0 { + return nil, false + } + values := make([]any, 0, len(list.List)) + for _, item := range list.List { + value, ok := comparisonPlanLiteral(column, item, PredicateEqual) + if !ok || value == nil { + return nil, false + } + values = append(values, value) + } + return &Predicate{Op: PredicateIn, Path: column.Path, Values: values}, true + } + if len(fn.Args) != 2 { + return nil, false + } + op, ok := comparisonPredicateOp(name) + if !ok { + return nil, false + } + column, columnOK := mappedColumn(fn.Args[0], columns) + value, valueOK := comparisonPlanLiteral(column, fn.Args[1], op) + if !columnOK || !valueOK { + column, columnOK = mappedColumn(fn.Args[1], columns) + if columnOK { + op = reversePredicateOp(op) + value, valueOK = comparisonPlanLiteral(column, fn.Args[0], op) + } + } + if !columnOK || !valueOK || value == nil || !eligibleComparisonColumn(column) { + return nil, false + } + return &Predicate{Op: op, Path: column.Path, Value: value}, true +} + +func eligibleComparisonColumn(column *plan.MongoColumnMapping) bool { + if column == nil || !strings.EqualFold(column.ConversionMode, ConversionTryNull) { + return false + } + switch types.T(column.MoType.Id) { + case types.T_bool, + types.T_int8, types.T_int16, types.T_int32, types.T_int64, + types.T_uint8, types.T_uint16, types.T_uint32, types.T_uint64, + types.T_datetime, types.T_timestamp: + return true + default: + // BSON int64/double values can collapse to the same FLOAT after + // float32 narrowing or float64's >2^53 rounding. Pushing the SQL + // comparison against the pre-conversion BSON value can then remove a + // row that the residual comparison would accept. Keep floating-point + // mappings residual-only until an outward-rounded candidate predicate + // is implemented and differentially proven. + return false + } +} + +func comparisonPlanLiteral(column *plan.MongoColumnMapping, expr *plan.Expr, op PredicateOp) (any, bool) { + if column == nil || expr == nil { + return nil, false + } + switch types.T(column.MoType.Id) { + case types.T_datetime, types.T_timestamp: + microseconds, ok := temporalLiteralUnixMicroseconds(expr) + if !ok { + return nil, false + } + milliseconds, ok := temporalCandidateMilliseconds(microseconds, op) + if !ok { + return nil, false + } + return bson.DateTime(milliseconds), true + default: + return scalarPlanLiteral(expr) + } +} + +func temporalLiteralUnixMicroseconds(expr *plan.Expr) (int64, bool) { + literal := expr.GetLit() + if literal != nil && !literal.Isnull { + if value, ok := literal.GetValue().(*plan.Literal_I64Val); ok { + switch types.T(expr.Typ.Id) { + case types.T_datetime: + datetime := types.Datetime(value.I64Val) + if datetime == types.ZeroDatetime { + return 0, false + } + return datetime.ConvertToGoTime(time.UTC).UnixMicro(), true + case types.T_timestamp: + timestamp := types.Timestamp(value.I64Val) + // Timestamp and Datetime share the internal epoch encoding here, + // so compare against the corresponding zero-datetime value. + if timestamp == types.Timestamp(types.ZeroDatetime) { + return 0, false + } + return timestamp.ToDatetime(time.UTC).ConvertToGoTime(time.UTC).UnixMicro(), true + } + } + } + + // SQL datetime string literals are bound as CAST(varchar AS datetime), not + // as an encoded I64 literal. DATETIME has no session-time-zone conversion, + // so it is safe to fold this narrow shape while planning a BSON DateTime + // candidate. TIMESTAMP casts remain residual-only because their meaning + // depends on the session time zone, which this driver-neutral bridge does + // not receive. + fn := expr.GetF() + if types.T(expr.Typ.Id) != types.T_datetime || fn == nil || fn.Func == nil || + !strings.EqualFold(fn.Func.ObjName, "cast") || len(fn.Args) == 0 { + return 0, false + } + source := fn.Args[0].GetLit() + if source == nil || source.Isnull { + return 0, false + } + text, ok := source.GetValue().(*plan.Literal_Sval) + if !ok { + return 0, false + } + datetime, err := types.ParseDatetime(text.Sval, expr.Typ.Scale) + if err != nil || datetime == types.ZeroDatetime { + return 0, false + } + return datetime.ConvertToGoTime(time.UTC).UnixMicro(), true +} + +func temporalCandidateMilliseconds(microseconds int64, op PredicateOp) (int64, bool) { + const microsPerMilli = int64(1000) + switch op { + case PredicateEqual, PredicateNotEqual: + if microseconds%microsPerMilli != 0 { + // BSON DateTime has millisecond precision, so no source value can be + // equal to this literal. Avoid manufacturing a narrower predicate; + // the MO residual will decide the constant true/false outcome. + return 0, false + } + return microseconds / microsPerMilli, true + case PredicateGreaterEqual, PredicateLess: + return ceilDiv(microseconds, microsPerMilli), true + case PredicateGreater, PredicateLessEqual: + return floorDiv(microseconds, microsPerMilli), true + default: + return 0, false + } +} + +func floorDiv(value, divisor int64) int64 { + quotient, remainder := value/divisor, value%divisor + if remainder < 0 { + quotient-- + } + return quotient +} + +func ceilDiv(value, divisor int64) int64 { + quotient, remainder := value/divisor, value%divisor + if remainder > 0 { + quotient++ + } + return quotient +} + +func mappedColumn(expr *plan.Expr, columns []*plan.MongoColumnMapping) (*plan.MongoColumnMapping, bool) { + ref := expr.GetCol() + if ref == nil || ref.ColPos < 0 || int(ref.ColPos) >= len(columns) || columns[ref.ColPos] == nil { + return nil, false + } + return columns[ref.ColPos], true +} + +func comparisonPredicateOp(name string) (PredicateOp, bool) { + switch name { + case "=": + return PredicateEqual, true + case "!=", "<>": + return PredicateNotEqual, true + case "<": + return PredicateLess, true + case "<=": + return PredicateLessEqual, true + case ">": + return PredicateGreater, true + case ">=": + return PredicateGreaterEqual, true + default: + return PredicateInvalid, false + } +} + +func reversePredicateOp(op PredicateOp) PredicateOp { + switch op { + case PredicateLess: + return PredicateGreater + case PredicateLessEqual: + return PredicateGreaterEqual + case PredicateGreater: + return PredicateLess + case PredicateGreaterEqual: + return PredicateLessEqual + default: + return op + } +} + +func scalarPlanLiteral(expr *plan.Expr) (any, bool) { + literal := expr.GetLit() + if literal == nil { + return nil, false + } + if literal.Isnull { + return nil, true + } + switch value := literal.Value.(type) { + case *plan.Literal_Bval: + return value.Bval, true + case *plan.Literal_I8Val: + return int32(value.I8Val), true + case *plan.Literal_I16Val: + return int32(value.I16Val), true + case *plan.Literal_I32Val: + return value.I32Val, true + case *plan.Literal_I64Val: + return value.I64Val, true + case *plan.Literal_U8Val: + return int32(value.U8Val), true + case *plan.Literal_U16Val: + return int32(value.U16Val), true + case *plan.Literal_U32Val: + return int64(value.U32Val), true + case *plan.Literal_U64Val: + if value.U64Val > uint64(^uint64(0)>>1) { + return nil, false + } + return int64(value.U64Val), true + case *plan.Literal_Fval: + return value.Fval, true + case *plan.Literal_Dval: + return value.Dval, true + case *plan.Literal_Sval: + return value.Sval, true + default: + return nil, false + } +} + +func residualDigest(filters []*plan.Expr) string { + if len(filters) == 0 { + return "" + } + // Deliberately expose shape only. Expression values and source endpoints + // must not appear in EXPLAIN, logs, or traces. + return "mo-residual:" + strings.Repeat("f", len(filters)) +} diff --git a/pkg/sql/mongodb/pool.go b/pkg/sql/mongodb/pool.go new file mode 100644 index 0000000000000..68b09e04e6ed4 --- /dev/null +++ b/pkg/sql/mongodb/pool.go @@ -0,0 +1,471 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "context" + "crypto/sha256" + "encoding/binary" + "sync" + "time" + + "github.com/matrixorigin/matrixone/pkg/common/moerr" +) + +const clientCleanupTimeout = 10 * time.Second + +type poolKey struct { + accountID uint32 + connectionID uint64 + version uint64 + identity string +} + +type poolEntry struct { + client Client + refs int + draining bool + lastUsed uint64 +} + +type connectionKey struct { + accountID uint32 + connectionID uint64 +} + +type retirementState struct { + versionFloor uint64 + dropped bool +} + +// ClientPool keeps authentication state tenant- and generation-local. A +// rotated connection creates a new key and drains prior generations only +// after their last cursor lease is released. +type ClientPool struct { + mu sync.Mutex + factory ClientFactory + // validator closes the resolver-to-pool race. Acquire registers an + // in-flight generation first, then rechecks the catalog version; therefore + // ALTER/DROP either makes validation fail or observes this Connect and keeps + // its retirement tombstone until publication finishes. + validator ConnectionResolver + entries map[poolKey]*poolEntry + // A statement can resolve version N just before ALTER/DROP, then finish + // Connect after the DDL retirement pass. These tombstones ensure that such + // a late client starts draining instead of republishing an old idle pool. + retirements map[connectionKey]retirementState + connecting map[connectionKey]int + closed bool + clock uint64 + maxIdle int +} + +func NewClientPool(factory ClientFactory, maxCachedClients ...int) *ClientPool { + return newClientPool(factory, nil, maxCachedClients...) +} + +func NewValidatedClientPool(factory ClientFactory, validator ConnectionResolver, maxCachedClients ...int) *ClientPool { + return newClientPool(factory, validator, maxCachedClients...) +} + +func newClientPool(factory ClientFactory, validator ConnectionResolver, maxCachedClients ...int) *ClientPool { + maxIdle := DefaultRuntimeConfig().MaxCachedClients + if len(maxCachedClients) > 0 && maxCachedClients[0] > 0 { + maxIdle = maxCachedClients[0] + } + return &ClientPool{ + factory: factory, + validator: validator, + entries: make(map[poolKey]*poolEntry), + retirements: make(map[connectionKey]retirementState), + connecting: make(map[connectionKey]int), + maxIdle: maxIdle, + } +} + +type ClientLease struct { + pool *ClientPool + key poolKey + client Client + once sync.Once +} + +func (l *ClientLease) Client() Client { return l.client } + +func (l *ClientLease) Release(ctx context.Context) error { + var err error + l.once.Do(func() { err = l.pool.release(ctx, l.key) }) + return err +} + +func (p *ClientPool) Acquire(ctx context.Context, connection Connection, credentials Credentials, cfg RuntimeConfig) (*ClientLease, error) { + key := poolKey{ + accountID: connection.AccountID, + connectionID: connection.ConnectionID, + version: connection.Version, + identity: credentialIdentity(credentials), + } + p.mu.Lock() + if p.closed { + p.mu.Unlock() + return nil, moerr.NewInternalError(ctx, "MongoDB client pool is closed") + } + if entry := p.entries[key]; entry != nil { + // Exact-key reuse is safe even while the generation is draining: only + // statements whose catalog plan already carries this old version can + // ask for it. New statements resolve the newer version and cannot land + // here. + entry.refs++ + client := entry.client + p.mu.Unlock() + return &ClientLease{pool: p, key: key, client: client}, nil + } + sourceKey := connectionKey{accountID: key.accountID, connectionID: key.connectionID} + p.connecting[sourceKey]++ + retired := p.evictIdleLocked(1) + p.mu.Unlock() + _ = disconnectClients(retired) + if p.validator != nil { + validated, validateErr := p.validator.ResolveMongoDBConnection( + ctx, connection.AccountID, connection.ConnectionID, connection.Version) + if validateErr != nil { + p.mu.Lock() + p.finishConnectLocked(sourceKey) + p.pruneRetirementLocked(sourceKey) + p.mu.Unlock() + return nil, validateErr + } + // A resolver is authoritative for all non-secret connection metadata. + // The secret was resolved from the first read immediately before this + // call, so a same-version identity mismatch is catalog corruption or an + // invalid resolver and must fail closed rather than mix credentials. + if validated.AccountID != connection.AccountID || + validated.ConnectionID != connection.ConnectionID || + validated.Version != connection.Version || + validated.CredentialSecretRef != connection.CredentialSecretRef || + validated.TLSCASecretRef != connection.TLSCASecretRef { + p.mu.Lock() + p.finishConnectLocked(sourceKey) + p.pruneRetirementLocked(sourceKey) + p.mu.Unlock() + return nil, moerr.NewInvalidInput(ctx, "MongoDB connection changed during client acquisition") + } + connection = validated + } + + client, err := p.factory.Connect(ctx, connection, credentials, cfg) + if err != nil { + p.mu.Lock() + p.finishConnectLocked(sourceKey) + p.pruneRetirementLocked(sourceKey) + p.mu.Unlock() + return nil, err + } + + p.mu.Lock() + p.finishConnectLocked(sourceKey) + if p.closed { + p.mu.Unlock() + _ = disconnectClients([]Client{client}) + return nil, moerr.NewInternalError(ctx, "MongoDB client pool is closed") + } + if entry := p.entries[key]; entry != nil { + entry.refs++ + existing := entry.client + p.pruneRetirementLocked(sourceKey) + p.mu.Unlock() + _ = disconnectClients([]Client{client}) + return &ClientLease{pool: p, key: key, client: existing}, nil + } + retired = retired[:0] + incomingDraining := p.isRetiredLocked(key) + for oldKey, entry := range p.entries { + if oldKey.accountID == key.accountID && oldKey.connectionID == key.connectionID && oldKey != key { + // A statement planned before a catalog-version rotation can finish + // Connect after the newer generation has already been published. It + // may use its own client, but it must not drain that newer generation. + // At the same catalog version, a changed credential digest represents + // in-place secret-manager rotation, so the newly resolved identity wins. + if oldKey.version > key.version { + incomingDraining = true + continue + } + entry.draining = true + if entry.refs == 0 { + delete(p.entries, oldKey) + retired = append(retired, entry.client) + } + } + } + retired = append(retired, p.evictIdleLocked(1)...) + p.clock++ + p.entries[key] = &poolEntry{client: client, refs: 1, draining: incomingDraining, lastUsed: p.clock} + p.pruneRetirementLocked(sourceKey) + p.mu.Unlock() + _ = disconnectClients(retired) + return &ClientLease{pool: p, key: key, client: client}, nil +} + +func credentialIdentity(credentials Credentials) string { + hash := sha256.New() + var size [8]byte + for _, value := range [][]byte{[]byte(credentials.Username), []byte(credentials.Password), credentials.TLSCA} { + binary.BigEndian.PutUint64(size[:], uint64(len(value))) + _, _ = hash.Write(size[:]) + _, _ = hash.Write(value) + } + // The digest is an opaque in-memory map key. It is never formatted or + // serialized, and unlike the secret references it changes when a secret + // manager rotates content in place. + return string(hash.Sum(nil)) +} + +func (p *ClientPool) release(_ context.Context, key poolKey) error { + p.mu.Lock() + entry := p.entries[key] + if entry == nil { + p.mu.Unlock() + return nil + } + if entry.refs > 0 { + entry.refs-- + } + if entry.refs != 0 { + p.mu.Unlock() + return nil + } + p.clock++ + entry.lastUsed = p.clock + var clients []Client + if entry.draining { + delete(p.entries, key) + clients = append(clients, entry.client) + } + clients = append(clients, p.evictIdleLocked(0)...) + p.pruneRetirementLocked(connectionKey{accountID: key.accountID, connectionID: key.connectionID}) + p.mu.Unlock() + return disconnectClients(clients) +} + +// RetireBefore marks every older generation of one tenant connection as +// draining. Idle clients disconnect immediately; active statements retain +// their leased client until the last release. The exclusive upper bound lets +// a DDL commit retire the version it replaced without racing and accidentally +// retiring a new-version client acquired immediately after that commit. +func (p *ClientPool) RetireBefore(accountID uint32, connectionID, versionExclusive uint64) error { + p.mu.Lock() + connection := connectionKey{accountID: accountID, connectionID: connectionID} + retirement := p.retirements[connection] + if versionExclusive > retirement.versionFloor { + retirement.versionFloor = versionExclusive + } + p.retirements[connection] = retirement + clients := make([]Client, 0) + for key, entry := range p.entries { + if key.accountID != accountID || key.connectionID != connectionID || key.version >= versionExclusive { + continue + } + entry.draining = true + if entry.refs == 0 { + delete(p.entries, key) + clients = append(clients, entry.client) + } + } + p.pruneRetirementLocked(connection) + p.mu.Unlock() + return disconnectClients(clients) +} + +// RetireConnection is used after DROP, where no catalog generation can be +// acquired again. It has the same active-lease semantics as RetireBefore. +func (p *ClientPool) RetireConnection(accountID uint32, connectionID uint64) error { + p.mu.Lock() + connection := connectionKey{accountID: accountID, connectionID: connectionID} + retirement := p.retirements[connection] + retirement.dropped = true + p.retirements[connection] = retirement + clients := make([]Client, 0) + for key, entry := range p.entries { + if key.accountID != accountID || key.connectionID != connectionID { + continue + } + entry.draining = true + if entry.refs == 0 { + delete(p.entries, key) + clients = append(clients, entry.client) + } + } + p.pruneRetirementLocked(connection) + p.mu.Unlock() + return disconnectClients(clients) +} + +// RetireAccount drains every client owned by an account after DROP ACCOUNT. +// It also installs per-connection tombstones for Connect calls that started +// before the catalog transaction committed and have not published yet. +func (p *ClientPool) RetireAccount(accountID uint32) error { + p.mu.Lock() + connections := make(map[connectionKey]struct{}) + clients := make([]Client, 0) + for key, entry := range p.entries { + if key.accountID != accountID { + continue + } + connection := connectionKey{accountID: key.accountID, connectionID: key.connectionID} + connections[connection] = struct{}{} + retirement := p.retirements[connection] + retirement.dropped = true + p.retirements[connection] = retirement + entry.draining = true + if entry.refs == 0 { + delete(p.entries, key) + clients = append(clients, entry.client) + } + } + for connection := range p.connecting { + if connection.accountID != accountID { + continue + } + connections[connection] = struct{}{} + retirement := p.retirements[connection] + retirement.dropped = true + p.retirements[connection] = retirement + } + for connection := range connections { + p.pruneRetirementLocked(connection) + } + p.mu.Unlock() + return disconnectClients(clients) +} + +func (p *ClientPool) isRetiredLocked(key poolKey) bool { + retirement := p.retirements[connectionKey{accountID: key.accountID, connectionID: key.connectionID}] + return retirement.dropped || key.version < retirement.versionFloor +} + +func (p *ClientPool) finishConnectLocked(connection connectionKey) { + if p.connecting[connection] <= 1 { + delete(p.connecting, connection) + } else { + p.connecting[connection]-- + } +} + +// A retirement tombstone is needed only while a pre-DDL Connect can still +// publish, or while an affected entry remains leased/reusable. Removing it at +// that point keeps repeated create/drop cycles from growing metadata without +// bound while preserving the generation race barrier. +func (p *ClientPool) pruneRetirementLocked(connection connectionKey) { + retirement, ok := p.retirements[connection] + if !ok || p.connecting[connection] != 0 { + return + } + for key := range p.entries { + if key.accountID != connection.accountID || key.connectionID != connection.connectionID { + continue + } + if retirement.dropped || key.version < retirement.versionFloor { + return + } + } + delete(p.retirements, connection) +} + +// evictIdleLocked bounds client objects (each of which owns a driver socket +// pool) without disrupting active statements. extra is the number of entries +// the caller is about to add. The mutex must be held. +func (p *ClientPool) evictIdleLocked(extra int) []Client { + clients := make([]Client, 0) + for len(p.entries)+extra > p.maxIdle { + var oldestKey poolKey + var oldest *poolEntry + for key, entry := range p.entries { + if entry.refs != 0 || oldest != nil && entry.lastUsed >= oldest.lastUsed { + continue + } + oldestKey, oldest = key, entry + } + if oldest == nil { + break + } + delete(p.entries, oldestKey) + clients = append(clients, oldest.client) + } + return clients +} + +func (p *ClientPool) Close(_ context.Context) error { + p.mu.Lock() + if p.closed { + p.mu.Unlock() + return nil + } + p.closed = true + clients := make([]Client, 0, len(p.entries)) + for _, entry := range p.entries { + clients = append(clients, entry.client) + } + p.entries = make(map[poolKey]*poolEntry) + p.retirements = make(map[connectionKey]retirementState) + p.connecting = make(map[connectionKey]int) + p.mu.Unlock() + return disconnectClients(clients) +} + +func disconnectClients(clients []Client) error { + if len(clients) == 0 { + return nil + } + ctx, cancel := context.WithTimeout(context.Background(), clientCleanupTimeout) + defer cancel() + var first error + for _, client := range clients { + if err := client.Disconnect(ctx); err != nil && first == nil { + first = err + } + } + return first +} + +type SecretResolver interface { + ResolveMongoDBCredentials(context.Context, uint32, string, string) (Credentials, error) +} + +// ConnectionResolver reads non-secret connection metadata for the current +// tenant and requires the catalog version to match the version embedded in the +// plan. Implementations must fail closed on a disabled or stale row. +type ConnectionResolver interface { + ResolveMongoDBConnection(context.Context, uint32, uint64, uint64) (Connection, error) +} + +// MappingResolver reads the exact tenant-scoped mapping generation embedded in +// the plan. The operator validates the returned namespace and schema before it +// opens a source cursor, so catalog drift cannot silently redirect an old plan. +type MappingResolver interface { + ResolveMongoDBMapping(context.Context, uint32, uint64, uint64) (TableMapping, error) +} + +type RuntimeDependencies struct { + Config RuntimeConfig + Connections ConnectionResolver + Mappings MappingResolver + Secrets SecretResolver + Pool *ClientPool + Limiter *SourceLimiter +} + +const ( + RuntimeDependenciesKey = "mongodb.runtime-dependencies" +) diff --git a/pkg/sql/mongodb/predicate.go b/pkg/sql/mongodb/predicate.go new file mode 100644 index 0000000000000..3103f756cd841 --- /dev/null +++ b/pkg/sql/mongodb/predicate.go @@ -0,0 +1,181 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "context" + "slices" + "strings" + + "github.com/matrixorigin/matrixone/pkg/common/moerr" + "go.mongodb.org/mongo-driver/v2/bson" +) + +type PredicateOp int32 + +const ( + PredicateInvalid PredicateOp = iota + PredicateAnd + PredicateEqual + PredicateNotEqual + PredicateLess + PredicateLessEqual + PredicateGreater + PredicateGreaterEqual + PredicateIn + PredicateIsNull + PredicateIsNotNull +) + +// Predicate is a driver-neutral, serializable subset whose Mongo and MO +// semantics have been explicitly reviewed. Unsupported SQL remains residual. +type Predicate struct { + Op PredicateOp + Path string + Value any + Values []any + Children []*Predicate +} + +func (p *Predicate) Validate(ctx context.Context) error { + if p == nil { + return nil + } + if p.Op == PredicateAnd { + if len(p.Children) == 0 { + return moerr.NewInvalidInput(ctx, "MongoDB AND predicate requires children") + } + for _, child := range p.Children { + if err := child.Validate(ctx); err != nil { + return err + } + } + return nil + } + if err := ValidateBSONPath(ctx, p.Path); err != nil { + return err + } + switch p.Op { + case PredicateEqual, PredicateNotEqual, PredicateLess, PredicateLessEqual, + PredicateGreater, PredicateGreaterEqual, PredicateIsNull, PredicateIsNotNull: + return nil + case PredicateIn: + if len(p.Values) == 0 { + return moerr.NewInvalidInput(ctx, "MongoDB IN predicate cannot be empty") + } + return nil + default: + return moerr.NewInvalidInput(ctx, "unsupported MongoDB predicate") + } +} + +func ValidateBSONPath(ctx context.Context, path string) error { + path = strings.TrimSpace(path) + if path == "" || strings.HasPrefix(path, ".") || strings.HasSuffix(path, ".") || strings.Contains(path, "..") { + return moerr.NewInvalidInput(ctx, "MongoDB column path must be a non-empty dotted scalar path") + } + for _, part := range strings.Split(path, ".") { + if part == "" || strings.HasPrefix(part, "$") || strings.ContainsAny(part, "\x00*[]") { + return moerr.NewInvalidInput(ctx, "MongoDB column path contains an unsupported component") + } + } + return nil +} + +func PredicateToBSON(ctx context.Context, p *Predicate) (bson.D, error) { + if p == nil { + return bson.D{}, nil + } + if err := p.Validate(ctx); err != nil { + return nil, err + } + if p.Op == PredicateAnd { + children := make(bson.A, 0, len(p.Children)) + for _, child := range p.Children { + doc, err := PredicateToBSON(ctx, child) + if err != nil { + return nil, err + } + children = append(children, doc) + } + return bson.D{{Key: "$and", Value: children}}, nil + } + switch p.Op { + case PredicateEqual: + return bson.D{{Key: p.Path, Value: p.Value}}, nil + case PredicateNotEqual: + return bson.D{{Key: p.Path, Value: bson.D{{Key: "$ne", Value: p.Value}}}}, nil + case PredicateLess: + return comparisonDocument(p.Path, "$lt", p.Value), nil + case PredicateLessEqual: + return comparisonDocument(p.Path, "$lte", p.Value), nil + case PredicateGreater: + return comparisonDocument(p.Path, "$gt", p.Value), nil + case PredicateGreaterEqual: + return comparisonDocument(p.Path, "$gte", p.Value), nil + case PredicateIn: + return bson.D{{Key: p.Path, Value: bson.D{{Key: "$in", Value: bson.A(p.Values)}}}}, nil + case PredicateIsNull: + // MongoDB {field: null} intentionally matches both missing and BSON null, + // exactly matching the MVP converter contract. + return bson.D{{Key: p.Path, Value: nil}}, nil + case PredicateIsNotNull: + return bson.D{{Key: "$and", Value: bson.A{ + bson.D{{Key: p.Path, Value: bson.D{{Key: "$exists", Value: true}}}}, + bson.D{{Key: p.Path, Value: bson.D{{Key: "$ne", Value: nil}}}}, + }}}, nil + default: + return nil, moerr.NewInvalidInput(ctx, "unsupported MongoDB predicate") + } +} + +func comparisonDocument(path, op string, value any) bson.D { + return bson.D{{Key: path, Value: bson.D{{Key: op, Value: value}}}} +} + +func ProjectionDocument(columns []ColumnMapping) bson.D { + projection := make(bson.D, 0, len(columns)) + for _, column := range columns { + covered := false + for _, selected := range projection { + if selected.Key == column.Path || strings.HasPrefix(column.Path, selected.Key+".") { + covered = true + break + } + } + if covered { + continue + } + // MongoDB rejects an inclusion projection containing both a parent and + // one of its descendants (for example payload and payload.value). If a + // later mapping asks for the parent, it already carries every child the + // converter needs, so replace the narrower entries with that parent. + projection = slices.DeleteFunc(projection, func(selected bson.E) bool { + return strings.HasPrefix(selected.Key, column.Path+".") + }) + projection = append(projection, bson.E{Key: column.Path, Value: 1}) + } + includeID := false + for _, selected := range projection { + if selected.Key == "_id" || strings.HasPrefix(selected.Key, "_id.") { + includeID = true + break + } + } + if !includeID { + projection = append(projection, bson.E{Key: "_id", Value: 0}) + } + return projection +} diff --git a/pkg/sql/mongodb/retirement.go b/pkg/sql/mongodb/retirement.go new file mode 100644 index 0000000000000..81c08c7a06528 --- /dev/null +++ b/pkg/sql/mongodb/retirement.go @@ -0,0 +1,106 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "context" + "strings" + "sync" + "time" + + "github.com/matrixorigin/matrixone/pkg/clusterservice" + "github.com/matrixorigin/matrixone/pkg/pb/metadata" + "github.com/matrixorigin/matrixone/pkg/pb/query" +) + +// ClientRetirement describes a committed catalog change. ConnectionID zero +// means the entire account. For one connection, VersionExclusive zero means +// DROP and a non-zero value means ALTER (retire older generations only). +type ClientRetirement struct { + AccountID uint32 + ConnectionID uint64 + VersionExclusive uint64 +} + +func (r ClientRetirement) Apply(pool *ClientPool) error { + if pool == nil { + return nil + } + if r.ConnectionID == 0 { + return pool.RetireAccount(r.AccountID) + } + if r.VersionExclusive == 0 { + return pool.RetireConnection(r.AccountID, r.ConnectionID) + } + return pool.RetireBefore(r.AccountID, r.ConnectionID, r.VersionExclusive) +} + +type QueryMessageClient interface { + ServiceID() string + NewRequest(query.CmdMethod) *query.Request + SendMessage(context.Context, string, *query.Request) (*query.Response, error) + Release(*query.Response) +} + +// ClusterRemoteClientRetirer broadcasts a committed retirement to every +// other CN. Delivery is best effort: catalog validation remains authoritative +// if one old CN is unavailable, and a remote failure must not turn a committed +// DDL into a client-visible failure. +type ClusterRemoteClientRetirer struct { + Cluster clusterservice.MOCluster + QueryClient QueryMessageClient + Timeout time.Duration +} + +func (r ClusterRemoteClientRetirer) Retire(ctx context.Context, retirement ClientRetirement) { + if r.Cluster == nil || r.QueryClient == nil { + return + } + if ctx == nil { + ctx = context.Background() + } + timeout := r.Timeout + if timeout <= 0 { + timeout = 3 * time.Second + } + self := r.QueryClient.ServiceID() + targets := make([]string, 0) + r.Cluster.GetCNService(clusterservice.NewSelector(), func(cn metadata.CNService) bool { + if strings.TrimSpace(cn.QueryAddress) != "" && (self == "" || cn.ServiceID != self) { + targets = append(targets, cn.QueryAddress) + } + return true + }) + + sendCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), timeout) + defer cancel() + var wg sync.WaitGroup + for _, address := range targets { + wg.Add(1) + go func(address string) { + defer wg.Done() + request := r.QueryClient.NewRequest(query.CmdMethod_MongoDBClientRetire) + request.MongoDBClientRetireRequest = query.MongoDBClientRetireRequest{ + AccountID: retirement.AccountID, ConnectionID: retirement.ConnectionID, + VersionExclusive: retirement.VersionExclusive, + } + resp, err := r.QueryClient.SendMessage(sendCtx, address, request) + if err == nil && resp != nil { + r.QueryClient.Release(resp) + } + }(address) + } + wg.Wait() +} diff --git a/pkg/sql/mongodb/retirement_test.go b/pkg/sql/mongodb/retirement_test.go new file mode 100644 index 0000000000000..9ad843bf37ff4 --- /dev/null +++ b/pkg/sql/mongodb/retirement_test.go @@ -0,0 +1,150 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "context" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/matrixorigin/matrixone/pkg/clusterservice" + "github.com/matrixorigin/matrixone/pkg/pb/metadata" + "github.com/matrixorigin/matrixone/pkg/pb/query" +) + +func TestClusterRemoteClientRetirerCoversEveryCNLifecycleScope(t *testing.T) { + for _, tc := range []struct { + name string + retirement ClientRetirement + connection Connection + }{ + { + name: "alter generation", + retirement: ClientRetirement{ + AccountID: 7, ConnectionID: 9, VersionExclusive: 4, + }, + connection: Connection{AccountID: 7, ConnectionID: 9, Version: 3}, + }, + { + name: "drop connection", + retirement: ClientRetirement{AccountID: 7, ConnectionID: 9}, + connection: Connection{AccountID: 7, ConnectionID: 9, Version: 3}, + }, + { + name: "drop account", + retirement: ClientRetirement{AccountID: 7}, + connection: Connection{AccountID: 7, ConnectionID: 9, Version: 3}, + }, + } { + t.Run(tc.name, func(t *testing.T) { + cluster := clusterservice.NewMOCluster( + "", nil, time.Second, clusterservice.WithDisableRefresh(), + clusterservice.WithServices([]metadata.CNService{ + {ServiceID: "self", QueryAddress: "self-addr"}, + {ServiceID: "remote-1", QueryAddress: "remote-1-addr"}, + {ServiceID: "remote-2", QueryAddress: "remote-2-addr"}, + {ServiceID: "remote-empty"}, + }, nil), + ) + defer cluster.Close() + + pools := map[string]*ClientPool{ + "self-addr": NewClientPool(&fakeFactory{}), + "remote-1-addr": NewClientPool(&fakeFactory{}), + "remote-2-addr": NewClientPool(&fakeFactory{}), + } + for _, pool := range pools { + t.Cleanup(func() { require.NoError(t, pool.Close(context.Background())) }) + } + targets := make(map[string]*fakeClient, len(pools)) + unaffected := make(map[string]*fakeClient, len(pools)) + for address, pool := range pools { + targets[address] = seedIdleClient(t, pool, tc.connection) + unaffected[address] = seedIdleClient(t, pool, Connection{AccountID: 8, ConnectionID: 9, Version: 3}) + } + + require.NoError(t, tc.retirement.Apply(pools["self-addr"])) + client := &retirementQueryClient{serviceID: "self", pools: pools} + ClusterRemoteClientRetirer{ + Cluster: cluster, QueryClient: client, Timeout: time.Second, + }.Retire(t.Context(), tc.retirement) + + for address := range pools { + require.Equal(t, 1, targets[address].count(), address) + require.Zero(t, unaffected[address].count(), address) + } + require.ElementsMatch(t, []string{"remote-1-addr", "remote-2-addr"}, client.addresses()) + require.Equal(t, 2, client.releasedCount()) + }) + } +} + +func seedIdleClient(t *testing.T, pool *ClientPool, connection Connection) *fakeClient { + t.Helper() + lease, err := pool.Acquire(t.Context(), connection, Credentials{}, RuntimeConfig{}) + require.NoError(t, err) + client := lease.Client().(*fakeClient) + require.NoError(t, lease.Release(t.Context())) + return client +} + +type retirementQueryClient struct { + serviceID string + pools map[string]*ClientPool + mu sync.Mutex + sent []string + released int +} + +func (c *retirementQueryClient) ServiceID() string { return c.serviceID } + +func (*retirementQueryClient) NewRequest(method query.CmdMethod) *query.Request { + return &query.Request{CmdMethod: method} +} + +func (c *retirementQueryClient) SendMessage( + ctx context.Context, address string, req *query.Request, +) (*query.Response, error) { + c.mu.Lock() + c.sent = append(c.sent, address) + c.mu.Unlock() + payload := req.GetMongoDBClientRetireRequest() + err := (ClientRetirement{ + AccountID: payload.AccountID, ConnectionID: payload.ConnectionID, + VersionExclusive: payload.VersionExclusive, + }).Apply(c.pools[address]) + return &query.Response{CmdMethod: req.CmdMethod, MongoDBClientRetireResponse: query.MongoDBClientRetireResponse{Success: err == nil}}, err +} + +func (c *retirementQueryClient) Release(*query.Response) { + c.mu.Lock() + c.released++ + c.mu.Unlock() +} + +func (c *retirementQueryClient) addresses() []string { + c.mu.Lock() + defer c.mu.Unlock() + return append([]string(nil), c.sent...) +} + +func (c *retirementQueryClient) releasedCount() int { + c.mu.Lock() + defer c.mu.Unlock() + return c.released +} diff --git a/pkg/sql/mongodb/security.go b/pkg/sql/mongodb/security.go new file mode 100644 index 0000000000000..833e695987157 --- /dev/null +++ b/pkg/sql/mongodb/security.go @@ -0,0 +1,300 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongodb + +import ( + "context" + "net" + "regexp" + "strings" + + "github.com/matrixorigin/matrixone/pkg/common/moerr" +) + +// HostResolver is injectable so DNS rebinding and SRV policy can be tested +// without depending on the machine resolver. +type HostResolver interface { + LookupIPAddr(context.Context, string) ([]net.IPAddr, error) + LookupSRV(context.Context, string, string, string) (string, []*net.SRV, error) +} + +type contextDialer interface { + DialContext(context.Context, string, string) (net.Conn, error) +} + +// policyDialer applies endpoint policy to every socket opened by the driver, +// including ReplicaSet members learned after seed discovery. It dials a +// validated resolved IP rather than asking the system resolver to resolve the +// hostname a second time, closing the DNS-rebinding gap. The MongoDB driver +// still retains the original hostname for TLS server-name verification. +type policyDialer struct { + cfg RuntimeConfig + resolver HostResolver + base contextDialer +} + +func newPolicyDialer(cfg RuntimeConfig, resolver HostResolver) *policyDialer { + if resolver == nil { + resolver = net.DefaultResolver + } + return &policyDialer{ + cfg: cfg, + resolver: resolver, + base: &net.Dialer{Timeout: cfg.ConnectTimeout}, + } +} + +func (d *policyDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) { + host, port, err := net.SplitHostPort(address) + if err != nil || port == "" { + return nil, moerr.NewInvalidInput(ctx, "MongoDB discovered an invalid endpoint") + } + if err = validateHost(ctx, host, d.cfg); err != nil { + return nil, err + } + if ip := net.ParseIP(host); ip != nil { + return d.base.DialContext(ctx, network, net.JoinHostPort(ip.String(), port)) + } + addresses, err := d.resolver.LookupIPAddr(ctx, host) + if err != nil || len(addresses) == 0 { + return nil, moerr.NewInvalidInput(ctx, "MongoDB DNS lookup failed or returned no addresses") + } + for _, resolved := range addresses { + if err = validateResolvedIP(ctx, resolved.IP, d.cfg, false); err != nil { + return nil, err + } + } + var lastErr error + for _, resolved := range addresses { + connection, dialErr := d.base.DialContext(ctx, network, net.JoinHostPort(resolved.IP.String(), port)) + if dialErr == nil { + return connection, nil + } + lastErr = dialErr + } + return nil, lastErr +} + +func ValidateSecretRef(ctx context.Context, value string, required bool) error { + value = strings.TrimSpace(value) + if value == "" && !required { + return nil + } + if !strings.HasPrefix(strings.ToLower(value), "secret://") || len(value) <= len("secret://") { + return moerr.NewInvalidInput(ctx, "MongoDB credentials and TLS material must use a secret:// reference") + } + return nil +} + +func ValidateConnection(ctx context.Context, c Connection, cfg RuntimeConfig) error { + if strings.TrimSpace(c.Name) == "" { + return moerr.NewInvalidInput(ctx, "MongoDB connection name cannot be empty") + } + if err := ValidateSecretRef(ctx, c.CredentialSecretRef, true); err != nil { + return err + } + if err := ValidateSecretRef(ctx, c.TLSCASecretRef, false); err != nil { + return err + } + if _, err := decodeConnectorOptions(ctx, c.OptionsJSON); err != nil { + return err + } + if !strings.EqualFold(c.AuthMechanism, "SCRAM-SHA-256") { + return moerr.NewInvalidInput(ctx, "MongoDB MVP supports only SCRAM-SHA-256 authentication") + } + switch strings.ToLower(strings.TrimSpace(c.TLSMode)) { + case "required", "disabled": + default: + return moerr.NewInvalidInput(ctx, "MongoDB tls_mode must be required or disabled") + } + if _, err := parseReadPreference(c.ReadPreference, c.MaxStalenessSeconds); err != nil { + return moerr.NewInvalidInput(ctx, "unsupported MongoDB read preference or max staleness") + } + switch strings.ToLower(strings.TrimSpace(c.ReadConcern)) { + case "majority", "local": + default: + return moerr.NewInvalidInput(ctx, "MongoDB read_concern must be majority or local") + } + hasHosts := strings.TrimSpace(c.Hosts) != "" + hasSRV := strings.TrimSpace(c.SRVHost) != "" + if hasHosts == hasSRV { + return moerr.NewInvalidInput(ctx, "MongoDB connection requires exactly one of hosts or srv_host") + } + if hasSRV { + if strings.ContainsAny(c.SRVHost, "/@:") { + return moerr.NewInvalidInput(ctx, "MongoDB srv_host must be a DNS name without URI userinfo, path, or port") + } + return validateHost(ctx, c.SRVHost, cfg) + } + for _, seed := range strings.Split(c.Hosts, ",") { + seed = strings.TrimSpace(seed) + if seed == "" || strings.Contains(seed, "://") || strings.Contains(seed, "@") { + return moerr.NewInvalidInput(ctx, "MongoDB hosts must contain host:port seeds without URI userinfo") + } + host, port, err := net.SplitHostPort(seed) + if err != nil || port == "" { + return moerr.NewInvalidInput(ctx, "MongoDB hosts must contain valid host:port seeds") + } + if err := validateHost(ctx, host, cfg); err != nil { + return err + } + } + return nil +} + +// ValidateResolvedEndpoints rechecks every address immediately before client +// creation. Hostname policy alone is insufficient because DNS can resolve an +// allowed name to loopback, link-local, metadata, or an out-of-policy CIDR. +func ValidateResolvedEndpoints(ctx context.Context, c Connection, cfg RuntimeConfig, resolver HostResolver) error { + if resolver == nil { + resolver = net.DefaultResolver + } + hosts := make([]string, 0, 4) + if strings.TrimSpace(c.SRVHost) != "" { + _, records, err := resolver.LookupSRV(ctx, "mongodb", "tcp", strings.TrimSuffix(c.SRVHost, ".")) + if err != nil || len(records) == 0 { + return moerr.NewInvalidInput(ctx, "MongoDB SRV lookup failed or returned no endpoints") + } + for _, record := range records { + hosts = append(hosts, strings.TrimSuffix(record.Target, ".")) + } + } else { + for _, seed := range strings.Split(c.Hosts, ",") { + host, _, err := net.SplitHostPort(strings.TrimSpace(seed)) + if err != nil { + return moerr.NewInvalidInput(ctx, "MongoDB seed endpoint is invalid") + } + hosts = append(hosts, host) + } + } + for _, host := range hosts { + if ip := net.ParseIP(host); ip != nil { + if err := validateHost(ctx, ip.String(), cfg); err != nil { + return err + } + continue + } + if err := validateHost(ctx, host, cfg); err != nil { + return err + } + addresses, err := resolver.LookupIPAddr(ctx, host) + if err != nil || len(addresses) == 0 { + return moerr.NewInvalidInput(ctx, "MongoDB DNS lookup failed or returned no addresses") + } + for _, address := range addresses { + if err := validateResolvedIP(ctx, address.IP, cfg, false); err != nil { + return err + } + } + } + return nil +} + +func validateHost(ctx context.Context, host string, cfg RuntimeConfig) error { + host = strings.TrimSuffix(strings.ToLower(strings.TrimSpace(host)), ".") + if host == "" { + return moerr.NewInvalidInput(ctx, "MongoDB host cannot be empty") + } + if ip := net.ParseIP(host); ip != nil { + return validateResolvedIP(ctx, ip, cfg, true) + } + if len(cfg.AllowedHostSuffixes) == 0 { + return moerr.NewInvalidInput(ctx, "MongoDB hostname endpoint requires an explicit suffix allowlist") + } + for _, suffix := range cfg.AllowedHostSuffixes { + suffix = strings.TrimPrefix(strings.ToLower(strings.TrimSpace(suffix)), ".") + if host == suffix || strings.HasSuffix(host, "."+suffix) { + return nil + } + } + return moerr.NewInvalidInput(ctx, "MongoDB endpoint is outside the configured hostname allowlist") +} + +func validateResolvedIP(ctx context.Context, ip net.IP, cfg RuntimeConfig, requireCIDR bool) error { + if ip == nil || ip.IsUnspecified() { + return moerr.NewInvalidInput(ctx, "MongoDB unspecified endpoint is not allowed") + } + if isMetadataEndpoint(ip) { + return moerr.NewInvalidInput(ctx, "MongoDB cloud metadata endpoint is not allowed") + } + if ip.IsLoopback() { + if !cfg.AllowLoopback { + return moerr.NewInvalidInput(ctx, "MongoDB loopback endpoint is not allowed") + } + return nil + } + if ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() || ip.IsMulticast() { + return moerr.NewInvalidInput(ctx, "MongoDB link-local or multicast endpoint is not allowed") + } + if len(cfg.AllowedCIDRs) == 0 { + if requireCIDR { + return moerr.NewInvalidInput(ctx, "MongoDB IP endpoint requires an explicit CIDR allowlist") + } + // The originating DNS name was already checked against the hostname + // allowlist. Still reject special IP classes above on every resolution. + return nil + } + for _, raw := range cfg.AllowedCIDRs { + _, network, err := net.ParseCIDR(strings.TrimSpace(raw)) + if err == nil && network.Contains(ip) { + return nil + } + } + return moerr.NewInvalidInput(ctx, "MongoDB endpoint is outside the configured CIDR allowlist") +} + +func isMetadataEndpoint(ip net.IP) bool { + // Link-local metadata addresses are rejected by the general link-local + // policy below. These well-known non-link-local endpoints need an explicit + // deny even when private MongoDB addresses are otherwise allowed. + for _, raw := range []string{ + "100.100.100.200", // Alibaba Cloud ECS metadata + "fd00:ec2::254", // AWS IMDS IPv6 + "fd20:ce::254", // Google Compute metadata IPv6 + } { + if ip.Equal(net.ParseIP(raw)) { + return true + } + } + return false +} + +var mongoDBUserInfoPattern = regexp.MustCompile(`(?i)(mongodb(?:\+srv)?://)[^/@\s]+@`) + +func Redact(value string) string { + if strings.TrimSpace(value) == "" { + return value + } + // Error and trace messages often contain a URI as only one token. Redact + // every embedded URI, not just inputs that parse as one complete URL. + value = mongoDBUserInfoPattern.ReplaceAllString(value, "$1") + for _, marker := range []string{"password=", "token=", "secret="} { + for searchFrom := 0; searchFrom < len(value); { + lower := strings.ToLower(value) + relative := strings.Index(lower[searchFrom:], marker) + if relative < 0 { + break + } + idx := searchFrom + relative + end := strings.IndexAny(value[idx+len(marker):], "&; ,") + if end < 0 { + end = len(value) - idx - len(marker) + } + value = value[:idx+len(marker)] + "******" + value[idx+len(marker)+end:] + searchFrom = idx + len(marker) + len("******") + } + } + return value +} diff --git a/pkg/sql/parsers/dialect/mysql/keywords.go b/pkg/sql/parsers/dialect/mysql/keywords.go index 4d9351f6ca33f..9ff16eb104a79 100644 --- a/pkg/sql/parsers/dialect/mysql/keywords.go +++ b/pkg/sql/parsers/dialect/mysql/keywords.go @@ -107,6 +107,7 @@ func init() { "consistent": CONSISTENT, "continue": UNUSED, "connection": CONNECTION, + "connections": CONNECTIONS, "connect": CONNECT, "convert": CONVERT, "config": CONFIG, @@ -251,6 +252,9 @@ func init() { "id": ID, "identified": IDENTIFIED, "iceberg": ICEBERG, + "mongodb": MONGODB, + "mongodb_convert": MONGODB_CONVERT, + "mongodb_path": MONGODB_PATH, "if": IF, "ignore": IGNORE, "in": IN, @@ -659,6 +663,7 @@ func init() { "preceding": PRECEDING, "following": FOLLOWING, "fill": FILL, + "gapfill": GAPFILL, "groups": GROUPS, "table_number": TABLE_NUMBER, "table_values": TABLE_VALUES, diff --git a/pkg/sql/parsers/dialect/mysql/mongodb_sql_test.go b/pkg/sql/parsers/dialect/mysql/mongodb_sql_test.go new file mode 100644 index 0000000000000..563503de8e751 --- /dev/null +++ b/pkg/sql/parsers/dialect/mysql/mongodb_sql_test.go @@ -0,0 +1,58 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package mysql + +import ( + "context" + "strings" + "testing" + + "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect" + "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" + "github.com/stretchr/testify/require" +) + +func TestMongoDBSQLSurfaceAndRedaction(t *testing.T) { + ctx := context.Background() + sqls := []string{ + "create mongodb connection if not exists sensor with ('hosts'='mongo:27017','credential_secret_ref'='secret://env/MONGO','tls_mode'='disabled')", + "alter mongodb connection sensor set ('credential_secret_ref'='secret://env/MONGO_NEXT')", + "alter mongodb connection sensor disable", + "alter mongodb connection sensor enable", + "drop mongodb connection if exists sensor", + "show mongodb connections", + "create external table events(ts datetime mongodb_path 'ts', measurement double mongodb_path 'payload.measurement' mongodb_convert 'try_null') engine=mongodb with ('connection'='sensor', 'database'='telemetry', 'collection'='events', 'max_parallelism'='1')", + } + for _, sql := range sqls { + stmt, err := ParseOne(ctx, sql, 1) + require.NoError(t, err, sql) + formatted := tree.String(stmt, dialect.MYSQL) + _, err = ParseOne(ctx, formatted, 1) + require.NoError(t, err, formatted) + require.NotContains(t, strings.ToLower(formatted), "mongo_next") + require.NotContains(t, strings.ToLower(formatted), "mongo:27017") + } +} + +func TestGapFillParserFormatRoundTrip(t *testing.T) { + ctx := context.Background() + sql := "select _wstart, id, sum(v) from t group by id interval(ts, 1, minute) gapfill(partition) fill(null)" + stmt, err := ParseOne(ctx, sql, 1) + require.NoError(t, err) + formatted := tree.String(stmt, dialect.MYSQL) + require.Contains(t, formatted, "gapfill(partition)") + require.Contains(t, formatted, "fill(null)") + _, err = ParseOne(ctx, formatted, 1) + require.NoError(t, err) +} diff --git a/pkg/sql/parsers/dialect/mysql/mysql_sql.go b/pkg/sql/parsers/dialect/mysql/mysql_sql.go index f2d13f3cbf48b..7b454e2e84440 100644 --- a/pkg/sql/parsers/dialect/mysql/mysql_sql.go +++ b/pkg/sql/parsers/dialect/mysql/mysql_sql.go @@ -760,40 +760,45 @@ const CALL = 58037 const PREV = 58038 const SLIDING = 58039 const FILL = 58040 -const SPBEGIN = 58041 -const BACKEND = 58042 -const SERVERS = 58043 -const HANDLER = 58044 -const PERCENT = 58045 -const SAMPLE = 58046 -const MO_TS = 58047 -const PITR = 58048 -const RECOVERY_WINDOW = 58049 -const INTERNAL = 58050 -const CDC_TASK_NAME = 58051 -const CDC = 58052 -const ICEBERG = 58053 -const CATALOG = 58054 -const CATALOGS = 58055 -const NAMESPACE = 58056 -const NAMESPACES = 58057 -const REF = 58058 -const FOR_ICEBERG = 58059 -const GROUPING = 58060 -const SETS = 58061 -const CUBE = 58062 -const ROLLUP = 58063 -const LOGSERVICE = 58064 -const REPLICAS = 58065 -const STORES = 58066 -const SETTINGS = 58067 -const KILL = 58068 -const BACKUP = 58069 -const FILESYSTEM = 58070 -const PARALLELISM = 58071 -const RESTORE = 58072 -const QUERY_RESULT = 58073 -const ARRAY = 58074 +const GAPFILL = 58041 +const SPBEGIN = 58042 +const BACKEND = 58043 +const SERVERS = 58044 +const HANDLER = 58045 +const PERCENT = 58046 +const SAMPLE = 58047 +const MO_TS = 58048 +const PITR = 58049 +const RECOVERY_WINDOW = 58050 +const INTERNAL = 58051 +const CDC_TASK_NAME = 58052 +const CDC = 58053 +const ICEBERG = 58054 +const CATALOG = 58055 +const CATALOGS = 58056 +const NAMESPACE = 58057 +const NAMESPACES = 58058 +const REF = 58059 +const FOR_ICEBERG = 58060 +const MONGODB = 58061 +const MONGODB_PATH = 58062 +const MONGODB_CONVERT = 58063 +const CONNECTIONS = 58064 +const GROUPING = 58065 +const SETS = 58066 +const CUBE = 58067 +const ROLLUP = 58068 +const LOGSERVICE = 58069 +const REPLICAS = 58070 +const STORES = 58071 +const SETTINGS = 58072 +const KILL = 58073 +const BACKUP = 58074 +const FILESYSTEM = 58075 +const PARALLELISM = 58076 +const RESTORE = 58077 +const QUERY_RESULT = 58078 +const ARRAY = 58079 var yyToknames = [...]string{ "$end", @@ -1511,6 +1516,7 @@ var yyToknames = [...]string{ "PREV", "SLIDING", "FILL", + "GAPFILL", "SPBEGIN", "BACKEND", "SERVERS", @@ -1530,6 +1536,10 @@ var yyToknames = [...]string{ "NAMESPACES", "REF", "FOR_ICEBERG", + "MONGODB", + "MONGODB_PATH", + "MONGODB_CONVERT", + "CONNECTIONS", "GROUPING", "SETS", "CUBE", @@ -1558,7841 +1568,8100 @@ const yyEofCode = 1 const yyErrCode = 2 const yyInitialStackSize = 16 -//line mysql_sql.y:15067 +//line mysql_sql.y:15225 //line yacctab:1 var yyExca = [...]int{ -1, 1, 1, -1, -2, 0, - -1, 145, - 46, 719, - 273, 719, - 300, 726, - 301, 726, - 535, 719, - -2, 757, - -1, 163, - 11, 934, - 24, 934, - -2, 927, - -1, 190, - 271, 1458, - 273, 1298, - -2, 1371, - -1, 261, - 753, 2350, - -2, 594, - -1, 626, - 753, 2477, + -1, 147, + 46, 726, + 273, 726, + 300, 733, + 301, 733, + 535, 726, + -2, 764, + -1, 165, + 11, 943, + 24, 943, + -2, 936, + -1, 193, + 271, 1472, + 273, 1311, + -2, 1384, + -1, 265, + 758, 2380, + -2, 599, + -1, 634, + 758, 2507, -2, 440, - -1, 684, - 753, 2536, + -1, 692, + 758, 2566, -2, 438, - -1, 685, - 753, 2537, + -1, 693, + 758, 2567, -2, 439, - -1, 686, - 753, 2538, + -1, 694, + 758, 2568, -2, 441, - -1, 832, - 530, 757, - 531, 757, - -2, 720, - -1, 905, + -1, 842, + 530, 764, + 531, 764, + -2, 727, + -1, 915, 352, 204, 507, 204, 508, 204, - -2, 2215, - -1, 973, - 89, 1970, - -2, 2413, - -1, 974, - 89, 1988, - -2, 2382, - -1, 978, - 89, 1989, + -2, 2241, + -1, 983, + 89, 1996, + -2, 2443, + -1, 984, + 89, 2014, -2, 2412, - -1, 1024, - 89, 1891, - -2, 2628, - -1, 1025, - 89, 1892, - -2, 2627, - -1, 1026, - 89, 1893, - -2, 2617, - -1, 1027, - 89, 2588, - -2, 2608, - -1, 1028, - 89, 2589, - -2, 2609, - -1, 1029, - 89, 2590, - -2, 2619, - -1, 1030, - 89, 2591, - -2, 2597, - -1, 1031, - 89, 2592, - -2, 2606, - -1, 1032, - 89, 2593, - -2, 2621, - -1, 1033, - 89, 2594, - -2, 2626, + -1, 988, + 89, 2015, + -2, 2442, -1, 1034, - 89, 2595, - -2, 2631, + 89, 1917, + -2, 2659, -1, 1035, - 89, 2596, - -2, 2632, + 89, 1918, + -2, 2658, -1, 1036, - 89, 1966, - -2, 2451, + 89, 1919, + -2, 2648, -1, 1037, - 89, 1967, - -2, 2195, + 89, 2619, + -2, 2639, -1, 1038, - 89, 1968, - -2, 2460, + 89, 2620, + -2, 2640, -1, 1039, - 89, 1969, - -2, 2208, + 89, 2621, + -2, 2650, + -1, 1040, + 89, 2622, + -2, 2628, -1, 1041, - 89, 1972, - -2, 2217, + 89, 2623, + -2, 2637, + -1, 1042, + 89, 2624, + -2, 2652, -1, 1043, - 89, 1974, - -2, 2485, + 89, 2625, + -2, 2657, + -1, 1044, + 89, 2626, + -2, 2662, -1, 1045, - 89, 1976, - -2, 2239, + 89, 2627, + -2, 2663, + -1, 1046, + 89, 1992, + -2, 2481, -1, 1047, - 89, 1978, - -2, 2497, + 89, 1993, + -2, 2221, -1, 1048, - 89, 1979, - -2, 2496, + 89, 1994, + -2, 2490, -1, 1049, - 89, 1980, - -2, 2306, - -1, 1050, - 89, 1981, - -2, 2408, + 89, 1995, + -2, 2234, + -1, 1051, + 89, 1998, + -2, 2243, -1, 1053, - 89, 1984, - -2, 2508, + 89, 2000, + -2, 2515, -1, 1055, - 89, 1986, - -2, 2511, - -1, 1056, - 89, 1987, - -2, 2513, + 89, 2002, + -2, 2265, -1, 1057, - 89, 1990, - -2, 2520, + 89, 2004, + -2, 2527, -1, 1058, - 89, 1991, - -2, 2391, + 89, 2005, + -2, 2526, -1, 1059, - 89, 1992, - -2, 2438, + 89, 2006, + -2, 2336, -1, 1060, - 89, 1993, - -2, 2402, - -1, 1061, - 89, 1994, - -2, 2428, - -1, 1072, - 89, 1867, - -2, 2622, - -1, 1073, - 89, 1868, - -2, 2623, - -1, 1074, - 89, 1869, - -2, 2624, - -1, 1194, - 131, 2195, - 142, 2195, - 174, 2195, - -2, 2161, - -1, 1329, - 24, 963, - -2, 906, - -1, 1527, - 11, 934, - 24, 934, - -2, 1726, - -1, 1625, - 24, 963, - -2, 906, - -1, 1913, - 46, 719, - 273, 719, - 300, 726, - 301, 726, - 535, 719, - -2, 757, - -1, 2016, - 89, 2040, - -2, 2410, - -1, 2017, - 89, 2041, - -2, 2411, - -1, 2300, - 11, 934, - 24, 934, - -2, 1079, - -1, 2737, - 90, 1154, - -2, 1160, - -1, 2754, - 114, 1363, - 161, 1363, - 209, 1363, - 212, 1363, - 313, 1363, - -2, 1356, - -1, 2965, - 90, 2147, - 175, 2147, - -2, 2393, - -1, 2966, - 90, 2147, - 175, 2147, - -2, 2392, - -1, 2967, - 90, 2105, - 175, 2105, - -2, 2379, - -1, 2968, - 90, 2106, - 175, 2106, - -2, 2384, - -1, 2969, - 90, 2107, - 175, 2107, - -2, 2294, - -1, 2970, - 90, 2108, - 175, 2108, - -2, 2287, - -1, 2971, - 90, 2109, - 175, 2109, - -2, 2180, - -1, 2972, - 90, 2110, - 175, 2110, - -2, 2381, - -1, 2973, - 90, 2111, - 175, 2111, - -2, 2292, - -1, 2974, - 90, 2112, - 175, 2112, - -2, 2286, - -1, 2975, - 90, 2113, - 175, 2113, - -2, 2271, - -1, 2976, - 90, 2147, - 175, 2147, - -2, 2272, - -1, 2977, - 90, 2147, - 175, 2147, - -2, 2273, - -1, 2979, - 90, 2118, - 175, 2118, - -2, 2428, - -1, 2980, - 90, 2095, - 175, 2095, - -2, 2413, - -1, 2981, - 90, 2145, - 175, 2145, - -2, 2382, - -1, 2982, - 90, 2145, - 175, 2145, - -2, 2412, - -1, 2983, - 90, 2145, - 175, 2145, - -2, 2218, - -1, 2984, - 90, 2143, - 175, 2143, - -2, 2402, - -1, 2985, - 89, 2075, - 90, 2075, - 164, 2075, - 165, 2075, - 167, 2075, - 175, 2075, - -2, 2179, - -1, 2986, - 89, 2076, - 90, 2076, - 164, 2076, - 165, 2076, - 167, 2076, - 175, 2076, - -2, 2181, - -1, 2987, - 89, 2077, - 90, 2077, - 164, 2077, - 165, 2077, - 167, 2077, - 175, 2077, - -2, 2456, - -1, 2988, - 89, 2079, - 90, 2079, - 164, 2079, - 165, 2079, - 167, 2079, - 175, 2079, - -2, 2383, - -1, 2989, - 89, 2081, - 90, 2081, - 164, 2081, - 165, 2081, - 167, 2081, - 175, 2081, - -2, 2360, - -1, 2990, - 89, 2083, - 90, 2083, - 164, 2083, - 165, 2083, - 167, 2083, - 175, 2083, - -2, 2293, - -1, 2991, - 89, 2085, - 90, 2085, - 164, 2085, - 165, 2085, - 167, 2085, - 175, 2085, - -2, 2264, - -1, 2992, - 89, 2086, - 90, 2086, - 164, 2086, - 165, 2086, - 167, 2086, - 175, 2086, - -2, 2265, - -1, 2993, - 89, 2088, - 90, 2088, - 164, 2088, - 165, 2088, - 167, 2088, - 175, 2088, - -2, 2178, + 89, 2007, + -2, 2438, + -1, 1063, + 89, 2010, + -2, 2538, + -1, 1065, + 89, 2012, + -2, 2541, + -1, 1066, + 89, 2013, + -2, 2543, + -1, 1067, + 89, 2016, + -2, 2550, + -1, 1068, + 89, 2017, + -2, 2421, + -1, 1069, + 89, 2018, + -2, 2468, + -1, 1070, + 89, 2019, + -2, 2432, + -1, 1071, + 89, 2020, + -2, 2458, + -1, 1082, + 89, 1893, + -2, 2653, + -1, 1083, + 89, 1894, + -2, 2654, + -1, 1084, + 89, 1895, + -2, 2655, + -1, 1206, + 131, 2221, + 142, 2221, + 174, 2221, + -2, 2187, + -1, 1342, + 24, 974, + -2, 915, + -1, 1541, + 11, 943, + 24, 943, + -2, 1752, + -1, 1639, + 24, 974, + -2, 915, + -1, 1930, + 46, 726, + 273, 726, + 300, 733, + 301, 733, + 535, 726, + -2, 764, + -1, 2034, + 89, 2066, + -2, 2440, + -1, 2035, + 89, 2067, + -2, 2441, + -1, 2319, + 11, 943, + 24, 943, + -2, 1090, + -1, 2762, + 90, 1167, + -2, 1173, + -1, 2779, + 114, 1376, + 161, 1376, + 209, 1376, + 212, 1376, + 313, 1376, + -2, 1369, -1, 2994, - 90, 2150, - 164, 2150, - 165, 2150, - 167, 2150, - 175, 2150, - -2, 2223, + 90, 2173, + 175, 2173, + -2, 2423, -1, 2995, - 90, 2150, - 164, 2150, - 165, 2150, - 167, 2150, - 175, 2150, - -2, 2240, + 90, 2173, + 175, 2173, + -2, 2422, -1, 2996, - 90, 2153, - 164, 2153, - 165, 2153, - 167, 2153, - 175, 2153, - -2, 2219, - -1, 2997, - 90, 2153, - 164, 2153, - 165, 2153, - 167, 2153, - 175, 2153, - -2, 2311, - -1, 2998, - 90, 2150, - 164, 2150, - 165, 2150, - 167, 2150, - 175, 2150, - -2, 2341, - -1, 2999, - 90, 2123, - 175, 2123, - -2, 2244, - -1, 3000, - 90, 2124, - 175, 2124, - -2, 2326, - -1, 3001, - 90, 2125, - 175, 2125, - -2, 2284, - -1, 3002, - 90, 2126, - 175, 2126, - -2, 2327, - -1, 3003, - 90, 2127, - 175, 2127, - -2, 2245, - -1, 3004, - 90, 2128, - 175, 2128, - -2, 2298, - -1, 3005, - 90, 2129, - 175, 2129, - -2, 2297, - -1, 3006, - 90, 2130, - 175, 2130, - -2, 2299, - -1, 3007, 90, 2131, 175, 2131, - -2, 2247, - -1, 3008, + -2, 2409, + -1, 2997, 90, 2132, 175, 2132, - -2, 2246, - -1, 3009, + -2, 2414, + -1, 2998, 90, 2133, 175, 2133, - -2, 2248, - -1, 3010, + -2, 2324, + -1, 2999, 90, 2134, 175, 2134, - -2, 2249, - -1, 3011, + -2, 2317, + -1, 3000, 90, 2135, 175, 2135, - -2, 2250, - -1, 3012, + -2, 2206, + -1, 3001, 90, 2136, 175, 2136, - -2, 2251, - -1, 3013, + -2, 2411, + -1, 3002, 90, 2137, 175, 2137, - -2, 2252, - -1, 3014, + -2, 2322, + -1, 3003, 90, 2138, 175, 2138, - -2, 2253, - -1, 3015, + -2, 2316, + -1, 3004, 90, 2139, 175, 2139, - -2, 2254, + -2, 2301, + -1, 3005, + 90, 2173, + 175, 2173, + -2, 2302, + -1, 3006, + 90, 2173, + 175, 2173, + -2, 2303, + -1, 3008, + 90, 2144, + 175, 2144, + -2, 2458, + -1, 3009, + 90, 2121, + 175, 2121, + -2, 2443, + -1, 3010, + 90, 2171, + 175, 2171, + -2, 2412, + -1, 3011, + 90, 2171, + 175, 2171, + -2, 2442, + -1, 3012, + 90, 2171, + 175, 2171, + -2, 2244, + -1, 3013, + 90, 2169, + 175, 2169, + -2, 2432, + -1, 3014, + 89, 2101, + 90, 2101, + 164, 2101, + 165, 2101, + 167, 2101, + 175, 2101, + -2, 2205, + -1, 3015, + 89, 2102, + 90, 2102, + 164, 2102, + 165, 2102, + 167, 2102, + 175, 2102, + -2, 2207, -1, 3016, - 90, 2140, - 175, 2140, - -2, 2255, - -1, 3303, - 114, 1363, - 161, 1363, - 209, 1363, - 212, 1363, - 313, 1363, - -2, 1357, - -1, 3342, - 87, 824, - 175, 824, - -2, 1592, - -1, 3821, - 212, 1363, - 337, 1689, - -2, 1655, - -1, 3866, - 11, 934, - 24, 934, - -2, 1726, - -1, 4049, - 114, 1363, - 161, 1363, - 209, 1363, - 212, 1363, - -2, 1524, - -1, 4055, - 114, 1363, - 161, 1363, - 209, 1363, - 212, 1363, - -2, 1524, - -1, 4072, - 87, 824, - 175, 824, - -2, 1592, - -1, 4104, - 212, 1363, - 337, 1689, - -2, 1656, - -1, 4300, - 114, 1363, - 161, 1363, - 209, 1363, - 212, 1363, - -2, 1525, - -1, 4340, - 90, 1476, - 175, 1476, - -2, 1363, - -1, 4541, - 90, 1476, - 175, 1476, - -2, 1363, - -1, 4763, - 90, 1480, - 175, 1480, - -2, 1363, - -1, 4820, - 90, 1481, - 175, 1481, - -2, 1363, + 89, 2103, + 90, 2103, + 164, 2103, + 165, 2103, + 167, 2103, + 175, 2103, + -2, 2486, + -1, 3017, + 89, 2105, + 90, 2105, + 164, 2105, + 165, 2105, + 167, 2105, + 175, 2105, + -2, 2413, + -1, 3018, + 89, 2107, + 90, 2107, + 164, 2107, + 165, 2107, + 167, 2107, + 175, 2107, + -2, 2390, + -1, 3019, + 89, 2109, + 90, 2109, + 164, 2109, + 165, 2109, + 167, 2109, + 175, 2109, + -2, 2323, + -1, 3020, + 89, 2111, + 90, 2111, + 164, 2111, + 165, 2111, + 167, 2111, + 175, 2111, + -2, 2290, + -1, 3021, + 89, 2112, + 90, 2112, + 164, 2112, + 165, 2112, + 167, 2112, + 175, 2112, + -2, 2291, + -1, 3022, + 89, 2114, + 90, 2114, + 164, 2114, + 165, 2114, + 167, 2114, + 175, 2114, + -2, 2204, + -1, 3023, + 90, 2176, + 164, 2176, + 165, 2176, + 167, 2176, + 175, 2176, + -2, 2249, + -1, 3024, + 90, 2176, + 164, 2176, + 165, 2176, + 167, 2176, + 175, 2176, + -2, 2266, + -1, 3025, + 90, 2179, + 164, 2179, + 165, 2179, + 167, 2179, + 175, 2179, + -2, 2245, + -1, 3026, + 90, 2179, + 164, 2179, + 165, 2179, + 167, 2179, + 175, 2179, + -2, 2341, + -1, 3027, + 90, 2176, + 164, 2176, + 165, 2176, + 167, 2176, + 175, 2176, + -2, 2371, + -1, 3028, + 90, 2149, + 175, 2149, + -2, 2270, + -1, 3029, + 90, 2150, + 175, 2150, + -2, 2356, + -1, 3030, + 90, 2151, + 175, 2151, + -2, 2314, + -1, 3031, + 90, 2152, + 175, 2152, + -2, 2357, + -1, 3032, + 90, 2153, + 175, 2153, + -2, 2271, + -1, 3033, + 90, 2154, + 175, 2154, + -2, 2328, + -1, 3034, + 90, 2155, + 175, 2155, + -2, 2327, + -1, 3035, + 90, 2156, + 175, 2156, + -2, 2329, + -1, 3036, + 90, 2157, + 175, 2157, + -2, 2273, + -1, 3037, + 90, 2158, + 175, 2158, + -2, 2272, + -1, 3038, + 90, 2159, + 175, 2159, + -2, 2274, + -1, 3039, + 90, 2160, + 175, 2160, + -2, 2275, + -1, 3040, + 90, 2161, + 175, 2161, + -2, 2276, + -1, 3041, + 90, 2162, + 175, 2162, + -2, 2277, + -1, 3042, + 90, 2163, + 175, 2163, + -2, 2278, + -1, 3043, + 90, 2164, + 175, 2164, + -2, 2279, + -1, 3044, + 90, 2165, + 175, 2165, + -2, 2280, + -1, 3045, + 90, 2166, + 175, 2166, + -2, 2281, + -1, 3329, + 114, 1376, + 161, 1376, + 209, 1376, + 212, 1376, + 313, 1376, + -2, 1370, + -1, 3368, + 87, 833, + 175, 833, + -2, 1616, + -1, 3863, + 212, 1376, + 337, 1715, + -2, 1679, + -1, 3908, + 11, 943, + 24, 943, + -2, 1752, + -1, 4093, + 114, 1376, + 161, 1376, + 209, 1376, + 212, 1376, + -2, 1548, + -1, 4099, + 114, 1376, + 161, 1376, + 209, 1376, + 212, 1376, + -2, 1548, + -1, 4116, + 87, 833, + 175, 833, + -2, 1616, + -1, 4153, + 212, 1376, + 337, 1715, + -2, 1680, + -1, 4352, + 114, 1376, + 161, 1376, + 209, 1376, + 212, 1376, + -2, 1549, + -1, 4394, + 90, 1490, + 175, 1490, + -2, 1376, + -1, 4599, + 90, 1490, + 175, 1490, + -2, 1376, + -1, 4823, + 90, 1494, + 175, 1494, + -2, 1376, + -1, 4880, + 90, 1495, + 175, 1495, + -2, 1376, } const yyPrivate = 57344 -const yyLast = 72745 +const yyLast = 75324 var yyAct = [...]int{ - 939, 1864, 915, 4872, 941, 4843, 2770, 3388, 4864, 4773, - 250, 3508, 2321, 4767, 1997, 4089, 4195, 4777, 3844, 4778, - 4766, 1863, 4666, 4150, 4541, 3807, 924, 3683, 4612, 4721, - 4371, 3911, 4118, 4514, 917, 3382, 4431, 4474, 3685, 4603, - 4190, 1770, 3912, 4540, 1565, 2063, 2953, 4525, 4640, 4020, - 1946, 4287, 3909, 737, 3251, 970, 1330, 3385, 4323, 4504, - 843, 4613, 4204, 4615, 4028, 1421, 3545, 4034, 237, 5, - 4105, 757, 3816, 4312, 2050, 4077, 1335, 3345, 3176, 1386, - 3253, 772, 782, 792, 3755, 1415, 792, 4302, 2834, 3738, - 4297, 3713, 4268, 3318, 2766, 3053, 4056, 2000, 3509, 1370, - 2412, 2047, 3981, 3742, 4018, 2415, 3411, 3477, 3836, 2301, - 868, 162, 2273, 4058, 3818, 3825, 3096, 3507, 3261, 3504, - 3372, 3863, 3370, 3973, 2046, 2457, 2498, 2960, 2069, 2568, - 3893, 3289, 235, 3720, 3703, 3824, 3716, 2294, 1763, 3495, - 3718, 3060, 3767, 3715, 2786, 1872, 2774, 2179, 859, 40, - 3714, 2772, 3304, 2700, 1840, 2767, 3665, 2494, 912, 2699, - 907, 2564, 908, 3095, 1847, 3034, 1202, 73, 863, 2600, - 1856, 1951, 2563, 2462, 3711, 1113, 73, 2408, 3277, 1187, - 1852, 3271, 2929, 1868, 1851, 3393, 2837, 2835, 2295, 2311, - 2302, 3322, 772, 1155, 2816, 3349, 4, 2065, 2785, 2754, - 246, 7, 245, 6, 2242, 2064, 3413, 2958, 1258, 1992, - 2565, 2596, 1711, 1424, 916, 1875, 2776, 2773, 1996, 1813, - 1742, 2745, 1779, 1748, 2303, 2491, 737, 906, 2279, 756, - 2057, 2702, 736, 2830, 2033, 1983, 2748, 1368, 2263, 37, - 1950, 1351, 2479, 1820, 1716, 41, 925, 2237, 789, 1186, - 250, 856, 250, 1373, 1248, 1249, 1991, 1425, 1747, 2241, - 15, 772, 914, 1744, 1154, 908, 1416, 25, 773, 1803, - 866, 1704, 1647, 1076, 26, 27, 2930, 236, 31, 2070, - 865, 18, 10, 16, 1131, 1228, 1193, 791, 1137, 1566, - 1400, 232, 862, 776, 1152, 1404, 228, 827, 1623, 2544, - 146, 76, 2305, 5, 75, 1492, 72, 1493, 1491, 4625, - 1245, 4500, 1492, 3223, 1493, 1491, 1147, 1492, 3930, 1493, - 1491, 784, 3223, 3223, 4075, 3675, 3788, 788, 3674, 3563, - 3562, 2580, 1336, 913, 1648, 4250, 4037, 1337, 3126, 3904, - 1078, 1199, 786, 1079, 3040, 3038, 3037, 3035, 2203, 1649, - 1276, 2192, 1827, 1823, 1240, 1241, 3175, 234, 758, 2698, - 787, 1382, 1383, 1384, 1746, 783, 4589, 2505, 1606, 1381, - 764, 1876, 3935, 796, 759, 760, 2530, 1790, 761, 1201, - 762, 2534, 1244, 2535, 1246, 1241, 1726, 1336, 2506, 1676, - 4054, 1241, 1642, 1100, 2954, 4234, 3676, 3672, 2713, 2705, - 2199, 73, 1651, 1097, 3660, 3657, 3658, 4855, 1441, 9, - 2186, 1638, 3655, 1825, 4188, 3541, 73, 1492, 73, 1493, - 1491, 3539, 1492, 14, 1493, 1491, 1881, 2467, 4775, 4774, - 4364, 1239, 3918, 4598, 4439, 7, 4432, 6, 4191, 3910, - 2490, 1560, 4617, 2769, 1077, 3058, 3627, 3701, 1276, 2486, - 2909, 2523, 2875, 897, 4878, 4611, 899, 4852, 1088, 4447, - 1926, 898, 4445, 4239, 4609, 4486, 4009, 3153, 2720, 4679, - 1787, 1374, 1657, 1655, 1654, 4004, 3704, 4237, 2371, 2735, - 2048, 2049, 1101, 1098, 1203, 1294, 1295, 1261, 1067, 861, - 1066, 1068, 1069, 3625, 1070, 1071, 3502, 2105, 1700, 2749, - 2950, 4488, 1489, 2212, 2578, 785, 3514, 3515, 1284, 1288, - 1290, 1292, 1297, 2951, 1302, 1298, 1299, 1300, 1301, 2425, - 1943, 1279, 1280, 1281, 1282, 1259, 1260, 1285, 2210, 1262, - 3513, 1264, 1265, 1266, 1267, 1263, 1268, 1269, 1270, 1271, - 1272, 1275, 1277, 1273, 1274, 1303, 1304, 1305, 1306, 1307, - 1308, 1309, 1310, 1312, 1311, 1313, 1314, 1315, 1316, 1317, - 1318, 1319, 1320, 1287, 1289, 1291, 1293, 1296, 1682, 1197, - 2392, 2393, 1198, 1879, 1379, 1089, 1380, 1378, 897, 2217, - 2218, 899, 1664, 1294, 1295, 1261, 898, 2937, 2391, 1250, - 2936, 2915, 1680, 2938, 1878, 1095, 1749, 1437, 1751, 3250, - 1438, 2914, 3682, 3811, 1278, 3809, 1284, 1288, 1290, 1292, - 1297, 3659, 1302, 1298, 1299, 1300, 1301, 3656, 1101, 1279, - 1280, 1281, 1282, 1259, 1260, 1285, 1672, 1262, 1098, 1264, - 1265, 1266, 1267, 1263, 1268, 1269, 1270, 1271, 1272, 1275, - 1277, 1273, 1274, 1303, 1304, 1305, 1306, 1307, 1308, 1309, - 1310, 1312, 1311, 1313, 1314, 1315, 1316, 1317, 1318, 1319, - 1320, 1287, 1289, 1291, 1293, 1296, 2403, 1276, 3246, 3054, - 1941, 1923, 3215, 3213, 3248, 192, 233, 191, 224, 193, - 1826, 1824, 1420, 1422, 1423, 1999, 1419, 1422, 1423, 192, - 233, 191, 224, 193, 192, 233, 191, 224, 193, 852, - 1482, 1440, 1278, 1965, 1487, 192, 233, 191, 224, 193, - 1412, 1196, 4781, 4782, 1195, 4620, 3217, 192, 233, 191, - 224, 193, 3273, 897, 4619, 2867, 899, 4747, 4620, 4735, - 4618, 898, 3274, 4807, 4601, 4619, 4734, 3546, 1099, 1681, - 4618, 4733, 1887, 3243, 2806, 4726, 2288, 2289, 1096, 3247, - 229, 4222, 4723, 2677, 1984, 4847, 4848, 1988, 4435, 4636, - 3913, 1343, 3913, 1732, 229, 3085, 4723, 772, 3547, 229, - 3548, 1340, 772, 3551, 1339, 2582, 1469, 3280, 3939, 1470, - 229, 1987, 3272, 4019, 1346, 4604, 4605, 4606, 4607, 2409, - 2574, 2399, 229, 4279, 792, 792, 1365, 2213, 772, 772, - 2579, 2003, 1294, 1295, 1261, 3432, 4026, 1472, 1979, 2917, - 4241, 2743, 1735, 1172, 1942, 2423, 2424, 1143, 3244, 769, - 1921, 3258, 2211, 3734, 4133, 1284, 1288, 1290, 1292, 1297, - 2924, 1302, 1298, 1299, 1300, 1301, 3588, 1251, 1279, 1280, - 1281, 1282, 1259, 1260, 1285, 4749, 1262, 1092, 1264, 1265, - 1266, 1267, 1263, 1268, 1269, 1270, 1271, 1272, 1275, 1277, - 1273, 1274, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, - 1312, 1311, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, - 1287, 1289, 1291, 1293, 1296, 1641, 4624, 1389, 4499, 3920, - 3942, 1439, 1199, 3249, 2202, 1398, 1683, 4238, 3586, 3592, - 3222, 1337, 1408, 1337, 1989, 4780, 3496, 4490, 4491, 1337, - 1427, 1428, 1418, 1430, 1431, 2507, 2369, 1433, 1484, 3732, - 1529, 1278, 1093, 3118, 1535, 3319, 1467, 4221, 1986, 221, - 1201, 1485, 1486, 1286, 2873, 4223, 2908, 1410, 2911, 1457, - 3564, 1349, 4189, 3540, 789, 789, 789, 3561, 3218, 2910, - 1480, 1481, 2605, 2920, 2921, 3728, 2002, 2001, 3490, 2919, - 2543, 1241, 3245, 2003, 1337, 4496, 1241, 1241, 1241, 4276, - 1921, 1338, 1339, 3729, 3730, 1241, 1241, 192, 233, 3739, - 1354, 1357, 4235, 1165, 1163, 3740, 1164, 2581, 1468, 3731, - 3225, 4455, 2927, 4456, 1479, 755, 4149, 1094, 4489, 4455, - 4446, 4456, 2008, 2011, 2012, 3036, 1569, 4568, 1432, 4450, - 1828, 4145, 3813, 2009, 1168, 4426, 4021, 784, 784, 784, - 2585, 2587, 2588, 788, 788, 788, 1435, 1436, 161, 1449, - 1199, 1286, 900, 901, 902, 903, 904, 4628, 786, 786, - 786, 1808, 1656, 1077, 1422, 1423, 1422, 1423, 1985, 1359, - 1375, 1358, 229, 1653, 2370, 3768, 787, 787, 787, 4458, - 4477, 783, 783, 783, 1329, 1256, 1649, 4458, 1201, 4240, - 1471, 1342, 1344, 1347, 4305, 4251, 1401, 1405, 1405, 1405, - 1649, 1363, 1364, 1332, 3726, 4043, 764, 1173, 3897, 4457, - 759, 760, 1644, 1646, 761, 1650, 762, 4457, 3216, 3753, - 3838, 3839, 3276, 1401, 1401, 1328, 3837, 4659, 1198, 1462, - 1880, 1668, 1464, 4651, 3323, 1671, 1406, 1407, 2002, 2001, - 3985, 1679, 1663, 2402, 4531, 3987, 4518, 1426, 1446, 3740, - 1429, 2756, 1621, 1169, 1102, 1626, 1442, 1443, 4138, 794, - 1465, 1091, 793, 1474, 3500, 2751, 1475, 3666, 4641, 772, - 772, 772, 4090, 1448, 1155, 3279, 4661, 900, 901, 902, - 903, 904, 1725, 1256, 4667, 3808, 772, 790, 1731, 1570, - 3387, 1737, 1922, 1536, 1477, 772, 1348, 4097, 1659, 737, - 737, 790, 1531, 1532, 1533, 1534, 790, 2410, 2840, 737, - 737, 2731, 1399, 1774, 1774, 1171, 772, 790, 3735, 1411, - 2290, 785, 785, 785, 1345, 4748, 3846, 4483, 2923, 790, - 3283, 3284, 3589, 4259, 1356, 1355, 3740, 2853, 1661, 792, - 1804, 757, 3996, 2833, 2856, 3282, 4280, 1816, 3999, 1354, - 1357, 1921, 3695, 74, 2907, 1776, 4154, 192, 233, 191, - 224, 193, 250, 1772, 1772, 4635, 4359, 74, 2400, 4886, - 1286, 737, 74, 3433, 1781, 3434, 3435, 3317, 3840, 1458, - 3841, 3843, 3842, 74, 2885, 1980, 4243, 4244, 4245, 2574, - 4867, 1390, 1581, 1582, 1145, 74, 1146, 1170, 4348, 1733, - 3497, 2855, 2884, 4492, 3814, 1460, 3383, 3384, 4207, 3387, - 192, 233, 2010, 1473, 1361, 3316, 3998, 3286, 1463, 1466, - 1358, 853, 900, 901, 902, 903, 904, 2905, 2906, 4532, - 2586, 4519, 229, 1936, 3312, 1759, 1023, 4354, 1902, 3214, - 1758, 1459, 1860, 1447, 1414, 1413, 1167, 1865, 1397, 1768, - 1769, 1396, 1395, 1478, 4668, 4765, 3727, 1877, 4505, 3817, - 1873, 3649, 1736, 4545, 2876, 1705, 4059, 2854, 3749, 2850, - 1652, 2839, 3838, 3839, 2833, 1476, 2841, 4186, 1753, 1755, - 4065, 1900, 4451, 1673, 861, 3310, 4452, 1903, 1766, 1767, - 4451, 1627, 1687, 4720, 4614, 1745, 1924, 1625, 1454, 1526, - 1525, 3982, 1256, 2840, 2843, 1867, 1715, 1692, 3523, 3524, - 2136, 2138, 2137, 3867, 3833, 1774, 855, 3114, 2942, 854, - 2913, 1737, 2871, 1461, 2703, 2571, 782, 2398, 73, 2386, - 2842, 1685, 1670, 3232, 1838, 3313, 1841, 1842, 4164, 2818, - 2820, 1658, 3882, 3845, 4868, 2843, 1964, 3869, 1843, 1844, - 1829, 4012, 3591, 1737, 1698, 1166, 3484, 1697, 1973, 1973, - 1162, 1737, 1835, 1737, 1737, 1849, 1850, 1696, 1710, 1695, - 1805, 1174, 1757, 798, 1774, 797, 1774, 1339, 3974, 1929, - 1932, 1933, 1925, 1356, 1355, 1706, 1707, 3834, 853, 2375, - 2373, 2755, 1858, 2135, 2374, 4362, 1948, 1949, 1453, 767, - 1855, 768, 3319, 1859, 190, 222, 231, 223, 1684, 3430, - 1782, 1156, 2931, 1958, 1959, 1968, 3461, 1796, 4544, 764, - 3750, 192, 233, 2195, 2732, 3929, 1802, 2597, 1913, 1158, - 1159, 1160, 789, 1817, 1970, 789, 789, 2583, 2584, 1818, - 3083, 2501, 1714, 3240, 1660, 1662, 2724, 1774, 2220, 789, - 2283, 2287, 2288, 2289, 2284, 2293, 2285, 2291, 1667, 4764, - 2286, 2844, 2292, 2221, 1339, 2067, 2839, 2833, 2838, 1529, - 2836, 2841, 2497, 1854, 1114, 1144, 4350, 2108, 2109, 2110, - 4349, 2118, 2828, 855, 3452, 3453, 854, 3989, 4865, 4866, - 2124, 2099, 2100, 2125, 2723, 2104, 2499, 2051, 2200, 4355, - 4356, 1917, 2844, 2119, 2219, 784, 2849, 1103, 784, 784, - 2847, 788, 2144, 2145, 788, 788, 2126, 1870, 2128, 2897, - 2129, 2130, 2131, 1104, 1969, 2842, 786, 4313, 1912, 786, - 786, 1885, 1976, 1944, 1888, 2819, 3928, 1995, 1952, 4066, - 1954, 1955, 2176, 1907, 787, 2726, 2725, 787, 787, 783, - 1673, 4888, 783, 783, 1961, 3315, 3889, 1910, 1905, 1886, - 1339, 1911, 1889, 1890, 1909, 1904, 1908, 1665, 1666, 4903, - 1938, 1939, 2204, 1401, 1998, 2013, 2207, 4899, 2194, 1199, - 4730, 772, 772, 772, 4892, 3233, 3264, 1405, 1853, 1107, - 2222, 2224, 1993, 2225, 1953, 2227, 2228, 1490, 2230, 1405, - 2102, 757, 1804, 1977, 1978, 4880, 1947, 2238, 3326, 1774, - 2244, 2245, 1921, 2247, 1737, 772, 3835, 1201, 4874, 3884, - 772, 3265, 3266, 1774, 3451, 1957, 4861, 2177, 1454, 2692, - 1155, 1391, 2117, 2274, 1972, 1974, 1175, 1962, 4822, 1107, - 853, 2297, 2297, 1725, 2297, 1994, 3787, 2306, 772, 772, - 2180, 2368, 1111, 1990, 1490, 2238, 2379, 1109, 1108, 1774, - 2383, 2384, 1490, 1674, 1675, 1725, 1677, 737, 1897, 3329, - 1686, 1688, 1689, 1690, 1691, 2196, 1693, 4015, 2502, 2932, - 3941, 737, 1699, 1774, 1894, 1895, 2035, 2870, 2641, 785, - 2576, 2640, 785, 785, 3462, 3464, 3465, 3466, 3463, 1391, - 2031, 2032, 1106, 4875, 2042, 2043, 1906, 1109, 1108, 2430, - 2432, 4823, 772, 2238, 1774, 74, 2438, 4793, 772, 772, - 772, 859, 859, 4823, 192, 233, 3888, 1391, 2448, 2183, - 2450, 2451, 2452, 3113, 3344, 855, 2458, 2323, 854, 4790, - 4425, 1193, 3850, 250, 1110, 3848, 250, 250, 4789, 250, - 1331, 1914, 230, 1915, 1199, 3802, 2747, 2188, 2018, 2019, - 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, - 2030, 3707, 4783, 2377, 2388, 3924, 1490, 2044, 2045, 2299, - 2246, 2304, 4761, 2132, 2133, 2248, 2812, 2426, 1899, 2418, - 2419, 4713, 1201, 3343, 2456, 4712, 3664, 1898, 2570, 229, - 1982, 2068, 4794, 2513, 2570, 3652, 2103, 1492, 4689, 1493, - 1491, 2434, 2395, 2184, 2397, 4662, 2178, 2440, 2441, 2442, - 2812, 1981, 4647, 3650, 4791, 2416, 2417, 2243, 3662, 2127, - 2232, 2685, 1492, 2576, 1493, 1491, 2193, 2570, 2197, 772, - 2274, 2259, 772, 2201, 2411, 3331, 2389, 2812, 2404, 2527, - 1492, 2529, 1493, 1491, 3889, 2533, 2476, 2615, 1492, 3526, - 1493, 1491, 2537, 2538, 2539, 3622, 2542, 4762, 1737, 3219, - 2265, 2233, 4560, 2489, 2508, 2466, 1490, 2382, 2469, 2470, - 1490, 2472, 3889, 2437, 3059, 2840, 2843, 2746, 2569, 2387, - 3653, 4559, 4558, 2615, 2271, 4557, 1737, 2275, 2269, 2270, - 2576, 1490, 2376, 1774, 2567, 2552, 2290, 4648, 3651, 73, - 1452, 4535, 73, 73, 1490, 73, 2686, 4534, 2381, 4372, - 4373, 4374, 4378, 4376, 4377, 4379, 4380, 4381, 4375, 2390, - 2405, 2394, 1993, 2396, 2283, 2287, 2288, 2289, 2284, 2293, - 2285, 2291, 4502, 4471, 2286, 1331, 2292, 2826, 3347, 3344, - 2454, 2697, 2521, 1451, 2483, 2683, 1454, 2615, 2590, 1454, - 2435, 2553, 2429, 2556, 2691, 3113, 2690, 2536, 2650, 2558, - 2436, 2560, 2443, 2444, 2649, 4468, 2615, 2615, 789, 2648, - 2615, 2502, 1492, 2463, 1493, 1491, 1975, 3293, 3299, 3300, - 3301, 3294, 3298, 3295, 3297, 3296, 2576, 1492, 2569, 1493, - 1491, 1392, 2576, 4327, 2139, 2140, 2141, 2142, 2519, 2481, - 2146, 2147, 2148, 2149, 2151, 2152, 2153, 2154, 2155, 2156, - 2157, 2158, 2159, 2160, 2161, 2162, 2163, 2615, 1490, 2283, - 2287, 2288, 2289, 2284, 2293, 2285, 2291, 4326, 2500, 2286, - 2684, 2292, 1452, 2844, 2276, 2421, 2385, 2614, 2839, 2833, - 2838, 784, 2836, 2841, 2517, 2551, 1492, 788, 1493, 1491, - 2783, 2651, 2652, 1492, 2654, 1493, 1491, 2561, 1199, 4260, - 1709, 2661, 786, 2054, 4159, 2515, 2520, 1492, 1918, 1493, - 1491, 1760, 2274, 1492, 4099, 1493, 1491, 4275, 4328, 4897, - 787, 2548, 1236, 1237, 1238, 783, 2554, 4086, 4045, 2555, - 1492, 3966, 1493, 1491, 4876, 2516, 1201, 2842, 2545, 1622, - 3962, 4587, 1387, 4025, 3621, 2704, 1388, 2706, 4420, 2708, - 2709, 3196, 2783, 2712, 4075, 3531, 3346, 1235, 3858, 3611, - 1232, 772, 1737, 772, 1737, 2613, 3228, 2562, 3116, 2603, - 3559, 2689, 3556, 3335, 2727, 3115, 1405, 3093, 3084, 3333, - 2733, 3328, 907, 2573, 3802, 772, 772, 772, 2611, 1921, - 2636, 2744, 2619, 2676, 2678, 2679, 2680, 2559, 2682, 4100, - 2617, 772, 772, 772, 772, 2598, 2518, 1081, 1082, 1083, - 1084, 2589, 3802, 4046, 2557, 2475, 3967, 2118, 2118, 2778, - 2461, 2446, 2591, 3194, 2673, 3963, 2787, 1725, 1725, 1725, - 1725, 1725, 1725, 1725, 2035, 3182, 3174, 2607, 3128, 1081, - 1082, 1083, 1084, 3859, 1490, 3088, 3050, 2297, 2198, 1882, - 1544, 2592, 2593, 2229, 1105, 3334, 4418, 3329, 3336, 2234, - 2235, 2236, 3149, 3150, 3334, 785, 3329, 1360, 1326, 3143, - 1321, 2862, 2250, 2251, 2252, 2253, 3048, 2821, 3046, 3044, - 2283, 2287, 2288, 2289, 2284, 2293, 2285, 2291, 2813, 4157, - 2286, 1785, 2292, 2782, 4520, 2693, 1302, 1298, 1299, 1300, - 1301, 2420, 909, 3148, 2657, 3147, 3146, 3144, 2783, 2656, - 2639, 2602, 2601, 1833, 1832, 2630, 4652, 2629, 2628, 2616, - 1490, 1490, 3792, 1490, 2594, 2595, 2575, 3583, 1199, 1891, - 2783, 3051, 1434, 2717, 2869, 2719, 772, 1973, 1402, 942, - 952, 1229, 1230, 1231, 1234, 3035, 1233, 4314, 1507, 943, - 1762, 944, 948, 951, 947, 945, 946, 737, 737, 3769, - 2694, 3049, 4653, 3045, 3045, 1339, 1201, 1526, 1525, 2775, - 2464, 1774, 772, 2812, 1086, 2107, 2106, 1387, 2783, 2707, - 2692, 1388, 1924, 2711, 2955, 4521, 3145, 1506, 1507, 1490, - 772, 2107, 2106, 4315, 1490, 1490, 1339, 3017, 757, 1569, - 1490, 2832, 1490, 1490, 2615, 1816, 1086, 1725, 2831, 2736, - 3025, 2576, 3027, 4211, 1892, 250, 949, 4062, 4060, 1934, - 2290, 2948, 1510, 1511, 1512, 1513, 1514, 1506, 1112, 4889, - 1387, 4522, 3574, 2912, 1388, 2811, 1387, 4851, 2868, 4626, - 1388, 3770, 4582, 3902, 3135, 4501, 2939, 950, 2940, 3021, - 2118, 2788, 2118, 772, 3069, 1761, 3064, 2810, 2779, 2780, - 1403, 3080, 4443, 4063, 4061, 2265, 2265, 2945, 2946, 3086, - 2807, 2825, 2789, 2790, 2791, 2792, 2793, 2794, 2933, 4390, - 1764, 3091, 4352, 4351, 4337, 3094, 3097, 3771, 4283, 2957, - 3099, 1765, 2150, 4069, 1774, 4036, 1930, 2962, 3890, 2845, - 2846, 2041, 2851, 1492, 3880, 1493, 1491, 3872, 2143, 4759, - 3110, 3860, 3804, 2567, 3905, 2290, 3024, 2038, 2040, 2037, - 1774, 2039, 1774, 3744, 3493, 3492, 3337, 1339, 3332, 3291, - 3687, 4656, 3224, 3125, 2944, 3127, 1753, 1755, 2710, 1387, - 4210, 1935, 3063, 1388, 3101, 2511, 1492, 3030, 1493, 1491, - 1242, 1243, 2510, 2922, 2509, 1247, 2928, 3039, 1702, 3090, - 3029, 1199, 1570, 3092, 2934, 1774, 1339, 1701, 1341, 3684, - 3156, 1492, 3157, 1493, 1491, 3102, 2058, 1821, 2608, 2464, - 3903, 73, 4078, 3256, 3107, 3108, 2058, 3165, 3111, 3687, - 3532, 2226, 1774, 2963, 2949, 1492, 4732, 1493, 1491, 1201, - 1493, 1491, 2952, 2775, 3137, 4526, 3151, 4470, 1937, 3684, - 1492, 4469, 1493, 1491, 1491, 1772, 1387, 1507, 1931, 3031, - 1388, 4367, 3061, 3062, 3023, 3057, 1492, 3018, 1493, 1491, - 1956, 4366, 3772, 3166, 1497, 1498, 1499, 1500, 1501, 1502, - 1503, 1495, 1772, 1507, 4343, 1492, 1963, 1493, 1491, 1966, - 1967, 3613, 3422, 3420, 1822, 3399, 3226, 3397, 3171, 3172, - 3100, 3230, 4704, 4705, 3234, 3055, 3686, 4798, 2632, 3066, - 3068, 772, 772, 772, 3078, 1508, 1509, 1510, 1511, 1512, - 1513, 1514, 1506, 1546, 3087, 3138, 4885, 3140, 4760, 1339, - 1492, 3124, 1493, 1491, 3119, 3598, 1545, 1774, 4078, 1492, - 1737, 1493, 1491, 4562, 4563, 4756, 1737, 2379, 3133, 3154, - 3198, 3206, 3199, 3207, 3201, 3612, 3203, 3204, 4707, 3164, - 4825, 3109, 4706, 3112, 3122, 1492, 4703, 1493, 1491, 3117, - 4770, 4284, 4285, 1821, 3339, 3342, 2290, 2623, 1993, 2631, - 4277, 3072, 1492, 4702, 1493, 1491, 4701, 1492, 3210, 1493, - 1491, 3071, 4884, 4676, 3129, 3130, 4700, 1492, 4229, 1493, - 1491, 4023, 3290, 1725, 4226, 3473, 1492, 4698, 1493, 1491, - 3471, 3152, 3142, 3374, 1492, 4697, 1493, 1491, 4696, 1874, - 1492, 1339, 1493, 1491, 4695, 1492, 4694, 1493, 1491, 3396, - 2962, 1492, 3305, 1493, 1491, 4693, 1339, 1339, 1339, 1973, - 5, 4278, 1339, 4225, 3406, 3407, 3408, 3409, 1339, 3416, - 3132, 3417, 3418, 1507, 3419, 3324, 3421, 1492, 2612, 1493, - 1491, 4691, 4024, 4029, 3308, 4690, 3472, 3416, 3211, 4214, - 1492, 3470, 1493, 1491, 4654, 1492, 4213, 1493, 1491, 2297, - 1504, 1515, 1516, 1517, 1518, 1508, 1509, 1510, 1511, 1512, - 1513, 1514, 1506, 3474, 2122, 3469, 1492, 3252, 1493, 1491, - 4212, 2610, 3458, 1492, 2323, 1493, 1491, 4548, 4538, 2123, - 737, 3287, 4523, 4495, 4467, 4887, 3377, 3306, 2379, 4433, - 4361, 4317, 1339, 1339, 4142, 4035, 2963, 1492, 4316, 1493, - 1491, 3954, 4091, 1774, 3511, 3947, 3267, 1492, 73, 1493, - 1491, 3285, 3268, 4064, 3270, 4022, 3719, 772, 3314, 3160, - 4879, 1492, 3479, 1493, 1491, 2243, 3468, 4005, 1492, 3733, - 1493, 1491, 1492, 3457, 1493, 1491, 3567, 3167, 3338, 3544, - 3543, 3390, 7, 3341, 6, 3482, 3456, 3354, 3455, 3355, - 1492, 3454, 1493, 1491, 3446, 3440, 3401, 3439, 3438, 3437, - 3220, 3089, 3052, 3362, 3311, 3366, 3367, 3368, 2941, 3654, - 3363, 2696, 2524, 3177, 3178, 3376, 3379, 2485, 2484, 3183, - 2482, 3528, 3392, 3394, 3485, 2478, 3398, 3394, 3391, 2477, - 2427, 3404, 250, 2209, 3512, 2206, 1492, 250, 1493, 1491, - 1883, 1640, 1324, 3391, 3402, 3403, 4493, 4494, 3075, 3405, - 4877, 3077, 4196, 4849, 2874, 3412, 3076, 2877, 2878, 2879, - 2880, 2881, 2882, 2883, 3498, 3527, 2886, 2887, 2888, 2889, - 2890, 2891, 2892, 2893, 2894, 2895, 2896, 3448, 2898, 2899, - 2900, 2901, 2902, 3436, 2903, 3566, 4813, 4744, 4742, 3623, - 4475, 4718, 4638, 4288, 3097, 4632, 4623, 4621, 3488, 3491, - 4688, 3494, 1323, 4608, 4599, 4577, 4576, 4567, 3617, 4566, - 4552, 4547, 3616, 1756, 1774, 3516, 1492, 3585, 1493, 1491, - 4546, 1842, 3519, 1507, 3558, 4498, 4482, 4480, 4466, 3510, - 3510, 1843, 1844, 4434, 4345, 1492, 3520, 1493, 1491, 1492, - 4292, 1493, 1491, 3614, 4281, 4265, 4264, 1849, 1850, 1505, - 1504, 1515, 1516, 1517, 1518, 1508, 1509, 1510, 1511, 1512, - 1513, 1514, 1506, 3195, 3533, 4262, 4256, 3193, 1858, 3537, - 1492, 3569, 1493, 1491, 3572, 3573, 1855, 4254, 4233, 1859, - 2643, 3192, 4232, 3576, 4231, 3191, 4901, 4228, 4227, 3579, - 1492, 4201, 1493, 1491, 1492, 3190, 1493, 1491, 73, 3535, - 4837, 2528, 4198, 73, 2531, 2532, 3534, 4194, 1492, 4192, - 1493, 1491, 1492, 3189, 1493, 1491, 4170, 3553, 4883, 4167, - 2546, 2547, 1492, 4161, 1493, 1491, 3670, 3478, 4017, 3673, - 2549, 2550, 3188, 4007, 3677, 3991, 772, 1737, 3187, 3549, - 1492, 3975, 1493, 1491, 3953, 3689, 3691, 3692, 3694, 3587, - 3696, 3697, 3186, 3951, 3945, 3919, 3878, 3571, 3877, 1492, - 3875, 1493, 1491, 1494, 1339, 1492, 3874, 1493, 1491, 3861, - 1339, 1528, 3856, 3185, 3855, 3581, 3722, 3724, 4674, 1492, - 1538, 1493, 1491, 3582, 3745, 3705, 3594, 3737, 3698, 3688, - 3595, 3678, 3671, 772, 3669, 4539, 2701, 3610, 3601, 3602, - 1492, 3593, 1493, 1491, 3590, 3565, 1548, 3542, 3752, 3184, - 3756, 1339, 3604, 3181, 772, 3518, 772, 2379, 1339, 3606, - 3607, 1339, 3486, 1507, 3483, 3480, 3467, 3459, 3449, 3447, - 2118, 3603, 2118, 3605, 3443, 3782, 1492, 3783, 1493, 1491, - 1492, 3180, 1493, 1491, 1725, 2787, 3179, 3791, 3663, 1505, - 1504, 1515, 1516, 1517, 1518, 1508, 1509, 1510, 1511, 1512, - 1513, 1514, 1506, 3173, 3442, 3441, 3748, 3358, 1492, 3257, - 1493, 1491, 3374, 1492, 3241, 1493, 1491, 3668, 3741, 3667, - 3161, 3229, 2862, 3751, 3155, 3389, 3221, 3070, 1023, 1022, - 1492, 3305, 1493, 1491, 3823, 3056, 3826, 3134, 3826, 3826, - 3019, 2728, 4670, 1339, 2715, 2714, 2488, 1492, 3680, 1493, - 1491, 1492, 2688, 1493, 1491, 2480, 1223, 3725, 2687, 2240, - 2208, 3851, 1199, 4472, 1492, 3779, 1493, 1491, 3847, 1774, - 1774, 2205, 2191, 2180, 3308, 2190, 2681, 1971, 3781, 1492, - 1884, 1493, 1491, 1577, 1573, 1492, 1572, 1493, 1491, 3810, - 3812, 1327, 1090, 3789, 192, 233, 3747, 4462, 4461, 4448, - 1201, 3708, 4444, 1492, 3395, 1493, 1491, 3391, 4263, 3275, - 3852, 3853, 2053, 4230, 2267, 3775, 772, 4208, 3780, 1772, - 1772, 3778, 3773, 2775, 4162, 3758, 3786, 4067, 4055, 3790, - 3722, 4053, 3763, 3821, 3803, 3765, 192, 233, 4049, 1492, - 1224, 1493, 1491, 1737, 4860, 2264, 2379, 2379, 3391, 3822, - 233, 191, 224, 193, 4014, 3391, 3831, 2832, 3391, 3805, - 233, 191, 224, 193, 2831, 3971, 3969, 1339, 4859, 2266, - 3628, 3629, 3156, 3827, 3828, 3968, 3630, 3631, 3632, 3633, - 3906, 3634, 3635, 3636, 3637, 3638, 3639, 3640, 3641, 3642, - 3643, 3644, 3645, 3832, 3849, 3965, 3964, 3952, 3759, 3950, - 3908, 192, 233, 194, 3907, 192, 233, 3766, 3892, 3797, - 3785, 229, 4686, 3709, 3777, 3857, 3706, 3661, 3619, 1815, - 3608, 3600, 3599, 3597, 229, 1217, 1212, 1207, 1211, 1215, - 3525, 3369, 772, 3865, 229, 3428, 3429, 3047, 3043, 4836, - 3391, 3042, 3041, 2662, 2655, 2647, 2646, 2645, 2644, 2642, - 3444, 3445, 3776, 1220, 2638, 3862, 161, 1210, 2637, 2635, - 2626, 2622, 2621, 3871, 3806, 3885, 3886, 1507, 2962, 3870, - 3873, 3879, 2487, 2169, 3876, 2167, 229, 233, 2166, 2165, - 229, 4684, 2164, 3489, 3927, 2121, 2120, 2111, 1786, 1784, - 4797, 3932, 3926, 4711, 3895, 1515, 1516, 1517, 1518, 1508, - 1509, 1510, 1511, 1512, 1513, 1514, 1506, 4675, 1218, 1567, - 4669, 4593, 4590, 3977, 3883, 4575, 4556, 3978, 4549, 2458, - 3916, 4428, 4427, 3923, 4385, 4365, 4363, 4358, 4336, 4311, - 1221, 3992, 4140, 3994, 4139, 4136, 4135, 1222, 4000, 4098, - 3374, 4095, 4093, 4038, 3955, 3990, 3986, 3798, 3795, 3702, - 3699, 229, 3938, 3988, 3609, 1837, 1848, 2809, 4334, 1839, - 1854, 1857, 1845, 3943, 2963, 3022, 1834, 3481, 3475, 3957, - 3400, 3959, 3327, 3961, 3320, 3309, 1208, 1712, 3269, 3197, - 772, 2379, 2943, 2904, 1940, 4001, 1507, 2799, 3995, 3937, - 3997, 2781, 2738, 2737, 4044, 2695, 2036, 3983, 229, 2503, - 1219, 2445, 2268, 4052, 2187, 1919, 1846, 1639, 1624, 1620, - 1960, 1619, 1505, 1504, 1515, 1516, 1517, 1518, 1508, 1509, - 1510, 1511, 1512, 1513, 1514, 1506, 1618, 2297, 1725, 4072, - 1617, 3976, 1616, 3972, 1615, 1614, 2274, 1613, 1209, 4081, - 1612, 1611, 3925, 3374, 3980, 3097, 4033, 1610, 1609, 1608, - 4011, 1607, 1606, 1605, 3865, 1604, 1603, 1602, 4101, 1601, - 3103, 1339, 4002, 1600, 4006, 3106, 4010, 1599, 1598, 1597, - 3823, 1596, 1723, 1595, 1339, 1594, 1593, 1592, 1591, 4030, - 1590, 1589, 1588, 2004, 2005, 2006, 2007, 1587, 1586, 1339, - 1585, 4156, 1584, 1583, 4042, 1774, 1580, 860, 1579, 1578, - 4032, 1576, 1575, 1574, 1571, 4151, 4152, 4153, 1564, 4074, - 4165, 4068, 1563, 1561, 1560, 1559, 1558, 1557, 1556, 1555, - 1216, 1554, 1553, 772, 1552, 2379, 1551, 1550, 2055, 1725, - 1339, 1549, 2059, 2060, 2061, 2062, 4158, 4071, 4180, 1543, - 1528, 1542, 4182, 2101, 250, 1772, 1541, 1540, 4079, 4125, - 4134, 1539, 2112, 770, 1456, 1325, 4682, 1213, 4137, 4088, - 1214, 4087, 4199, 4085, 4070, 3350, 3351, 2753, 2541, 1205, - 1366, 4179, 4829, 4827, 4779, 3868, 4203, 3487, 3353, 3292, - 2956, 2765, 1455, 4146, 4174, 4141, 4171, 4143, 1385, 2797, - 3361, 3800, 2804, 77, 2802, 4155, 4013, 2805, 4224, 2803, - 2796, 3801, 3360, 4016, 3359, 3356, 2168, 4160, 2170, 2171, - 2172, 2173, 2174, 2808, 4168, 2800, 4166, 2181, 4163, 2795, - 2801, 4731, 4172, 4169, 4610, 4898, 4341, 2274, 4176, 3557, - 4246, 3330, 4248, 1703, 4252, 3743, 4177, 3555, 4175, 4051, - 4258, 4206, 4173, 2261, 2262, 2256, 2257, 2258, 3819, 2872, - 3820, 4147, 3799, 4197, 3921, 3922, 1339, 3896, 4102, 4200, - 3424, 2360, 1830, 3325, 1151, 1869, 3829, 763, 3425, 3426, - 3427, 4144, 3061, 3062, 4553, 3123, 4187, 2722, 1225, 1339, - 1774, 1774, 1204, 1206, 4293, 3764, 3412, 3756, 2721, 1866, - 2090, 4255, 1161, 4257, 2729, 2447, 2372, 1450, 4261, 3717, - 3710, 3378, 4301, 3321, 3073, 2824, 1339, 2763, 4301, 2272, - 73, 2231, 2107, 2106, 1635, 1636, 4840, 4318, 4817, 4325, - 4551, 4290, 4295, 4296, 4289, 3854, 4236, 3510, 1633, 1634, - 1772, 2051, 2925, 770, 1339, 2918, 1339, 4330, 2822, 4242, - 1631, 1632, 4249, 1629, 1630, 2380, 1445, 4271, 4333, 4272, - 4335, 4270, 1444, 1774, 4267, 4291, 2181, 4304, 1483, 3560, - 4282, 2181, 2181, 2512, 3894, 3365, 2730, 2514, 1928, 1694, - 1394, 4294, 1393, 1377, 772, 4309, 1339, 1339, 954, 163, - 1339, 1339, 1417, 4092, 2526, 4094, 4310, 4307, 163, 2508, - 4074, 4308, 4322, 4303, 4804, 4274, 4802, 3121, 4750, 4728, - 4727, 4387, 4329, 2051, 4273, 4419, 3120, 4725, 4642, 4382, - 4594, 4331, 4389, 4339, 2465, 4342, 4193, 2468, 4084, 4083, - 2471, 4369, 4370, 2473, 3956, 4383, 4384, 4346, 3915, 4429, - 4430, 3914, 4125, 4134, 3900, 2492, 2857, 2827, 1871, 3899, - 3530, 1391, 4831, 4830, 4757, 4758, 4830, 1774, 4253, 3993, - 3979, 3580, 765, 3391, 3236, 3235, 3227, 3020, 2624, 1362, - 163, 1333, 4831, 4360, 2495, 4178, 4818, 1081, 1082, 1083, - 1084, 4808, 1331, 3254, 4269, 4463, 4464, 4421, 772, 4057, - 3552, 2757, 1862, 1331, 766, 1409, 85, 4454, 4442, 2, - 4853, 4854, 4476, 1, 4478, 3212, 2185, 1772, 1637, 1085, - 4422, 1080, 1750, 3510, 4436, 2935, 2086, 2422, 1778, 2189, - 1087, 4441, 2814, 2083, 2815, 3364, 2817, 2085, 2082, 2084, - 2088, 2089, 4449, 4437, 4453, 2087, 2428, 1372, 3242, 2572, - 3499, 1998, 2916, 1998, 2742, 4298, 3736, 1713, 1157, 2113, - 1896, 4479, 1353, 4481, 4459, 4460, 4510, 4215, 1893, 4216, - 1352, 4217, 4515, 4508, 4484, 1350, 2056, 2134, 956, 2768, - 3476, 3450, 4080, 4839, 4871, 4325, 4796, 4842, 1916, 4528, - 4485, 940, 4719, 3917, 3550, 4600, 4800, 1339, 4332, 4602, - 4440, 2577, 1488, 4503, 3774, 823, 1000, 4497, 968, 1562, - 2496, 4537, 3626, 4543, 3624, 967, 4027, 3281, 4424, 3522, - 4517, 824, 3568, 4509, 3570, 2474, 1507, 4597, 1200, 4206, - 4512, 4511, 4438, 163, 3575, 1831, 1836, 4524, 2823, 3577, - 3578, 4530, 4665, 4527, 4340, 3815, 1339, 3386, 163, 4533, - 163, 1861, 1505, 1504, 1515, 1516, 1517, 1518, 1508, 1509, - 1510, 1511, 1512, 1513, 1514, 1506, 4660, 2604, 4096, 4220, - 4218, 2609, 4219, 867, 2401, 735, 4550, 1507, 1774, 2618, - 1184, 4588, 4386, 2764, 2540, 4391, 4555, 1128, 4008, 4591, - 4592, 4561, 4338, 2093, 2094, 2095, 2096, 2097, 2098, 2091, - 2092, 2752, 4344, 1505, 1504, 1515, 1516, 1517, 1518, 1508, - 1509, 1510, 1511, 1512, 1513, 1514, 1506, 1129, 2627, 4585, - 1121, 3303, 3302, 2014, 1496, 2034, 2634, 3647, 1772, 3648, - 4622, 1537, 911, 2606, 4039, 4040, 4041, 4616, 4627, 4388, - 3278, 4119, 4047, 4048, 3517, 84, 83, 4634, 82, 4595, - 81, 258, 959, 257, 2653, 4473, 4286, 4714, 4844, 2658, - 2659, 2660, 937, 936, 2663, 2664, 2665, 2666, 2667, 2668, - 2669, 2670, 2671, 2672, 935, 2674, 2675, 934, 933, 932, - 4643, 2281, 2282, 2280, 2278, 2277, 4639, 4629, 1720, 4630, - 1719, 3529, 3898, 2453, 1998, 2455, 3754, 3415, 4631, 4148, - 3410, 2312, 2310, 1741, 2852, 4506, 2859, 2309, 4776, 3944, - 4209, 4677, 4637, 4678, 4664, 4357, 3460, 1339, 3620, 4205, - 4645, 4646, 2255, 2848, 2329, 3431, 2326, 2325, 3423, 4692, - 4353, 4347, 2357, 4513, 4300, 4658, 1339, 4103, 4104, 4110, - 1283, 4681, 4683, 4685, 4687, 4663, 1507, 1774, 4709, 2762, - 4699, 1257, 1252, 1254, 4715, 4672, 1255, 1253, 3141, 1151, - 3881, 2829, 4680, 3712, 1334, 3263, 3262, 3260, 3259, 1678, - 4655, 4716, 1505, 1504, 1515, 1516, 1517, 1518, 1508, 1509, - 1510, 1511, 1512, 1513, 1514, 1506, 4633, 4746, 4708, 4743, - 1369, 1371, 1492, 4266, 1493, 1491, 4717, 1772, 2961, 2959, - 1376, 1920, 4724, 1367, 4722, 1774, 1322, 3352, 3348, 4515, - 4736, 4738, 2777, 3681, 1645, 1643, 3357, 2798, 2493, 3554, - 1721, 4737, 4739, 4741, 1718, 1717, 1227, 1226, 4763, 1812, - 1507, 4740, 3131, 3984, 4771, 4050, 51, 3501, 4751, 4745, - 2926, 3074, 4753, 3373, 4754, 4755, 4752, 4487, 2260, 1122, - 2750, 121, 45, 138, 120, 1772, 1505, 1504, 1515, 1516, - 1517, 1518, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1506, - 211, 66, 210, 4784, 65, 4785, 19, 4786, 136, 4787, - 208, 64, 4788, 2090, 50, 49, 206, 115, 114, 113, - 112, 135, 205, 4792, 63, 242, 241, 244, 243, 240, - 3032, 3033, 4803, 239, 4805, 4806, 1819, 238, 2181, 4729, - 2181, 1339, 4801, 4799, 4795, 4306, 4710, 1075, 48, 4616, - 47, 4809, 212, 46, 122, 4810, 67, 4811, 44, 2181, - 2181, 43, 2525, 1998, 3700, 1927, 4543, 4816, 4003, 3255, - 3887, 2734, 42, 3891, 38, 4819, 4821, 13, 4820, 4824, - 12, 4812, 39, 24, 23, 4838, 4828, 4826, 4846, 1901, - 22, 30, 4845, 29, 28, 36, 35, 1815, 4832, 4833, - 4834, 4835, 156, 155, 34, 154, 1339, 153, 1339, 152, - 151, 4850, 150, 149, 148, 33, 21, 58, 57, 4858, - 4856, 56, 4857, 4664, 55, 4863, 54, 4862, 53, 8, - 4869, 3931, 4076, 4873, 3933, 3934, 141, 142, 139, 134, - 132, 3936, 32, 133, 130, 131, 125, 124, 4870, 123, - 2118, 118, 3079, 116, 3082, 4881, 4882, 96, 95, 94, - 109, 108, 107, 106, 105, 104, 4846, 4891, 102, 103, - 4845, 4890, 822, 4417, 93, 4893, 92, 91, 90, 89, - 129, 4873, 4894, 126, 111, 119, 117, 100, 4900, 110, - 101, 99, 98, 4902, 3104, 3105, 97, 88, 87, 86, - 128, 127, 140, 213, 68, 189, 163, 163, 163, 1200, - 188, 187, 185, 184, 186, 182, 183, 181, 765, 180, - 179, 178, 177, 176, 59, 60, 61, 62, 201, 2086, - 200, 202, 214, 204, 207, 203, 2083, 209, 4814, 198, - 2085, 2082, 2084, 2088, 2089, 196, 199, 197, 2087, 195, - 78, 3136, 11, 137, 3139, 20, 17, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 3158, 3159, 0, 0, - 0, 1151, 1151, 1708, 0, 3162, 3163, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1729, 0, - 0, 3168, 3169, 3170, 0, 0, 0, 1743, 0, 0, - 0, 0, 0, 1998, 0, 3510, 0, 0, 0, 0, - 0, 1727, 1728, 0, 1730, 0, 0, 1734, 1780, 1738, - 1739, 1740, 0, 0, 0, 0, 0, 3200, 0, 3202, - 0, 0, 3205, 0, 2004, 2181, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1527, 0, 0, - 0, 4073, 1788, 1789, 0, 1791, 1792, 1793, 1794, 1795, - 0, 1797, 1798, 1799, 1800, 1801, 0, 0, 0, 1807, - 0, 1809, 1810, 1811, 0, 4129, 0, 0, 0, 0, - 0, 4108, 0, 0, 0, 2071, 2072, 2073, 2074, 2075, - 2076, 2077, 2078, 2079, 2080, 2081, 2093, 2094, 2095, 2096, - 2097, 2098, 2091, 2092, 0, 0, 0, 0, 4564, 4565, - 192, 233, 191, 224, 193, 4569, 4570, 4571, 4572, 4573, - 4574, 0, 0, 4120, 4578, 4579, 4580, 4581, 0, 0, - 225, 4583, 4584, 0, 4586, 0, 4111, 217, 0, 0, - 0, 226, 0, 0, 0, 0, 0, 4106, 0, 0, - 0, 0, 4131, 4132, 194, 3615, 0, 0, 4107, 0, - 0, 161, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 147, 0, 0, 0, - 0, 0, 0, 1507, 0, 229, 1145, 0, 1146, 2090, - 0, 0, 0, 0, 4202, 0, 0, 0, 4112, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1628, 1505, - 1504, 1515, 1516, 1517, 1518, 1508, 1509, 1510, 1511, 1512, - 1513, 1514, 1506, 1507, 0, 4644, 1520, 1126, 1524, 0, - 0, 4649, 4650, 0, 0, 0, 0, 0, 0, 0, - 0, 1140, 0, 1136, 1521, 1523, 1519, 0, 1522, 1505, - 1504, 1515, 1516, 1517, 1518, 1508, 1509, 1510, 1511, 1512, - 1513, 1514, 1506, 0, 0, 0, 1507, 4673, 0, 1520, - 0, 1524, 0, 0, 170, 171, 2181, 172, 173, 0, - 2620, 0, 174, 0, 0, 175, 0, 1521, 1523, 1519, - 1724, 1522, 1505, 1504, 1515, 1516, 1517, 1518, 1508, 1509, - 1510, 1511, 1512, 1513, 1514, 1506, 0, 0, 0, 0, - 0, 1116, 0, 0, 0, 4130, 0, 2838, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1783, 0, 0, - 0, 765, 4320, 4321, 0, 0, 0, 0, 0, 0, - 0, 0, 4116, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 190, 222, 231, - 223, 79, 143, 0, 4113, 4117, 4115, 4114, 0, 0, - 163, 0, 0, 0, 0, 0, 0, 0, 3536, 0, - 3538, 145, 216, 215, 4396, 0, 0, 0, 80, 0, - 0, 0, 0, 0, 0, 0, 1142, 0, 1135, 0, - 0, 0, 2495, 0, 0, 2086, 169, 1139, 1138, 0, - 0, 0, 2083, 0, 0, 0, 2085, 2082, 2084, 2088, - 2089, 0, 4123, 4124, 2087, 0, 0, 1507, 1127, 2599, - 0, 0, 0, 144, 0, 0, 0, 4423, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1134, 218, - 219, 220, 0, 1505, 1504, 1515, 1516, 1517, 1518, 1508, - 1509, 1510, 1511, 1512, 1513, 1514, 1506, 1144, 0, 4395, - 0, 0, 1133, 0, 163, 0, 1132, 163, 163, 0, - 3596, 0, 1120, 2214, 2215, 2216, 0, 0, 0, 4133, - 0, 163, 0, 0, 0, 0, 0, 1507, 0, 0, - 0, 1125, 4109, 0, 0, 4122, 0, 3618, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2249, 0, 227, - 2625, 0, 2254, 1505, 1504, 1515, 1516, 1517, 1518, 1508, - 1509, 1510, 1511, 1512, 1513, 1514, 1506, 0, 0, 3646, - 157, 0, 0, 0, 221, 0, 158, 1123, 0, 0, - 2307, 2308, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, - 2080, 2081, 2093, 2094, 2095, 2096, 2097, 2098, 2091, 2092, - 0, 0, 0, 0, 0, 0, 1143, 811, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 159, 0, 0, 0, 0, 0, 0, 1124, - 0, 0, 0, 0, 1371, 71, 0, 0, 0, 0, - 1371, 1371, 1371, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2433, 0, - 0, 4127, 0, 0, 2439, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4392, 0, 2449, 0, 0, 0, - 807, 808, 0, 0, 0, 0, 0, 0, 74, 0, - 2181, 853, 0, 0, 0, 2181, 1527, 0, 0, 0, - 3784, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3793, 1141, 0, 3794, 0, 0, 3796, 0, 0, 4596, - 0, 0, 0, 0, 167, 230, 168, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, - 0, 0, 2504, 4121, 0, 0, 0, 0, 0, 0, - 4126, 1130, 0, 0, 0, 0, 0, 0, 4128, 0, - 1119, 1369, 0, 3830, 2522, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4397, 4398, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 855, 0, 0, 854, - 0, 4393, 4394, 0, 4401, 4400, 4399, 4412, 4413, 4414, - 4402, 4403, 4406, 4408, 4407, 4404, 4405, 4409, 4410, 4411, - 0, 0, 0, 0, 4415, 811, 0, 0, 0, 0, - 0, 160, 52, 0, 0, 4416, 0, 0, 70, 0, - 0, 0, 9, 0, 0, 0, 0, 0, 839, 0, - 0, 0, 0, 0, 3864, 0, 0, 0, 812, 0, - 0, 0, 0, 163, 0, 0, 0, 0, 0, 164, - 165, 0, 0, 166, 0, 0, 0, 0, 0, 1117, - 0, 2300, 0, 1115, 1118, 814, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 807, 808, - 0, 0, 0, 1724, 0, 0, 0, 0, 0, 853, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 879, 878, - 885, 875, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 882, 883, 0, 884, 888, 0, 0, 869, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 893, 0, - 0, 0, 835, 0, 837, 834, 0, 0, 0, 838, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 163, 0, 0, 163, 163, 3946, 163, 0, 0, - 0, 0, 0, 0, 3948, 3949, 0, 0, 0, 0, - 0, 0, 0, 0, 855, 897, 0, 854, 899, 833, - 0, 0, 0, 898, 0, 0, 0, 0, 0, 0, - 0, 806, 0, 0, 3958, 0, 3960, 0, 0, 0, - 0, 163, 813, 848, 0, 3970, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 163, 0, 0, 0, 844, 0, 839, 0, 0, 0, - 0, 0, 0, 2716, 0, 2718, 812, 0, 0, 0, - 0, 0, 0, 0, 0, 3864, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2739, 2740, 2741, - 845, 849, 800, 814, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2758, 2759, 2760, 2761, 0, 0, 0, - 0, 830, 0, 828, 832, 852, 0, 0, 0, 829, - 826, 825, 0, 831, 816, 817, 815, 0, 805, 818, - 819, 820, 821, 801, 0, 0, 850, 0, 851, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 846, - 847, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 835, 0, 837, 834, 870, 872, 871, 838, 0, 0, - 0, 0, 0, 0, 0, 0, 877, 842, 0, 0, - 0, 0, 0, 841, 0, 1527, 0, 0, 881, 0, - 0, 802, 0, 0, 0, 896, 879, 878, 885, 875, - 836, 0, 874, 0, 0, 0, 864, 833, 0, 882, - 883, 0, 884, 888, 0, 0, 869, 0, 0, 806, - 0, 0, 0, 0, 0, 0, 893, 0, 1743, 0, - 813, 848, 0, 0, 0, 0, 2181, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 844, 2181, 0, 0, 0, 0, 0, 0, - 0, 0, 4181, 0, 1780, 0, 0, 0, 0, 0, - 0, 0, 0, 897, 0, 0, 899, 0, 0, 0, - 0, 898, 1371, 0, 0, 0, 0, 0, 845, 849, - 0, 0, 0, 0, 840, 0, 0, 0, 0, 0, - 809, 810, 0, 0, 799, 803, 0, 0, 0, 830, - 0, 828, 832, 852, 0, 0, 804, 829, 826, 825, - 0, 831, 816, 817, 815, 0, 805, 818, 819, 820, - 821, 801, 0, 0, 850, 0, 851, 0, 0, 0, - 0, 0, 0, 0, 0, 3067, 0, 846, 847, 0, - 0, 876, 880, 886, 0, 887, 889, 0, 0, 890, - 891, 892, 0, 0, 0, 894, 895, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2358, 842, 0, 0, 0, 2319, - 0, 841, 2366, 0, 0, 0, 0, 0, 0, 802, - 0, 0, 0, 0, 0, 0, 0, 0, 836, 0, - 0, 0, 0, 0, 0, 1200, 0, 0, 163, 163, - 0, 0, 2360, 2328, 0, 1724, 1724, 1724, 1724, 1724, - 1724, 1724, 4319, 2361, 2362, 0, 0, 0, 0, 0, - 0, 0, 870, 872, 871, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 877, 0, 0, 0, 0, 2327, - 0, 0, 0, 0, 0, 0, 881, 0, 0, 0, - 0, 0, 0, 896, 0, 0, 0, 2335, 0, 0, - 874, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 840, 0, 0, 0, 0, 0, 809, 810, - 0, 0, 799, 803, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 804, 0, 873, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2351, 0, 0, - 0, 0, 0, 3237, 3238, 3239, 0, 0, 0, 0, - 0, 0, 0, 0, 900, 901, 902, 903, 904, 0, - 879, 878, 885, 875, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 882, 883, 0, 884, 888, 0, 0, - 869, 0, 0, 0, 0, 1724, 0, 0, 0, 0, - 893, 0, 0, 163, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3340, 0, 876, - 880, 886, 0, 887, 889, 0, 0, 890, 891, 892, - 2318, 2320, 2317, 894, 895, 0, 2314, 0, 1200, 0, - 0, 2339, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2345, 0, 0, 0, 2358, 0, 0, 0, - 2330, 2319, 2313, 0, 2366, 0, 0, 0, 0, 0, - 0, 0, 2333, 2367, 0, 0, 2334, 2336, 2338, 0, - 2340, 2341, 2342, 2346, 2347, 2348, 2350, 2353, 2354, 2355, - 0, 0, 0, 0, 2360, 2328, 0, 2343, 2352, 2344, - 0, 0, 0, 0, 0, 2361, 2362, 0, 0, 2322, - 0, 0, 0, 0, 0, 0, 0, 0, 4554, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2327, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2335, - 0, 2359, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3521, - 0, 0, 0, 0, 873, 0, 0, 2315, 2316, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1548, 0, 0, 0, 2356, 870, 872, 871, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 877, 2351, - 0, 0, 0, 2332, 0, 0, 0, 2331, 0, 0, - 881, 0, 900, 901, 902, 903, 904, 896, 0, 0, - 0, 0, 0, 0, 874, 0, 0, 0, 0, 0, - 0, 2349, 0, 0, 0, 0, 0, 0, 0, 0, - 2337, 0, 0, 0, 0, 0, 0, 0, 0, 4657, - 0, 0, 0, 0, 2364, 2363, 0, 0, 0, 0, - 2358, 0, 0, 0, 0, 0, 0, 163, 192, 233, - 0, 0, 4671, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2318, 3381, 2317, 0, 0, 0, 3380, 0, - 163, 0, 4299, 2339, 0, 0, 0, 0, 2360, 0, - 0, 0, 0, 0, 2345, 0, 0, 0, 0, 0, - 0, 2324, 0, 0, 0, 0, 0, 0, 0, 2358, - 0, 1724, 0, 0, 2333, 2367, 0, 0, 2334, 2336, - 2338, 0, 2340, 2341, 2342, 2346, 2347, 2348, 2350, 2353, - 2354, 2355, 0, 229, 0, 0, 0, 0, 0, 2343, - 2352, 2344, 0, 2335, 0, 0, 0, 2360, 0, 2365, - 0, 2322, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 876, 880, 886, 0, 887, 889, 0, - 0, 890, 891, 892, 0, 0, 0, 894, 895, 0, - 0, 0, 4768, 0, 0, 0, 0, 0, 4772, 0, - 0, 0, 4542, 2359, 0, 0, 0, 0, 0, 0, - 0, 0, 2335, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2358, 0, 0, 0, - 0, 0, 0, 2351, 0, 0, 0, 0, 3679, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2315, - 2316, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2360, 0, 0, 2356, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2332, 0, 0, 4768, 2331, - 0, 0, 2351, 0, 0, 3746, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2349, 0, 0, 3760, 0, 3761, 2335, - 0, 0, 2337, 0, 0, 0, 0, 2339, 0, 0, - 0, 0, 0, 0, 0, 0, 2364, 2363, 2345, 0, - 163, 0, 0, 0, 0, 163, 4768, 0, 873, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2333, 2367, - 0, 0, 2334, 2336, 2338, 0, 2340, 2341, 2342, 2346, - 2347, 2348, 2350, 2353, 2354, 2355, 0, 0, 0, 0, - 0, 0, 0, 2343, 2352, 2344, 2339, 0, 0, 0, - 0, 0, 0, 2324, 0, 4507, 0, 2345, 0, 2351, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 4896, 0, 0, 0, 0, 2333, 2367, 0, - 0, 2334, 2336, 2338, 0, 2340, 2341, 2342, 2346, 2347, - 2348, 2350, 2353, 2354, 2355, 0, 0, 2359, 0, 0, - 0, 2365, 2343, 2352, 2344, 0, 0, 0, 0, 2358, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1371, 0, - 0, 0, 0, 0, 0, 0, 0, 2360, 0, 0, - 0, 0, 0, 2339, 0, 0, 2359, 0, 0, 0, - 0, 2356, 0, 0, 2345, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2332, - 0, 0, 0, 2331, 2333, 2367, 0, 0, 2334, 2336, - 2338, 0, 2340, 2341, 2342, 2346, 2347, 2348, 2350, 2353, - 2354, 2355, 2335, 0, 0, 0, 0, 2349, 0, 2343, - 2352, 2344, 0, 0, 0, 0, 2337, 0, 0, 0, - 2356, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2332, 0, - 0, 0, 2331, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3940, 0, 0, 0, 0, 0, - 0, 0, 0, 2359, 0, 0, 2349, 0, 0, 0, - 0, 0, 0, 0, 0, 2337, 0, 0, 0, 1200, - 0, 163, 2351, 0, 0, 0, 0, 0, 0, 0, - 163, 0, 0, 0, 0, 0, 0, 163, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1724, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2356, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2332, 0, 163, 0, 2331, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2349, 0, 0, 2339, 0, 0, 0, - 0, 0, 2337, 0, 0, 0, 0, 2345, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1371, 0, 0, 0, 0, 2333, 2367, 0, - 0, 2334, 2336, 2338, 0, 2340, 2341, 2342, 2346, 2347, - 2348, 2350, 2353, 2354, 2355, 0, 0, 0, 0, 0, - 0, 0, 2343, 2352, 2344, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3866, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 949, 925, 1881, 4932, 951, 4903, 2795, 3420, 4924, 2341, + 254, 4833, 4827, 4837, 3540, 2015, 4138, 4826, 4246, 4838, + 4599, 3849, 1880, 3886, 4201, 4725, 2981, 934, 4670, 3721, + 4780, 4487, 3953, 4427, 4169, 927, 3279, 3414, 4572, 4531, + 3723, 4661, 4241, 2081, 3954, 1579, 4583, 4598, 4698, 4064, + 4339, 980, 1786, 746, 3275, 1429, 1964, 3951, 3417, 4377, + 4561, 4255, 4072, 41, 853, 1343, 241, 5, 1435, 4671, + 4673, 766, 3577, 4078, 2068, 4354, 3858, 4366, 2862, 3205, + 4121, 781, 791, 801, 4349, 1400, 801, 3371, 4154, 4320, + 3277, 4024, 3344, 3777, 3752, 2018, 4100, 164, 3082, 2292, + 3541, 2435, 1383, 3794, 2065, 4062, 2791, 3781, 3509, 2320, + 1348, 878, 3878, 3443, 3539, 3860, 3867, 3404, 4102, 3125, + 3536, 2313, 3398, 3287, 3905, 239, 3402, 4016, 2087, 3396, + 2064, 2478, 2590, 2519, 3935, 2989, 3757, 3742, 3315, 3753, + 3759, 2799, 3755, 3806, 3089, 797, 3866, 873, 1969, 3754, + 869, 2797, 2811, 1889, 3750, 2724, 2197, 40, 2792, 2432, + 3330, 3124, 917, 3527, 2723, 918, 3703, 2515, 2083, 1214, + 73, 2622, 1864, 3063, 1885, 1869, 2483, 1123, 1873, 73, + 1686, 2428, 2585, 3303, 922, 3297, 1857, 2314, 2586, 2863, + 2957, 3425, 1199, 3348, 2331, 781, 1166, 2321, 1868, 2841, + 3445, 3375, 2810, 250, 7, 2779, 2261, 249, 6, 4, + 2987, 2010, 1726, 2082, 1271, 2618, 2587, 2801, 1892, 926, + 2798, 2512, 1438, 1795, 1758, 2770, 2298, 2282, 1764, 1830, + 746, 2014, 2075, 2858, 1779, 2322, 916, 2726, 2051, 1381, + 2001, 1364, 2773, 1968, 25, 745, 1731, 935, 2500, 1837, + 1439, 798, 866, 2009, 254, 1386, 254, 2256, 1261, 1262, + 15, 1198, 2865, 1165, 2260, 781, 1763, 765, 1760, 31, + 918, 1086, 782, 1820, 1430, 2088, 1719, 2958, 1414, 875, + 26, 876, 240, 1241, 1142, 27, 18, 1418, 16, 10, + 800, 232, 236, 1148, 1205, 1163, 1637, 1580, 872, 837, + 1088, 2566, 4683, 4557, 1089, 5, 3247, 3247, 3247, 148, + 37, 76, 75, 72, 2324, 1506, 1158, 1507, 1505, 924, + 1506, 1258, 1507, 1505, 1506, 4119, 1507, 1505, 2221, 3972, + 3827, 1211, 3713, 3712, 3595, 3594, 2602, 1349, 4301, 4081, + 1350, 3946, 795, 3155, 3069, 3067, 1662, 3064, 1663, 3066, + 2210, 796, 1844, 1254, 238, 767, 1840, 1253, 2722, 1656, + 1762, 4647, 1661, 1620, 1395, 773, 1396, 1397, 1398, 1893, + 792, 4098, 4098, 2526, 3977, 2555, 805, 2556, 4704, 1257, + 1289, 1259, 2551, 768, 1806, 769, 770, 771, 1741, 1690, + 2982, 1213, 793, 1254, 2527, 4285, 1254, 1394, 1110, 1349, + 1107, 3714, 3710, 2737, 2729, 2217, 1665, 3690, 73, 14, + 3692, 3687, 3689, 4915, 1455, 9, 2204, 2718, 1652, 4239, + 3573, 3696, 3694, 73, 3571, 73, 2488, 785, 4835, 4834, + 4420, 1184, 1842, 1506, 3960, 1507, 1505, 1506, 4656, 1507, + 1505, 4495, 7, 4488, 4242, 3952, 6, 2511, 1252, 1574, + 4675, 1898, 2794, 1087, 923, 3087, 3659, 3204, 3740, 2507, + 2937, 2544, 1404, 907, 4290, 3698, 909, 2903, 4938, 4669, + 4912, 908, 4503, 1943, 4667, 4543, 4501, 4053, 4288, 1289, + 3182, 2744, 1098, 4738, 1387, 1803, 1111, 1671, 1669, 1668, + 4048, 794, 3743, 2760, 1108, 1215, 871, 2391, 1077, 3657, + 1076, 1078, 1079, 2600, 1080, 1081, 2123, 1715, 2230, 3534, + 2066, 2067, 2774, 2978, 1105, 1307, 1308, 1274, 1451, 4545, + 2228, 1452, 1503, 2965, 2445, 919, 2964, 1678, 2979, 2966, + 3546, 3547, 3545, 1209, 2412, 2413, 1697, 1210, 1297, 1301, + 1303, 1305, 1310, 2411, 1315, 1311, 1312, 1313, 1314, 2235, + 2236, 1292, 1293, 1294, 1295, 1272, 1273, 1298, 1391, 1275, + 1695, 1277, 1278, 1279, 1280, 1276, 1281, 1282, 1283, 1284, + 1285, 1288, 1290, 1286, 1287, 1316, 1317, 1318, 1319, 1320, + 1321, 1322, 1323, 1325, 1324, 1326, 1327, 1328, 1329, 1330, + 1331, 1332, 1333, 1300, 1302, 1304, 1306, 1309, 1896, 1099, + 1961, 1177, 1175, 1392, 1176, 1393, 1765, 2943, 1767, 2942, + 1436, 1437, 1426, 3691, 1307, 1308, 1274, 3688, 3720, 1895, + 1263, 3083, 1454, 1111, 862, 1108, 1940, 2017, 2831, 3274, + 2307, 2308, 1180, 1983, 1291, 4841, 4842, 1297, 1301, 1303, + 1305, 1310, 1501, 1315, 1311, 1312, 1313, 1314, 1748, 1496, + 1292, 1293, 1294, 1295, 1272, 1273, 1298, 2423, 1275, 3270, + 1277, 1278, 1279, 1280, 1276, 1281, 1282, 1283, 1284, 1285, + 1288, 1290, 1286, 1287, 1316, 1317, 1318, 1319, 1320, 1321, + 1322, 1323, 1325, 1324, 1326, 1327, 1328, 1329, 1330, 1331, + 1332, 1333, 1300, 1302, 1304, 1306, 1309, 3699, 907, 1843, + 1841, 909, 3853, 3299, 3272, 1185, 908, 1696, 1208, 1207, + 4678, 4794, 2002, 3300, 907, 2006, 3851, 909, 4678, 2895, + 4273, 4677, 908, 4677, 4793, 195, 237, 194, 228, 196, + 4676, 1434, 2699, 1291, 3267, 1433, 1436, 1437, 4659, 2005, + 4867, 4676, 4792, 4806, 1109, 3955, 1106, 4907, 4908, 4782, + 1959, 1181, 195, 237, 194, 228, 196, 3578, 1483, 4782, + 3579, 1484, 3580, 3298, 4785, 4491, 1102, 195, 237, 194, + 228, 196, 3955, 1367, 1370, 1938, 781, 1255, 1256, 3271, + 3114, 781, 1260, 1352, 195, 237, 194, 228, 196, 1486, + 1807, 1742, 4362, 195, 237, 194, 228, 196, 1691, 2601, + 233, 1353, 2231, 801, 801, 1378, 2021, 781, 781, 3268, + 3583, 4292, 1453, 1183, 2229, 1476, 4694, 2604, 1478, 1751, + 2443, 2444, 4662, 4663, 4664, 4665, 2429, 233, 4840, 3981, + 2021, 1033, 2419, 1919, 1359, 4063, 3464, 2596, 3773, 1424, + 3306, 1103, 233, 1997, 1371, 4070, 1479, 3697, 3528, 1264, + 797, 797, 797, 4547, 4548, 3771, 4511, 1655, 4512, 233, + 1904, 3620, 2007, 2952, 1698, 4331, 2945, 1154, 233, 2768, + 195, 237, 4184, 778, 2220, 195, 237, 194, 228, 196, + 3284, 1499, 1500, 4808, 4682, 4556, 2004, 1211, 3984, 3624, + 3246, 225, 1432, 3962, 1960, 1182, 4272, 3618, 4289, 1494, + 1495, 1498, 3147, 1403, 4274, 2901, 1471, 1350, 1481, 3768, + 3769, 1412, 1350, 4240, 3572, 3522, 1104, 2947, 1422, 1350, + 4553, 163, 2528, 3273, 4514, 3770, 1441, 1442, 4328, 1444, + 1445, 1543, 4286, 1447, 1549, 2389, 2948, 2949, 3778, 1938, + 3779, 3249, 1356, 3767, 1179, 233, 2936, 1213, 2939, 2955, + 233, 1351, 1493, 3269, 4513, 3596, 798, 798, 798, 2938, + 3593, 2020, 2019, 1299, 2627, 1472, 764, 2565, 1254, 4200, + 1482, 1254, 1254, 1254, 3855, 4626, 1446, 1362, 2026, 2029, + 2030, 1350, 1352, 1254, 1254, 2020, 2019, 4196, 4065, 2027, + 1825, 1474, 1670, 4511, 1667, 4512, 4686, 2603, 4534, 193, + 226, 235, 227, 4357, 1477, 1480, 2003, 1369, 1368, 1449, + 1450, 4506, 4302, 4087, 4502, 4482, 4546, 1583, 1463, 3939, + 3792, 3065, 3302, 1930, 4589, 1845, 1211, 1473, 3807, 4718, + 2607, 2609, 2610, 4710, 3882, 1372, 3883, 3885, 3884, 4030, + 4576, 3349, 910, 911, 912, 913, 914, 795, 795, 795, + 4028, 1087, 1485, 1112, 1178, 803, 796, 796, 796, 1173, + 1101, 4514, 1299, 1388, 3532, 1663, 1174, 1677, 3695, 802, + 4291, 1342, 3765, 2390, 1341, 792, 792, 792, 1210, 1415, + 1419, 1419, 1419, 1663, 2309, 4699, 1213, 2776, 3779, 2881, + 773, 4513, 1345, 1376, 1377, 2861, 2884, 793, 793, 793, + 1269, 1425, 1658, 1660, 2781, 1664, 1415, 1415, 768, 1475, + 769, 770, 771, 4720, 2422, 4294, 4295, 4296, 1420, 1421, + 4189, 1682, 1367, 1370, 3704, 1685, 4139, 1939, 4726, 3850, + 3415, 3416, 1694, 3419, 1456, 1457, 1897, 3888, 3419, 1440, + 3880, 3881, 1443, 1436, 1437, 4146, 3879, 1413, 1673, 1460, + 1584, 1635, 4042, 2883, 1640, 2913, 4540, 1436, 1437, 2755, + 781, 781, 781, 1488, 4310, 1166, 1489, 4039, 3733, 1462, + 2868, 2935, 4205, 1740, 4693, 4415, 4946, 2912, 781, 1938, + 1747, 3343, 4258, 1753, 1550, 3779, 1374, 781, 1675, 2933, + 2934, 746, 746, 1371, 1491, 3312, 794, 794, 794, 1269, + 1954, 746, 746, 1775, 1774, 1790, 1790, 1461, 781, 4590, + 1428, 1427, 1361, 3774, 1355, 1357, 1360, 799, 3305, 2882, + 4041, 4807, 3529, 1411, 2430, 4577, 4404, 4507, 1410, 4549, + 1409, 4672, 801, 1821, 766, 4727, 1156, 3621, 1157, 4825, + 1833, 2951, 4562, 3859, 1890, 3681, 3856, 3242, 2904, 1545, + 1546, 1547, 1548, 4410, 1358, 254, 1720, 4927, 1792, 799, + 4103, 1788, 1788, 4603, 746, 863, 2861, 1702, 2028, 2154, + 2156, 2155, 4237, 3309, 3310, 1797, 799, 910, 911, 912, + 913, 914, 1406, 74, 3465, 799, 3466, 3467, 3308, 2420, + 1595, 1596, 1749, 910, 911, 912, 913, 914, 4332, 2878, + 1998, 1687, 2596, 1540, 1539, 871, 4109, 1688, 1689, 4779, + 74, 1692, 3788, 1487, 1761, 1701, 1703, 1704, 1705, 1706, + 2608, 1708, 2843, 2845, 3766, 74, 4025, 1714, 3880, 3881, + 1468, 1752, 3909, 2867, 3875, 1877, 3555, 3556, 2869, 3256, + 1882, 3143, 74, 2970, 2941, 2899, 1931, 234, 1932, 2727, + 1894, 74, 2153, 1492, 3887, 2593, 1369, 1368, 2418, 2406, + 865, 1684, 1666, 864, 4507, 4215, 1117, 799, 4508, 2871, + 1707, 3924, 2213, 3911, 1917, 1490, 3623, 1713, 1712, 1711, + 1920, 1710, 1641, 1769, 1771, 1639, 1186, 807, 806, 1941, + 4056, 1672, 2870, 1782, 1783, 4428, 4429, 4430, 4434, 4432, + 4433, 4435, 4436, 4437, 4431, 3516, 3345, 1884, 1730, 1790, + 776, 4928, 777, 2868, 2871, 1753, 2395, 2393, 4602, 3876, + 791, 2394, 797, 4418, 73, 797, 797, 1700, 3462, 1121, + 1467, 2619, 3971, 74, 1119, 1118, 4017, 1784, 1785, 1929, + 1982, 2605, 2606, 4824, 2780, 1942, 1508, 1753, 1871, 1167, + 1699, 3112, 1991, 1991, 1542, 1753, 1846, 1753, 1753, 1855, + 1725, 1858, 1859, 1552, 3789, 1729, 1866, 1867, 1790, 1852, + 1790, 1352, 2756, 1860, 1861, 1773, 1721, 1722, 1946, 1949, + 1950, 1953, 1169, 1170, 1171, 195, 237, 2238, 1872, 1562, + 3342, 1876, 3264, 1875, 1674, 1676, 1966, 1967, 863, 1117, + 2748, 1822, 1681, 1798, 4406, 2239, 773, 1124, 4405, 3338, + 1813, 4032, 1986, 1976, 1977, 4411, 4412, 1155, 2844, 195, + 237, 1120, 1819, 2747, 1834, 1687, 2872, 2212, 798, 2750, + 2749, 798, 798, 2218, 1988, 863, 2877, 1835, 2237, 2522, + 2875, 1790, 2925, 3970, 1113, 798, 3319, 3325, 3326, 3327, + 3320, 3324, 3321, 3323, 3322, 4925, 4926, 1114, 1352, 2085, + 3336, 4367, 1116, 1870, 1543, 4110, 2960, 1119, 1118, 1405, + 2518, 2872, 2126, 2127, 2128, 2136, 2867, 2861, 2866, 3826, + 2864, 2869, 2898, 1679, 1680, 2142, 2117, 2118, 2143, 2772, + 2122, 3257, 2856, 865, 2520, 1987, 864, 2069, 2137, 1934, + 4948, 1902, 3369, 1994, 1905, 3931, 2477, 2162, 2163, 4481, + 3339, 2144, 2592, 2146, 1405, 2147, 2148, 2149, 1887, 795, + 3484, 3485, 795, 795, 2214, 4789, 3930, 1405, 796, 1504, + 865, 796, 796, 864, 1993, 2870, 1924, 2194, 2592, 2016, + 1962, 1970, 3352, 1972, 1973, 1928, 3493, 792, 3877, 4963, + 792, 792, 195, 237, 1352, 1938, 1927, 1979, 2013, 1211, + 1415, 1922, 1926, 4959, 1925, 1921, 2222, 3370, 2000, 793, + 2225, 3926, 793, 793, 1419, 781, 781, 781, 1187, 1468, + 1091, 1092, 1093, 1094, 2240, 2242, 1419, 2243, 1965, 2245, + 2246, 2195, 1971, 2249, 2120, 2031, 766, 1821, 1999, 2011, + 1995, 1996, 2257, 3966, 1790, 2263, 2264, 2837, 2266, 1753, + 781, 1975, 1344, 2714, 2663, 781, 1914, 2662, 1790, 1213, + 2771, 1956, 1957, 1980, 2837, 1166, 2135, 233, 2293, 1990, + 1992, 3290, 1911, 1912, 1504, 4952, 2316, 2316, 1740, 2316, + 2198, 4940, 2325, 2326, 781, 781, 2008, 2388, 1504, 4934, + 2012, 2257, 2399, 2959, 4921, 1790, 2403, 2404, 3370, 4059, + 3483, 1740, 2475, 746, 1801, 1832, 3291, 3292, 794, 3931, + 1504, 794, 794, 1468, 4882, 1115, 2523, 746, 1465, 1790, + 2592, 2053, 3931, 2284, 4013, 1923, 1903, 1466, 3983, 1906, + 1907, 2302, 2306, 2307, 2308, 2303, 2312, 2304, 2310, 3142, + 3142, 2305, 1504, 2311, 4853, 2450, 2452, 3892, 3890, 781, + 2257, 1790, 4850, 2459, 2201, 781, 781, 781, 869, 869, + 3355, 2343, 2206, 3844, 1468, 2469, 2598, 2471, 2472, 2473, + 3341, 4849, 2636, 2479, 4935, 1211, 1916, 4843, 3841, 4883, + 254, 1205, 3746, 254, 254, 1915, 254, 1096, 4821, 4327, + 3702, 2049, 2050, 2446, 2265, 2060, 2061, 2267, 2318, 4883, + 2323, 1344, 1506, 1955, 1507, 1505, 2397, 1466, 3357, 3684, + 2408, 2247, 2248, 2150, 2151, 2837, 1504, 1401, 2253, 2254, + 2255, 1402, 3558, 3243, 1506, 1974, 1507, 1505, 3088, 4854, + 2591, 2269, 2270, 2271, 2272, 1213, 1506, 4851, 1507, 1505, + 2534, 1981, 2410, 2854, 1984, 1985, 4772, 2721, 2196, 2523, + 4771, 2455, 3122, 4069, 2713, 2202, 2598, 2461, 2462, 2463, + 2635, 2712, 2637, 2424, 3494, 3496, 3497, 3498, 3495, 4748, + 2672, 1958, 2671, 4822, 2574, 2262, 781, 2293, 2670, 781, + 2510, 2591, 3654, 2540, 2438, 2439, 2548, 2441, 2550, 2278, + 2405, 1122, 2554, 2521, 3685, 2409, 2497, 1978, 4721, 2458, + 2559, 2560, 2561, 2251, 2564, 2487, 1753, 2431, 2490, 2491, + 2252, 2493, 797, 2036, 2037, 2038, 2039, 2040, 2041, 2042, + 2043, 2044, 2045, 2046, 2047, 2048, 2402, 1506, 2290, 1507, + 1505, 1504, 2062, 2063, 1753, 1504, 2407, 2294, 2288, 2289, + 4706, 1790, 2589, 4618, 2415, 2529, 2417, 1724, 2396, 73, + 2072, 4617, 73, 73, 2637, 73, 2086, 2436, 2437, 2401, + 2211, 2121, 2215, 2868, 2871, 1636, 1506, 2219, 1507, 1505, + 2022, 2023, 2024, 2025, 1935, 2414, 2542, 2416, 2425, 1776, + 4957, 4936, 2011, 2598, 2145, 3653, 2504, 3682, 4645, 2302, + 2306, 2307, 2308, 2303, 2312, 2304, 2310, 2612, 4476, 2305, + 2449, 2311, 2707, 3373, 2457, 2575, 2558, 2456, 4119, 4616, + 2464, 2465, 3563, 3372, 1506, 2073, 1507, 1505, 798, 2077, + 2078, 2079, 2080, 4615, 2573, 4707, 2484, 1542, 2637, 1506, + 2119, 1507, 1505, 3252, 4593, 2578, 2637, 4592, 4559, 2130, + 4528, 2580, 3145, 2582, 4525, 3144, 3113, 2157, 2158, 2159, + 2160, 4381, 2502, 2164, 2165, 2166, 2167, 2169, 2170, 2171, + 2172, 2173, 2174, 2175, 2176, 2177, 2178, 2179, 2180, 2181, + 2658, 4380, 3683, 2302, 2306, 2307, 2308, 2303, 2312, 2304, + 2310, 4312, 2583, 2305, 2641, 2311, 4474, 2708, 2295, 2536, + 4311, 2538, 1211, 2186, 2637, 2188, 2189, 2190, 2191, 2192, + 2673, 2674, 2581, 2676, 2199, 2705, 2539, 4210, 2637, 795, + 2683, 1091, 1092, 1093, 1094, 2541, 4148, 2482, 796, 2598, + 2293, 2872, 2598, 2637, 4133, 1504, 2867, 2861, 2866, 2808, + 2864, 2869, 1506, 2467, 1507, 1505, 4382, 792, 2570, 4130, + 4089, 2216, 1899, 2576, 4008, 4004, 2577, 3900, 1506, 2567, + 1507, 1505, 1213, 2728, 1558, 2730, 2808, 2732, 2733, 793, + 1506, 2736, 1507, 1505, 3643, 1506, 3844, 1507, 1505, 781, + 1753, 781, 1753, 1373, 3591, 3841, 1339, 1419, 1334, 2625, + 2584, 2496, 2751, 4208, 3588, 2870, 2440, 2309, 2757, 2758, + 2706, 917, 1938, 3831, 781, 781, 781, 2595, 3361, 3359, + 2769, 4149, 2698, 2700, 2701, 2702, 3225, 2704, 3615, 3844, + 781, 781, 781, 781, 2579, 3354, 4949, 2620, 2711, 2695, + 2611, 3223, 2639, 2633, 3841, 4090, 2136, 2136, 2803, 4009, + 4005, 4911, 3901, 2896, 2613, 2812, 1740, 1740, 1740, 1740, + 1740, 1740, 1740, 2053, 3211, 2199, 1521, 2629, 3808, 1504, + 2199, 2199, 3203, 3157, 3117, 3079, 2316, 3077, 794, 3360, + 3075, 2302, 2306, 2307, 2308, 2303, 2312, 2304, 2310, 3355, + 3073, 2305, 2838, 2311, 2807, 2715, 2537, 2679, 1096, 4684, + 2678, 2890, 4640, 3362, 3360, 1520, 2661, 2846, 2652, 2651, + 3178, 3179, 2284, 2284, 1850, 1849, 3944, 3172, 4262, 2650, + 3355, 2638, 2597, 1908, 2486, 4711, 2808, 2489, 2624, 2623, + 2492, 1540, 1539, 2494, 1778, 4578, 2614, 2615, 2741, 1416, + 2743, 2125, 2124, 1211, 1315, 1311, 1312, 1313, 1314, 1504, + 3809, 3177, 1401, 3176, 3175, 3173, 1402, 1504, 1504, 2808, + 3080, 4558, 3078, 2125, 2124, 3074, 781, 1991, 2897, 2549, + 1780, 4712, 2552, 2553, 2516, 3074, 2557, 2837, 4368, 2808, + 2714, 1781, 1504, 4499, 2716, 1504, 4446, 746, 746, 2568, + 2569, 1504, 4408, 1504, 1504, 1352, 3810, 4407, 2800, 2571, + 2572, 1790, 781, 1213, 1504, 1448, 2637, 2598, 1909, 4391, + 4106, 4335, 1941, 2731, 2983, 2984, 1521, 2735, 1401, 1951, + 3606, 781, 1402, 4113, 4369, 4080, 4579, 1352, 3046, 766, + 1583, 1947, 1521, 3932, 3174, 3164, 1833, 2860, 1740, 1777, + 3922, 3054, 4104, 3056, 2859, 4261, 254, 2761, 1522, 1523, + 1524, 1525, 1526, 1527, 1528, 1520, 4107, 2976, 2168, 3064, + 3050, 1417, 3914, 2836, 2940, 2309, 1524, 1525, 1526, 1527, + 1528, 1520, 4580, 2616, 2617, 3902, 2804, 2805, 2059, 3846, + 2161, 2136, 3843, 2136, 781, 3098, 2835, 3093, 4105, 3783, + 3525, 2813, 3109, 3524, 2056, 2058, 2055, 2832, 2057, 3363, + 3115, 2853, 3358, 2814, 2815, 2816, 2817, 2818, 2819, 1401, + 3317, 3248, 3120, 1402, 3154, 2972, 3123, 3126, 2734, 2532, + 2531, 2530, 3128, 2986, 1717, 1506, 1790, 1507, 1505, 2873, + 2874, 2991, 2879, 1716, 1354, 2967, 3947, 2968, 3058, 1401, + 2485, 1952, 3139, 1402, 2076, 2589, 2630, 3053, 1838, 2309, + 2485, 1401, 1790, 1948, 1790, 1402, 2973, 2974, 2626, 1352, + 4819, 4715, 2631, 1584, 3722, 3725, 1506, 3156, 1507, 1505, + 2640, 3059, 4122, 1249, 1250, 1251, 3282, 3068, 1211, 1769, + 1771, 1506, 3130, 1507, 1505, 3092, 2076, 2950, 2244, 4122, + 2956, 3725, 3564, 1507, 1505, 2992, 3119, 1790, 1352, 2962, + 3121, 4791, 3185, 4584, 2961, 3186, 4527, 4526, 1248, 2649, + 1505, 1245, 1521, 3131, 4423, 73, 4422, 2656, 1506, 3194, + 1507, 1505, 3136, 3137, 1790, 2977, 3811, 3945, 2980, 4858, + 1506, 3454, 1507, 1505, 2800, 4945, 3452, 3431, 1213, 3166, + 1506, 3429, 1507, 1505, 3722, 2675, 4397, 3086, 1838, 3180, + 2680, 2681, 2682, 1788, 3140, 2685, 2686, 2687, 2688, 2689, + 2690, 2691, 2692, 2693, 2694, 3052, 2696, 2697, 3724, 952, + 962, 3129, 4820, 3193, 3645, 1506, 3195, 1507, 1505, 953, + 1788, 954, 958, 961, 957, 955, 956, 2654, 4763, 4764, + 3250, 1560, 3084, 4620, 4621, 3254, 3047, 4816, 3258, 3200, + 3201, 4944, 3097, 3095, 1559, 781, 781, 781, 3107, 1511, + 1512, 1513, 1514, 1515, 1516, 1517, 1509, 4336, 4337, 4329, + 3116, 4067, 4766, 3167, 1352, 3169, 4765, 3151, 3153, 4762, + 4761, 1506, 1790, 1507, 1505, 1753, 3148, 2309, 3644, 3630, + 3060, 1753, 2399, 3227, 3183, 3228, 959, 3230, 4760, 3232, + 3233, 1506, 3505, 1507, 1505, 3235, 3503, 3236, 2653, 3316, + 1839, 3141, 3138, 3146, 4759, 1506, 3162, 1507, 1505, 3365, + 3368, 1506, 4885, 1507, 1505, 4757, 3239, 960, 3090, 3091, + 4330, 2645, 4068, 2011, 4756, 1506, 4755, 1507, 1505, 2140, + 3158, 3159, 1242, 1243, 1244, 1247, 4830, 1246, 1740, 1506, + 4754, 1507, 1505, 3501, 2141, 4753, 2634, 3337, 3400, 3406, + 3171, 3181, 3101, 3504, 2632, 3331, 4752, 3502, 1506, 1352, + 1507, 1505, 3100, 1506, 4750, 1507, 1505, 3428, 2991, 4749, + 4713, 3276, 4735, 5, 1352, 1352, 1352, 1991, 4606, 4519, + 1352, 4596, 3438, 3439, 3440, 3441, 1352, 3448, 4581, 3449, + 3450, 3240, 3451, 3350, 3453, 1506, 3334, 1507, 1505, 1506, + 4552, 1507, 1505, 4524, 3500, 3448, 1506, 1891, 1507, 1505, + 4489, 3490, 4417, 4073, 4371, 4277, 4370, 2316, 4140, 1506, + 4276, 1507, 1505, 3313, 4265, 1506, 4108, 1507, 1505, 3332, + 2343, 3506, 2992, 1506, 4066, 1507, 1505, 3051, 4264, 3161, + 4049, 2199, 1506, 2199, 1507, 1505, 3772, 1506, 746, 1507, + 1505, 1506, 3599, 1507, 1505, 4263, 2399, 3409, 3576, 3575, + 1352, 1352, 2199, 2199, 4193, 1506, 3514, 1507, 1505, 3488, + 3996, 1790, 3489, 3487, 3293, 3543, 73, 3294, 3311, 3296, + 3486, 3478, 1506, 3472, 1507, 1505, 781, 3471, 3470, 3340, + 3511, 1506, 3989, 1507, 1505, 3469, 3686, 1506, 3422, 1507, + 1505, 1832, 3655, 2262, 3244, 3118, 3081, 3649, 2969, 2720, + 7, 4939, 3367, 3433, 6, 2545, 3364, 4079, 3380, 1506, + 3381, 1507, 1505, 1506, 2506, 1507, 1505, 3423, 2505, 1506, + 2503, 1507, 1505, 3132, 1506, 3388, 1507, 1505, 3135, 2499, + 3389, 2498, 3423, 3434, 3435, 3408, 3427, 2447, 3437, 3411, + 3560, 2227, 3424, 3517, 3444, 2224, 3108, 1900, 3111, 1654, + 3430, 254, 3104, 3758, 1337, 3106, 254, 3436, 2902, 4937, + 3105, 2905, 2906, 2907, 2908, 2909, 2910, 2911, 4550, 4551, + 2914, 2915, 2916, 2917, 2918, 2919, 2920, 2921, 2922, 2923, + 2924, 4247, 2926, 2927, 2928, 2929, 2930, 3559, 2931, 3133, + 3134, 4909, 3189, 4873, 3480, 3468, 3392, 3393, 3394, 4803, + 4801, 4532, 4777, 4696, 3598, 4340, 3530, 4690, 3648, 4681, + 3196, 3544, 3646, 3126, 1336, 4679, 4666, 3426, 3542, 3542, + 3520, 3426, 4657, 4635, 3526, 4634, 3206, 3207, 3224, 4625, + 3523, 4624, 3212, 1790, 4610, 1506, 3617, 1507, 1505, 1506, + 4605, 1507, 1505, 3548, 3551, 3552, 3165, 4604, 4555, 3168, + 3222, 4539, 3590, 4537, 4523, 1506, 4490, 1507, 1505, 4401, + 4400, 3187, 3188, 4399, 4344, 4333, 4317, 4316, 4314, 4307, + 3191, 3192, 1859, 1521, 1866, 1867, 3565, 1506, 4305, 1507, + 1505, 3569, 1860, 1861, 4284, 4283, 3197, 3198, 3199, 3221, + 1872, 4282, 4279, 1876, 4947, 1875, 3601, 4278, 4252, 3604, + 3605, 1529, 1530, 1531, 1532, 1522, 1523, 1524, 1525, 1526, + 1527, 1528, 1520, 4249, 3611, 3220, 1506, 4245, 1507, 1505, + 73, 4243, 3229, 4221, 3231, 73, 3567, 3234, 3566, 2022, + 2199, 4218, 4212, 3510, 4061, 4051, 3608, 4034, 4018, 3219, + 3708, 3995, 1506, 3711, 1507, 1505, 3585, 3993, 3715, 3581, + 781, 1753, 3987, 3961, 3920, 3218, 3919, 3917, 3916, 3727, + 3729, 3730, 3732, 3903, 3734, 3735, 1506, 3217, 1507, 1505, + 3898, 3619, 3216, 3897, 3603, 1738, 3784, 1772, 3744, 3736, + 1352, 3614, 1506, 3726, 1507, 1505, 1352, 3716, 3709, 3707, + 2725, 3625, 3761, 3763, 1506, 3622, 1507, 1505, 3597, 1506, + 3574, 1507, 1505, 3776, 3550, 3518, 3515, 964, 165, 781, + 3626, 3512, 3499, 3491, 3481, 3215, 3479, 165, 3475, 3642, + 4897, 3613, 3474, 3473, 3791, 3214, 3795, 1352, 3384, 3283, + 781, 3265, 781, 2399, 1352, 3627, 3253, 1352, 3213, 3636, + 3638, 3639, 1506, 3210, 1507, 1505, 2136, 3209, 2136, 3633, + 3634, 3821, 1506, 3822, 1507, 1505, 779, 3245, 1033, 1032, + 1740, 2812, 3701, 3830, 3635, 1506, 3637, 1507, 1505, 3099, + 1506, 3085, 1507, 1505, 1506, 3048, 1507, 1505, 2752, 2739, + 3208, 774, 2738, 2509, 3202, 4747, 3787, 2501, 3400, 165, + 2259, 2226, 3798, 3706, 3406, 3331, 2223, 2209, 3780, 3718, + 3190, 3805, 2208, 3705, 2890, 3184, 1989, 1506, 3816, 1507, + 1505, 1506, 3163, 1507, 1505, 1901, 3865, 4745, 3868, 1591, + 3868, 3868, 1587, 1586, 1211, 1352, 1340, 1506, 1100, 1507, + 1505, 2710, 1506, 3790, 1507, 1505, 2709, 4733, 4920, 1506, + 4729, 1507, 1505, 3893, 4529, 2198, 4518, 3334, 3747, 4517, + 3820, 1790, 1790, 3818, 3423, 3889, 2703, 3764, 1506, 4504, + 1507, 1505, 4919, 1506, 3848, 1507, 1505, 4500, 4315, 3828, + 1162, 4281, 195, 237, 3852, 3854, 4259, 2199, 3301, 4213, + 3786, 3797, 4111, 1506, 1213, 1507, 1505, 4099, 3802, 3819, + 4097, 3804, 2071, 195, 237, 3423, 4093, 3817, 781, 2800, + 3814, 3812, 3423, 3894, 3895, 3423, 4058, 1788, 1788, 4014, + 3825, 4012, 3761, 3829, 4011, 4010, 4007, 3842, 3863, 1506, + 3845, 1507, 1505, 3815, 4006, 1753, 3994, 3992, 2399, 2399, + 195, 237, 3864, 3950, 3949, 237, 194, 228, 196, 3873, + 779, 1212, 3847, 3934, 163, 2860, 165, 233, 4961, 1352, + 2286, 3836, 2859, 3824, 3185, 237, 194, 228, 196, 195, + 237, 165, 3948, 165, 3874, 3748, 3869, 3870, 233, 237, + 3745, 3700, 3600, 3651, 3602, 3640, 3632, 3631, 197, 3891, + 3568, 2283, 3570, 3629, 3607, 3557, 3395, 3076, 3072, 3609, + 3610, 3071, 3070, 3423, 2684, 2677, 2669, 2668, 2667, 2666, + 3899, 3907, 3871, 2664, 2516, 2285, 4943, 3460, 3461, 233, + 4889, 2660, 2659, 2657, 781, 2648, 2644, 2643, 2508, 2187, + 2185, 2184, 3476, 3477, 2183, 2182, 2139, 2138, 2129, 233, + 4743, 1802, 1800, 3421, 233, 4896, 3969, 4857, 4770, 4734, + 3904, 1581, 3967, 233, 4728, 4651, 4648, 3912, 3927, 3928, + 3660, 3661, 3913, 2991, 4633, 3521, 3662, 3663, 3664, 3665, + 3921, 3666, 3667, 3668, 3669, 3670, 3671, 3672, 3673, 3674, + 3675, 3676, 3677, 3925, 4614, 4607, 4484, 4483, 4441, 3974, + 3918, 4421, 3628, 4419, 3937, 4414, 3968, 4390, 4365, 4191, + 4190, 4187, 4186, 4147, 4144, 4142, 4082, 4033, 4029, 3837, + 3834, 4020, 3741, 3738, 3737, 4021, 3958, 2479, 3641, 3650, + 1854, 1865, 3965, 1856, 1871, 1874, 1862, 2992, 1851, 4035, + 3513, 4037, 3507, 3432, 3353, 3346, 4043, 3335, 3400, 3406, + 1727, 3295, 3241, 3226, 2971, 3997, 2932, 3980, 2824, 2806, + 2763, 3678, 2762, 4031, 2719, 2054, 233, 2524, 3915, 2466, + 3979, 3985, 3999, 4044, 4001, 2287, 4003, 2205, 1936, 1863, + 1653, 1638, 1634, 1633, 1632, 1631, 1630, 1629, 1628, 781, + 2399, 1627, 1626, 1625, 1624, 1623, 4038, 1622, 4040, 1621, + 1620, 1619, 1618, 4088, 1617, 1616, 1615, 870, 1614, 1613, + 1612, 1611, 4096, 1610, 1609, 1608, 1607, 1606, 1605, 1604, + 1603, 1602, 1601, 4057, 1600, 1599, 1598, 1597, 1594, 1593, + 4060, 1592, 1590, 1589, 1588, 1585, 2316, 1740, 4116, 4026, + 1578, 4015, 1577, 4019, 1575, 2293, 1574, 1573, 4125, 3907, + 1572, 1571, 3400, 4077, 3126, 3406, 1570, 4135, 4023, 1569, + 1568, 1567, 4055, 1566, 1565, 1564, 1563, 1557, 1556, 1555, + 4150, 1554, 1553, 1352, 1470, 4046, 4050, 4045, 1338, 4741, + 4054, 4188, 3865, 3376, 3377, 2778, 1352, 2563, 1379, 2199, + 4887, 4074, 4086, 4839, 2199, 3910, 3519, 3379, 3318, 3823, + 2985, 1352, 2790, 4207, 1469, 1399, 2822, 1790, 2834, 3832, + 4076, 2829, 3833, 77, 3387, 3835, 2830, 2821, 4202, 4203, + 4204, 2827, 4216, 3386, 2825, 3385, 2828, 3382, 4118, 2826, + 3839, 2833, 4112, 2820, 4790, 781, 4668, 2399, 4958, 4395, + 3840, 1740, 1352, 3589, 4123, 3356, 4115, 1718, 2848, 4176, + 4231, 3782, 4185, 2280, 2281, 4233, 254, 4114, 4095, 4209, + 2275, 2276, 2277, 1788, 3861, 3587, 3862, 2900, 3872, 2850, + 2849, 3456, 4132, 4131, 4129, 4250, 4137, 3963, 3964, 3457, + 3458, 3459, 4198, 3938, 4230, 2380, 1847, 772, 4254, 3351, + 1886, 3838, 3090, 3091, 4611, 3152, 4222, 2746, 4192, 4197, + 4194, 2745, 1883, 1172, 2753, 4225, 2468, 2392, 1464, 4313, + 3756, 4275, 3749, 3929, 4206, 3410, 3933, 3347, 3102, 2852, + 4211, 2788, 2291, 2250, 2125, 2124, 1649, 1650, 4900, 4217, + 4877, 4214, 1647, 1648, 1645, 1646, 4609, 4223, 3896, 4220, + 2293, 4151, 4227, 4297, 4228, 2953, 4299, 4303, 2946, 3906, + 4226, 4224, 2847, 4309, 4195, 2108, 2400, 4257, 1643, 1644, + 1459, 1458, 4356, 1497, 3592, 2533, 3936, 3391, 4248, 3444, + 1352, 1162, 2754, 2535, 3973, 3803, 1347, 3975, 3976, 1945, + 1709, 4238, 1408, 4251, 3978, 4219, 1407, 1390, 1431, 2547, + 4326, 3150, 4864, 1352, 1790, 1790, 4862, 4809, 4345, 4325, + 3149, 3795, 1382, 1384, 4306, 4787, 4308, 4786, 4784, 4700, + 3542, 4652, 4385, 4353, 165, 165, 165, 1212, 4244, 4353, + 1352, 4128, 4127, 3998, 3957, 73, 774, 3956, 4287, 3942, + 2513, 2885, 2855, 4379, 4372, 1888, 4341, 4347, 4348, 4293, + 3941, 4300, 3562, 1405, 4891, 4890, 4342, 4817, 4818, 4890, + 1788, 2069, 4304, 1352, 4036, 1352, 4384, 4022, 3612, 3260, + 4324, 3259, 3251, 3049, 4323, 4322, 2646, 4350, 4387, 4343, + 4389, 4319, 1375, 1346, 1790, 4891, 4416, 4229, 4334, 4878, + 4868, 3988, 1091, 1092, 1093, 1094, 3280, 1344, 3278, 3990, + 3991, 4321, 4101, 3584, 4364, 781, 4355, 1352, 1352, 4363, + 4359, 1352, 1352, 4361, 4346, 2782, 1879, 1344, 775, 1423, + 85, 4376, 2, 4913, 4118, 4914, 1, 3693, 2717, 4000, + 2203, 4002, 1651, 1095, 1090, 4383, 4475, 4443, 1766, 2963, + 2069, 2442, 1794, 4438, 4445, 2207, 4393, 2529, 3423, 4176, + 4425, 4426, 4185, 1097, 4439, 4440, 2839, 2840, 4402, 3390, + 4485, 4486, 4396, 2842, 2448, 1385, 1541, 3266, 2594, 3531, + 2944, 2767, 3775, 1728, 1168, 2131, 1913, 1366, 1790, 1910, + 1365, 2104, 1363, 2074, 2152, 966, 2793, 3906, 2101, 3508, + 3482, 4124, 2103, 2100, 2102, 2106, 2107, 4899, 3542, 4931, + 2105, 4478, 4856, 4902, 1933, 950, 4520, 4521, 4778, 781, + 3959, 4117, 3582, 4658, 4477, 4860, 4660, 4496, 2599, 4510, + 1502, 3813, 833, 4533, 1010, 4535, 4141, 978, 4143, 1576, + 4498, 2016, 2517, 2016, 1788, 3658, 1521, 3656, 977, 4071, + 3307, 4492, 4480, 3554, 4575, 4497, 834, 2495, 4655, 4494, + 1848, 1853, 4536, 2851, 4538, 4588, 4724, 4394, 3857, 3418, + 4493, 4505, 4509, 1518, 1529, 1530, 1531, 1532, 1522, 1523, + 1524, 1525, 1526, 1527, 1528, 1520, 4515, 4516, 4567, 1878, + 4719, 4145, 4565, 4271, 4269, 4541, 4573, 4270, 877, 2421, + 744, 1196, 4442, 2789, 2562, 4447, 4613, 1139, 4052, 4379, + 4542, 2777, 1140, 4586, 1132, 3329, 3328, 2032, 1510, 2052, + 3679, 1352, 3680, 1551, 921, 4560, 2628, 4554, 3304, 4170, + 3549, 84, 83, 82, 4601, 81, 4595, 1642, 262, 969, + 261, 4530, 4338, 4773, 4904, 4563, 947, 946, 945, 4566, + 944, 943, 942, 4568, 2300, 4570, 4257, 2301, 2111, 2112, + 2113, 2114, 2115, 2116, 2109, 2110, 2299, 4253, 4585, 2297, + 4582, 2199, 1352, 2296, 4591, 1162, 1162, 1723, 1735, 1734, + 4266, 3561, 4267, 3940, 4268, 2474, 2476, 3793, 2199, 3447, + 4199, 3442, 2332, 1745, 2330, 1757, 2880, 4232, 4608, 2887, + 2329, 4836, 1759, 3986, 1790, 4260, 4736, 4646, 4737, 4413, + 3492, 4256, 2274, 2876, 2349, 4619, 4649, 4650, 3463, 2346, + 1739, 2345, 3455, 1796, 4409, 4403, 2377, 4134, 3405, 4360, + 4571, 4352, 4152, 4153, 4159, 1296, 2787, 4083, 4084, 4085, + 1270, 1265, 1267, 1268, 1266, 4091, 4092, 3170, 3923, 2857, + 3751, 3289, 3288, 3286, 3285, 1693, 4643, 4680, 1799, 4691, + 1788, 4805, 774, 4318, 4674, 4685, 2990, 2988, 1389, 4280, + 1937, 1380, 1335, 3378, 4692, 3374, 2802, 3719, 1659, 1657, + 4653, 3383, 2823, 2514, 3586, 1736, 1733, 1732, 1240, 2016, + 1239, 1829, 4027, 4094, 4687, 51, 4688, 3533, 2954, 3103, + 3399, 4544, 165, 2279, 4701, 1133, 2775, 4374, 4375, 121, + 45, 139, 120, 214, 4697, 66, 213, 65, 19, 137, + 211, 64, 50, 49, 209, 4689, 115, 114, 113, 112, + 136, 208, 4392, 63, 246, 245, 248, 247, 4695, 4723, + 244, 3061, 4398, 3062, 243, 1352, 1836, 4703, 242, 4705, + 4788, 4358, 4769, 1085, 48, 47, 215, 4751, 46, 122, + 67, 44, 4717, 43, 1352, 2546, 3739, 1944, 4714, 4373, + 4740, 4742, 4744, 4746, 4047, 1790, 4768, 4722, 3281, 4758, + 2759, 4444, 4774, 42, 4731, 38, 13, 12, 4739, 39, + 24, 23, 1918, 22, 30, 29, 28, 36, 35, 158, + 157, 4775, 34, 156, 155, 154, 165, 153, 152, 165, + 165, 151, 150, 33, 21, 58, 57, 4802, 56, 4479, + 55, 54, 53, 165, 8, 4120, 4776, 4767, 143, 142, + 144, 1788, 4783, 1790, 4781, 140, 135, 133, 4573, 4799, + 4795, 4797, 32, 134, 131, 132, 125, 4804, 124, 123, + 118, 4796, 4798, 4800, 116, 96, 95, 4823, 94, 109, + 108, 107, 106, 4831, 1521, 105, 104, 102, 4810, 103, + 832, 4812, 93, 92, 4814, 4815, 4813, 91, 90, 89, + 130, 129, 126, 111, 119, 4811, 117, 100, 110, 1788, + 1519, 1518, 1529, 1530, 1531, 1532, 1522, 1523, 1524, 1525, + 1526, 1527, 1528, 1520, 101, 4844, 99, 4845, 98, 4846, + 97, 4847, 88, 4848, 87, 86, 128, 127, 141, 216, + 68, 2665, 192, 4852, 191, 190, 187, 186, 1506, 189, + 1507, 1505, 2016, 4863, 188, 4865, 4866, 184, 4855, 185, + 1352, 183, 4861, 4859, 182, 181, 180, 179, 178, 4674, + 4869, 59, 60, 61, 62, 204, 4870, 203, 4871, 205, + 4872, 218, 4876, 4601, 217, 207, 210, 206, 212, 201, + 199, 202, 200, 4881, 4880, 198, 78, 11, 4879, 4597, + 138, 20, 4888, 17, 4884, 4898, 3, 4886, 4906, 0, + 0, 0, 4905, 0, 0, 0, 0, 0, 0, 4892, + 4893, 4894, 4895, 0, 0, 0, 1352, 1521, 1352, 1541, + 0, 0, 0, 4910, 0, 0, 0, 0, 0, 2108, + 4723, 4916, 4918, 4917, 0, 0, 4922, 4923, 0, 0, + 4929, 0, 4933, 1519, 1518, 1529, 1530, 1531, 1532, 1522, + 1523, 1524, 1525, 1526, 1527, 1528, 1520, 0, 0, 4930, + 2136, 0, 0, 0, 0, 4941, 4942, 0, 4473, 0, + 0, 0, 0, 0, 0, 0, 4906, 4951, 0, 0, + 4905, 4950, 0, 0, 0, 0, 4953, 4612, 0, 0, + 4933, 0, 4954, 0, 0, 0, 4654, 0, 4960, 0, + 2232, 2233, 2234, 0, 4962, 0, 0, 0, 0, 0, + 0, 0, 0, 1743, 1744, 0, 1746, 0, 4874, 1750, + 0, 1754, 1755, 1756, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2268, 0, 0, 0, 0, + 2273, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1804, 1805, 0, 0, 1808, 1809, + 1810, 1811, 1812, 0, 1814, 1815, 1816, 1817, 1818, 2327, + 2328, 0, 1824, 0, 1826, 1827, 1828, 165, 0, 0, + 1562, 0, 0, 0, 2016, 0, 3542, 0, 0, 0, + 0, 0, 0, 0, 0, 2319, 0, 0, 0, 0, + 889, 888, 895, 885, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 892, 893, 0, 894, 898, 1739, 0, + 879, 4388, 4569, 0, 0, 0, 0, 0, 0, 0, + 903, 0, 0, 0, 1384, 0, 0, 0, 0, 0, + 1384, 1384, 1384, 0, 0, 2104, 0, 0, 0, 1521, + 4716, 0, 2101, 0, 0, 0, 2103, 2100, 2102, 2106, + 2107, 0, 0, 0, 2105, 0, 0, 0, 0, 0, + 0, 0, 0, 4730, 0, 1519, 1518, 1529, 1530, 1531, + 1532, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1520, 0, + 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, + 165, 165, 0, 165, 0, 0, 0, 0, 4622, 4623, + 0, 0, 0, 0, 0, 4627, 4628, 4629, 4630, 4631, + 4632, 0, 0, 0, 4636, 4637, 4638, 4639, 0, 0, + 0, 4641, 4642, 0, 4644, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1382, 0, 0, 2543, 0, 165, 0, 0, 1289, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4180, + 0, 0, 0, 0, 0, 4157, 0, 0, 0, 0, + 0, 0, 0, 0, 4828, 0, 0, 0, 0, 0, + 4832, 2089, 2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, + 2098, 2099, 2111, 2112, 2113, 2114, 2115, 2116, 2109, 2110, + 0, 0, 0, 0, 0, 0, 4702, 4171, 0, 0, + 0, 0, 0, 4708, 4709, 0, 0, 0, 0, 0, + 4160, 195, 237, 194, 228, 196, 880, 882, 881, 0, + 0, 4155, 0, 0, 0, 0, 4182, 4183, 887, 0, + 0, 229, 4156, 0, 0, 0, 0, 0, 221, 4732, + 891, 0, 230, 0, 0, 0, 0, 906, 0, 0, + 0, 0, 0, 0, 884, 197, 0, 0, 0, 0, + 0, 4828, 163, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4163, 0, 1307, 1308, 1274, 149, 4452, 0, + 0, 0, 1541, 0, 0, 0, 233, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1297, 1301, 1303, + 1305, 1310, 0, 1315, 1311, 1312, 1313, 1314, 0, 0, + 1292, 1293, 1294, 1295, 1272, 1273, 1298, 0, 1275, 4828, + 1277, 1278, 1279, 1280, 1276, 1281, 1282, 1283, 1284, 1285, + 1288, 1290, 1286, 1287, 1316, 1317, 1318, 1319, 1320, 1321, + 1322, 1323, 1325, 1324, 1326, 1327, 1328, 1329, 1330, 1331, + 1332, 1333, 1300, 1302, 1304, 1306, 1309, 0, 0, 0, + 0, 0, 0, 4451, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 172, 173, 0, 174, 175, + 821, 0, 0, 176, 0, 4956, 177, 0, 0, 4181, + 0, 2866, 0, 1291, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 886, 890, 896, 0, 897, 899, 0, + 0, 900, 901, 902, 0, 0, 4167, 904, 905, 0, + 0, 0, 0, 0, 2740, 0, 2742, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 4164, 4168, + 4166, 4165, 0, 0, 0, 0, 0, 0, 0, 2764, + 2765, 2766, 0, 817, 818, 0, 0, 1236, 193, 226, + 235, 227, 79, 145, 863, 2783, 2784, 2785, 2786, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 147, 220, 219, 0, 0, 0, 0, 80, + 0, 0, 0, 0, 0, 0, 4174, 4175, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 171, 0, 0, + 0, 0, 0, 1212, 2453, 2454, 165, 165, 0, 0, + 0, 2460, 0, 1739, 1739, 1739, 1739, 1739, 1739, 1739, + 4386, 0, 0, 2470, 146, 0, 0, 0, 0, 0, + 0, 1237, 0, 0, 0, 0, 0, 0, 4448, 0, + 222, 223, 224, 0, 0, 0, 0, 0, 1521, 865, + 0, 0, 864, 4184, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4158, 0, 883, 4173, + 0, 0, 0, 0, 1519, 1518, 1529, 1530, 1531, 1532, + 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1520, 0, 2525, + 0, 1759, 2108, 0, 0, 0, 0, 0, 0, 0, + 0, 849, 0, 0, 0, 0, 0, 0, 0, 0, + 231, 822, 0, 0, 0, 0, 1230, 1225, 1220, 1224, + 1228, 0, 0, 0, 0, 0, 0, 1796, 0, 0, + 0, 159, 0, 0, 0, 225, 0, 160, 824, 4453, + 4454, 0, 0, 0, 1233, 0, 1384, 0, 1223, 0, + 0, 0, 0, 0, 0, 4449, 4450, 0, 4457, 4456, + 4455, 4468, 4469, 4470, 4458, 4459, 4462, 4464, 4463, 4460, + 4461, 4465, 4466, 4467, 0, 0, 0, 0, 4471, 0, + 0, 821, 0, 0, 0, 3652, 0, 0, 0, 4472, + 0, 0, 0, 161, 0, 1739, 0, 0, 0, 1231, + 0, 0, 0, 165, 0, 4178, 71, 0, 0, 3096, + 0, 0, 1299, 1521, 0, 845, 0, 847, 844, 0, + 0, 1234, 848, 0, 0, 0, 0, 0, 1235, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1212, 1519, + 1518, 1529, 1530, 1531, 1532, 1522, 1523, 1524, 1525, 1526, + 1527, 1528, 1520, 0, 817, 818, 0, 0, 0, 74, + 0, 0, 843, 0, 0, 863, 0, 1221, 0, 0, + 0, 0, 0, 0, 816, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 823, 858, 4172, 0, 0, + 0, 1232, 0, 0, 4177, 169, 234, 170, 0, 0, + 0, 0, 4179, 0, 0, 0, 0, 854, 2104, 0, + 69, 0, 0, 0, 0, 2101, 0, 0, 0, 2103, + 2100, 2102, 2106, 2107, 0, 0, 0, 2105, 0, 1222, + 0, 0, 0, 0, 0, 0, 0, 0, 4161, 4162, + 0, 0, 0, 855, 859, 809, 0, 0, 0, 1269, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 865, 0, 0, 864, 840, 0, 838, 842, 862, 0, + 0, 0, 839, 836, 835, 0, 841, 826, 827, 825, + 0, 815, 828, 829, 830, 831, 810, 0, 0, 860, + 0, 861, 162, 52, 0, 0, 0, 0, 0, 70, + 0, 0, 856, 857, 9, 0, 0, 0, 0, 0, + 0, 1229, 849, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 822, 0, 0, 0, 0, 0, 0, 0, + 3261, 3262, 3263, 0, 0, 166, 167, 0, 0, 168, + 852, 0, 0, 0, 0, 0, 851, 0, 1226, 824, + 0, 1227, 0, 0, 811, 0, 0, 0, 0, 0, + 1217, 0, 0, 846, 2089, 2090, 2091, 2092, 2093, 2094, + 2095, 2096, 2097, 2098, 2099, 2111, 2112, 2113, 2114, 2115, + 2116, 2109, 2110, 1521, 0, 0, 1534, 0, 1538, 0, + 0, 0, 0, 0, 1156, 3366, 1157, 0, 0, 0, + 0, 165, 0, 0, 1535, 1537, 1533, 0, 1536, 1519, + 1518, 1529, 1530, 1531, 1532, 1522, 1523, 1524, 1525, 1526, + 1527, 1528, 1520, 0, 165, 0, 845, 0, 847, 844, + 0, 0, 0, 848, 0, 1137, 0, 0, 0, 0, + 2642, 0, 0, 0, 0, 0, 0, 0, 0, 1151, + 0, 1147, 0, 0, 0, 1739, 0, 0, 850, 0, + 0, 0, 0, 0, 819, 820, 3647, 0, 808, 812, + 1238, 0, 0, 843, 1216, 1218, 813, 0, 1521, 0, + 0, 1534, 1219, 1538, 814, 816, 0, 0, 0, 0, + 0, 0, 0, 0, 1521, 0, 823, 858, 0, 1535, + 1537, 1533, 0, 1536, 1519, 1518, 1529, 1530, 1531, 1532, + 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1520, 854, 1126, + 1519, 1518, 1529, 1530, 1531, 1532, 1522, 1523, 1524, 1525, + 1526, 1527, 1528, 1520, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 889, 888, 895, 885, 0, 0, 0, + 0, 0, 0, 0, 855, 859, 892, 893, 0, 894, + 898, 0, 0, 879, 0, 0, 0, 0, 0, 0, + 0, 3553, 0, 903, 0, 840, 0, 838, 842, 862, + 0, 0, 0, 839, 836, 835, 0, 841, 826, 827, + 825, 0, 815, 828, 829, 830, 831, 810, 0, 0, + 860, 0, 861, 0, 1153, 0, 1146, 0, 0, 0, + 0, 0, 0, 856, 857, 1150, 1149, 0, 0, 0, + 907, 0, 0, 909, 0, 0, 0, 0, 908, 0, + 0, 0, 0, 0, 0, 0, 1138, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 889, 888, 895, + 885, 852, 0, 0, 0, 0, 1145, 851, 0, 0, + 892, 893, 0, 894, 898, 811, 1521, 879, 3160, 0, + 0, 0, 0, 0, 846, 1155, 0, 903, 165, 0, + 1144, 0, 0, 165, 1143, 0, 0, 0, 0, 0, + 1131, 0, 1519, 1518, 1529, 1530, 1531, 1532, 1522, 1523, + 1524, 1525, 1526, 1527, 1528, 1520, 0, 1521, 0, 1136, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 907, 0, 0, 909, 0, 0, + 2647, 0, 908, 1519, 1518, 1529, 1530, 1531, 1532, 1522, + 1523, 1524, 1525, 1526, 1527, 1528, 1520, 0, 0, 0, + 0, 0, 0, 0, 0, 1134, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 850, + 0, 0, 0, 0, 0, 819, 820, 0, 0, 808, + 812, 0, 0, 0, 0, 0, 0, 813, 0, 880, + 882, 881, 0, 0, 1154, 814, 0, 0, 0, 0, + 0, 887, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 891, 0, 0, 0, 1135, 0, 0, + 906, 0, 0, 0, 0, 0, 0, 884, 0, 0, + 0, 874, 0, 0, 1521, 0, 2621, 0, 0, 0, + 0, 0, 0, 0, 0, 3717, 0, 0, 1521, 0, + 0, 2378, 0, 0, 0, 0, 2339, 0, 0, 2386, + 1519, 1518, 1529, 1530, 1531, 1532, 1522, 1523, 1524, 1525, + 1526, 1527, 1528, 1520, 1519, 1518, 1529, 1530, 1531, 1532, + 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1520, 0, 2380, + 2348, 0, 0, 880, 882, 881, 0, 0, 0, 1152, + 2381, 2382, 0, 0, 3785, 887, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 891, 0, 0, + 0, 0, 0, 0, 906, 3799, 2347, 3800, 0, 0, + 0, 884, 0, 0, 0, 0, 0, 0, 0, 1141, + 0, 0, 0, 0, 2355, 0, 0, 0, 1130, 0, + 0, 0, 0, 0, 1212, 0, 165, 0, 0, 0, + 0, 0, 0, 0, 0, 165, 0, 0, 0, 0, + 0, 0, 165, 0, 2378, 0, 886, 890, 896, 0, + 897, 899, 195, 237, 900, 901, 902, 1739, 0, 0, + 904, 905, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4351, 0, 0, 0, + 0, 0, 2380, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2371, 0, 0, 0, 165, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 233, 1127, 0, + 0, 0, 1125, 1128, 0, 0, 0, 2355, 0, 0, + 1129, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 886, 890, 896, 0, 897, 899, 0, 2378, 900, 901, + 902, 0, 0, 1384, 904, 905, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2338, 2340, 2337, + 0, 0, 0, 2334, 0, 0, 0, 0, 2359, 0, + 0, 0, 0, 0, 0, 2380, 0, 0, 0, 2365, + 0, 3908, 0, 0, 0, 0, 0, 2350, 0, 2333, + 0, 0, 0, 0, 0, 0, 0, 2371, 0, 2353, + 2387, 883, 0, 2354, 2356, 2358, 0, 2360, 2361, 2362, + 2366, 2367, 2368, 2370, 2373, 2374, 2375, 0, 0, 0, + 4600, 0, 0, 0, 2363, 2372, 2364, 0, 0, 0, + 2355, 0, 0, 0, 0, 0, 2342, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 910, + 911, 912, 913, 914, 0, 0, 165, 0, 0, 3982, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2379, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2359, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2365, 0, 0, 883, 0, 0, 0, 0, + 2371, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2353, 2387, 2335, 2336, 2354, 2356, 2358, 0, + 2360, 2361, 2362, 2366, 2367, 2368, 2370, 2373, 2374, 2375, + 0, 0, 2376, 0, 0, 0, 0, 2363, 2372, 2364, + 0, 0, 0, 910, 911, 912, 913, 914, 0, 0, + 2352, 0, 0, 0, 2351, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2369, 0, + 0, 0, 0, 0, 0, 0, 0, 2357, 0, 0, + 0, 2379, 0, 0, 2359, 0, 0, 0, 0, 3908, + 0, 2384, 2383, 0, 1384, 2365, 0, 165, 0, 0, + 0, 0, 0, 0, 165, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2353, 2387, 0, 0, 2354, + 2356, 2358, 0, 2360, 2361, 2362, 2366, 2367, 2368, 2370, + 2373, 2374, 2375, 0, 0, 0, 0, 0, 0, 0, + 2363, 2372, 2364, 0, 0, 2376, 0, 0, 2344, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2352, 0, 0, 0, 2351, 0, 0, + 0, 0, 0, 0, 1739, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2369, 0, 0, 2379, 0, 2385, 0, 0, 0, + 2357, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1384, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2376, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2352, 0, 1739, 0, + 2351, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 165, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2369, 0, 0, 0, 0, 0, + 0, 0, 0, 2357, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3908, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 985, 0, 0, 0, 0, 0, 0, 0, 0, 476, + 0, 165, 618, 652, 641, 727, 606, 0, 0, 0, + 0, 0, 0, 936, 0, 0, 0, 385, 0, 0, + 442, 656, 637, 648, 638, 482, 623, 624, 625, 632, + 397, 626, 757, 628, 598, 629, 599, 630, 631, 976, + 655, 605, 517, 458, 0, 672, 0, 0, 1056, 1064, + 0, 0, 0, 0, 0, 0, 0, 0, 1052, 0, + 4424, 0, 0, 928, 0, 0, 965, 1033, 1032, 952, + 962, 0, 0, 353, 260, 600, 723, 602, 601, 953, + 0, 954, 958, 961, 957, 955, 956, 0, 1047, 0, + 0, 0, 0, 0, 0, 920, 932, 0, 937, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 929, 930, 0, 0, 0, 0, + 986, 0, 931, 0, 0, 0, 0, 0, 518, 547, + 0, 560, 0, 422, 423, 981, 959, 963, 0, 0, + 0, 0, 338, 525, 544, 354, 512, 558, 359, 520, + 537, 349, 475, 509, 4522, 0, 340, 542, 519, 455, + 339, 0, 502, 382, 399, 379, 473, 960, 0, 984, + 988, 378, 1070, 982, 552, 342, 0, 551, 472, 538, + 543, 456, 449, 0, 341, 540, 454, 448, 433, 389, + 1071, 434, 435, 403, 488, 446, 489, 404, 460, 459, + 461, 405, 406, 407, 408, 409, 410, 411, 412, 413, + 414, 0, 0, 0, 0, 0, 582, 583, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 716, 979, 0, 720, 0, 554, 0, + 0, 1054, 0, 0, 0, 523, 0, 0, 436, 165, + 0, 0, 983, 0, 505, 478, 1067, 0, 0, 503, + 444, 539, 490, 545, 526, 553, 497, 491, 332, 527, + 381, 457, 350, 352, 748, 383, 386, 390, 391, 466, + 467, 484, 511, 530, 531, 532, 380, 364, 504, 365, + 400, 366, 333, 372, 370, 373, 513, 374, 335, 485, + 536, 0, 396, 500, 452, 336, 451, 486, 535, 534, + 351, 562, 569, 570, 660, 0, 575, 760, 761, 762, + 584, 0, 492, 347, 344, 0, 0, 0, 376, 487, + 360, 362, 363, 361, 481, 483, 589, 590, 591, 593, + 0, 594, 595, 0, 0, 0, 0, 596, 661, 677, + 645, 614, 577, 669, 611, 615, 616, 417, 418, 419, + 680, 2133, 2132, 2134, 568, 437, 438, 0, 388, 387, + 453, 337, 0, 0, 430, 416, 493, 343, 384, 432, + 421, 439, 440, 441, 394, 327, 328, 754, 1051, 474, + 682, 718, 719, 607, 0, 1066, 1046, 1048, 1049, 1053, + 1057, 1058, 1059, 1060, 1061, 1063, 1065, 1069, 753, 0, + 662, 676, 758, 675, 750, 480, 0, 510, 673, 620, + 0, 666, 639, 640, 0, 667, 635, 671, 0, 609, + 0, 578, 581, 610, 695, 696, 697, 334, 580, 699, + 700, 701, 702, 703, 704, 705, 698, 1068, 643, 619, + 646, 559, 622, 621, 0, 0, 657, 987, 658, 659, + 462, 463, 464, 465, 1055, 683, 358, 579, 495, 496, + 0, 644, 0, 0, 0, 0, 0, 0, 0, 0, + 649, 650, 647, 763, 0, 706, 707, 0, 0, 573, + 574, 393, 0, 592, 401, 357, 479, 395, 557, 424, + 0, 585, 651, 586, 498, 499, 710, 715, 711, 712, + 714, 734, 469, 415, 420, 514, 431, 445, 501, 556, + 477, 506, 355, 546, 516, 450, 636, 664, 1077, 1050, + 1076, 1078, 1079, 1075, 1080, 1081, 1062, 941, 0, 994, + 995, 1073, 1072, 1074, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 691, 690, 689, 688, 687, + 686, 685, 684, 0, 0, 633, 533, 371, 321, 367, + 368, 375, 751, 747, 752, 735, 738, 737, 713, 948, + 329, 613, 443, 494, 392, 678, 679, 0, 733, 1040, + 1003, 1004, 1005, 938, 1006, 1000, 1001, 939, 1002, 1041, + 992, 1037, 1038, 967, 997, 1007, 1036, 1008, 1039, 968, + 1042, 1082, 1083, 1014, 998, 291, 1084, 1011, 1043, 1035, + 1034, 1009, 993, 1044, 1045, 975, 970, 1012, 1013, 999, + 1020, 1021, 1022, 1025, 940, 1026, 1027, 1028, 1029, 1030, + 1024, 1023, 989, 990, 991, 1015, 1016, 1018, 1019, 996, + 524, 971, 972, 973, 974, 0, 0, 563, 564, 565, + 588, 0, 566, 548, 612, 402, 330, 528, 555, 749, + 0, 0, 0, 0, 0, 0, 0, 663, 674, 708, + 709, 0, 721, 722, 724, 726, 1031, 728, 521, 522, + 736, 0, 0, 425, 345, 346, 470, 471, 508, 0, + 426, 427, 428, 429, 1017, 731, 732, 729, 447, 507, + 529, 515, 0, 755, 603, 604, 756, 717, 331, 0, + 933, 195, 237, 985, 0, 0, 0, 0, 0, 0, + 0, 0, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 0, 0, 0, 0, 936, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 976, 655, 605, 517, 458, 0, 672, 0, + 0, 1056, 1064, 0, 0, 0, 0, 0, 0, 0, + 0, 1052, 0, 0, 0, 0, 928, 0, 0, 965, + 1033, 1032, 952, 962, 0, 0, 353, 260, 600, 723, + 602, 601, 953, 0, 954, 958, 961, 957, 955, 956, + 0, 1047, 0, 0, 0, 0, 0, 0, 920, 932, + 0, 937, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 929, 930, 0, + 0, 0, 0, 986, 0, 931, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 981, 959, + 963, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 960, 0, 984, 988, 378, 1070, 982, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 1071, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 979, 0, 720, + 0, 554, 0, 0, 1054, 0, 0, 0, 523, 0, + 0, 436, 0, 0, 0, 983, 0, 505, 478, 1067, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 0, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 1051, 474, 682, 718, 719, 607, 0, 1066, 1046, + 1048, 1049, 1053, 1057, 1058, 1059, 1060, 1061, 1063, 1065, + 1069, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 1068, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 987, 658, 659, 462, 463, 464, 465, 1055, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 1077, 1050, 1076, 1078, 1079, 1075, 1080, 1081, 1062, + 941, 0, 994, 995, 1073, 1072, 1074, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 948, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 1040, 1003, 1004, 1005, 938, 1006, 1000, 1001, + 939, 1002, 1041, 992, 1037, 1038, 967, 997, 1007, 1036, + 1008, 1039, 968, 1042, 1082, 1083, 1014, 998, 291, 1084, + 1011, 1043, 1035, 1034, 1009, 993, 1044, 1045, 975, 970, + 1012, 1013, 999, 1020, 1021, 1022, 1025, 940, 1026, 1027, + 1028, 1029, 1030, 1024, 1023, 989, 990, 991, 1015, 1016, + 1018, 1019, 996, 524, 971, 972, 973, 974, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 1031, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 1017, 731, 732, + 729, 447, 507, 529, 515, 985, 755, 603, 604, 756, + 717, 331, 0, 933, 476, 0, 0, 618, 652, 641, + 727, 606, 0, 0, 0, 0, 0, 0, 936, 0, + 0, 0, 385, 2200, 0, 442, 656, 637, 648, 638, + 482, 623, 624, 625, 632, 397, 626, 757, 628, 598, + 629, 599, 630, 631, 976, 655, 605, 517, 458, 0, + 672, 0, 0, 1056, 1064, 0, 0, 0, 0, 0, + 0, 0, 0, 1052, 0, 2433, 0, 0, 928, 0, + 0, 965, 1033, 1032, 952, 962, 0, 0, 353, 260, + 600, 723, 602, 601, 953, 0, 954, 958, 961, 957, + 955, 956, 0, 1047, 0, 0, 0, 0, 0, 0, + 920, 932, 0, 937, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 929, + 930, 0, 0, 0, 0, 986, 0, 931, 0, 0, + 0, 0, 0, 518, 547, 0, 560, 0, 422, 423, + 2434, 959, 963, 0, 0, 0, 0, 338, 525, 544, + 354, 512, 558, 359, 520, 537, 349, 475, 509, 0, + 0, 340, 542, 519, 455, 339, 0, 502, 382, 399, + 379, 473, 960, 0, 984, 988, 378, 1070, 982, 552, + 342, 0, 551, 472, 538, 543, 456, 449, 0, 341, + 540, 454, 448, 433, 389, 1071, 434, 435, 403, 488, + 446, 489, 404, 460, 459, 461, 405, 406, 407, 408, + 409, 410, 411, 412, 413, 414, 0, 0, 0, 0, + 0, 582, 583, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 716, 979, + 0, 720, 0, 554, 0, 0, 1054, 0, 0, 0, + 523, 0, 0, 436, 0, 0, 0, 983, 0, 505, + 478, 1067, 0, 0, 503, 444, 539, 490, 545, 526, + 553, 497, 491, 332, 527, 381, 457, 350, 352, 748, + 383, 386, 390, 391, 466, 467, 484, 511, 530, 531, + 532, 380, 364, 504, 365, 400, 366, 333, 372, 370, + 373, 513, 374, 335, 485, 536, 0, 396, 500, 452, + 336, 451, 486, 535, 534, 351, 562, 569, 570, 660, + 0, 575, 760, 761, 762, 584, 0, 492, 347, 344, + 0, 0, 0, 376, 487, 360, 362, 363, 361, 481, + 483, 589, 590, 591, 593, 0, 594, 595, 0, 0, + 0, 0, 596, 661, 677, 645, 614, 577, 669, 611, + 615, 616, 417, 418, 419, 680, 0, 0, 0, 568, + 437, 438, 0, 388, 387, 453, 337, 0, 0, 430, + 416, 493, 343, 384, 432, 421, 439, 440, 441, 394, + 327, 328, 754, 1051, 474, 682, 718, 719, 607, 0, + 1066, 1046, 1048, 1049, 1053, 1057, 1058, 1059, 1060, 1061, + 1063, 1065, 1069, 753, 0, 662, 676, 758, 675, 750, + 480, 0, 510, 673, 620, 0, 666, 639, 640, 0, + 667, 635, 671, 0, 609, 0, 578, 581, 610, 695, + 696, 697, 334, 580, 699, 700, 701, 702, 703, 704, + 705, 698, 1068, 643, 619, 646, 559, 622, 621, 0, + 0, 657, 987, 658, 659, 462, 463, 464, 465, 1055, + 683, 358, 579, 495, 496, 0, 644, 0, 0, 0, + 0, 0, 0, 0, 0, 649, 650, 647, 763, 0, + 706, 707, 0, 0, 573, 574, 393, 0, 592, 401, + 357, 479, 395, 557, 424, 0, 585, 651, 586, 498, + 499, 710, 715, 711, 712, 714, 734, 469, 415, 420, + 514, 431, 445, 501, 556, 477, 506, 355, 546, 516, + 450, 636, 664, 1077, 1050, 1076, 1078, 1079, 1075, 1080, + 1081, 1062, 941, 0, 994, 995, 1073, 1072, 1074, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 691, 690, 689, 688, 687, 686, 685, 684, 0, 0, + 633, 533, 371, 321, 367, 368, 375, 751, 747, 752, + 735, 738, 737, 713, 948, 329, 613, 443, 494, 392, + 678, 679, 0, 733, 1040, 1003, 1004, 1005, 938, 1006, + 1000, 1001, 939, 1002, 1041, 992, 1037, 1038, 967, 997, + 1007, 1036, 1008, 1039, 968, 1042, 1082, 1083, 1014, 998, + 291, 1084, 1011, 1043, 1035, 1034, 1009, 993, 1044, 1045, + 975, 970, 1012, 1013, 999, 1020, 1021, 1022, 1025, 940, + 1026, 1027, 1028, 1029, 1030, 1024, 1023, 989, 990, 991, + 1015, 1016, 1018, 1019, 996, 524, 971, 972, 973, 974, + 0, 0, 563, 564, 565, 588, 0, 566, 548, 612, + 402, 330, 528, 555, 749, 0, 0, 0, 0, 0, + 0, 0, 663, 674, 708, 709, 0, 721, 722, 724, + 726, 1031, 728, 521, 522, 736, 0, 0, 425, 345, + 346, 470, 471, 508, 0, 426, 427, 428, 429, 1017, + 731, 732, 729, 447, 507, 529, 515, 0, 755, 603, + 604, 756, 717, 331, 0, 933, 195, 237, 985, 0, + 0, 0, 0, 0, 0, 0, 0, 476, 0, 0, + 618, 652, 641, 727, 606, 0, 0, 0, 0, 0, + 0, 936, 0, 0, 0, 385, 0, 0, 442, 656, + 637, 648, 638, 482, 623, 624, 625, 632, 397, 626, + 757, 628, 598, 629, 599, 630, 631, 1544, 655, 605, + 517, 458, 0, 672, 0, 0, 1056, 1064, 0, 0, + 0, 0, 0, 0, 0, 0, 1052, 0, 0, 0, + 0, 928, 0, 0, 965, 1033, 1032, 952, 962, 0, + 0, 353, 260, 600, 723, 602, 601, 953, 0, 954, + 958, 961, 957, 955, 956, 0, 1047, 0, 0, 0, + 0, 0, 0, 920, 932, 0, 937, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 929, 930, 0, 0, 0, 0, 986, 0, + 931, 0, 0, 0, 0, 0, 518, 547, 0, 560, + 0, 422, 423, 981, 959, 963, 0, 0, 0, 0, + 338, 525, 544, 354, 512, 558, 359, 520, 537, 349, + 475, 509, 0, 0, 340, 542, 519, 455, 339, 0, + 502, 382, 399, 379, 473, 960, 0, 984, 988, 378, + 1070, 982, 552, 342, 0, 551, 472, 538, 543, 456, + 449, 0, 341, 540, 454, 448, 433, 389, 1071, 434, + 435, 403, 488, 446, 489, 404, 460, 459, 461, 405, + 406, 407, 408, 409, 410, 411, 412, 413, 414, 0, + 0, 0, 0, 0, 582, 583, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 716, 979, 0, 720, 0, 554, 0, 0, 1054, + 0, 0, 0, 523, 0, 0, 436, 0, 0, 0, + 983, 0, 505, 478, 1067, 0, 0, 503, 444, 539, + 490, 545, 526, 553, 497, 491, 332, 527, 381, 457, + 350, 352, 748, 383, 386, 390, 391, 466, 467, 484, + 511, 530, 531, 532, 380, 364, 504, 365, 400, 366, + 333, 372, 370, 373, 513, 374, 335, 485, 536, 0, + 396, 500, 452, 336, 451, 486, 535, 534, 351, 562, + 569, 570, 660, 0, 575, 760, 761, 762, 584, 0, + 492, 347, 344, 0, 0, 0, 376, 487, 360, 362, + 363, 361, 481, 483, 589, 590, 591, 593, 0, 594, + 595, 0, 0, 0, 0, 596, 661, 677, 645, 614, + 577, 669, 611, 615, 616, 417, 418, 419, 680, 0, + 0, 0, 568, 437, 438, 0, 388, 387, 453, 337, + 0, 0, 430, 416, 493, 343, 384, 432, 421, 439, + 440, 441, 394, 327, 328, 754, 1051, 474, 682, 718, + 719, 607, 0, 1066, 1046, 1048, 1049, 1053, 1057, 1058, + 1059, 1060, 1061, 1063, 1065, 1069, 753, 0, 662, 676, + 758, 675, 750, 480, 0, 510, 673, 620, 0, 666, + 639, 640, 0, 667, 635, 671, 0, 609, 0, 578, + 581, 610, 695, 696, 697, 334, 580, 699, 700, 701, + 702, 703, 704, 705, 698, 1068, 643, 619, 646, 559, + 622, 621, 0, 0, 657, 987, 658, 659, 462, 463, + 464, 465, 1055, 683, 358, 579, 495, 496, 0, 644, + 0, 0, 0, 0, 0, 0, 0, 0, 649, 650, + 647, 763, 0, 706, 707, 0, 0, 573, 574, 393, + 0, 592, 401, 357, 479, 395, 557, 424, 0, 585, + 651, 586, 498, 499, 710, 715, 711, 712, 714, 734, + 469, 415, 420, 514, 431, 445, 501, 556, 477, 506, + 355, 546, 516, 450, 636, 664, 1077, 1050, 1076, 1078, + 1079, 1075, 1080, 1081, 1062, 941, 0, 994, 995, 1073, + 1072, 1074, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 691, 690, 689, 688, 687, 686, 685, + 684, 0, 0, 633, 533, 371, 321, 367, 368, 375, + 751, 747, 752, 735, 738, 737, 713, 948, 329, 613, + 443, 494, 392, 678, 679, 0, 733, 1040, 1003, 1004, + 1005, 938, 1006, 1000, 1001, 939, 1002, 1041, 992, 1037, + 1038, 967, 997, 1007, 1036, 1008, 1039, 968, 1042, 1082, + 1083, 1014, 998, 291, 1084, 1011, 1043, 1035, 1034, 1009, + 993, 1044, 1045, 975, 970, 1012, 1013, 999, 1020, 1021, + 1022, 1025, 940, 1026, 1027, 1028, 1029, 1030, 1024, 1023, + 989, 990, 991, 1015, 1016, 1018, 1019, 996, 524, 971, + 972, 973, 974, 0, 0, 563, 564, 565, 588, 0, + 566, 548, 612, 402, 330, 528, 555, 749, 0, 0, + 0, 0, 0, 0, 0, 663, 674, 708, 709, 0, + 721, 722, 724, 726, 1031, 728, 521, 522, 736, 0, + 0, 425, 345, 346, 470, 471, 508, 0, 426, 427, + 428, 429, 1017, 731, 732, 729, 447, 507, 529, 515, + 985, 755, 603, 604, 756, 717, 331, 0, 933, 476, + 0, 0, 618, 652, 641, 727, 606, 0, 0, 0, + 0, 0, 0, 936, 0, 0, 0, 385, 4955, 0, + 442, 656, 637, 648, 638, 482, 623, 624, 625, 632, + 397, 626, 757, 628, 598, 629, 599, 630, 631, 976, + 655, 605, 517, 458, 0, 672, 0, 0, 1056, 1064, + 0, 0, 0, 0, 0, 0, 0, 0, 1052, 0, + 0, 0, 0, 928, 0, 0, 965, 1033, 1032, 952, + 962, 0, 0, 353, 260, 600, 723, 602, 601, 953, + 0, 954, 958, 961, 957, 955, 956, 0, 1047, 0, + 0, 0, 0, 0, 0, 920, 932, 0, 937, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 929, 930, 0, 0, 0, 0, + 986, 0, 931, 0, 0, 0, 0, 0, 518, 547, + 0, 560, 0, 422, 423, 981, 959, 963, 0, 0, + 0, 0, 338, 525, 544, 354, 512, 558, 359, 520, + 537, 349, 475, 509, 0, 0, 340, 542, 519, 455, + 339, 0, 502, 382, 399, 379, 473, 960, 0, 984, + 988, 378, 1070, 982, 552, 342, 0, 551, 472, 538, + 543, 456, 449, 0, 341, 540, 454, 448, 433, 389, + 1071, 434, 435, 403, 488, 446, 489, 404, 460, 459, + 461, 405, 406, 407, 408, 409, 410, 411, 412, 413, + 414, 0, 0, 0, 0, 0, 582, 583, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 716, 979, 0, 720, 0, 554, 0, + 0, 1054, 0, 0, 0, 523, 0, 0, 436, 0, + 0, 0, 983, 0, 505, 478, 1067, 0, 0, 503, + 444, 539, 490, 545, 526, 553, 497, 491, 332, 527, + 381, 457, 350, 352, 748, 383, 386, 390, 391, 466, + 467, 484, 511, 530, 531, 532, 380, 364, 504, 365, + 400, 366, 333, 372, 370, 373, 513, 374, 335, 485, + 536, 0, 396, 500, 452, 336, 451, 486, 535, 534, + 351, 562, 569, 570, 660, 0, 575, 760, 761, 762, + 584, 0, 492, 347, 344, 0, 0, 0, 376, 487, + 360, 362, 363, 361, 481, 483, 589, 590, 591, 593, + 0, 594, 595, 0, 0, 0, 0, 596, 661, 677, + 645, 614, 577, 669, 611, 615, 616, 417, 418, 419, + 680, 0, 0, 0, 568, 437, 438, 0, 388, 387, + 453, 337, 0, 0, 430, 416, 493, 343, 384, 432, + 421, 439, 440, 441, 394, 327, 328, 754, 1051, 474, + 682, 718, 719, 607, 0, 1066, 1046, 1048, 1049, 1053, + 1057, 1058, 1059, 1060, 1061, 1063, 1065, 1069, 753, 0, + 662, 676, 758, 675, 750, 480, 0, 510, 673, 620, + 0, 666, 639, 640, 0, 667, 635, 671, 0, 609, + 0, 578, 581, 610, 695, 696, 697, 334, 580, 699, + 700, 701, 702, 703, 704, 705, 698, 1068, 643, 619, + 646, 559, 622, 621, 0, 0, 657, 987, 658, 659, + 462, 463, 464, 465, 1055, 683, 358, 579, 495, 496, + 0, 644, 0, 0, 0, 0, 0, 0, 0, 0, + 649, 650, 647, 763, 0, 706, 707, 0, 0, 573, + 574, 393, 0, 592, 401, 357, 479, 395, 557, 424, + 0, 585, 651, 586, 498, 499, 710, 715, 711, 712, + 714, 734, 469, 415, 420, 514, 431, 445, 501, 556, + 477, 506, 355, 546, 516, 450, 636, 664, 1077, 1050, + 1076, 1078, 1079, 1075, 1080, 1081, 1062, 941, 0, 994, + 995, 1073, 1072, 1074, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 691, 690, 689, 688, 687, + 686, 685, 684, 0, 0, 633, 533, 371, 321, 367, + 368, 375, 751, 747, 752, 735, 738, 737, 713, 948, + 329, 613, 443, 494, 392, 678, 679, 0, 733, 1040, + 1003, 1004, 1005, 938, 1006, 1000, 1001, 939, 1002, 1041, + 992, 1037, 1038, 967, 997, 1007, 1036, 1008, 1039, 968, + 1042, 1082, 1083, 1014, 998, 291, 1084, 1011, 1043, 1035, + 1034, 1009, 993, 1044, 1045, 975, 970, 1012, 1013, 999, + 1020, 1021, 1022, 1025, 940, 1026, 1027, 1028, 1029, 1030, + 1024, 1023, 989, 990, 991, 1015, 1016, 1018, 1019, 996, + 524, 971, 972, 973, 974, 0, 0, 563, 564, 565, + 588, 0, 566, 548, 612, 402, 330, 528, 555, 749, + 0, 0, 0, 0, 0, 0, 0, 663, 674, 708, + 709, 0, 721, 722, 724, 726, 1031, 728, 521, 522, + 736, 0, 0, 425, 345, 346, 470, 471, 508, 0, + 426, 427, 428, 429, 1017, 731, 732, 729, 447, 507, + 529, 515, 985, 755, 603, 604, 756, 717, 331, 0, + 933, 476, 0, 0, 618, 652, 641, 727, 606, 0, + 0, 0, 0, 0, 0, 936, 0, 0, 0, 385, + 0, 0, 442, 656, 637, 648, 638, 482, 623, 624, + 625, 632, 397, 626, 757, 628, 598, 629, 599, 630, + 631, 976, 655, 605, 517, 458, 0, 672, 0, 0, + 1056, 1064, 0, 0, 0, 0, 0, 0, 0, 0, + 1052, 0, 0, 0, 0, 928, 0, 0, 965, 1033, + 1032, 952, 962, 0, 0, 353, 260, 600, 723, 602, + 601, 953, 0, 954, 958, 961, 957, 955, 956, 0, + 1047, 0, 0, 0, 0, 0, 0, 920, 932, 0, + 937, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 929, 930, 0, 0, + 0, 0, 986, 0, 931, 0, 0, 0, 0, 0, + 518, 547, 0, 560, 0, 422, 423, 981, 959, 963, + 0, 0, 0, 0, 338, 525, 544, 354, 512, 558, + 359, 520, 537, 349, 475, 509, 0, 0, 340, 542, + 519, 455, 339, 0, 502, 382, 399, 379, 473, 960, + 0, 984, 988, 378, 1070, 982, 552, 342, 0, 551, + 472, 538, 543, 456, 449, 0, 341, 540, 454, 448, + 433, 389, 1071, 434, 435, 403, 488, 446, 489, 404, + 460, 459, 461, 405, 406, 407, 408, 409, 410, 411, + 412, 413, 414, 0, 0, 0, 0, 0, 582, 583, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 716, 979, 0, 720, 0, + 554, 0, 0, 1054, 0, 0, 0, 523, 0, 0, + 436, 0, 0, 0, 983, 0, 505, 478, 1067, 4829, + 0, 503, 444, 539, 490, 545, 526, 553, 497, 491, + 332, 527, 381, 457, 350, 352, 748, 383, 386, 390, + 391, 466, 467, 484, 511, 530, 531, 532, 380, 364, + 504, 365, 400, 366, 333, 372, 370, 373, 513, 374, + 335, 485, 536, 0, 396, 500, 452, 336, 451, 486, + 535, 534, 351, 562, 569, 570, 660, 0, 575, 760, + 761, 762, 584, 0, 492, 347, 344, 0, 0, 0, + 376, 487, 360, 362, 363, 361, 481, 483, 589, 590, + 591, 593, 0, 594, 595, 0, 0, 0, 0, 596, + 661, 677, 645, 614, 577, 669, 611, 615, 616, 417, + 418, 419, 680, 0, 0, 0, 568, 437, 438, 0, + 388, 387, 453, 337, 0, 0, 430, 416, 493, 343, + 384, 432, 421, 439, 440, 441, 394, 327, 328, 754, + 1051, 474, 682, 718, 719, 607, 0, 1066, 1046, 1048, + 1049, 1053, 1057, 1058, 1059, 1060, 1061, 1063, 1065, 1069, + 753, 0, 662, 676, 758, 675, 750, 480, 0, 510, + 673, 620, 0, 666, 639, 640, 0, 667, 635, 671, + 0, 609, 0, 578, 581, 610, 695, 696, 697, 334, + 580, 699, 700, 701, 702, 703, 704, 705, 698, 1068, + 643, 619, 646, 559, 622, 621, 0, 0, 657, 987, + 658, 659, 462, 463, 464, 465, 1055, 683, 358, 579, + 495, 496, 0, 644, 0, 0, 0, 0, 0, 0, + 0, 0, 649, 650, 647, 763, 0, 706, 707, 0, + 0, 573, 574, 393, 0, 592, 401, 357, 479, 395, + 557, 424, 0, 585, 651, 586, 498, 499, 710, 715, + 711, 712, 714, 734, 469, 415, 420, 514, 431, 445, + 501, 556, 477, 506, 355, 546, 516, 450, 636, 664, + 1077, 1050, 1076, 1078, 1079, 1075, 1080, 1081, 1062, 941, + 0, 994, 995, 1073, 1072, 1074, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 691, 690, 689, + 688, 687, 686, 685, 684, 0, 0, 633, 533, 371, + 321, 367, 368, 375, 751, 747, 752, 735, 738, 737, + 713, 948, 329, 613, 443, 494, 392, 678, 679, 0, + 733, 1040, 1003, 1004, 1005, 938, 1006, 1000, 1001, 939, + 1002, 1041, 992, 1037, 1038, 967, 997, 1007, 1036, 1008, + 1039, 968, 1042, 1082, 1083, 1014, 998, 291, 1084, 1011, + 1043, 1035, 1034, 1009, 993, 1044, 1045, 975, 970, 1012, + 1013, 999, 1020, 1021, 1022, 1025, 940, 1026, 1027, 1028, + 1029, 1030, 1024, 1023, 989, 990, 991, 1015, 1016, 1018, + 1019, 996, 524, 971, 972, 973, 974, 0, 0, 563, + 564, 565, 588, 0, 566, 548, 612, 402, 330, 528, + 555, 749, 0, 0, 0, 0, 0, 0, 0, 663, + 674, 708, 709, 0, 721, 722, 724, 726, 1031, 728, + 521, 522, 736, 0, 0, 425, 345, 346, 470, 471, + 508, 0, 426, 427, 428, 429, 1017, 731, 732, 729, + 447, 507, 529, 515, 985, 755, 603, 604, 756, 717, + 331, 0, 933, 476, 0, 0, 618, 652, 641, 727, + 606, 0, 0, 0, 0, 0, 0, 936, 0, 0, + 0, 385, 2200, 0, 442, 656, 637, 648, 638, 482, + 623, 624, 625, 632, 397, 626, 757, 628, 598, 629, + 599, 630, 631, 976, 655, 605, 517, 458, 0, 672, + 0, 0, 1056, 1064, 0, 0, 0, 0, 0, 0, + 0, 0, 1052, 0, 0, 0, 0, 928, 0, 0, + 965, 1033, 1032, 952, 962, 0, 0, 353, 260, 600, + 723, 602, 601, 953, 0, 954, 958, 961, 957, 955, + 956, 0, 1047, 0, 0, 0, 0, 0, 0, 920, + 932, 0, 937, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 929, 930, + 0, 0, 0, 0, 986, 0, 931, 0, 0, 0, + 0, 0, 518, 547, 0, 560, 0, 422, 423, 981, + 959, 963, 0, 0, 0, 0, 338, 525, 544, 354, + 512, 558, 359, 520, 537, 349, 475, 509, 0, 0, + 340, 542, 519, 455, 339, 0, 502, 382, 399, 379, + 473, 960, 0, 984, 988, 378, 1070, 982, 552, 342, + 0, 551, 472, 538, 543, 456, 449, 0, 341, 540, + 454, 448, 433, 389, 1071, 434, 435, 403, 488, 446, + 489, 404, 460, 459, 461, 405, 406, 407, 408, 409, + 410, 411, 412, 413, 414, 0, 0, 0, 0, 0, + 582, 583, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 716, 979, 0, + 720, 0, 554, 0, 0, 1054, 0, 0, 0, 523, + 0, 0, 436, 0, 0, 0, 983, 0, 505, 478, + 1067, 0, 0, 503, 444, 539, 490, 545, 526, 553, + 497, 491, 332, 527, 381, 457, 350, 352, 748, 383, + 386, 390, 391, 466, 467, 484, 511, 530, 531, 532, + 380, 364, 504, 365, 400, 366, 333, 372, 370, 373, + 513, 374, 335, 485, 536, 0, 396, 500, 452, 336, + 451, 486, 535, 534, 351, 562, 569, 570, 660, 0, + 575, 760, 761, 762, 584, 0, 492, 347, 344, 0, + 0, 0, 376, 487, 360, 362, 363, 361, 481, 483, + 589, 590, 591, 593, 0, 594, 595, 0, 0, 0, + 0, 596, 661, 677, 645, 614, 577, 669, 611, 615, + 616, 417, 418, 419, 680, 0, 0, 0, 568, 437, + 438, 0, 388, 387, 453, 337, 0, 0, 430, 416, + 493, 343, 384, 432, 421, 439, 440, 441, 394, 327, + 328, 754, 1051, 474, 682, 718, 719, 607, 0, 1066, + 1046, 1048, 1049, 1053, 1057, 1058, 1059, 1060, 1061, 1063, + 1065, 1069, 753, 0, 662, 676, 758, 675, 750, 480, + 0, 510, 673, 620, 0, 666, 639, 640, 0, 667, + 635, 671, 0, 609, 0, 578, 581, 610, 695, 696, + 697, 334, 580, 699, 700, 701, 702, 703, 704, 705, + 698, 1068, 643, 619, 646, 559, 622, 621, 0, 0, + 657, 987, 658, 659, 462, 463, 464, 465, 1055, 683, + 358, 579, 495, 496, 0, 644, 0, 0, 0, 0, + 0, 0, 0, 0, 649, 650, 647, 763, 0, 706, + 707, 0, 0, 573, 574, 393, 0, 592, 401, 357, + 479, 395, 557, 424, 0, 585, 651, 586, 498, 499, + 710, 715, 711, 712, 714, 734, 469, 415, 420, 514, + 431, 445, 501, 556, 477, 506, 355, 546, 516, 450, + 636, 664, 1077, 1050, 1076, 1078, 1079, 1075, 1080, 1081, + 1062, 941, 0, 994, 995, 1073, 1072, 1074, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 691, + 690, 689, 688, 687, 686, 685, 684, 0, 0, 633, + 533, 371, 321, 367, 368, 375, 751, 747, 752, 735, + 738, 737, 713, 948, 329, 613, 443, 494, 392, 678, + 679, 0, 733, 1040, 1003, 1004, 1005, 938, 1006, 1000, + 1001, 939, 1002, 1041, 992, 1037, 1038, 967, 997, 1007, + 1036, 1008, 1039, 968, 1042, 1082, 1083, 1014, 998, 291, + 1084, 1011, 1043, 1035, 1034, 1009, 993, 1044, 1045, 975, + 970, 1012, 1013, 999, 1020, 1021, 1022, 1025, 940, 1026, + 1027, 1028, 1029, 1030, 1024, 1023, 989, 990, 991, 1015, + 1016, 1018, 1019, 996, 524, 971, 972, 973, 974, 0, + 0, 563, 564, 565, 588, 0, 566, 548, 612, 402, + 330, 528, 555, 749, 0, 0, 0, 0, 0, 0, + 0, 663, 674, 708, 709, 0, 721, 722, 724, 726, + 1031, 728, 521, 522, 736, 0, 0, 425, 345, 346, + 470, 471, 508, 0, 426, 427, 428, 429, 1017, 731, + 732, 729, 447, 507, 529, 515, 985, 755, 603, 604, + 756, 717, 331, 0, 933, 476, 0, 0, 618, 652, + 641, 727, 606, 0, 0, 0, 0, 0, 0, 936, + 0, 0, 0, 385, 0, 0, 442, 656, 637, 648, + 638, 482, 623, 624, 625, 632, 397, 626, 757, 628, + 598, 629, 599, 630, 631, 976, 655, 605, 517, 458, + 0, 672, 0, 0, 1056, 1064, 0, 0, 0, 0, + 0, 0, 0, 0, 1052, 0, 0, 0, 0, 928, + 0, 0, 965, 1033, 1032, 952, 962, 0, 0, 353, + 260, 600, 723, 602, 601, 953, 0, 954, 958, 961, + 957, 955, 956, 0, 1047, 0, 0, 0, 0, 0, + 0, 920, 932, 0, 937, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 929, 930, 1831, 0, 0, 0, 986, 0, 931, 0, + 0, 0, 0, 0, 518, 547, 0, 560, 0, 422, + 423, 981, 959, 963, 0, 0, 0, 0, 338, 525, + 544, 354, 512, 558, 359, 520, 537, 349, 475, 509, + 0, 0, 340, 542, 519, 455, 339, 0, 502, 382, + 399, 379, 473, 960, 0, 984, 988, 378, 1070, 982, + 552, 342, 0, 551, 472, 538, 543, 456, 449, 0, + 341, 540, 454, 448, 433, 389, 1071, 434, 435, 403, + 488, 446, 489, 404, 460, 459, 461, 405, 406, 407, + 408, 409, 410, 411, 412, 413, 414, 0, 0, 0, + 0, 0, 582, 583, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 716, + 979, 0, 720, 0, 554, 0, 0, 1054, 0, 0, + 0, 523, 0, 0, 436, 0, 0, 0, 983, 0, + 505, 478, 1067, 0, 0, 503, 444, 539, 490, 545, + 526, 553, 497, 491, 332, 527, 381, 457, 350, 352, + 748, 383, 386, 390, 391, 466, 467, 484, 511, 530, + 531, 532, 380, 364, 504, 365, 400, 366, 333, 372, + 370, 373, 513, 374, 335, 485, 536, 0, 396, 500, + 452, 336, 451, 486, 535, 534, 351, 562, 569, 570, + 660, 0, 575, 760, 761, 762, 584, 0, 492, 347, + 344, 0, 0, 0, 376, 487, 360, 362, 363, 361, + 481, 483, 589, 590, 591, 593, 0, 594, 595, 0, + 0, 0, 0, 596, 661, 677, 645, 614, 577, 669, + 611, 615, 616, 417, 418, 419, 680, 0, 0, 0, + 568, 437, 438, 0, 388, 387, 453, 337, 0, 0, + 430, 416, 493, 343, 384, 432, 421, 439, 440, 441, + 394, 327, 328, 754, 1051, 474, 682, 718, 719, 607, + 0, 1066, 1046, 1048, 1049, 1053, 1057, 1058, 1059, 1060, + 1061, 1063, 1065, 1069, 753, 0, 662, 676, 758, 675, + 750, 480, 0, 510, 673, 620, 0, 666, 639, 640, + 0, 667, 635, 671, 0, 609, 0, 578, 581, 610, + 695, 696, 697, 334, 580, 699, 700, 701, 702, 703, + 704, 705, 698, 1068, 643, 619, 646, 559, 622, 621, + 0, 0, 657, 987, 658, 659, 462, 463, 464, 465, + 1055, 683, 358, 579, 495, 496, 0, 644, 0, 0, + 0, 0, 0, 0, 0, 0, 649, 650, 647, 763, + 0, 706, 707, 0, 0, 573, 574, 393, 0, 592, + 401, 357, 479, 395, 557, 424, 0, 585, 651, 586, + 498, 499, 710, 715, 711, 712, 714, 734, 469, 415, + 420, 514, 431, 445, 501, 556, 477, 506, 355, 546, + 516, 450, 636, 664, 1077, 1050, 1076, 1078, 1079, 1075, + 1080, 1081, 1062, 941, 0, 994, 995, 1073, 1072, 1074, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 691, 690, 689, 688, 687, 686, 685, 684, 0, + 0, 633, 533, 371, 321, 367, 368, 375, 751, 747, + 752, 735, 738, 737, 713, 948, 329, 613, 443, 494, + 392, 678, 679, 0, 733, 1040, 1003, 1004, 1005, 938, + 1006, 1000, 1001, 939, 1002, 1041, 992, 1037, 1038, 967, + 997, 1007, 1036, 1008, 1039, 968, 1042, 1082, 1083, 1014, + 998, 291, 1084, 1011, 1043, 1035, 1034, 1009, 993, 1044, + 1045, 975, 970, 1012, 1013, 999, 1020, 1021, 1022, 1025, + 940, 1026, 1027, 1028, 1029, 1030, 1024, 1023, 989, 990, + 991, 1015, 1016, 1018, 1019, 996, 524, 971, 972, 973, + 974, 0, 0, 563, 564, 565, 588, 0, 566, 548, + 612, 402, 330, 528, 555, 749, 0, 0, 0, 0, + 0, 0, 0, 663, 674, 708, 709, 0, 721, 722, + 724, 726, 1031, 728, 521, 522, 736, 0, 0, 425, + 345, 346, 470, 471, 508, 0, 426, 427, 428, 429, + 1017, 731, 732, 729, 447, 507, 529, 515, 0, 755, + 603, 604, 756, 717, 331, 985, 933, 0, 2655, 0, + 0, 0, 0, 0, 476, 0, 0, 618, 652, 641, + 727, 606, 0, 0, 0, 0, 0, 0, 936, 0, + 0, 0, 385, 0, 0, 442, 656, 637, 648, 638, + 482, 623, 624, 625, 632, 397, 626, 757, 628, 598, + 629, 599, 630, 631, 976, 655, 605, 517, 458, 0, + 672, 0, 0, 1056, 1064, 0, 0, 0, 0, 0, + 0, 0, 0, 1052, 0, 0, 0, 0, 928, 0, + 0, 965, 1033, 1032, 952, 962, 0, 0, 353, 260, + 600, 723, 602, 601, 953, 0, 954, 958, 961, 957, + 955, 956, 0, 1047, 0, 0, 0, 0, 0, 0, + 920, 932, 0, 937, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 929, + 930, 0, 0, 0, 0, 986, 0, 931, 0, 0, + 0, 0, 0, 518, 547, 0, 560, 0, 422, 423, + 981, 959, 963, 0, 0, 0, 0, 338, 525, 544, + 354, 512, 558, 359, 520, 537, 349, 475, 509, 0, + 0, 340, 542, 519, 455, 339, 0, 502, 382, 399, + 379, 473, 960, 0, 984, 988, 378, 1070, 982, 552, + 342, 0, 551, 472, 538, 543, 456, 449, 0, 341, + 540, 454, 448, 433, 389, 1071, 434, 435, 403, 488, + 446, 489, 404, 460, 459, 461, 405, 406, 407, 408, + 409, 410, 411, 412, 413, 414, 0, 0, 0, 0, + 0, 582, 583, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 716, 979, + 0, 720, 0, 554, 0, 0, 1054, 0, 0, 0, + 523, 0, 0, 436, 0, 0, 0, 983, 0, 505, + 478, 1067, 0, 0, 503, 444, 539, 490, 545, 526, + 553, 497, 491, 332, 527, 381, 457, 350, 352, 748, + 383, 386, 390, 391, 466, 467, 484, 511, 530, 531, + 532, 380, 364, 504, 365, 400, 366, 333, 372, 370, + 373, 513, 374, 335, 485, 536, 0, 396, 500, 452, + 336, 451, 486, 535, 534, 351, 562, 569, 570, 660, + 0, 575, 760, 761, 762, 584, 0, 492, 347, 344, + 0, 0, 0, 376, 487, 360, 362, 363, 361, 481, + 483, 589, 590, 591, 593, 0, 594, 595, 0, 0, + 0, 0, 596, 661, 677, 645, 614, 577, 669, 611, + 615, 616, 417, 418, 419, 680, 0, 0, 0, 568, + 437, 438, 0, 388, 387, 453, 337, 0, 0, 430, + 416, 493, 343, 384, 432, 421, 439, 440, 441, 394, + 327, 328, 754, 1051, 474, 682, 718, 719, 607, 0, + 1066, 1046, 1048, 1049, 1053, 1057, 1058, 1059, 1060, 1061, + 1063, 1065, 1069, 753, 0, 662, 676, 758, 675, 750, + 480, 0, 510, 673, 620, 0, 666, 639, 640, 0, + 667, 635, 671, 0, 609, 0, 578, 581, 610, 695, + 696, 697, 334, 580, 699, 700, 701, 702, 703, 704, + 705, 698, 1068, 643, 619, 646, 559, 622, 621, 0, + 0, 657, 987, 658, 659, 462, 463, 464, 465, 1055, + 683, 358, 579, 495, 496, 0, 644, 0, 0, 0, + 0, 0, 0, 0, 0, 649, 650, 647, 763, 0, + 706, 707, 0, 0, 573, 574, 393, 0, 592, 401, + 357, 479, 395, 557, 424, 0, 585, 651, 586, 498, + 499, 710, 715, 711, 712, 714, 734, 469, 415, 420, + 514, 431, 445, 501, 556, 477, 506, 355, 546, 516, + 450, 636, 664, 1077, 1050, 1076, 1078, 1079, 1075, 1080, + 1081, 1062, 941, 0, 994, 995, 1073, 1072, 1074, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 691, 690, 689, 688, 687, 686, 685, 684, 0, 0, + 633, 533, 371, 321, 367, 368, 375, 751, 747, 752, + 735, 738, 737, 713, 948, 329, 613, 443, 494, 392, + 678, 679, 0, 733, 1040, 1003, 1004, 1005, 938, 1006, + 1000, 1001, 939, 1002, 1041, 992, 1037, 1038, 967, 997, + 1007, 1036, 1008, 1039, 968, 1042, 1082, 1083, 1014, 998, + 291, 1084, 1011, 1043, 1035, 1034, 1009, 993, 1044, 1045, + 975, 970, 1012, 1013, 999, 1020, 1021, 1022, 1025, 940, + 1026, 1027, 1028, 1029, 1030, 1024, 1023, 989, 990, 991, + 1015, 1016, 1018, 1019, 996, 524, 971, 972, 973, 974, + 0, 0, 563, 564, 565, 588, 0, 566, 548, 612, + 402, 330, 528, 555, 749, 0, 0, 0, 0, 0, + 0, 0, 663, 674, 708, 709, 0, 721, 722, 724, + 726, 1031, 728, 521, 522, 736, 0, 0, 425, 345, + 346, 470, 471, 508, 0, 426, 427, 428, 429, 1017, + 731, 732, 729, 447, 507, 529, 515, 985, 755, 603, + 604, 756, 717, 331, 0, 933, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 936, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 976, 655, 605, 517, + 458, 0, 672, 0, 0, 1056, 1064, 0, 0, 0, + 0, 0, 0, 0, 0, 1052, 0, 0, 0, 0, + 928, 0, 0, 965, 1033, 1032, 952, 962, 0, 0, + 353, 260, 600, 723, 602, 601, 953, 0, 954, 958, + 961, 957, 955, 956, 0, 1047, 0, 0, 0, 0, + 0, 0, 920, 932, 0, 937, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 929, 930, 2193, 0, 0, 0, 986, 0, 931, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 981, 959, 963, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 960, 0, 984, 988, 378, 1070, + 982, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 1071, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 979, 0, 720, 0, 554, 0, 0, 1054, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 983, + 0, 505, 478, 1067, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 1051, 474, 682, 718, 719, + 607, 0, 1066, 1046, 1048, 1049, 1053, 1057, 1058, 1059, + 1060, 1061, 1063, 1065, 1069, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 1068, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 987, 658, 659, 462, 463, 464, + 465, 1055, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 1077, 1050, 1076, 1078, 1079, + 1075, 1080, 1081, 1062, 941, 0, 994, 995, 1073, 1072, + 1074, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 948, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 1040, 1003, 1004, 1005, + 938, 1006, 1000, 1001, 939, 1002, 1041, 992, 1037, 1038, + 967, 997, 1007, 1036, 1008, 1039, 968, 1042, 1082, 1083, + 1014, 998, 291, 1084, 1011, 1043, 1035, 1034, 1009, 993, + 1044, 1045, 975, 970, 1012, 1013, 999, 1020, 1021, 1022, + 1025, 940, 1026, 1027, 1028, 1029, 1030, 1024, 1023, 989, + 990, 991, 1015, 1016, 1018, 1019, 996, 524, 971, 972, + 973, 974, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 1031, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 1017, 731, 732, 729, 447, 507, 529, 515, 985, + 755, 603, 604, 756, 717, 331, 0, 933, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 936, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 976, 655, + 605, 517, 458, 0, 672, 0, 0, 1056, 1064, 0, + 0, 0, 0, 0, 0, 0, 0, 1052, 0, 0, + 0, 0, 928, 0, 0, 965, 1033, 1032, 952, 962, + 0, 0, 353, 260, 600, 723, 602, 601, 953, 0, + 954, 958, 961, 957, 955, 956, 0, 1047, 0, 0, + 0, 0, 0, 0, 920, 932, 0, 937, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 929, 930, 0, 0, 0, 0, 986, + 0, 931, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 981, 959, 963, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 960, 0, 984, 988, + 378, 1070, 982, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 1071, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 979, 0, 720, 0, 554, 0, 0, + 1054, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 983, 0, 505, 478, 1067, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 1051, 474, 682, + 718, 719, 607, 0, 1066, 1046, 1048, 1049, 1053, 1057, + 1058, 1059, 1060, 1061, 1063, 1065, 1069, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 1068, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 987, 658, 659, 462, + 463, 464, 465, 1055, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 1077, 1050, 1076, + 1078, 1079, 1075, 1080, 1081, 1062, 941, 0, 994, 995, + 1073, 1072, 1074, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 948, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 1040, 1003, + 1004, 1005, 938, 1006, 1000, 1001, 939, 1002, 1041, 992, + 1037, 1038, 967, 997, 1007, 1036, 1008, 1039, 968, 1042, + 1082, 1083, 1014, 998, 291, 1084, 1011, 1043, 1035, 1034, + 1009, 993, 1044, 1045, 975, 970, 1012, 1013, 999, 1020, + 1021, 1022, 1025, 940, 1026, 1027, 1028, 1029, 1030, 1024, + 1023, 989, 990, 991, 1015, 1016, 1018, 1019, 996, 524, + 971, 972, 973, 974, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 1031, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 1017, 731, 732, 729, 447, 507, 529, + 515, 985, 755, 603, 604, 756, 717, 331, 0, 933, + 476, 0, 0, 618, 652, 641, 727, 606, 0, 0, + 0, 0, 0, 0, 936, 0, 0, 0, 385, 0, + 0, 442, 656, 637, 648, 638, 482, 623, 624, 625, + 632, 397, 626, 757, 628, 598, 629, 599, 630, 631, + 976, 655, 605, 517, 458, 0, 672, 0, 0, 1056, + 1064, 0, 0, 0, 0, 0, 0, 0, 0, 1052, + 0, 0, 0, 0, 928, 0, 0, 965, 1033, 1032, + 952, 962, 0, 0, 353, 260, 600, 723, 602, 601, + 953, 0, 954, 958, 961, 957, 955, 956, 0, 1047, + 0, 0, 0, 0, 0, 0, 920, 932, 0, 937, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 929, 930, 0, 0, 0, + 0, 986, 0, 931, 0, 0, 0, 0, 0, 518, + 547, 0, 560, 0, 422, 423, 981, 959, 963, 0, + 0, 0, 0, 338, 525, 544, 354, 512, 558, 359, + 520, 537, 349, 475, 509, 0, 0, 340, 542, 519, + 455, 339, 0, 502, 382, 399, 379, 473, 960, 0, + 984, 988, 378, 1070, 982, 552, 342, 0, 551, 472, + 538, 543, 456, 449, 0, 341, 540, 454, 448, 433, + 389, 1071, 434, 435, 403, 488, 446, 489, 404, 460, + 459, 461, 405, 406, 407, 408, 409, 410, 411, 412, + 413, 414, 0, 0, 0, 0, 0, 582, 583, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 716, 979, 0, 720, 0, 554, + 0, 0, 1054, 0, 0, 0, 523, 0, 0, 436, + 0, 0, 0, 983, 0, 505, 478, 1067, 0, 0, + 503, 444, 539, 490, 545, 526, 553, 497, 491, 332, + 527, 381, 457, 350, 352, 748, 383, 386, 390, 391, + 466, 467, 484, 511, 530, 531, 532, 380, 364, 504, + 365, 400, 366, 333, 372, 370, 373, 513, 374, 335, + 485, 536, 0, 396, 500, 452, 336, 451, 486, 535, + 534, 351, 562, 569, 570, 660, 0, 575, 760, 761, + 762, 584, 0, 492, 347, 344, 0, 0, 0, 376, + 487, 360, 362, 363, 361, 481, 483, 589, 590, 591, + 593, 0, 594, 595, 0, 0, 0, 0, 596, 661, + 677, 645, 614, 577, 669, 611, 615, 616, 417, 418, + 419, 680, 0, 0, 0, 568, 437, 438, 0, 388, + 387, 453, 337, 0, 0, 430, 416, 493, 343, 384, + 432, 421, 439, 440, 441, 394, 327, 328, 754, 1051, + 474, 682, 718, 719, 607, 0, 1066, 1046, 1048, 1049, + 1053, 1057, 1058, 1059, 1060, 1061, 1063, 1065, 1069, 753, + 0, 662, 676, 758, 675, 750, 480, 0, 510, 673, + 620, 0, 666, 639, 640, 0, 667, 635, 671, 0, + 609, 0, 578, 581, 610, 695, 696, 697, 334, 580, + 699, 700, 701, 702, 703, 704, 705, 698, 1068, 643, + 619, 646, 559, 622, 621, 0, 0, 657, 987, 658, + 659, 462, 463, 464, 465, 1055, 683, 358, 579, 495, + 496, 0, 644, 0, 0, 0, 0, 0, 0, 0, + 0, 649, 650, 647, 763, 0, 706, 707, 0, 0, + 573, 574, 393, 0, 592, 401, 357, 479, 395, 557, + 424, 0, 585, 651, 586, 498, 499, 710, 715, 711, + 712, 714, 734, 469, 415, 420, 514, 431, 445, 501, + 556, 477, 506, 355, 546, 516, 450, 636, 664, 1077, + 1050, 1076, 1078, 1079, 1075, 1080, 1081, 1062, 941, 0, + 994, 995, 1073, 1072, 1074, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 691, 690, 689, 688, + 687, 686, 685, 684, 0, 0, 633, 533, 371, 321, + 367, 368, 375, 751, 747, 752, 735, 738, 737, 713, + 948, 329, 613, 443, 494, 392, 678, 679, 0, 733, + 1040, 1003, 1004, 1005, 938, 1006, 1000, 1001, 939, 1002, + 1041, 992, 1037, 1038, 967, 997, 1007, 1036, 1008, 1039, + 968, 1042, 1082, 1083, 1014, 998, 291, 1084, 1011, 1043, + 1035, 1034, 1009, 993, 1044, 1045, 975, 970, 1012, 1013, + 999, 1020, 1021, 1022, 1025, 940, 1026, 1027, 1028, 1029, + 1030, 1024, 1023, 989, 990, 991, 1015, 1016, 1018, 1019, + 996, 524, 971, 972, 973, 974, 0, 0, 563, 564, + 565, 588, 0, 566, 548, 612, 402, 330, 528, 555, + 749, 0, 0, 0, 0, 0, 0, 0, 663, 674, + 708, 709, 0, 721, 722, 724, 726, 1031, 728, 521, + 522, 736, 0, 0, 425, 345, 346, 470, 471, 508, + 0, 426, 427, 428, 429, 4234, 731, 4235, 4236, 447, + 507, 529, 515, 985, 755, 603, 604, 756, 717, 331, + 0, 933, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 0, 0, 0, 0, 936, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 976, 655, 605, 517, 458, 0, 672, 0, + 0, 1056, 1064, 0, 0, 0, 0, 0, 0, 0, + 0, 1052, 0, 0, 0, 0, 928, 0, 0, 965, + 1033, 1032, 952, 962, 0, 0, 353, 260, 600, 723, + 602, 601, 3237, 0, 3238, 958, 961, 957, 955, 956, + 0, 1047, 0, 0, 0, 0, 0, 0, 920, 932, + 0, 937, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 929, 930, 0, + 0, 0, 0, 986, 0, 931, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 981, 959, + 963, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 960, 0, 984, 988, 378, 1070, 982, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 1071, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 979, 0, 720, + 0, 554, 0, 0, 1054, 0, 0, 0, 523, 0, + 0, 436, 0, 0, 0, 983, 0, 505, 478, 1067, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 0, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 1051, 474, 682, 718, 719, 607, 0, 1066, 1046, + 1048, 1049, 1053, 1057, 1058, 1059, 1060, 1061, 1063, 1065, + 1069, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 1068, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 987, 658, 659, 462, 463, 464, 465, 1055, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 1077, 1050, 1076, 1078, 1079, 1075, 1080, 1081, 1062, + 941, 0, 994, 995, 1073, 1072, 1074, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 948, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 1040, 1003, 1004, 1005, 938, 1006, 1000, 1001, + 939, 1002, 1041, 992, 1037, 1038, 967, 997, 1007, 1036, + 1008, 1039, 968, 1042, 1082, 1083, 1014, 998, 291, 1084, + 1011, 1043, 1035, 1034, 1009, 993, 1044, 1045, 975, 970, + 1012, 1013, 999, 1020, 1021, 1022, 1025, 940, 1026, 1027, + 1028, 1029, 1030, 1024, 1023, 989, 990, 991, 1015, 1016, + 1018, 1019, 996, 524, 971, 972, 973, 974, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 1031, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 1017, 731, 732, + 729, 447, 507, 529, 515, 985, 755, 603, 604, 756, + 717, 331, 0, 933, 476, 0, 0, 618, 652, 641, + 727, 606, 0, 0, 2033, 0, 0, 0, 936, 0, + 0, 0, 385, 0, 0, 442, 656, 637, 648, 638, + 482, 623, 624, 625, 632, 397, 626, 757, 628, 598, + 629, 599, 630, 631, 976, 655, 605, 517, 458, 0, + 672, 0, 0, 1056, 1064, 0, 0, 0, 0, 0, + 0, 0, 0, 1052, 0, 0, 0, 0, 928, 0, + 0, 965, 1033, 1032, 952, 962, 0, 0, 353, 260, + 600, 723, 602, 601, 953, 0, 954, 958, 961, 957, + 955, 956, 0, 1047, 0, 0, 0, 0, 0, 0, + 0, 932, 0, 937, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 929, + 930, 0, 0, 0, 0, 986, 0, 931, 0, 0, + 0, 0, 0, 518, 547, 0, 560, 0, 422, 423, + 981, 959, 963, 0, 0, 0, 0, 338, 525, 544, + 354, 512, 558, 359, 520, 537, 349, 475, 509, 0, + 0, 340, 542, 519, 455, 339, 0, 502, 382, 399, + 379, 473, 960, 0, 984, 988, 378, 1070, 982, 552, + 342, 0, 551, 472, 538, 543, 456, 449, 0, 341, + 540, 454, 448, 433, 389, 1071, 434, 435, 403, 488, + 446, 489, 404, 460, 459, 461, 405, 406, 407, 408, + 409, 410, 411, 412, 413, 414, 0, 0, 0, 0, + 0, 582, 583, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 716, 979, + 0, 720, 0, 554, 0, 0, 1054, 0, 0, 0, + 523, 0, 0, 436, 0, 0, 0, 983, 0, 505, + 478, 1067, 0, 0, 503, 444, 539, 490, 545, 526, + 553, 497, 491, 332, 527, 381, 457, 350, 352, 748, + 383, 386, 390, 391, 466, 467, 484, 511, 530, 531, + 532, 380, 364, 504, 365, 400, 366, 333, 372, 370, + 373, 513, 374, 335, 485, 536, 0, 396, 500, 452, + 336, 451, 486, 535, 534, 351, 562, 2034, 2035, 660, + 0, 575, 760, 761, 762, 584, 0, 492, 347, 344, + 0, 0, 0, 376, 487, 360, 362, 363, 361, 481, + 483, 589, 590, 591, 593, 0, 594, 595, 0, 0, + 0, 0, 596, 661, 677, 645, 614, 577, 669, 611, + 615, 616, 417, 418, 419, 680, 0, 0, 0, 568, + 437, 438, 0, 388, 387, 453, 337, 0, 0, 430, + 416, 493, 343, 384, 432, 421, 439, 440, 441, 394, + 327, 328, 754, 1051, 474, 682, 718, 719, 607, 0, + 1066, 1046, 1048, 1049, 1053, 1057, 1058, 1059, 1060, 1061, + 1063, 1065, 1069, 753, 0, 662, 676, 758, 675, 750, + 480, 0, 510, 673, 620, 0, 666, 639, 640, 0, + 667, 635, 671, 0, 609, 0, 578, 581, 610, 695, + 696, 697, 334, 580, 699, 700, 701, 702, 703, 704, + 705, 698, 1068, 643, 619, 646, 559, 622, 621, 0, + 0, 657, 987, 658, 659, 462, 463, 464, 465, 1055, + 683, 358, 579, 495, 496, 0, 644, 0, 0, 0, + 0, 0, 0, 0, 0, 649, 650, 647, 763, 0, + 706, 707, 0, 0, 573, 574, 393, 0, 592, 401, + 357, 479, 395, 557, 424, 0, 585, 651, 586, 498, + 499, 710, 715, 711, 712, 714, 734, 469, 415, 420, + 514, 431, 445, 501, 556, 477, 506, 355, 546, 516, + 450, 636, 664, 1077, 1050, 1076, 1078, 1079, 1075, 1080, + 1081, 1062, 941, 0, 994, 995, 1073, 1072, 1074, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 691, 690, 689, 688, 687, 686, 685, 684, 0, 0, + 633, 533, 371, 321, 367, 368, 375, 751, 747, 752, + 735, 738, 737, 713, 948, 329, 613, 443, 494, 392, + 678, 679, 0, 733, 1040, 1003, 1004, 1005, 938, 1006, + 1000, 1001, 939, 1002, 1041, 992, 1037, 1038, 967, 997, + 1007, 1036, 1008, 1039, 968, 1042, 1082, 1083, 1014, 998, + 291, 1084, 1011, 1043, 1035, 1034, 1009, 993, 1044, 1045, + 975, 970, 1012, 1013, 999, 1020, 1021, 1022, 1025, 940, + 1026, 1027, 1028, 1029, 1030, 1024, 1023, 989, 990, 991, + 1015, 1016, 1018, 1019, 996, 524, 971, 972, 973, 974, + 0, 0, 563, 564, 565, 588, 0, 566, 548, 612, + 402, 330, 528, 555, 749, 0, 0, 0, 0, 0, + 0, 0, 663, 674, 708, 709, 0, 721, 722, 724, + 726, 1031, 728, 521, 522, 736, 0, 0, 425, 345, + 346, 470, 471, 508, 0, 426, 427, 428, 429, 1017, + 731, 732, 729, 447, 507, 529, 515, 985, 755, 603, + 604, 756, 717, 331, 0, 933, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 936, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 976, 655, 605, 517, + 458, 0, 672, 0, 0, 1056, 1064, 0, 0, 0, + 0, 0, 0, 0, 0, 1052, 0, 0, 0, 0, + 1561, 0, 0, 965, 1033, 1032, 952, 962, 0, 0, + 353, 260, 600, 723, 602, 601, 953, 0, 954, 958, + 961, 957, 955, 956, 0, 1047, 0, 0, 0, 0, + 0, 0, 920, 932, 0, 937, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 929, 930, 0, 0, 0, 0, 986, 0, 931, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 981, 959, 963, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 960, 0, 984, 988, 378, 1070, + 982, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 1071, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 979, 0, 720, 0, 554, 0, 0, 1054, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 983, + 0, 505, 478, 1067, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 1051, 474, 682, 718, 719, + 607, 0, 1066, 1046, 1048, 1049, 1053, 1057, 1058, 1059, + 1060, 1061, 1063, 1065, 1069, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 1068, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 987, 658, 659, 462, 463, 464, + 465, 1055, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 1077, 1050, 1076, 1078, 1079, + 1075, 1080, 1081, 1062, 941, 0, 994, 995, 1073, 1072, + 1074, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 948, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 1040, 1003, 1004, 1005, + 938, 1006, 1000, 1001, 939, 1002, 1041, 992, 1037, 1038, + 967, 997, 1007, 1036, 1008, 1039, 968, 1042, 1082, 1083, + 1014, 998, 291, 1084, 1011, 1043, 1035, 1034, 1009, 993, + 1044, 1045, 975, 970, 1012, 1013, 999, 1020, 1021, 1022, + 1025, 940, 1026, 1027, 1028, 1029, 1030, 1024, 1023, 989, + 990, 991, 1015, 1016, 1018, 1019, 996, 524, 971, 972, + 973, 974, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 1031, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 1017, 731, 732, 729, 447, 507, 529, 515, 985, + 755, 603, 604, 756, 717, 331, 0, 933, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 936, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 976, 655, + 605, 517, 458, 0, 672, 0, 0, 1056, 1064, 0, + 0, 0, 0, 0, 0, 0, 0, 1052, 0, 0, + 0, 0, 928, 0, 0, 965, 1033, 1032, 952, 962, + 0, 0, 353, 260, 600, 723, 602, 601, 953, 0, + 954, 958, 961, 957, 955, 956, 0, 1047, 0, 0, + 0, 0, 0, 0, 0, 932, 0, 937, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 929, 930, 0, 0, 0, 0, 986, + 0, 931, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 981, 959, 963, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 960, 0, 984, 988, + 378, 1070, 982, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 1071, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 979, 0, 720, 0, 554, 0, 0, + 1054, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 983, 0, 505, 478, 1067, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 1051, 474, 682, + 718, 719, 607, 0, 1066, 1046, 1048, 1049, 1053, 1057, + 1058, 1059, 1060, 1061, 1063, 1065, 1069, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 1068, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 987, 658, 659, 462, + 463, 464, 465, 1055, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 1077, 1050, 1076, + 1078, 1079, 1075, 1080, 1081, 1062, 941, 0, 994, 995, + 1073, 1072, 1074, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 948, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 1040, 1003, + 1004, 1005, 938, 1006, 1000, 1001, 939, 1002, 1041, 992, + 1037, 1038, 967, 997, 1007, 1036, 1008, 1039, 968, 1042, + 1082, 1083, 1014, 998, 291, 1084, 1011, 1043, 1035, 1034, + 1009, 993, 1044, 1045, 975, 970, 1012, 1013, 999, 1020, + 1021, 1022, 1025, 940, 1026, 1027, 1028, 1029, 1030, 1024, + 1023, 989, 990, 991, 1015, 1016, 1018, 1019, 996, 524, + 971, 972, 973, 974, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 1031, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 1017, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 0, 933, + 195, 237, 194, 228, 196, 0, 0, 0, 0, 0, + 0, 476, 0, 0, 618, 652, 641, 727, 606, 0, + 229, 0, 0, 0, 0, 0, 0, 221, 0, 385, + 0, 230, 442, 656, 637, 648, 638, 482, 623, 624, + 625, 632, 397, 626, 627, 628, 598, 629, 599, 630, + 631, 163, 655, 605, 517, 458, 0, 672, 0, 0, + 0, 0, 0, 0, 0, 0, 149, 0, 0, 0, + 0, 0, 0, 0, 0, 233, 0, 0, 259, 0, + 0, 0, 0, 0, 0, 353, 260, 600, 723, 602, + 601, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 356, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 251, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 518, 547, 0, 560, 0, 422, 423, 0, 0, 0, + 0, 0, 0, 0, 338, 525, 544, 354, 512, 558, + 359, 520, 537, 349, 475, 509, 0, 0, 340, 542, + 519, 455, 339, 0, 502, 382, 399, 379, 473, 0, + 0, 541, 571, 378, 561, 0, 552, 342, 0, 551, + 472, 538, 543, 456, 449, 0, 341, 540, 454, 448, + 433, 389, 587, 434, 435, 403, 488, 446, 489, 404, + 460, 459, 461, 405, 406, 407, 408, 409, 410, 411, + 412, 413, 414, 0, 0, 0, 0, 0, 582, 583, + 0, 0, 0, 0, 0, 0, 0, 193, 226, 235, + 227, 79, 145, 0, 0, 716, 0, 0, 720, 0, + 554, 0, 0, 252, 0, 0, 0, 523, 0, 0, + 436, 147, 220, 219, 572, 0, 505, 478, 264, 0, + 0, 503, 444, 539, 490, 545, 526, 553, 497, 491, + 332, 527, 381, 457, 350, 352, 272, 383, 386, 390, + 391, 466, 467, 484, 511, 530, 531, 532, 380, 364, + 504, 365, 400, 366, 333, 372, 370, 373, 513, 374, + 335, 485, 536, 146, 396, 500, 452, 336, 451, 486, + 535, 534, 351, 562, 569, 570, 660, 0, 575, 692, + 693, 694, 584, 0, 492, 347, 344, 0, 0, 0, + 376, 487, 360, 362, 363, 361, 481, 483, 589, 590, + 591, 593, 0, 594, 595, 0, 0, 0, 0, 596, + 661, 677, 645, 614, 577, 669, 611, 615, 616, 417, + 418, 419, 680, 0, 0, 0, 568, 437, 438, 0, + 388, 387, 453, 337, 0, 0, 430, 416, 493, 343, + 384, 432, 421, 439, 440, 441, 394, 327, 328, 549, + 377, 474, 682, 718, 719, 607, 0, 670, 608, 617, + 369, 642, 654, 653, 468, 567, 255, 665, 668, 597, + 265, 0, 662, 676, 634, 675, 266, 480, 0, 510, + 673, 620, 0, 666, 639, 640, 0, 667, 635, 671, + 0, 609, 0, 578, 581, 610, 695, 696, 697, 334, + 580, 699, 700, 701, 702, 703, 704, 705, 698, 550, + 643, 619, 646, 559, 622, 621, 0, 0, 657, 576, + 658, 659, 462, 463, 464, 465, 398, 683, 358, 579, + 495, 496, 161, 644, 0, 0, 0, 0, 0, 0, + 0, 0, 649, 650, 647, 263, 0, 706, 707, 0, + 0, 573, 574, 393, 0, 592, 401, 357, 479, 395, + 557, 424, 0, 585, 651, 586, 498, 499, 710, 715, + 711, 712, 714, 734, 469, 415, 420, 514, 431, 445, + 501, 556, 477, 506, 355, 546, 516, 450, 636, 664, + 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, + 0, 314, 315, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 691, 690, 689, + 688, 687, 686, 685, 684, 0, 0, 633, 533, 371, + 321, 367, 368, 375, 270, 348, 271, 735, 738, 737, + 713, 0, 329, 613, 443, 494, 392, 678, 679, 69, + 733, 273, 274, 275, 276, 277, 278, 279, 280, 322, + 281, 282, 283, 284, 285, 286, 287, 292, 293, 294, + 295, 296, 297, 298, 299, 681, 290, 291, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, + 312, 313, 0, 0, 0, 0, 323, 739, 740, 741, + 742, 743, 0, 0, 324, 325, 326, 0, 0, 288, + 289, 316, 524, 317, 318, 319, 320, 0, 0, 563, + 564, 565, 588, 0, 566, 548, 612, 402, 330, 528, + 555, 267, 52, 253, 256, 258, 257, 0, 70, 663, + 674, 708, 709, 9, 721, 722, 724, 726, 725, 728, + 521, 522, 736, 0, 0, 425, 345, 346, 470, 471, + 508, 0, 426, 427, 428, 429, 730, 731, 732, 729, + 447, 507, 529, 515, 166, 268, 603, 604, 269, 717, + 331, 195, 237, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 163, 655, 605, 517, 458, 0, 672, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 233, 0, 0, 259, + 0, 0, 0, 0, 0, 0, 353, 260, 600, 723, + 602, 601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 356, 2868, 2871, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 0, 0, + 0, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 0, 0, 541, 571, 378, 561, 0, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 587, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 0, 0, 720, + 2872, 554, 0, 0, 0, 2867, 0, 2866, 523, 2864, + 2869, 436, 0, 0, 0, 572, 0, 505, 478, 759, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 2870, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 377, 474, 682, 718, 719, 607, 0, 670, 608, + 617, 369, 642, 654, 653, 468, 567, 0, 665, 668, + 597, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 550, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 576, 658, 659, 462, 463, 464, 465, 398, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 315, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 0, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 273, 274, 275, 276, 277, 278, 279, 280, + 322, 281, 282, 283, 284, 285, 286, 287, 292, 293, + 294, 295, 296, 297, 298, 299, 681, 290, 291, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 0, 0, 0, 0, 323, 739, 740, + 741, 742, 743, 0, 0, 324, 325, 326, 0, 0, + 288, 289, 316, 524, 317, 318, 319, 320, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 725, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 730, 731, 732, + 729, 447, 507, 529, 515, 0, 755, 603, 604, 756, + 717, 331, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 0, 655, 605, 517, 458, 0, 672, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1582, 0, 0, 259, + 0, 0, 952, 962, 0, 0, 353, 260, 600, 723, + 602, 601, 953, 0, 954, 958, 961, 957, 955, 956, + 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 0, 959, + 0, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 960, 0, 541, 571, 378, 561, 0, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 587, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 0, 0, 720, + 0, 554, 0, 0, 0, 0, 0, 0, 523, 0, + 0, 436, 0, 0, 0, 572, 0, 505, 478, 759, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 0, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 377, 474, 682, 718, 719, 607, 0, 670, 608, + 617, 369, 642, 654, 653, 468, 567, 0, 665, 668, + 597, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 550, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 576, 658, 659, 462, 463, 464, 465, 398, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 315, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 0, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 273, 274, 275, 276, 277, 278, 279, 280, + 322, 281, 282, 283, 284, 285, 286, 287, 292, 293, + 294, 295, 296, 297, 298, 299, 681, 290, 291, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 0, 0, 0, 0, 323, 739, 740, + 741, 742, 743, 0, 0, 324, 325, 326, 0, 0, + 288, 289, 316, 524, 317, 318, 319, 320, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 725, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 730, 731, 732, + 729, 447, 507, 529, 515, 0, 755, 603, 604, 756, + 717, 331, 195, 237, 194, 228, 196, 0, 0, 0, + 0, 0, 0, 476, 783, 0, 618, 652, 641, 727, + 606, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 385, 0, 0, 442, 656, 637, 648, 638, 482, + 623, 624, 625, 632, 397, 626, 757, 628, 598, 629, + 599, 630, 631, 0, 655, 605, 517, 458, 0, 672, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 790, + 0, 0, 0, 0, 0, 0, 0, 789, 0, 0, + 259, 0, 0, 0, 0, 0, 0, 353, 260, 600, + 723, 602, 601, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 356, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 518, 547, 0, 560, 0, 422, 423, 0, + 0, 0, 0, 0, 0, 0, 338, 525, 544, 354, + 512, 558, 359, 520, 537, 349, 475, 509, 0, 0, + 340, 542, 519, 455, 339, 0, 502, 382, 399, 379, + 473, 0, 0, 541, 571, 378, 561, 0, 552, 342, + 0, 551, 472, 538, 543, 456, 449, 0, 341, 540, + 454, 448, 433, 389, 587, 434, 435, 403, 488, 446, + 489, 404, 460, 459, 461, 405, 406, 407, 408, 409, + 410, 411, 412, 413, 414, 0, 0, 0, 0, 0, + 582, 583, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 787, 788, 0, 716, 0, 0, + 720, 0, 554, 0, 0, 0, 0, 0, 0, 523, + 0, 0, 436, 0, 0, 0, 572, 0, 505, 478, + 759, 0, 0, 503, 444, 539, 490, 545, 526, 553, + 497, 491, 332, 527, 381, 457, 350, 352, 748, 383, + 386, 390, 391, 466, 467, 484, 511, 530, 531, 532, + 380, 364, 504, 365, 400, 366, 333, 372, 370, 373, + 513, 374, 335, 485, 536, 0, 396, 500, 452, 336, + 451, 486, 535, 534, 351, 562, 569, 570, 660, 0, + 575, 760, 761, 762, 584, 0, 492, 347, 344, 0, + 0, 0, 376, 487, 360, 362, 363, 361, 481, 483, + 589, 590, 591, 593, 0, 594, 595, 0, 0, 0, + 0, 596, 661, 677, 645, 614, 577, 669, 611, 615, + 616, 417, 418, 419, 680, 0, 0, 0, 568, 437, + 438, 0, 388, 387, 453, 337, 0, 0, 430, 416, + 493, 343, 384, 432, 421, 439, 440, 441, 394, 327, + 328, 754, 377, 474, 682, 718, 719, 607, 0, 670, + 608, 617, 369, 642, 654, 653, 468, 567, 0, 665, + 668, 597, 753, 0, 662, 676, 758, 675, 750, 480, + 0, 510, 673, 620, 0, 666, 639, 640, 0, 667, + 635, 671, 0, 609, 0, 578, 581, 610, 695, 696, + 697, 334, 580, 699, 700, 701, 702, 703, 704, 705, + 698, 550, 643, 619, 646, 559, 622, 621, 0, 0, + 657, 576, 658, 659, 462, 463, 464, 465, 784, 786, + 358, 579, 495, 496, 799, 644, 0, 0, 0, 0, + 0, 0, 0, 0, 649, 650, 647, 763, 0, 706, + 707, 0, 0, 573, 574, 393, 0, 592, 401, 357, + 479, 395, 557, 424, 0, 585, 651, 586, 498, 499, + 710, 715, 711, 712, 714, 734, 469, 415, 420, 514, + 431, 445, 501, 556, 477, 506, 355, 546, 516, 450, + 636, 664, 0, 0, 0, 0, 0, 0, 0, 0, + 74, 0, 0, 314, 315, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 691, + 690, 689, 688, 687, 686, 685, 684, 0, 0, 633, + 533, 371, 321, 367, 368, 375, 751, 747, 752, 735, + 738, 737, 713, 0, 329, 613, 443, 494, 392, 678, + 679, 0, 733, 273, 274, 275, 276, 277, 278, 279, + 280, 322, 281, 282, 283, 284, 285, 286, 287, 292, + 293, 294, 295, 296, 297, 298, 299, 681, 290, 291, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 0, 0, 0, 0, 323, 739, + 740, 741, 742, 743, 0, 0, 324, 325, 326, 0, + 0, 288, 289, 316, 524, 317, 318, 319, 320, 0, + 0, 563, 564, 565, 588, 0, 566, 548, 612, 402, + 330, 528, 555, 749, 0, 0, 0, 0, 0, 0, + 0, 663, 674, 708, 709, 0, 721, 722, 724, 726, + 725, 728, 521, 522, 736, 0, 0, 425, 345, 346, + 470, 471, 508, 0, 426, 427, 428, 429, 730, 731, + 732, 729, 447, 507, 529, 515, 0, 755, 603, 604, + 756, 717, 331, 476, 0, 0, 618, 652, 641, 727, + 606, 0, 1289, 0, 0, 0, 0, 0, 0, 0, + 0, 385, 0, 0, 442, 656, 637, 648, 638, 482, + 623, 624, 625, 632, 397, 626, 757, 628, 598, 629, + 599, 630, 631, 0, 655, 605, 517, 458, 0, 672, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 259, 0, 0, 0, 0, 0, 0, 353, 260, 600, + 723, 602, 601, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 356, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 518, 547, 0, 560, 0, 3020, 3021, 1274, + 0, 0, 0, 0, 0, 0, 338, 525, 544, 354, + 512, 558, 359, 520, 537, 349, 475, 509, 0, 0, + 3014, 3017, 3018, 3019, 3022, 0, 3027, 3023, 3024, 3025, + 3026, 0, 0, 3010, 3011, 3012, 3013, 1272, 2994, 3015, + 0, 2995, 472, 2996, 2997, 2998, 2999, 1276, 3000, 3001, + 3002, 3003, 3004, 3007, 3008, 3005, 3006, 3028, 3029, 3030, + 3031, 3032, 3033, 3034, 3035, 3037, 3036, 3038, 3039, 3040, + 3041, 3042, 3043, 3044, 3045, 1300, 1302, 1304, 1306, 1309, + 582, 583, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 716, 0, 0, + 720, 0, 554, 0, 0, 0, 0, 0, 0, 523, + 0, 0, 436, 0, 0, 0, 3009, 0, 505, 478, + 759, 0, 0, 503, 444, 539, 490, 545, 526, 553, + 497, 491, 332, 527, 381, 457, 350, 352, 748, 383, + 386, 390, 391, 466, 467, 484, 511, 530, 531, 532, + 380, 364, 504, 365, 400, 366, 333, 372, 370, 373, + 513, 374, 335, 485, 536, 0, 396, 500, 452, 336, + 451, 486, 535, 534, 351, 562, 569, 570, 660, 0, + 575, 760, 761, 762, 584, 0, 492, 347, 344, 0, + 0, 0, 376, 487, 360, 362, 363, 361, 481, 483, + 589, 590, 591, 593, 0, 594, 595, 0, 0, 0, + 0, 596, 661, 677, 645, 614, 577, 669, 611, 615, + 616, 417, 418, 419, 680, 0, 0, 0, 568, 437, + 438, 0, 388, 387, 453, 337, 0, 0, 430, 416, + 493, 343, 384, 432, 421, 439, 440, 441, 394, 327, + 328, 754, 377, 474, 682, 718, 719, 607, 0, 670, + 608, 617, 369, 642, 654, 653, 468, 567, 0, 665, + 668, 597, 753, 0, 662, 676, 758, 675, 750, 480, + 0, 510, 673, 620, 0, 666, 639, 640, 0, 667, + 635, 671, 0, 609, 0, 578, 581, 610, 695, 696, + 697, 334, 580, 699, 700, 701, 702, 703, 704, 705, + 698, 550, 643, 619, 646, 559, 622, 621, 0, 0, + 657, 576, 658, 659, 462, 463, 464, 465, 398, 683, + 358, 579, 495, 496, 0, 644, 0, 0, 0, 0, + 0, 0, 0, 0, 649, 650, 647, 763, 0, 706, + 707, 0, 0, 573, 574, 393, 0, 592, 401, 357, + 479, 395, 557, 424, 0, 585, 651, 586, 498, 499, + 710, 715, 711, 712, 714, 734, 469, 415, 420, 514, + 431, 445, 501, 556, 477, 506, 355, 546, 516, 450, + 636, 664, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 314, 315, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 691, + 690, 689, 688, 687, 686, 685, 684, 0, 0, 633, + 533, 371, 321, 367, 368, 375, 751, 747, 752, 735, + 738, 737, 713, 0, 329, 3016, 443, 494, 392, 678, + 679, 0, 733, 273, 274, 275, 276, 277, 278, 279, + 280, 322, 281, 282, 283, 284, 285, 286, 287, 292, + 293, 294, 295, 296, 297, 298, 299, 681, 290, 291, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 0, 0, 0, 0, 323, 739, + 740, 741, 742, 743, 0, 0, 324, 325, 326, 0, + 0, 288, 289, 316, 524, 317, 318, 319, 320, 0, + 0, 563, 564, 565, 588, 0, 566, 548, 612, 402, + 330, 528, 555, 749, 0, 0, 0, 0, 0, 0, + 0, 663, 674, 708, 709, 0, 721, 722, 724, 726, + 725, 728, 521, 522, 736, 0, 0, 425, 345, 346, + 470, 471, 508, 0, 426, 427, 428, 429, 730, 731, + 732, 729, 447, 507, 529, 515, 0, 755, 603, 604, + 756, 717, 2993, 476, 0, 0, 618, 652, 641, 727, + 606, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 385, 0, 0, 442, 656, 637, 648, 638, 482, + 623, 624, 625, 632, 397, 626, 757, 628, 598, 629, + 599, 630, 631, 0, 655, 605, 517, 458, 0, 672, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 259, 0, 0, 0, 0, 0, 0, 353, 260, 600, + 723, 602, 601, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 356, 2868, 2871, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 518, 547, 0, 560, 0, 422, 423, 0, + 0, 0, 0, 0, 0, 0, 338, 525, 544, 354, + 512, 558, 359, 520, 537, 349, 475, 509, 0, 0, + 340, 542, 519, 455, 339, 0, 502, 382, 399, 379, + 473, 0, 0, 541, 571, 378, 561, 0, 552, 342, + 0, 551, 472, 538, 543, 456, 449, 0, 341, 540, + 454, 448, 433, 389, 587, 434, 435, 403, 488, 446, + 489, 404, 460, 459, 461, 405, 406, 407, 408, 409, + 410, 411, 412, 413, 414, 0, 0, 0, 0, 0, + 582, 583, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 716, 0, 0, + 720, 2872, 554, 0, 0, 0, 2867, 0, 2866, 523, + 2864, 2869, 436, 0, 0, 0, 572, 0, 505, 478, + 759, 0, 0, 503, 444, 539, 490, 545, 526, 553, + 497, 491, 332, 527, 381, 457, 350, 352, 748, 383, + 386, 390, 391, 466, 467, 484, 511, 530, 531, 532, + 380, 364, 504, 365, 400, 366, 333, 372, 370, 373, + 513, 374, 335, 485, 536, 2870, 396, 500, 452, 336, + 451, 486, 535, 534, 351, 562, 569, 570, 660, 0, + 575, 760, 761, 762, 584, 0, 492, 347, 344, 0, + 0, 0, 376, 487, 360, 362, 363, 361, 481, 483, + 589, 590, 591, 593, 0, 594, 595, 0, 0, 0, + 0, 596, 661, 677, 645, 614, 577, 669, 611, 615, + 616, 417, 418, 419, 680, 0, 0, 0, 568, 437, + 438, 0, 388, 387, 453, 337, 0, 0, 430, 416, + 493, 343, 384, 432, 421, 439, 440, 441, 394, 327, + 328, 754, 377, 474, 682, 718, 719, 607, 0, 670, + 608, 617, 369, 642, 654, 653, 468, 567, 0, 665, + 668, 597, 753, 0, 662, 676, 758, 675, 750, 480, + 0, 510, 673, 620, 0, 666, 639, 640, 0, 667, + 635, 671, 0, 609, 0, 578, 581, 610, 695, 696, + 697, 334, 580, 699, 700, 701, 702, 703, 704, 705, + 698, 550, 643, 619, 646, 559, 622, 621, 0, 0, + 657, 576, 658, 659, 462, 463, 464, 465, 398, 683, + 358, 579, 495, 496, 0, 644, 0, 0, 0, 0, + 0, 0, 0, 0, 649, 650, 647, 763, 0, 706, + 707, 0, 0, 573, 574, 393, 0, 592, 401, 357, + 479, 395, 557, 424, 0, 585, 651, 586, 498, 499, + 710, 715, 711, 712, 714, 734, 469, 415, 420, 514, + 431, 445, 501, 556, 477, 506, 355, 546, 516, 450, + 636, 664, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 314, 315, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 691, + 690, 689, 688, 687, 686, 685, 684, 0, 0, 633, + 533, 371, 321, 367, 368, 375, 751, 747, 752, 735, + 738, 737, 713, 0, 329, 613, 443, 494, 392, 678, + 679, 0, 733, 273, 274, 275, 276, 277, 278, 279, + 280, 322, 281, 282, 283, 284, 285, 286, 287, 292, + 293, 294, 295, 296, 297, 298, 299, 681, 290, 291, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 0, 0, 0, 0, 323, 739, + 740, 741, 742, 743, 0, 0, 324, 325, 326, 0, + 0, 288, 289, 316, 524, 317, 318, 319, 320, 0, + 0, 563, 564, 565, 588, 0, 566, 548, 612, 402, + 330, 528, 555, 749, 0, 0, 0, 0, 0, 0, + 0, 663, 674, 708, 709, 0, 721, 722, 724, 726, + 725, 728, 521, 522, 736, 0, 0, 425, 345, 346, + 470, 471, 508, 0, 426, 427, 428, 429, 730, 731, + 732, 729, 447, 507, 529, 515, 0, 755, 603, 604, + 756, 717, 331, 476, 0, 0, 618, 652, 641, 727, + 606, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 385, 0, 0, 442, 656, 637, 648, 638, 482, + 623, 624, 625, 632, 397, 626, 757, 628, 598, 629, + 599, 630, 631, 0, 655, 605, 517, 458, 0, 672, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 259, 0, 0, 0, 0, 0, 0, 353, 260, 600, + 723, 602, 601, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 356, 0, 2889, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 518, 547, 0, 560, 0, 422, 423, 0, + 0, 0, 0, 0, 0, 0, 338, 525, 544, 354, + 512, 558, 359, 520, 537, 349, 475, 509, 0, 0, + 340, 542, 519, 455, 339, 0, 502, 382, 399, 379, + 473, 0, 0, 541, 571, 378, 561, 0, 552, 342, + 0, 551, 472, 538, 543, 456, 449, 0, 341, 540, + 454, 448, 433, 389, 587, 434, 435, 403, 488, 446, + 489, 404, 460, 459, 461, 405, 406, 407, 408, 409, + 410, 411, 412, 413, 414, 0, 0, 0, 0, 0, + 582, 583, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 716, 0, 0, + 720, 2888, 554, 0, 0, 0, 2894, 2891, 2893, 523, + 0, 2892, 436, 0, 0, 0, 572, 0, 505, 478, + 759, 0, 2886, 503, 444, 539, 490, 545, 526, 553, + 497, 491, 332, 527, 381, 457, 350, 352, 748, 383, + 386, 390, 391, 466, 467, 484, 511, 530, 531, 532, + 380, 364, 504, 365, 400, 366, 333, 372, 370, 373, + 513, 374, 335, 485, 536, 0, 396, 500, 452, 336, + 451, 486, 535, 534, 351, 562, 569, 570, 660, 0, + 575, 760, 761, 762, 584, 0, 492, 347, 344, 0, + 0, 0, 376, 487, 360, 362, 363, 361, 481, 483, + 589, 590, 591, 593, 0, 594, 595, 0, 0, 0, + 0, 596, 661, 677, 645, 614, 577, 669, 611, 615, + 616, 417, 418, 419, 680, 0, 0, 0, 568, 437, + 438, 0, 388, 387, 453, 337, 0, 0, 430, 416, + 493, 343, 384, 432, 421, 439, 440, 441, 394, 327, + 328, 754, 377, 474, 682, 718, 719, 607, 0, 670, + 608, 617, 369, 642, 654, 653, 468, 567, 0, 665, + 668, 597, 753, 0, 662, 676, 758, 675, 750, 480, + 0, 510, 673, 620, 0, 666, 639, 640, 0, 667, + 635, 671, 0, 609, 0, 578, 581, 610, 695, 696, + 697, 334, 580, 699, 700, 701, 702, 703, 704, 705, + 698, 550, 643, 619, 646, 559, 622, 621, 0, 0, + 657, 576, 658, 659, 462, 463, 464, 465, 398, 683, + 358, 579, 495, 496, 0, 644, 0, 0, 0, 0, + 0, 0, 0, 0, 649, 650, 647, 763, 0, 706, + 707, 0, 0, 573, 574, 393, 0, 592, 401, 357, + 479, 395, 557, 424, 0, 585, 651, 586, 498, 499, + 710, 715, 711, 712, 714, 734, 469, 415, 420, 514, + 431, 445, 501, 556, 477, 506, 355, 546, 516, 450, + 636, 664, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 314, 315, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 691, + 690, 689, 688, 687, 686, 685, 684, 0, 0, 633, + 533, 371, 321, 367, 368, 375, 751, 747, 752, 735, + 738, 737, 713, 0, 329, 613, 443, 494, 392, 678, + 679, 0, 733, 273, 274, 275, 276, 277, 278, 279, + 280, 322, 281, 282, 283, 284, 285, 286, 287, 292, + 293, 294, 295, 296, 297, 298, 299, 681, 290, 291, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 0, 0, 0, 0, 323, 739, + 740, 741, 742, 743, 0, 0, 324, 325, 326, 0, + 0, 288, 289, 316, 524, 317, 318, 319, 320, 0, + 0, 563, 564, 565, 588, 0, 566, 548, 612, 402, + 330, 528, 555, 749, 0, 0, 0, 0, 0, 0, + 0, 663, 674, 708, 709, 0, 721, 722, 724, 726, + 725, 728, 521, 522, 736, 0, 0, 425, 345, 346, + 470, 471, 508, 0, 426, 427, 428, 429, 730, 731, + 732, 729, 447, 507, 529, 515, 0, 755, 603, 604, + 756, 717, 331, 476, 0, 0, 618, 652, 641, 727, + 606, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 385, 0, 0, 442, 656, 637, 648, 638, 482, + 623, 624, 625, 632, 397, 626, 757, 628, 598, 629, + 599, 630, 631, 0, 655, 605, 517, 458, 0, 672, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 259, 0, 0, 0, 0, 0, 0, 353, 260, 600, + 723, 602, 601, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 356, 0, 2889, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 518, 547, 0, 560, 0, 422, 423, 0, + 0, 0, 0, 0, 0, 0, 338, 525, 544, 354, + 512, 558, 359, 520, 537, 349, 475, 509, 0, 0, + 340, 542, 519, 455, 339, 0, 502, 382, 399, 379, + 473, 0, 0, 541, 571, 378, 561, 0, 552, 342, + 0, 551, 472, 538, 543, 456, 449, 0, 341, 540, + 454, 448, 433, 389, 587, 434, 435, 403, 488, 446, + 489, 404, 460, 459, 461, 405, 406, 407, 408, 409, + 410, 411, 412, 413, 414, 0, 0, 0, 0, 0, + 582, 583, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 716, 0, 0, + 720, 2888, 554, 0, 0, 0, 2894, 2891, 2893, 523, + 0, 2892, 436, 0, 0, 0, 572, 0, 505, 478, + 759, 0, 0, 503, 444, 539, 490, 545, 526, 553, + 497, 491, 332, 527, 381, 457, 350, 352, 748, 383, + 386, 390, 391, 466, 467, 484, 511, 530, 531, 532, + 380, 364, 504, 365, 400, 366, 333, 372, 370, 373, + 513, 374, 335, 485, 536, 0, 396, 500, 452, 336, + 451, 486, 535, 534, 351, 562, 569, 570, 660, 0, + 575, 760, 761, 762, 584, 0, 492, 347, 344, 0, + 0, 0, 376, 487, 360, 362, 363, 361, 481, 483, + 589, 590, 591, 593, 0, 594, 595, 0, 0, 0, + 0, 596, 661, 677, 645, 614, 577, 669, 611, 615, + 616, 417, 418, 419, 680, 0, 0, 0, 568, 437, + 438, 0, 388, 387, 453, 337, 0, 0, 430, 416, + 493, 343, 384, 432, 421, 439, 440, 441, 394, 327, + 328, 754, 377, 474, 682, 718, 719, 607, 0, 670, + 608, 617, 369, 642, 654, 653, 468, 567, 0, 665, + 668, 597, 753, 0, 662, 676, 758, 675, 750, 480, + 0, 510, 673, 620, 0, 666, 639, 640, 0, 667, + 635, 671, 0, 609, 0, 578, 581, 610, 695, 696, + 697, 334, 580, 699, 700, 701, 702, 703, 704, 705, + 698, 550, 643, 619, 646, 559, 622, 621, 0, 0, + 657, 576, 658, 659, 462, 463, 464, 465, 398, 683, + 358, 579, 495, 496, 0, 644, 0, 0, 0, 0, + 0, 0, 0, 0, 649, 650, 647, 763, 0, 706, + 707, 0, 0, 573, 574, 393, 0, 592, 401, 357, + 479, 395, 557, 424, 0, 585, 651, 586, 498, 499, + 710, 715, 711, 712, 714, 734, 469, 415, 420, 514, + 431, 445, 501, 556, 477, 506, 355, 546, 516, 450, + 636, 664, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 314, 315, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 691, + 690, 689, 688, 687, 686, 685, 684, 0, 0, 633, + 533, 371, 321, 367, 368, 375, 751, 747, 752, 735, + 738, 737, 713, 0, 329, 613, 443, 494, 392, 678, + 679, 0, 733, 273, 274, 275, 276, 277, 278, 279, + 280, 322, 281, 282, 283, 284, 285, 286, 287, 292, + 293, 294, 295, 296, 297, 298, 299, 681, 290, 291, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 0, 0, 0, 0, 323, 739, + 740, 741, 742, 743, 0, 0, 324, 325, 326, 0, + 0, 288, 289, 316, 524, 317, 318, 319, 320, 0, + 0, 563, 564, 565, 588, 0, 566, 548, 612, 402, + 330, 528, 555, 749, 0, 0, 0, 0, 0, 0, + 0, 663, 674, 708, 709, 0, 721, 722, 724, 726, + 725, 728, 521, 522, 736, 0, 0, 425, 345, 346, + 470, 471, 508, 0, 426, 427, 428, 429, 730, 731, + 732, 729, 447, 507, 529, 515, 0, 755, 603, 604, + 756, 717, 331, 195, 237, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 476, 0, 0, 618, 652, 641, + 727, 606, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 385, 0, 0, 442, 656, 637, 648, 638, + 482, 623, 624, 625, 632, 397, 626, 757, 628, 598, + 629, 599, 630, 631, 163, 655, 605, 517, 458, 0, + 672, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 233, 3094, + 0, 259, 0, 0, 0, 0, 0, 0, 353, 260, + 600, 723, 602, 601, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 356, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 518, 547, 0, 560, 0, 422, 423, + 0, 0, 0, 0, 0, 0, 0, 338, 525, 544, + 354, 512, 558, 359, 520, 537, 349, 475, 509, 0, + 0, 340, 542, 519, 455, 339, 0, 502, 382, 399, + 379, 473, 0, 0, 541, 571, 378, 561, 0, 552, + 342, 0, 551, 472, 538, 543, 456, 449, 0, 341, + 540, 454, 448, 433, 389, 587, 434, 435, 403, 488, + 446, 489, 404, 460, 459, 461, 405, 406, 407, 408, + 409, 410, 411, 412, 413, 414, 0, 0, 0, 0, + 0, 582, 583, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 716, 0, + 0, 720, 0, 554, 0, 0, 0, 0, 0, 0, + 523, 0, 0, 436, 0, 0, 0, 572, 0, 505, + 478, 759, 0, 0, 503, 444, 539, 490, 545, 526, + 553, 497, 491, 332, 527, 381, 457, 350, 352, 748, + 383, 386, 390, 391, 466, 467, 484, 511, 530, 531, + 532, 380, 364, 504, 365, 400, 366, 333, 372, 370, + 373, 513, 374, 335, 485, 536, 0, 396, 500, 452, + 336, 451, 486, 535, 534, 351, 562, 569, 570, 660, + 0, 575, 760, 761, 762, 584, 0, 492, 347, 344, + 0, 0, 0, 376, 487, 360, 362, 363, 361, 481, + 483, 589, 590, 591, 593, 0, 594, 595, 0, 0, + 0, 0, 596, 661, 677, 645, 614, 577, 669, 611, + 615, 616, 417, 418, 419, 680, 0, 0, 0, 568, + 437, 438, 0, 388, 387, 453, 337, 0, 0, 430, + 416, 493, 343, 384, 432, 421, 439, 440, 441, 394, + 327, 328, 754, 377, 474, 682, 718, 719, 607, 0, + 670, 608, 617, 369, 642, 654, 653, 468, 567, 0, + 665, 668, 597, 753, 0, 662, 676, 758, 675, 750, + 480, 0, 510, 673, 620, 0, 666, 639, 640, 0, + 667, 635, 671, 0, 609, 0, 578, 581, 610, 695, + 696, 697, 334, 580, 699, 700, 701, 702, 703, 704, + 705, 698, 550, 643, 619, 646, 559, 622, 621, 0, + 0, 657, 576, 658, 659, 462, 463, 464, 465, 398, + 683, 358, 579, 495, 496, 0, 644, 0, 0, 0, + 0, 0, 0, 0, 0, 649, 650, 647, 763, 0, + 706, 707, 0, 0, 573, 574, 393, 0, 592, 401, + 357, 479, 395, 557, 424, 0, 585, 651, 586, 498, + 499, 710, 715, 711, 712, 714, 734, 469, 415, 420, + 514, 431, 445, 501, 556, 477, 506, 355, 546, 516, + 450, 636, 664, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 314, 315, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 691, 690, 689, 688, 687, 686, 685, 684, 0, 0, + 633, 533, 371, 321, 367, 368, 375, 751, 747, 752, + 735, 738, 737, 713, 0, 329, 613, 443, 494, 392, + 678, 679, 0, 733, 273, 274, 275, 276, 277, 278, + 279, 280, 322, 281, 282, 283, 284, 285, 286, 287, + 292, 293, 294, 295, 296, 297, 298, 299, 681, 290, + 291, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 0, 0, 0, 0, 323, + 739, 740, 741, 742, 743, 0, 0, 324, 325, 326, + 0, 0, 288, 289, 316, 524, 317, 318, 319, 320, + 0, 0, 563, 564, 565, 588, 0, 566, 548, 612, + 402, 330, 528, 555, 749, 0, 0, 0, 0, 0, + 0, 0, 663, 674, 708, 709, 0, 721, 722, 724, + 726, 725, 728, 521, 522, 736, 0, 0, 425, 345, + 346, 470, 471, 508, 0, 426, 427, 428, 429, 730, + 731, 732, 729, 447, 507, 529, 515, 0, 755, 603, + 604, 756, 717, 331, 195, 237, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 476, 0, 0, 618, 652, + 641, 727, 606, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 385, 0, 0, 442, 656, 637, 648, + 638, 482, 623, 624, 625, 632, 397, 626, 757, 628, + 598, 629, 599, 630, 631, 163, 655, 605, 517, 458, + 0, 672, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, + 2796, 0, 259, 0, 0, 0, 0, 0, 0, 353, + 260, 600, 723, 602, 601, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 356, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 518, 547, 0, 560, 0, 422, + 423, 0, 0, 0, 0, 0, 0, 0, 338, 525, + 544, 354, 512, 558, 359, 520, 537, 349, 475, 509, + 0, 0, 340, 542, 519, 455, 339, 0, 502, 382, + 399, 379, 473, 0, 0, 541, 571, 378, 561, 0, + 552, 342, 0, 551, 472, 538, 543, 456, 449, 0, + 341, 540, 454, 448, 433, 389, 587, 434, 435, 403, + 488, 446, 489, 404, 460, 459, 461, 405, 406, 407, + 408, 409, 410, 411, 412, 413, 414, 0, 0, 0, + 0, 0, 582, 583, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 716, + 0, 0, 720, 0, 554, 0, 0, 0, 0, 0, + 0, 523, 0, 0, 436, 0, 0, 0, 572, 0, + 505, 478, 759, 0, 0, 503, 444, 539, 490, 545, + 526, 553, 497, 491, 332, 527, 381, 457, 350, 352, + 748, 383, 386, 390, 391, 466, 467, 484, 511, 530, + 531, 532, 380, 364, 504, 365, 400, 366, 333, 372, + 370, 373, 513, 374, 335, 485, 536, 0, 396, 500, + 452, 336, 451, 486, 535, 534, 351, 562, 569, 570, + 660, 0, 575, 760, 761, 762, 584, 0, 492, 347, + 344, 0, 0, 0, 376, 487, 360, 362, 363, 361, + 481, 483, 589, 590, 591, 593, 0, 594, 595, 0, + 0, 0, 0, 596, 661, 677, 645, 614, 577, 669, + 611, 615, 616, 417, 418, 419, 680, 0, 0, 0, + 568, 437, 438, 0, 388, 387, 453, 337, 0, 0, + 430, 416, 493, 343, 384, 432, 421, 439, 440, 441, + 394, 327, 328, 754, 377, 474, 682, 718, 719, 607, + 0, 670, 608, 617, 369, 642, 654, 653, 468, 567, + 0, 665, 668, 597, 753, 0, 662, 676, 758, 675, + 750, 480, 0, 510, 673, 620, 0, 666, 639, 640, + 0, 667, 635, 671, 0, 609, 0, 578, 581, 610, + 695, 696, 697, 334, 580, 699, 700, 701, 702, 703, + 704, 705, 698, 550, 643, 619, 646, 559, 622, 621, + 0, 0, 657, 576, 658, 659, 462, 463, 464, 465, + 398, 683, 358, 579, 495, 496, 0, 644, 0, 0, + 0, 0, 0, 0, 0, 0, 649, 650, 647, 763, + 0, 706, 707, 0, 0, 573, 574, 393, 0, 592, + 401, 357, 479, 395, 557, 424, 0, 585, 651, 586, + 498, 499, 710, 715, 711, 712, 714, 734, 469, 415, + 420, 514, 431, 445, 501, 556, 477, 506, 355, 546, + 516, 450, 636, 664, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 314, 315, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 691, 690, 689, 688, 687, 686, 685, 684, 0, + 0, 633, 533, 371, 321, 367, 368, 375, 751, 747, + 752, 735, 738, 737, 713, 0, 329, 613, 443, 494, + 392, 678, 679, 0, 733, 273, 274, 275, 276, 277, + 278, 279, 280, 322, 281, 282, 283, 284, 285, 286, + 287, 292, 293, 294, 295, 296, 297, 298, 299, 681, + 290, 291, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 0, 0, 0, 0, + 323, 739, 740, 741, 742, 743, 0, 0, 324, 325, + 326, 0, 0, 288, 289, 316, 524, 317, 318, 319, + 320, 0, 0, 563, 564, 565, 588, 0, 566, 548, + 612, 402, 330, 528, 555, 749, 0, 0, 0, 0, + 0, 0, 0, 663, 674, 708, 709, 0, 721, 722, + 724, 726, 725, 728, 521, 522, 736, 0, 0, 425, + 345, 346, 470, 471, 508, 0, 426, 427, 428, 429, + 730, 731, 732, 729, 447, 507, 529, 515, 0, 755, + 603, 604, 756, 717, 331, 476, 0, 0, 618, 652, + 641, 727, 606, 0, 0, 0, 0, 0, 2480, 0, + 0, 0, 0, 385, 0, 0, 442, 656, 637, 648, + 638, 482, 623, 624, 625, 632, 397, 626, 757, 628, + 598, 629, 599, 630, 631, 0, 655, 605, 517, 458, + 0, 672, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 259, 0, 0, 2481, 0, 0, 0, 353, + 260, 600, 723, 602, 601, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 356, 0, 0, 1506, 0, 1507, + 1505, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 518, 547, 0, 560, 0, 422, + 423, 0, 0, 0, 0, 0, 0, 0, 338, 525, + 544, 354, 512, 558, 359, 520, 537, 349, 475, 509, + 0, 0, 340, 542, 519, 455, 339, 0, 502, 382, + 399, 379, 473, 0, 0, 541, 571, 378, 561, 0, + 552, 342, 0, 551, 472, 538, 543, 456, 449, 0, + 341, 540, 454, 448, 433, 389, 587, 434, 435, 403, + 488, 446, 489, 404, 460, 459, 461, 405, 406, 407, + 408, 409, 410, 411, 412, 413, 414, 0, 0, 0, + 0, 0, 582, 583, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 716, + 0, 0, 720, 0, 554, 0, 0, 0, 0, 0, + 0, 523, 0, 0, 436, 0, 0, 0, 572, 0, + 505, 478, 759, 0, 0, 503, 444, 539, 490, 545, + 526, 553, 497, 491, 332, 527, 381, 457, 350, 352, + 748, 383, 386, 390, 391, 466, 467, 484, 511, 530, + 531, 532, 380, 364, 504, 365, 400, 366, 333, 372, + 370, 373, 513, 374, 335, 485, 536, 0, 396, 500, + 452, 336, 451, 486, 535, 534, 351, 562, 569, 570, + 660, 0, 575, 760, 761, 762, 584, 0, 492, 347, + 344, 0, 0, 0, 376, 487, 360, 362, 363, 361, + 481, 483, 589, 590, 591, 593, 0, 594, 595, 0, + 0, 0, 0, 596, 661, 677, 645, 614, 577, 669, + 611, 615, 616, 417, 418, 419, 680, 0, 0, 0, + 568, 437, 438, 0, 388, 387, 453, 337, 0, 0, + 430, 416, 493, 343, 384, 432, 421, 439, 440, 441, + 394, 327, 328, 754, 377, 474, 682, 718, 719, 607, + 0, 670, 608, 617, 369, 642, 654, 653, 468, 567, + 0, 665, 668, 597, 753, 0, 662, 676, 758, 675, + 750, 480, 0, 510, 673, 620, 0, 666, 639, 640, + 0, 667, 635, 671, 0, 609, 0, 578, 581, 610, + 695, 696, 697, 334, 580, 699, 700, 701, 702, 703, + 704, 705, 698, 550, 643, 619, 646, 559, 622, 621, + 0, 0, 657, 576, 658, 659, 462, 463, 464, 465, + 398, 683, 358, 579, 495, 496, 0, 644, 0, 0, + 0, 0, 0, 0, 0, 0, 649, 650, 647, 763, + 0, 706, 707, 0, 0, 573, 574, 393, 0, 592, + 401, 357, 479, 395, 557, 424, 0, 585, 651, 586, + 498, 499, 710, 715, 711, 712, 714, 734, 469, 415, + 420, 514, 431, 445, 501, 556, 477, 506, 355, 546, + 516, 450, 636, 664, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 314, 315, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 691, 690, 689, 688, 687, 686, 685, 684, 0, + 0, 633, 533, 371, 321, 367, 368, 375, 751, 747, + 752, 735, 738, 737, 713, 0, 329, 613, 443, 494, + 392, 678, 679, 0, 733, 273, 274, 275, 276, 277, + 278, 279, 280, 322, 281, 282, 283, 284, 285, 286, + 287, 292, 293, 294, 295, 296, 297, 298, 299, 681, + 290, 291, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 0, 0, 0, 0, + 323, 739, 740, 741, 742, 743, 0, 0, 324, 325, + 326, 0, 0, 288, 289, 316, 524, 317, 318, 319, + 320, 0, 0, 563, 564, 565, 588, 0, 566, 548, + 612, 402, 330, 528, 555, 749, 0, 0, 0, 0, + 0, 0, 0, 663, 674, 708, 709, 0, 721, 722, + 724, 726, 725, 728, 521, 522, 736, 0, 0, 425, + 345, 346, 470, 471, 508, 0, 426, 427, 428, 429, + 730, 731, 732, 729, 447, 507, 529, 515, 0, 755, + 603, 604, 756, 717, 331, 476, 0, 0, 618, 652, + 641, 727, 606, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 385, 1195, 0, 442, 656, 637, 648, + 638, 482, 623, 624, 625, 632, 397, 626, 757, 628, + 598, 629, 599, 630, 631, 0, 655, 605, 517, 458, + 0, 672, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 259, 1202, 1203, 0, 0, 0, 0, 353, + 260, 600, 723, 602, 601, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1206, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 518, 547, 0, 560, 0, 422, + 423, 0, 0, 0, 0, 0, 0, 0, 338, 525, + 1189, 354, 512, 558, 359, 520, 537, 349, 475, 509, + 0, 0, 340, 542, 519, 455, 339, 0, 502, 382, + 399, 379, 473, 0, 0, 541, 571, 378, 561, 865, + 552, 342, 864, 551, 472, 538, 543, 456, 449, 0, + 341, 540, 454, 448, 433, 389, 587, 434, 435, 403, + 488, 446, 489, 404, 460, 459, 461, 405, 406, 407, + 408, 409, 410, 411, 412, 413, 414, 0, 0, 0, + 0, 0, 582, 583, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 716, + 0, 0, 720, 0, 554, 0, 0, 0, 0, 0, + 0, 523, 0, 0, 436, 0, 0, 0, 572, 0, + 505, 478, 759, 0, 0, 503, 444, 539, 490, 545, + 526, 553, 1193, 491, 332, 527, 381, 457, 350, 352, + 748, 383, 386, 390, 391, 466, 467, 484, 511, 530, + 531, 532, 380, 364, 504, 365, 400, 366, 333, 372, + 370, 373, 513, 374, 335, 485, 536, 0, 396, 500, + 452, 336, 451, 486, 535, 534, 351, 562, 569, 570, + 660, 0, 575, 760, 761, 762, 584, 0, 492, 347, + 344, 0, 0, 0, 376, 487, 360, 362, 363, 361, + 481, 483, 589, 590, 591, 593, 0, 594, 595, 0, + 0, 0, 0, 596, 661, 677, 645, 614, 577, 669, + 611, 615, 616, 417, 418, 419, 680, 0, 0, 0, + 568, 437, 438, 0, 388, 387, 453, 337, 0, 0, + 430, 416, 493, 343, 384, 432, 421, 439, 440, 441, + 394, 327, 328, 754, 377, 474, 682, 718, 719, 607, + 0, 670, 608, 617, 369, 642, 654, 653, 468, 567, + 0, 665, 668, 597, 753, 0, 662, 676, 758, 675, + 750, 480, 0, 510, 673, 620, 0, 666, 639, 640, + 0, 667, 635, 671, 0, 609, 0, 578, 581, 610, + 695, 696, 697, 334, 580, 699, 700, 701, 702, 703, + 704, 1194, 698, 550, 643, 619, 646, 559, 622, 621, + 0, 0, 657, 1197, 658, 659, 462, 463, 464, 465, + 398, 683, 1192, 579, 495, 496, 0, 644, 0, 0, + 0, 0, 0, 0, 0, 0, 649, 650, 647, 763, + 0, 706, 707, 0, 0, 573, 574, 393, 0, 592, + 401, 357, 479, 395, 557, 424, 0, 585, 651, 586, + 498, 499, 710, 715, 711, 712, 714, 734, 1204, 1190, + 1200, 1191, 431, 445, 501, 556, 477, 506, 355, 546, + 516, 1201, 636, 664, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 314, 315, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 691, 690, 689, 688, 687, 686, 685, 684, 0, + 0, 633, 533, 371, 321, 367, 368, 375, 751, 747, + 752, 735, 738, 737, 713, 0, 329, 613, 443, 494, + 392, 678, 679, 0, 733, 273, 274, 275, 276, 277, + 278, 279, 280, 322, 281, 282, 283, 284, 285, 286, + 287, 292, 293, 294, 295, 296, 297, 298, 299, 681, + 290, 291, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 0, 0, 0, 0, + 323, 739, 740, 741, 742, 743, 0, 0, 324, 325, + 326, 0, 0, 288, 289, 316, 524, 317, 318, 319, + 320, 0, 0, 563, 564, 565, 588, 0, 566, 548, + 612, 402, 330, 528, 555, 749, 0, 0, 0, 0, + 0, 0, 0, 663, 674, 708, 709, 0, 721, 722, + 724, 726, 725, 728, 521, 522, 736, 0, 0, 425, + 345, 346, 470, 471, 508, 0, 426, 427, 428, 429, + 730, 731, 732, 729, 1188, 507, 529, 515, 0, 755, + 603, 604, 756, 717, 331, 476, 0, 0, 618, 652, + 641, 727, 606, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 385, 0, 0, 442, 656, 637, 648, + 638, 482, 623, 624, 625, 632, 397, 626, 757, 628, + 598, 629, 599, 630, 631, 0, 655, 605, 517, 458, + 0, 672, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 259, 1202, 1203, 0, 0, 0, 0, 353, + 260, 600, 723, 602, 601, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1206, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 518, 547, 0, 560, 0, 422, + 423, 0, 0, 0, 0, 0, 0, 0, 338, 525, + 544, 354, 512, 558, 359, 520, 537, 349, 475, 509, + 0, 0, 340, 542, 519, 455, 339, 0, 502, 382, + 399, 379, 473, 0, 0, 541, 571, 378, 561, 865, + 552, 342, 864, 551, 472, 538, 543, 456, 449, 0, + 341, 540, 454, 448, 433, 389, 587, 434, 435, 403, + 488, 446, 489, 404, 460, 459, 461, 405, 406, 407, + 408, 409, 410, 411, 412, 413, 414, 0, 0, 0, + 0, 0, 582, 583, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 716, + 0, 0, 720, 0, 554, 0, 0, 0, 0, 0, + 0, 523, 0, 0, 436, 0, 0, 0, 572, 0, + 505, 478, 759, 0, 0, 503, 444, 539, 490, 545, + 526, 553, 497, 491, 332, 527, 381, 457, 350, 352, + 748, 383, 386, 390, 391, 466, 467, 484, 511, 530, + 531, 532, 380, 364, 504, 365, 400, 366, 333, 372, + 370, 373, 513, 374, 335, 485, 536, 0, 396, 500, + 452, 336, 451, 486, 535, 534, 351, 562, 569, 570, + 660, 0, 575, 760, 761, 762, 584, 0, 492, 347, + 344, 0, 0, 0, 376, 487, 360, 362, 363, 361, + 481, 483, 589, 590, 591, 593, 0, 594, 595, 0, + 0, 0, 0, 596, 661, 677, 645, 614, 577, 669, + 611, 615, 616, 417, 418, 419, 680, 0, 0, 0, + 568, 437, 438, 0, 388, 387, 453, 337, 0, 0, + 430, 416, 493, 343, 384, 432, 421, 439, 440, 441, + 394, 327, 328, 754, 377, 474, 682, 718, 719, 607, + 0, 670, 608, 617, 369, 642, 654, 653, 468, 567, + 0, 665, 668, 597, 753, 0, 662, 676, 758, 675, + 750, 480, 0, 510, 673, 620, 0, 666, 639, 640, + 0, 667, 635, 671, 0, 609, 0, 578, 581, 610, + 695, 696, 697, 334, 580, 699, 700, 701, 702, 703, + 704, 705, 698, 550, 643, 619, 646, 559, 622, 621, + 0, 0, 657, 576, 658, 659, 462, 463, 464, 465, + 398, 683, 358, 579, 495, 496, 0, 644, 0, 0, + 0, 0, 0, 0, 0, 0, 649, 650, 647, 763, + 0, 706, 707, 0, 0, 573, 574, 393, 0, 592, + 401, 357, 479, 395, 557, 424, 0, 585, 651, 586, + 498, 499, 710, 715, 711, 712, 714, 734, 1204, 2426, + 1200, 2427, 431, 445, 501, 556, 477, 506, 355, 546, + 516, 1201, 636, 664, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 314, 315, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 691, 690, 689, 688, 687, 686, 685, 684, 0, + 0, 633, 533, 371, 321, 367, 368, 375, 751, 747, + 752, 735, 738, 737, 713, 0, 329, 613, 443, 494, + 392, 678, 679, 0, 733, 273, 274, 275, 276, 277, + 278, 279, 280, 322, 281, 282, 283, 284, 285, 286, + 287, 292, 293, 294, 295, 296, 297, 298, 299, 681, + 290, 291, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 0, 0, 0, 0, + 323, 739, 740, 741, 742, 743, 0, 0, 324, 325, + 326, 0, 0, 288, 289, 316, 524, 317, 318, 319, + 320, 0, 0, 563, 564, 565, 588, 0, 566, 548, + 612, 402, 330, 528, 555, 749, 0, 0, 0, 0, + 0, 0, 0, 663, 674, 708, 709, 0, 721, 722, + 724, 726, 725, 728, 521, 522, 736, 0, 0, 425, + 345, 346, 470, 471, 508, 0, 426, 427, 428, 429, + 730, 731, 732, 729, 447, 507, 529, 515, 0, 755, + 603, 604, 756, 717, 331, 195, 237, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 163, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1737, 0, 0, 259, 0, 0, 0, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 3535, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 0, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3538, 0, 0, 0, 0, 3537, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 1793, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 1791, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 1789, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 1787, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 1791, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 1789, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4901, 0, 259, 1033, 0, 0, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 1791, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 1789, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 1791, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 2070, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 2315, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 2317, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 2480, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 2481, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 3760, 3762, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3403, 0, 0, 259, 0, 0, 3407, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3397, 0, 0, 259, 0, 0, 3401, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 2975, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 1791, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1161, 385, 0, 0, 442, 656, 637, + 648, 638, 1159, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 0, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 1160, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 1033, 0, 0, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4875, 0, 0, 259, 0, 0, 0, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 4574, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2084, 0, 0, 259, 0, 0, 0, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4594, 0, 259, 0, 0, 0, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 0, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 4587, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 0, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 4378, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 3796, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 4298, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1737, 0, 0, 259, 0, 0, 0, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 4136, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 3407, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 3127, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 3401, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 0, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 4126, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 0, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3831, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 4075, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 0, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 0, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3943, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 476, 0, 0, 618, + 652, 641, 727, 606, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 385, 0, 0, 442, 656, 637, + 648, 638, 482, 623, 624, 625, 632, 397, 626, 757, + 628, 598, 629, 599, 630, 631, 0, 655, 605, 517, + 458, 0, 672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 0, 3801, 0, 0, 0, + 353, 260, 600, 723, 602, 601, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 518, 547, 0, 560, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 338, + 525, 544, 354, 512, 558, 359, 520, 537, 349, 475, + 509, 0, 0, 340, 542, 519, 455, 339, 0, 502, + 382, 399, 379, 473, 0, 0, 541, 571, 378, 561, + 0, 552, 342, 0, 551, 472, 538, 543, 456, 449, + 0, 341, 540, 454, 448, 433, 389, 587, 434, 435, + 403, 488, 446, 489, 404, 460, 459, 461, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 0, 0, 582, 583, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 716, 0, 0, 720, 0, 554, 0, 0, 0, 0, + 0, 0, 523, 0, 0, 436, 0, 0, 0, 572, + 0, 505, 478, 759, 0, 0, 503, 444, 539, 490, + 545, 526, 553, 497, 491, 332, 527, 381, 457, 350, + 352, 748, 383, 386, 390, 391, 466, 467, 484, 511, + 530, 531, 532, 380, 364, 504, 365, 400, 366, 333, + 372, 370, 373, 513, 374, 335, 485, 536, 0, 396, + 500, 452, 336, 451, 486, 535, 534, 351, 562, 569, + 570, 660, 0, 575, 760, 761, 762, 584, 0, 492, + 347, 344, 0, 0, 0, 376, 487, 360, 362, 363, + 361, 481, 483, 589, 590, 591, 593, 0, 594, 595, + 0, 0, 0, 0, 596, 661, 677, 645, 614, 577, + 669, 611, 615, 616, 417, 418, 419, 680, 0, 0, + 0, 568, 437, 438, 0, 388, 387, 453, 337, 0, + 0, 430, 416, 493, 343, 384, 432, 421, 439, 440, + 441, 394, 327, 328, 754, 377, 474, 682, 718, 719, + 607, 0, 670, 608, 617, 369, 642, 654, 653, 468, + 567, 0, 665, 668, 597, 753, 0, 662, 676, 758, + 675, 750, 480, 0, 510, 673, 620, 0, 666, 639, + 640, 0, 667, 635, 671, 0, 609, 0, 578, 581, + 610, 695, 696, 697, 334, 580, 699, 700, 701, 702, + 703, 704, 705, 698, 550, 643, 619, 646, 559, 622, + 621, 0, 0, 657, 576, 658, 659, 462, 463, 464, + 465, 398, 683, 358, 579, 495, 496, 0, 644, 0, + 0, 0, 0, 0, 0, 0, 0, 649, 650, 647, + 763, 0, 706, 707, 0, 0, 573, 574, 393, 0, + 592, 401, 357, 479, 395, 557, 424, 0, 585, 651, + 586, 498, 499, 710, 715, 711, 712, 714, 734, 469, + 415, 420, 514, 431, 445, 501, 556, 477, 506, 355, + 546, 516, 450, 636, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 691, 690, 689, 688, 687, 686, 685, 684, + 0, 0, 633, 533, 371, 321, 367, 368, 375, 751, + 747, 752, 735, 738, 737, 713, 0, 329, 613, 443, + 494, 392, 678, 679, 0, 733, 273, 274, 275, 276, + 277, 278, 279, 280, 322, 281, 282, 283, 284, 285, + 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, + 681, 290, 291, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 0, 0, 0, + 0, 323, 739, 740, 741, 742, 743, 0, 0, 324, + 325, 326, 0, 0, 288, 289, 316, 524, 317, 318, + 319, 320, 0, 0, 563, 564, 565, 588, 0, 566, + 548, 612, 402, 330, 528, 555, 749, 0, 0, 0, + 0, 0, 0, 0, 663, 674, 708, 709, 0, 721, + 722, 724, 726, 725, 728, 521, 522, 736, 0, 0, + 425, 345, 346, 470, 471, 508, 0, 426, 427, 428, + 429, 730, 731, 732, 729, 447, 507, 529, 515, 0, + 755, 603, 604, 756, 717, 331, 3728, 0, 0, 0, + 0, 0, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 0, 655, 605, 517, 458, 0, 672, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, + 0, 0, 0, 0, 0, 0, 353, 260, 600, 723, + 602, 601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 0, 0, + 0, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 0, 0, 541, 571, 378, 561, 0, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 587, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 0, 0, 720, + 0, 554, 0, 0, 0, 0, 0, 0, 523, 0, + 0, 436, 0, 0, 0, 572, 0, 505, 478, 759, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 0, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 377, 474, 682, 718, 719, 607, 0, 670, 608, + 617, 369, 642, 654, 653, 468, 567, 0, 665, 668, + 597, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 550, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 576, 658, 659, 462, 463, 464, 465, 398, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 315, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 0, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 273, 274, 275, 276, 277, 278, 279, 280, + 322, 281, 282, 283, 284, 285, 286, 287, 292, 293, + 294, 295, 296, 297, 298, 299, 681, 290, 291, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 0, 0, 0, 0, 323, 739, 740, + 741, 742, 743, 0, 0, 324, 325, 326, 0, 0, + 288, 289, 316, 524, 317, 318, 319, 320, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 725, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 730, 731, 732, + 729, 447, 507, 529, 515, 0, 755, 603, 604, 756, + 717, 331, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 0, 655, 605, 517, 458, 0, 672, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, + 0, 0, 0, 0, 0, 0, 353, 260, 600, 723, + 602, 601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3616, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 0, 0, + 0, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 0, 0, 541, 571, 378, 561, 0, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 587, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 0, 0, 720, + 0, 554, 0, 0, 0, 0, 0, 0, 523, 0, + 0, 436, 0, 0, 0, 572, 0, 505, 478, 759, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 0, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 377, 474, 682, 718, 719, 607, 0, 670, 608, + 617, 369, 642, 654, 653, 468, 567, 0, 665, 668, + 597, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 550, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 576, 658, 659, 462, 463, 464, 465, 398, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 315, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 0, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 273, 274, 275, 276, 277, 278, 279, 280, + 322, 281, 282, 283, 284, 285, 286, 287, 292, 293, + 294, 295, 296, 297, 298, 299, 681, 290, 291, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 0, 0, 0, 0, 323, 739, 740, + 741, 742, 743, 0, 0, 324, 325, 326, 0, 0, + 288, 289, 316, 524, 317, 318, 319, 320, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 725, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 730, 731, 732, + 729, 447, 507, 529, 515, 0, 755, 603, 604, 756, + 717, 331, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 0, 655, 605, 517, 458, 0, 672, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, + 0, 0, 1791, 0, 0, 0, 353, 260, 600, 723, + 602, 601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 0, 0, + 0, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 0, 0, 541, 571, 378, 561, 0, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 587, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 0, 0, 720, + 0, 554, 0, 0, 0, 0, 0, 0, 523, 0, + 0, 436, 0, 0, 0, 572, 0, 505, 478, 759, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 0, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 377, 474, 682, 718, 719, 607, 0, 670, 608, + 617, 369, 642, 654, 653, 468, 567, 0, 665, 668, + 597, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 550, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 576, 658, 659, 462, 463, 464, 465, 398, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 315, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 0, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 273, 274, 275, 276, 277, 278, 279, 280, + 322, 281, 282, 283, 284, 285, 286, 287, 292, 293, + 294, 295, 296, 297, 298, 299, 681, 290, 291, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 0, 0, 0, 0, 323, 739, 740, + 741, 742, 743, 0, 0, 324, 325, 326, 0, 0, + 288, 289, 316, 524, 317, 318, 319, 320, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 725, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 730, 731, 732, + 729, 447, 507, 529, 515, 0, 755, 603, 604, 756, + 717, 331, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 0, 655, 605, 517, 458, 0, 672, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, + 0, 0, 2317, 0, 0, 0, 353, 260, 600, 723, + 602, 601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 0, 0, + 0, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 0, 0, 541, 571, 378, 561, 0, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 587, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 0, 0, 720, + 0, 554, 0, 0, 0, 0, 0, 0, 523, 0, + 0, 436, 0, 0, 0, 572, 0, 505, 478, 759, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 0, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 377, 474, 682, 718, 719, 607, 0, 670, 608, + 617, 369, 642, 654, 653, 468, 567, 0, 665, 668, + 597, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 550, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 576, 658, 659, 462, 463, 464, 465, 398, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 315, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 0, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 273, 274, 275, 276, 277, 278, 279, 280, + 322, 281, 282, 283, 284, 285, 286, 287, 292, 293, + 294, 295, 296, 297, 298, 299, 681, 290, 291, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 0, 0, 0, 0, 323, 739, 740, + 741, 742, 743, 0, 0, 324, 325, 326, 0, 0, + 288, 289, 316, 524, 317, 318, 319, 320, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 725, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 730, 731, 732, + 729, 447, 507, 529, 515, 0, 755, 603, 604, 756, + 717, 331, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 3446, 0, 0, 0, 0, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 0, 655, 605, 517, 458, 0, 672, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, + 0, 0, 0, 0, 0, 0, 353, 260, 600, 723, + 602, 601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 0, 0, + 0, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 0, 0, 541, 571, 378, 561, 0, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 587, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 0, 0, 720, + 0, 554, 0, 0, 0, 0, 0, 0, 523, 0, + 0, 436, 0, 0, 0, 572, 0, 505, 478, 759, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 0, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 377, 474, 682, 718, 719, 607, 0, 670, 608, + 617, 369, 642, 654, 653, 468, 567, 0, 665, 668, + 597, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 550, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 576, 658, 659, 462, 463, 464, 465, 398, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 315, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 0, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 273, 274, 275, 276, 277, 278, 279, 280, + 322, 281, 282, 283, 284, 285, 286, 287, 292, 293, + 294, 295, 296, 297, 298, 299, 681, 290, 291, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 0, 0, 0, 0, 323, 739, 740, + 741, 742, 743, 0, 0, 324, 325, 326, 0, 0, + 288, 289, 316, 524, 317, 318, 319, 320, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 725, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 730, 731, 732, + 729, 447, 507, 529, 515, 0, 755, 603, 604, 756, + 717, 331, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 0, 655, 605, 517, 458, 0, 672, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, + 0, 0, 3333, 0, 0, 0, 353, 260, 600, 723, + 602, 601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 0, 0, + 0, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 0, 0, 541, 571, 378, 561, 0, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 587, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 0, 0, 720, + 0, 554, 0, 0, 0, 0, 0, 0, 523, 0, + 0, 436, 0, 0, 0, 572, 0, 505, 478, 759, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 0, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 377, 474, 682, 718, 719, 607, 0, 670, 608, + 617, 369, 642, 654, 653, 468, 567, 0, 665, 668, + 597, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 550, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 576, 658, 659, 462, 463, 464, 465, 398, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 315, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 0, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 273, 274, 275, 276, 277, 278, 279, 280, + 322, 281, 282, 283, 284, 285, 286, 287, 292, 293, + 294, 295, 296, 297, 298, 299, 681, 290, 291, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 0, 0, 0, 0, 323, 739, 740, + 741, 742, 743, 0, 0, 324, 325, 326, 0, 0, + 288, 289, 316, 524, 317, 318, 319, 320, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 725, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 730, 731, 732, + 729, 447, 507, 529, 515, 0, 755, 603, 604, 756, + 717, 331, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 0, 655, 605, 517, 458, 0, 672, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, + 0, 0, 0, 0, 0, 0, 353, 260, 600, 723, + 602, 601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3314, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 0, 0, + 0, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 0, 0, 541, 571, 378, 561, 0, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 587, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 0, 0, 720, + 0, 554, 0, 0, 0, 0, 0, 0, 523, 0, + 0, 436, 0, 0, 0, 572, 0, 505, 478, 759, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 0, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 377, 474, 682, 718, 719, 607, 0, 670, 608, + 617, 369, 642, 654, 653, 468, 567, 0, 665, 668, + 597, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 550, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 576, 658, 659, 462, 463, 464, 465, 398, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 315, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 0, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 273, 274, 275, 276, 277, 278, 279, 280, + 322, 281, 282, 283, 284, 285, 286, 287, 292, 293, + 294, 295, 296, 297, 298, 299, 681, 290, 291, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 0, 0, 0, 0, 323, 739, 740, + 741, 742, 743, 0, 0, 324, 325, 326, 0, 0, + 288, 289, 316, 524, 317, 318, 319, 320, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 725, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 730, 731, 732, + 729, 447, 507, 529, 515, 0, 755, 603, 604, 756, + 717, 331, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 0, 655, 605, 517, 458, 0, 672, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, + 0, 0, 3255, 0, 0, 0, 353, 260, 600, 723, + 602, 601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 0, 0, + 0, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 0, 0, 541, 571, 378, 561, 0, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 587, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 0, 0, 720, + 0, 554, 0, 0, 0, 0, 0, 0, 523, 0, + 0, 436, 0, 0, 0, 572, 0, 505, 478, 759, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 0, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 377, 474, 682, 718, 719, 607, 0, 670, 608, + 617, 369, 642, 654, 653, 468, 567, 0, 665, 668, + 597, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 550, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 576, 658, 659, 462, 463, 464, 465, 398, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 315, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 0, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 273, 274, 275, 276, 277, 278, 279, 280, + 322, 281, 282, 283, 284, 285, 286, 287, 292, 293, + 294, 295, 296, 297, 298, 299, 681, 290, 291, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 0, 0, 0, 0, 323, 739, 740, + 741, 742, 743, 0, 0, 324, 325, 326, 0, 0, + 288, 289, 316, 524, 317, 318, 319, 320, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 725, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 730, 731, 732, + 729, 447, 507, 529, 515, 0, 755, 603, 604, 756, + 717, 331, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 0, 655, 605, 517, 458, 0, 672, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, + 0, 0, 0, 0, 0, 0, 353, 260, 600, 723, + 602, 601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2588, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 0, 0, + 0, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 0, 0, 541, 571, 378, 561, 0, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 587, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 0, 0, 720, + 0, 554, 0, 0, 0, 0, 0, 0, 523, 0, + 0, 436, 0, 0, 0, 572, 0, 505, 478, 759, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 0, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 377, 474, 682, 718, 719, 607, 0, 670, 608, + 617, 369, 642, 654, 653, 468, 567, 0, 665, 668, + 597, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 550, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 576, 658, 659, 462, 463, 464, 465, 398, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 315, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 0, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 273, 274, 275, 276, 277, 278, 279, 280, + 322, 281, 282, 283, 284, 285, 286, 287, 292, 293, + 294, 295, 296, 297, 298, 299, 681, 290, 291, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 0, 0, 0, 0, 323, 739, 740, + 741, 742, 743, 0, 0, 324, 325, 326, 0, 0, + 288, 289, 316, 524, 317, 318, 319, 320, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 725, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 730, 731, 732, + 729, 447, 507, 529, 515, 0, 755, 603, 604, 756, + 717, 331, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 0, 655, 605, 517, 458, 0, 672, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, + 0, 0, 3110, 0, 0, 0, 353, 260, 600, 723, + 602, 601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 0, 0, + 0, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 0, 0, 541, 571, 378, 561, 0, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 587, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 0, 0, 720, + 0, 554, 0, 0, 0, 0, 0, 0, 523, 0, + 0, 436, 0, 0, 0, 572, 0, 505, 478, 759, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 0, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 377, 474, 682, 718, 719, 607, 0, 670, 608, + 617, 369, 642, 654, 653, 468, 567, 0, 665, 668, + 597, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 550, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 576, 658, 659, 462, 463, 464, 465, 398, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 315, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 0, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 273, 274, 275, 276, 277, 278, 279, 280, + 322, 281, 282, 283, 284, 285, 286, 287, 292, 293, + 294, 295, 296, 297, 298, 299, 681, 290, 291, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 0, 0, 0, 0, 323, 739, 740, + 741, 742, 743, 0, 0, 324, 325, 326, 0, 0, + 288, 289, 316, 524, 317, 318, 319, 320, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 725, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 730, 731, 732, + 729, 447, 507, 529, 515, 0, 755, 603, 604, 756, + 717, 331, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 0, 655, 605, 517, 458, 0, 672, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, + 0, 0, 0, 0, 0, 0, 353, 260, 600, 723, + 602, 601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3057, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 0, 0, + 0, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 0, 0, 541, 571, 378, 561, 0, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 587, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 0, 0, 720, + 0, 554, 0, 0, 0, 0, 0, 0, 523, 0, + 0, 436, 0, 0, 0, 572, 0, 505, 478, 759, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 0, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 377, 474, 682, 718, 719, 607, 0, 670, 608, + 617, 369, 642, 654, 653, 468, 567, 0, 665, 668, + 597, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 550, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 576, 658, 659, 462, 463, 464, 465, 398, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 315, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 0, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 273, 274, 275, 276, 277, 278, 279, 280, + 322, 281, 282, 283, 284, 285, 286, 287, 292, 293, + 294, 295, 296, 297, 298, 299, 681, 290, 291, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 0, 0, 0, 0, 323, 739, 740, + 741, 742, 743, 0, 0, 324, 325, 326, 0, 0, + 288, 289, 316, 524, 317, 318, 319, 320, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 725, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 730, 731, 732, + 729, 447, 507, 529, 515, 0, 755, 603, 604, 756, + 717, 331, 476, 0, 0, 618, 652, 641, 727, 606, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 385, 0, 0, 442, 656, 637, 648, 638, 482, 623, + 624, 625, 632, 397, 626, 757, 628, 598, 629, 599, + 630, 631, 0, 655, 605, 517, 458, 0, 672, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, + 0, 0, 3055, 0, 0, 0, 353, 260, 600, 723, + 602, 601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 518, 547, 0, 560, 0, 422, 423, 0, 0, + 0, 0, 0, 0, 0, 338, 525, 544, 354, 512, + 558, 359, 520, 537, 349, 475, 509, 0, 0, 340, + 542, 519, 455, 339, 0, 502, 382, 399, 379, 473, + 0, 0, 541, 571, 378, 561, 0, 552, 342, 0, + 551, 472, 538, 543, 456, 449, 0, 341, 540, 454, + 448, 433, 389, 587, 434, 435, 403, 488, 446, 489, + 404, 460, 459, 461, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 0, 582, + 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 716, 0, 0, 720, + 0, 554, 0, 0, 0, 0, 0, 0, 523, 0, + 0, 436, 0, 0, 0, 572, 0, 505, 478, 759, + 0, 0, 503, 444, 539, 490, 545, 526, 553, 497, + 491, 332, 527, 381, 457, 350, 352, 748, 383, 386, + 390, 391, 466, 467, 484, 511, 530, 531, 532, 380, + 364, 504, 365, 400, 366, 333, 372, 370, 373, 513, + 374, 335, 485, 536, 0, 396, 500, 452, 336, 451, + 486, 535, 534, 351, 562, 569, 570, 660, 0, 575, + 760, 761, 762, 584, 0, 492, 347, 344, 0, 0, + 0, 376, 487, 360, 362, 363, 361, 481, 483, 589, + 590, 591, 593, 0, 594, 595, 0, 0, 0, 0, + 596, 661, 677, 645, 614, 577, 669, 611, 615, 616, + 417, 418, 419, 680, 0, 0, 0, 568, 437, 438, + 0, 388, 387, 453, 337, 0, 0, 430, 416, 493, + 343, 384, 432, 421, 439, 440, 441, 394, 327, 328, + 754, 377, 474, 682, 718, 719, 607, 0, 670, 608, + 617, 369, 642, 654, 653, 468, 567, 0, 665, 668, + 597, 753, 0, 662, 676, 758, 675, 750, 480, 0, + 510, 673, 620, 0, 666, 639, 640, 0, 667, 635, + 671, 0, 609, 0, 578, 581, 610, 695, 696, 697, + 334, 580, 699, 700, 701, 702, 703, 704, 705, 698, + 550, 643, 619, 646, 559, 622, 621, 0, 0, 657, + 576, 658, 659, 462, 463, 464, 465, 398, 683, 358, + 579, 495, 496, 0, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 649, 650, 647, 763, 0, 706, 707, + 0, 0, 573, 574, 393, 0, 592, 401, 357, 479, + 395, 557, 424, 0, 585, 651, 586, 498, 499, 710, + 715, 711, 712, 714, 734, 469, 415, 420, 514, 431, + 445, 501, 556, 477, 506, 355, 546, 516, 450, 636, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 315, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 691, 690, + 689, 688, 687, 686, 685, 684, 0, 0, 633, 533, + 371, 321, 367, 368, 375, 751, 747, 752, 735, 738, + 737, 713, 0, 329, 613, 443, 494, 392, 678, 679, + 0, 733, 273, 274, 275, 276, 277, 278, 279, 280, + 322, 281, 282, 283, 284, 285, 286, 287, 292, 293, + 294, 295, 296, 297, 298, 299, 681, 290, 291, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 0, 0, 0, 0, 323, 739, 740, + 741, 742, 743, 0, 0, 324, 325, 326, 0, 0, + 288, 289, 316, 524, 317, 318, 319, 320, 0, 0, + 563, 564, 565, 588, 0, 566, 548, 612, 402, 330, + 528, 555, 749, 0, 0, 0, 0, 0, 0, 0, + 663, 674, 708, 709, 0, 721, 722, 724, 726, 725, + 728, 521, 522, 736, 0, 0, 425, 345, 346, 470, + 471, 508, 0, 426, 427, 428, 429, 730, 731, 732, + 729, 447, 507, 529, 515, 0, 755, 603, 604, 756, + 717, 331, 2809, 0, 0, 0, 0, 0, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 2258, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 1387, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 2451, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 2398, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 1791, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 1963, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 1823, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1161, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 780, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 1164, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 3731, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 2241, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 1770, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 1768, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 1683, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 915, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 867, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 868, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 713, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 0, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 0, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 476, 0, + 0, 618, 652, 641, 727, 606, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 385, 0, 0, 442, + 656, 637, 648, 638, 482, 623, 624, 625, 632, 397, + 626, 757, 628, 598, 629, 599, 630, 631, 0, 655, + 605, 517, 458, 0, 672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 353, 260, 600, 723, 602, 601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 547, 0, + 560, 0, 422, 423, 0, 0, 0, 0, 0, 0, + 0, 338, 525, 544, 354, 512, 558, 359, 520, 537, + 349, 475, 509, 0, 0, 340, 542, 519, 455, 339, + 0, 502, 382, 399, 379, 473, 0, 0, 541, 571, + 378, 561, 0, 552, 342, 0, 551, 472, 538, 543, + 456, 449, 0, 341, 540, 454, 448, 433, 389, 587, + 434, 435, 403, 488, 446, 489, 404, 460, 459, 461, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 0, 0, 0, 0, 0, 582, 583, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 716, 0, 0, 720, 0, 554, 0, 0, + 0, 0, 0, 0, 523, 0, 0, 436, 0, 0, + 0, 572, 0, 505, 478, 759, 0, 0, 503, 444, + 539, 490, 545, 526, 553, 497, 491, 332, 527, 381, + 457, 350, 352, 748, 383, 386, 390, 391, 466, 467, + 484, 511, 530, 531, 532, 380, 364, 504, 365, 400, + 366, 333, 372, 370, 373, 513, 374, 335, 485, 536, + 0, 396, 500, 452, 336, 451, 486, 535, 534, 351, + 562, 569, 570, 660, 0, 575, 760, 761, 762, 584, + 0, 492, 347, 344, 0, 0, 0, 376, 487, 360, + 362, 363, 361, 481, 483, 589, 590, 591, 593, 0, + 594, 595, 0, 0, 0, 0, 596, 661, 677, 645, + 614, 577, 669, 611, 615, 616, 417, 418, 419, 680, + 0, 0, 0, 568, 437, 438, 0, 388, 387, 453, + 337, 0, 0, 430, 416, 493, 343, 384, 432, 421, + 439, 440, 441, 394, 327, 328, 754, 377, 474, 682, + 718, 719, 607, 0, 670, 608, 617, 369, 642, 654, + 653, 468, 567, 0, 665, 668, 597, 753, 0, 662, + 676, 758, 675, 750, 480, 0, 510, 673, 620, 0, + 666, 639, 640, 0, 667, 635, 671, 0, 609, 0, + 578, 581, 610, 695, 696, 697, 334, 580, 699, 700, + 701, 702, 703, 704, 705, 698, 550, 643, 619, 646, + 559, 622, 621, 0, 0, 657, 576, 658, 659, 462, + 463, 464, 465, 398, 683, 358, 579, 495, 496, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 649, + 650, 647, 763, 0, 706, 707, 0, 0, 573, 574, + 393, 0, 592, 401, 357, 479, 395, 557, 424, 0, + 585, 651, 586, 498, 499, 710, 715, 711, 712, 714, + 734, 469, 415, 420, 514, 431, 445, 501, 556, 477, + 506, 355, 546, 516, 450, 636, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 691, 690, 689, 688, 687, 686, + 685, 684, 0, 0, 633, 533, 371, 321, 367, 368, + 375, 751, 747, 752, 735, 738, 737, 804, 0, 329, + 613, 443, 494, 392, 678, 679, 0, 733, 273, 274, + 275, 276, 277, 278, 279, 280, 322, 281, 282, 283, + 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, + 298, 299, 681, 290, 291, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 0, + 0, 2378, 0, 323, 739, 740, 741, 742, 743, 0, + 0, 324, 325, 326, 0, 0, 288, 289, 316, 524, + 317, 318, 319, 320, 0, 0, 563, 564, 565, 588, + 0, 566, 548, 612, 402, 330, 528, 555, 749, 2380, + 0, 0, 0, 0, 0, 0, 663, 674, 708, 709, + 0, 721, 722, 724, 726, 725, 728, 521, 522, 736, + 0, 0, 425, 345, 346, 470, 471, 508, 0, 426, + 427, 428, 429, 730, 731, 732, 729, 447, 507, 529, + 515, 0, 755, 603, 604, 756, 717, 331, 2378, 0, + 0, 0, 0, 2339, 2355, 0, 2386, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2380, 2348, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2381, 2382, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2347, 0, 0, 0, 0, 0, 2378, + 4564, 0, 0, 0, 2371, 0, 0, 0, 0, 0, + 0, 2355, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2380, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2371, 2355, 0, 0, 0, 0, 0, 2359, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2365, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2353, + 2387, 0, 0, 2354, 2356, 2358, 0, 2360, 2361, 2362, + 2366, 2367, 2368, 2370, 2373, 2374, 2375, 0, 0, 0, + 0, 0, 0, 0, 2363, 2372, 2364, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2371, 0, 2338, 3413, 2337, 0, 0, 0, + 3412, 0, 0, 0, 0, 2359, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2365, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2379, 0, + 0, 0, 0, 0, 0, 0, 2353, 2387, 0, 0, + 2354, 2356, 2358, 0, 2360, 2361, 2362, 2366, 2367, 2368, + 2370, 2373, 2374, 2375, 0, 0, 0, 0, 0, 0, + 0, 2363, 2372, 2364, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2359, 0, 0, 0, + 0, 0, 2376, 0, 0, 0, 0, 2365, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2352, 0, 0, 0, 2351, 2379, 0, 2353, 2387, 0, + 0, 2354, 2356, 2358, 0, 2360, 2361, 2362, 2366, 2367, + 2368, 2370, 2373, 2374, 2375, 0, 0, 0, 2369, 0, + 0, 0, 2363, 2372, 2364, 0, 0, 2357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2335, 2336, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 163, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1371, 0, 0, 0, 0, - 2356, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2332, 0, - 0, 0, 2331, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2349, 0, 0, 0, - 0, 0, 0, 0, 0, 2337, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3866, 0, 0, 0, 0, 0, 0, 0, 163, - 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1724, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2379, 2352, 0, 0, + 0, 2351, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4368, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1724, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 163, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4465, 0, 975, 0, 0, 0, 0, 0, 0, 0, - 0, 468, 0, 0, 610, 644, 633, 718, 598, 0, - 0, 0, 0, 0, 0, 926, 0, 0, 0, 381, - 0, 0, 434, 648, 629, 640, 630, 474, 615, 616, - 617, 624, 393, 618, 748, 620, 590, 621, 591, 622, - 623, 966, 647, 597, 509, 450, 0, 664, 0, 3866, - 1046, 1054, 0, 0, 0, 0, 0, 0, 0, 0, - 1042, 0, 0, 0, 0, 918, 0, 0, 955, 1023, - 1022, 942, 952, 0, 0, 349, 256, 592, 714, 594, - 593, 943, 0, 944, 948, 951, 947, 945, 946, 0, - 1037, 0, 0, 0, 0, 0, 0, 910, 922, 0, - 927, 0, 0, 0, 0, 0, 0, 0, 163, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 919, 920, 0, 0, - 0, 0, 976, 0, 921, 0, 0, 0, 0, 0, - 510, 539, 0, 552, 0, 418, 419, 971, 949, 953, - 0, 0, 0, 0, 334, 517, 536, 350, 504, 550, - 355, 512, 529, 345, 467, 501, 0, 0, 336, 534, - 511, 447, 335, 0, 494, 378, 395, 375, 465, 950, - 0, 974, 978, 374, 1060, 972, 544, 338, 0, 543, - 464, 530, 535, 448, 441, 0, 337, 532, 446, 440, - 425, 385, 1061, 426, 427, 399, 480, 438, 481, 400, - 452, 451, 453, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 0, 0, 0, 0, 0, 574, 575, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 707, 969, 0, 711, 0, - 546, 0, 0, 1044, 0, 0, 0, 515, 0, 0, - 428, 0, 0, 0, 973, 0, 497, 470, 1057, 0, - 0, 495, 436, 531, 482, 537, 518, 545, 489, 483, - 328, 519, 377, 449, 346, 348, 739, 379, 382, 386, - 387, 458, 459, 476, 503, 522, 523, 524, 376, 360, - 496, 361, 396, 362, 329, 368, 366, 369, 505, 370, - 331, 477, 528, 0, 392, 492, 444, 332, 443, 478, - 527, 526, 347, 554, 561, 562, 652, 0, 567, 751, - 752, 753, 576, 0, 484, 343, 340, 0, 0, 0, - 372, 479, 356, 358, 359, 357, 473, 475, 581, 582, - 583, 585, 0, 586, 587, 0, 0, 0, 163, 588, - 653, 669, 637, 606, 569, 661, 603, 607, 608, 413, - 414, 415, 672, 2115, 2114, 2116, 560, 429, 430, 0, - 384, 383, 445, 333, 0, 0, 422, 412, 485, 339, - 380, 424, 417, 431, 432, 433, 390, 323, 324, 745, - 1041, 466, 674, 709, 710, 599, 0, 1056, 1036, 1038, - 1039, 1043, 1047, 1048, 1049, 1050, 1051, 1053, 1055, 1059, - 744, 0, 654, 668, 749, 667, 741, 472, 0, 502, - 665, 612, 0, 658, 631, 632, 0, 659, 627, 663, - 0, 601, 0, 570, 573, 602, 687, 688, 689, 330, - 572, 691, 692, 693, 694, 695, 696, 697, 690, 1058, - 635, 611, 638, 551, 614, 613, 0, 0, 649, 977, - 650, 651, 454, 455, 456, 457, 1045, 675, 354, 571, - 487, 488, 0, 636, 0, 0, 0, 0, 0, 0, - 0, 0, 641, 642, 639, 754, 0, 698, 699, 0, - 0, 565, 566, 389, 0, 584, 397, 353, 471, 391, - 549, 420, 0, 577, 643, 578, 490, 491, 701, 706, - 702, 703, 705, 725, 461, 411, 416, 506, 423, 437, - 493, 548, 469, 498, 351, 538, 508, 442, 628, 656, - 1067, 1040, 1066, 1068, 1069, 1065, 1070, 1071, 1052, 931, - 0, 984, 985, 1063, 1062, 1064, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 683, 682, 681, - 680, 679, 678, 677, 676, 0, 0, 625, 525, 367, - 317, 363, 364, 371, 742, 738, 743, 726, 729, 728, - 704, 938, 325, 605, 435, 486, 388, 670, 671, 0, - 724, 1030, 993, 994, 995, 928, 996, 990, 991, 929, - 992, 1031, 982, 1027, 1028, 957, 987, 997, 1026, 998, - 1029, 958, 1032, 1072, 1073, 1004, 988, 287, 1074, 1001, - 1033, 1025, 1024, 999, 983, 1034, 1035, 965, 960, 1002, - 1003, 989, 1010, 1011, 1012, 1015, 930, 1016, 1017, 1018, - 1019, 1020, 1014, 1013, 979, 980, 981, 1005, 1006, 1008, - 1009, 986, 516, 961, 962, 963, 964, 0, 0, 555, - 556, 557, 580, 0, 558, 540, 604, 398, 326, 520, - 547, 740, 0, 0, 0, 0, 0, 0, 0, 655, - 666, 700, 0, 712, 713, 715, 717, 1021, 719, 513, - 514, 727, 0, 0, 421, 341, 342, 462, 463, 500, - 0, 1007, 722, 723, 720, 439, 499, 521, 507, 0, - 746, 595, 596, 747, 708, 327, 0, 923, 192, 233, - 975, 0, 0, 0, 0, 0, 0, 0, 0, 468, - 0, 0, 610, 644, 633, 718, 598, 0, 0, 0, - 0, 0, 0, 926, 0, 0, 0, 381, 0, 0, - 434, 648, 629, 640, 630, 474, 615, 616, 617, 624, - 393, 618, 748, 620, 590, 621, 591, 622, 623, 966, - 647, 597, 509, 450, 0, 664, 0, 0, 1046, 1054, - 0, 0, 0, 0, 0, 0, 0, 0, 1042, 0, - 0, 0, 0, 918, 0, 0, 955, 1023, 1022, 942, - 952, 0, 0, 349, 256, 592, 714, 594, 593, 943, - 0, 944, 948, 951, 947, 945, 946, 0, 1037, 0, - 0, 0, 0, 0, 0, 910, 922, 0, 927, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 919, 920, 0, 0, 0, 0, - 976, 0, 921, 0, 0, 0, 0, 0, 510, 539, - 0, 552, 0, 418, 419, 971, 949, 953, 0, 0, - 0, 0, 334, 517, 536, 350, 504, 550, 355, 512, - 529, 345, 467, 501, 0, 0, 336, 534, 511, 447, - 335, 0, 494, 378, 395, 375, 465, 950, 0, 974, - 978, 374, 1060, 972, 544, 338, 0, 543, 464, 530, - 535, 448, 441, 0, 337, 532, 446, 440, 425, 385, - 1061, 426, 427, 399, 480, 438, 481, 400, 452, 451, - 453, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 0, 0, 0, 0, 574, 575, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 707, 969, 0, 711, 0, 546, 0, - 0, 1044, 0, 0, 0, 515, 0, 0, 428, 0, - 0, 0, 973, 0, 497, 470, 1057, 0, 0, 495, - 436, 531, 482, 537, 518, 545, 489, 483, 328, 519, - 377, 449, 346, 348, 739, 379, 382, 386, 387, 458, - 459, 476, 503, 522, 523, 524, 376, 360, 496, 361, - 396, 362, 329, 368, 366, 369, 505, 370, 331, 477, - 528, 0, 392, 492, 444, 332, 443, 478, 527, 526, - 347, 554, 561, 562, 652, 0, 567, 751, 752, 753, - 576, 0, 484, 343, 340, 0, 0, 0, 372, 479, - 356, 358, 359, 357, 473, 475, 581, 582, 583, 585, - 0, 586, 587, 0, 0, 0, 0, 588, 653, 669, - 637, 606, 569, 661, 603, 607, 608, 413, 414, 415, - 672, 0, 0, 0, 560, 429, 430, 0, 384, 383, - 445, 333, 0, 0, 422, 412, 485, 339, 380, 424, - 417, 431, 432, 433, 390, 323, 324, 745, 1041, 466, - 674, 709, 710, 599, 0, 1056, 1036, 1038, 1039, 1043, - 1047, 1048, 1049, 1050, 1051, 1053, 1055, 1059, 744, 0, - 654, 668, 749, 667, 741, 472, 0, 502, 665, 612, - 0, 658, 631, 632, 0, 659, 627, 663, 0, 601, - 0, 570, 573, 602, 687, 688, 689, 330, 572, 691, - 692, 693, 694, 695, 696, 697, 690, 1058, 635, 611, - 638, 551, 614, 613, 0, 0, 649, 977, 650, 651, - 454, 455, 456, 457, 1045, 675, 354, 571, 487, 488, - 0, 636, 0, 0, 0, 0, 0, 0, 0, 0, - 641, 642, 639, 754, 0, 698, 699, 0, 0, 565, - 566, 389, 0, 584, 397, 353, 471, 391, 549, 420, - 0, 577, 643, 578, 490, 491, 701, 706, 702, 703, - 705, 725, 461, 411, 416, 506, 423, 437, 493, 548, - 469, 498, 351, 538, 508, 442, 628, 656, 1067, 1040, - 1066, 1068, 1069, 1065, 1070, 1071, 1052, 931, 0, 984, - 985, 1063, 1062, 1064, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 683, 682, 681, 680, 679, - 678, 677, 676, 0, 0, 625, 525, 367, 317, 363, - 364, 371, 742, 738, 743, 726, 729, 728, 704, 938, - 325, 605, 435, 486, 388, 670, 671, 0, 724, 1030, - 993, 994, 995, 928, 996, 990, 991, 929, 992, 1031, - 982, 1027, 1028, 957, 987, 997, 1026, 998, 1029, 958, - 1032, 1072, 1073, 1004, 988, 287, 1074, 1001, 1033, 1025, - 1024, 999, 983, 1034, 1035, 965, 960, 1002, 1003, 989, - 1010, 1011, 1012, 1015, 930, 1016, 1017, 1018, 1019, 1020, - 1014, 1013, 979, 980, 981, 1005, 1006, 1008, 1009, 986, - 516, 961, 962, 963, 964, 0, 0, 555, 556, 557, - 580, 0, 558, 540, 604, 398, 326, 520, 547, 740, - 0, 0, 0, 0, 0, 0, 0, 655, 666, 700, - 0, 712, 713, 715, 717, 1021, 719, 513, 514, 727, - 0, 0, 421, 341, 342, 462, 463, 500, 0, 1007, - 722, 723, 720, 439, 499, 521, 507, 975, 746, 595, - 596, 747, 708, 327, 0, 923, 468, 0, 0, 610, - 644, 633, 718, 598, 0, 0, 0, 0, 0, 0, - 926, 0, 0, 0, 381, 2182, 0, 434, 648, 629, - 640, 630, 474, 615, 616, 617, 624, 393, 618, 748, - 620, 590, 621, 591, 622, 623, 966, 647, 597, 509, - 450, 0, 664, 0, 0, 1046, 1054, 0, 0, 0, - 0, 0, 0, 0, 0, 1042, 0, 2413, 0, 0, - 918, 0, 0, 955, 1023, 1022, 942, 952, 0, 0, - 349, 256, 592, 714, 594, 593, 943, 0, 944, 948, - 951, 947, 945, 946, 0, 1037, 0, 0, 0, 0, - 0, 0, 910, 922, 0, 927, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 919, 920, 0, 0, 0, 0, 976, 0, 921, - 0, 0, 0, 0, 0, 510, 539, 0, 552, 0, - 418, 419, 2414, 949, 953, 0, 0, 0, 0, 334, - 517, 536, 350, 504, 550, 355, 512, 529, 345, 467, - 501, 0, 0, 336, 534, 511, 447, 335, 0, 494, - 378, 395, 375, 465, 950, 0, 974, 978, 374, 1060, - 972, 544, 338, 0, 543, 464, 530, 535, 448, 441, - 0, 337, 532, 446, 440, 425, 385, 1061, 426, 427, - 399, 480, 438, 481, 400, 452, 451, 453, 401, 402, - 403, 404, 405, 406, 407, 408, 409, 410, 0, 0, - 0, 0, 0, 574, 575, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 707, 969, 0, 711, 0, 546, 0, 0, 1044, 0, - 0, 0, 515, 0, 0, 428, 0, 0, 0, 973, - 0, 497, 470, 1057, 0, 0, 495, 436, 531, 482, - 537, 518, 545, 489, 483, 328, 519, 377, 449, 346, - 348, 739, 379, 382, 386, 387, 458, 459, 476, 503, - 522, 523, 524, 376, 360, 496, 361, 396, 362, 329, - 368, 366, 369, 505, 370, 331, 477, 528, 0, 392, - 492, 444, 332, 443, 478, 527, 526, 347, 554, 561, - 562, 652, 0, 567, 751, 752, 753, 576, 0, 484, - 343, 340, 0, 0, 0, 372, 479, 356, 358, 359, - 357, 473, 475, 581, 582, 583, 585, 0, 586, 587, - 0, 0, 0, 0, 588, 653, 669, 637, 606, 569, - 661, 603, 607, 608, 413, 414, 415, 672, 0, 0, - 0, 560, 429, 430, 0, 384, 383, 445, 333, 0, - 0, 422, 412, 485, 339, 380, 424, 417, 431, 432, - 433, 390, 323, 324, 745, 1041, 466, 674, 709, 710, - 599, 0, 1056, 1036, 1038, 1039, 1043, 1047, 1048, 1049, - 1050, 1051, 1053, 1055, 1059, 744, 0, 654, 668, 749, - 667, 741, 472, 0, 502, 665, 612, 0, 658, 631, - 632, 0, 659, 627, 663, 0, 601, 0, 570, 573, - 602, 687, 688, 689, 330, 572, 691, 692, 693, 694, - 695, 696, 697, 690, 1058, 635, 611, 638, 551, 614, - 613, 0, 0, 649, 977, 650, 651, 454, 455, 456, - 457, 1045, 675, 354, 571, 487, 488, 0, 636, 0, - 0, 0, 0, 0, 0, 0, 0, 641, 642, 639, - 754, 0, 698, 699, 0, 0, 565, 566, 389, 0, - 584, 397, 353, 471, 391, 549, 420, 0, 577, 643, - 578, 490, 491, 701, 706, 702, 703, 705, 725, 461, - 411, 416, 506, 423, 437, 493, 548, 469, 498, 351, - 538, 508, 442, 628, 656, 1067, 1040, 1066, 1068, 1069, - 1065, 1070, 1071, 1052, 931, 0, 984, 985, 1063, 1062, - 1064, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 683, 682, 681, 680, 679, 678, 677, 676, - 0, 0, 625, 525, 367, 317, 363, 364, 371, 742, - 738, 743, 726, 729, 728, 704, 938, 325, 605, 435, - 486, 388, 670, 671, 0, 724, 1030, 993, 994, 995, - 928, 996, 990, 991, 929, 992, 1031, 982, 1027, 1028, - 957, 987, 997, 1026, 998, 1029, 958, 1032, 1072, 1073, - 1004, 988, 287, 1074, 1001, 1033, 1025, 1024, 999, 983, - 1034, 1035, 965, 960, 1002, 1003, 989, 1010, 1011, 1012, - 1015, 930, 1016, 1017, 1018, 1019, 1020, 1014, 1013, 979, - 980, 981, 1005, 1006, 1008, 1009, 986, 516, 961, 962, - 963, 964, 0, 0, 555, 556, 557, 580, 0, 558, - 540, 604, 398, 326, 520, 547, 740, 0, 0, 0, - 0, 0, 0, 0, 655, 666, 700, 0, 712, 713, - 715, 717, 1021, 719, 513, 514, 727, 0, 0, 421, - 341, 342, 462, 463, 500, 0, 1007, 722, 723, 720, - 439, 499, 521, 507, 0, 746, 595, 596, 747, 708, - 327, 0, 923, 192, 233, 975, 0, 0, 0, 0, - 0, 0, 0, 0, 468, 0, 0, 610, 644, 633, - 718, 598, 0, 0, 0, 0, 0, 0, 926, 0, - 0, 0, 381, 0, 0, 434, 648, 629, 640, 630, - 474, 615, 616, 617, 624, 393, 618, 748, 620, 590, - 621, 591, 622, 623, 1530, 647, 597, 509, 450, 0, - 664, 0, 0, 1046, 1054, 0, 0, 0, 0, 0, - 0, 0, 0, 1042, 0, 0, 0, 0, 918, 0, - 0, 955, 1023, 1022, 942, 952, 0, 0, 349, 256, - 592, 714, 594, 593, 943, 0, 944, 948, 951, 947, - 945, 946, 0, 1037, 0, 0, 0, 0, 0, 0, - 910, 922, 0, 927, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 919, - 920, 0, 0, 0, 0, 976, 0, 921, 0, 0, - 0, 0, 0, 510, 539, 0, 552, 0, 418, 419, - 971, 949, 953, 0, 0, 0, 0, 334, 517, 536, - 350, 504, 550, 355, 512, 529, 345, 467, 501, 0, - 0, 336, 534, 511, 447, 335, 0, 494, 378, 395, - 375, 465, 950, 0, 974, 978, 374, 1060, 972, 544, - 338, 0, 543, 464, 530, 535, 448, 441, 0, 337, - 532, 446, 440, 425, 385, 1061, 426, 427, 399, 480, - 438, 481, 400, 452, 451, 453, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 0, 0, 0, 0, - 0, 574, 575, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 707, 969, - 0, 711, 0, 546, 0, 0, 1044, 0, 0, 0, - 515, 0, 0, 428, 0, 0, 0, 973, 0, 497, - 470, 1057, 0, 0, 495, 436, 531, 482, 537, 518, - 545, 489, 483, 328, 519, 377, 449, 346, 348, 739, - 379, 382, 386, 387, 458, 459, 476, 503, 522, 523, - 524, 376, 360, 496, 361, 396, 362, 329, 368, 366, - 369, 505, 370, 331, 477, 528, 0, 392, 492, 444, - 332, 443, 478, 527, 526, 347, 554, 561, 562, 652, - 0, 567, 751, 752, 753, 576, 0, 484, 343, 340, - 0, 0, 0, 372, 479, 356, 358, 359, 357, 473, - 475, 581, 582, 583, 585, 0, 586, 587, 0, 0, - 0, 0, 588, 653, 669, 637, 606, 569, 661, 603, - 607, 608, 413, 414, 415, 672, 0, 0, 0, 560, - 429, 430, 0, 384, 383, 445, 333, 0, 0, 422, - 412, 485, 339, 380, 424, 417, 431, 432, 433, 390, - 323, 324, 745, 1041, 466, 674, 709, 710, 599, 0, - 1056, 1036, 1038, 1039, 1043, 1047, 1048, 1049, 1050, 1051, - 1053, 1055, 1059, 744, 0, 654, 668, 749, 667, 741, - 472, 0, 502, 665, 612, 0, 658, 631, 632, 0, - 659, 627, 663, 0, 601, 0, 570, 573, 602, 687, - 688, 689, 330, 572, 691, 692, 693, 694, 695, 696, - 697, 690, 1058, 635, 611, 638, 551, 614, 613, 0, - 0, 649, 977, 650, 651, 454, 455, 456, 457, 1045, - 675, 354, 571, 487, 488, 0, 636, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 639, 754, 0, - 698, 699, 0, 0, 565, 566, 389, 0, 584, 397, - 353, 471, 391, 549, 420, 0, 577, 643, 578, 490, - 491, 701, 706, 702, 703, 705, 725, 461, 411, 416, - 506, 423, 437, 493, 548, 469, 498, 351, 538, 508, - 442, 628, 656, 1067, 1040, 1066, 1068, 1069, 1065, 1070, - 1071, 1052, 931, 0, 984, 985, 1063, 1062, 1064, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 683, 682, 681, 680, 679, 678, 677, 676, 0, 0, - 625, 525, 367, 317, 363, 364, 371, 742, 738, 743, - 726, 729, 728, 704, 938, 325, 605, 435, 486, 388, - 670, 671, 0, 724, 1030, 993, 994, 995, 928, 996, - 990, 991, 929, 992, 1031, 982, 1027, 1028, 957, 987, - 997, 1026, 998, 1029, 958, 1032, 1072, 1073, 1004, 988, - 287, 1074, 1001, 1033, 1025, 1024, 999, 983, 1034, 1035, - 965, 960, 1002, 1003, 989, 1010, 1011, 1012, 1015, 930, - 1016, 1017, 1018, 1019, 1020, 1014, 1013, 979, 980, 981, - 1005, 1006, 1008, 1009, 986, 516, 961, 962, 963, 964, - 0, 0, 555, 556, 557, 580, 0, 558, 540, 604, - 398, 326, 520, 547, 740, 0, 0, 0, 0, 0, - 0, 0, 655, 666, 700, 0, 712, 713, 715, 717, - 1021, 719, 513, 514, 727, 0, 0, 421, 341, 342, - 462, 463, 500, 0, 1007, 722, 723, 720, 439, 499, - 521, 507, 975, 746, 595, 596, 747, 708, 327, 0, - 923, 468, 0, 0, 610, 644, 633, 718, 598, 0, - 0, 0, 0, 0, 0, 926, 0, 0, 0, 381, - 4895, 0, 434, 648, 629, 640, 630, 474, 615, 616, - 617, 624, 393, 618, 748, 620, 590, 621, 591, 622, - 623, 966, 647, 597, 509, 450, 0, 664, 0, 0, - 1046, 1054, 0, 0, 0, 0, 0, 0, 0, 0, - 1042, 0, 0, 0, 0, 918, 0, 0, 955, 1023, - 1022, 942, 952, 0, 0, 349, 256, 592, 714, 594, - 593, 943, 0, 944, 948, 951, 947, 945, 946, 0, - 1037, 0, 0, 0, 0, 0, 0, 910, 922, 0, - 927, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 919, 920, 0, 0, - 0, 0, 976, 0, 921, 0, 0, 0, 0, 0, - 510, 539, 0, 552, 0, 418, 419, 971, 949, 953, - 0, 0, 0, 0, 334, 517, 536, 350, 504, 550, - 355, 512, 529, 345, 467, 501, 0, 0, 336, 534, - 511, 447, 335, 0, 494, 378, 395, 375, 465, 950, - 0, 974, 978, 374, 1060, 972, 544, 338, 0, 543, - 464, 530, 535, 448, 441, 0, 337, 532, 446, 440, - 425, 385, 1061, 426, 427, 399, 480, 438, 481, 400, - 452, 451, 453, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 0, 0, 0, 0, 0, 574, 575, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 707, 969, 0, 711, 0, - 546, 0, 0, 1044, 0, 0, 0, 515, 0, 0, - 428, 0, 0, 0, 973, 0, 497, 470, 1057, 0, - 0, 495, 436, 531, 482, 537, 518, 545, 489, 483, - 328, 519, 377, 449, 346, 348, 739, 379, 382, 386, - 387, 458, 459, 476, 503, 522, 523, 524, 376, 360, - 496, 361, 396, 362, 329, 368, 366, 369, 505, 370, - 331, 477, 528, 0, 392, 492, 444, 332, 443, 478, - 527, 526, 347, 554, 561, 562, 652, 0, 567, 751, - 752, 753, 576, 0, 484, 343, 340, 0, 0, 0, - 372, 479, 356, 358, 359, 357, 473, 475, 581, 582, - 583, 585, 0, 586, 587, 0, 0, 0, 0, 588, - 653, 669, 637, 606, 569, 661, 603, 607, 608, 413, - 414, 415, 672, 0, 0, 0, 560, 429, 430, 0, - 384, 383, 445, 333, 0, 0, 422, 412, 485, 339, - 380, 424, 417, 431, 432, 433, 390, 323, 324, 745, - 1041, 466, 674, 709, 710, 599, 0, 1056, 1036, 1038, - 1039, 1043, 1047, 1048, 1049, 1050, 1051, 1053, 1055, 1059, - 744, 0, 654, 668, 749, 667, 741, 472, 0, 502, - 665, 612, 0, 658, 631, 632, 0, 659, 627, 663, - 0, 601, 0, 570, 573, 602, 687, 688, 689, 330, - 572, 691, 692, 693, 694, 695, 696, 697, 690, 1058, - 635, 611, 638, 551, 614, 613, 0, 0, 649, 977, - 650, 651, 454, 455, 456, 457, 1045, 675, 354, 571, - 487, 488, 0, 636, 0, 0, 0, 0, 0, 0, - 0, 0, 641, 642, 639, 754, 0, 698, 699, 0, - 0, 565, 566, 389, 0, 584, 397, 353, 471, 391, - 549, 420, 0, 577, 643, 578, 490, 491, 701, 706, - 702, 703, 705, 725, 461, 411, 416, 506, 423, 437, - 493, 548, 469, 498, 351, 538, 508, 442, 628, 656, - 1067, 1040, 1066, 1068, 1069, 1065, 1070, 1071, 1052, 931, - 0, 984, 985, 1063, 1062, 1064, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 683, 682, 681, - 680, 679, 678, 677, 676, 0, 0, 625, 525, 367, - 317, 363, 364, 371, 742, 738, 743, 726, 729, 728, - 704, 938, 325, 605, 435, 486, 388, 670, 671, 0, - 724, 1030, 993, 994, 995, 928, 996, 990, 991, 929, - 992, 1031, 982, 1027, 1028, 957, 987, 997, 1026, 998, - 1029, 958, 1032, 1072, 1073, 1004, 988, 287, 1074, 1001, - 1033, 1025, 1024, 999, 983, 1034, 1035, 965, 960, 1002, - 1003, 989, 1010, 1011, 1012, 1015, 930, 1016, 1017, 1018, - 1019, 1020, 1014, 1013, 979, 980, 981, 1005, 1006, 1008, - 1009, 986, 516, 961, 962, 963, 964, 0, 0, 555, - 556, 557, 580, 0, 558, 540, 604, 398, 326, 520, - 547, 740, 0, 0, 0, 0, 0, 0, 0, 655, - 666, 700, 0, 712, 713, 715, 717, 1021, 719, 513, - 514, 727, 0, 0, 421, 341, 342, 462, 463, 500, - 0, 1007, 722, 723, 720, 439, 499, 521, 507, 975, - 746, 595, 596, 747, 708, 327, 0, 923, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 0, 0, - 0, 0, 926, 0, 0, 0, 381, 0, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 966, 647, - 597, 509, 450, 0, 664, 0, 0, 1046, 1054, 0, - 0, 0, 0, 0, 0, 0, 0, 1042, 0, 0, - 0, 0, 918, 0, 0, 955, 1023, 1022, 942, 952, - 0, 0, 349, 256, 592, 714, 594, 593, 943, 0, - 944, 948, 951, 947, 945, 946, 0, 1037, 0, 0, - 0, 0, 0, 0, 910, 922, 0, 927, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 919, 920, 0, 0, 0, 0, 976, - 0, 921, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 971, 949, 953, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 950, 0, 974, 978, - 374, 1060, 972, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 1061, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 969, 0, 711, 0, 546, 0, 0, - 1044, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 973, 0, 497, 470, 1057, 4769, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 1041, 466, 674, - 709, 710, 599, 0, 1056, 1036, 1038, 1039, 1043, 1047, - 1048, 1049, 1050, 1051, 1053, 1055, 1059, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 1058, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 977, 650, 651, 454, - 455, 456, 457, 1045, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 1067, 1040, 1066, - 1068, 1069, 1065, 1070, 1071, 1052, 931, 0, 984, 985, - 1063, 1062, 1064, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 938, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 1030, 993, - 994, 995, 928, 996, 990, 991, 929, 992, 1031, 982, - 1027, 1028, 957, 987, 997, 1026, 998, 1029, 958, 1032, - 1072, 1073, 1004, 988, 287, 1074, 1001, 1033, 1025, 1024, - 999, 983, 1034, 1035, 965, 960, 1002, 1003, 989, 1010, - 1011, 1012, 1015, 930, 1016, 1017, 1018, 1019, 1020, 1014, - 1013, 979, 980, 981, 1005, 1006, 1008, 1009, 986, 516, - 961, 962, 963, 964, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 1021, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 1007, 722, - 723, 720, 439, 499, 521, 507, 975, 746, 595, 596, - 747, 708, 327, 0, 923, 468, 0, 0, 610, 644, - 633, 718, 598, 0, 0, 0, 0, 0, 0, 926, - 0, 0, 0, 381, 2182, 0, 434, 648, 629, 640, - 630, 474, 615, 616, 617, 624, 393, 618, 748, 620, - 590, 621, 591, 622, 623, 966, 647, 597, 509, 450, - 0, 664, 0, 0, 1046, 1054, 0, 0, 0, 0, - 0, 0, 0, 0, 1042, 0, 0, 0, 0, 918, - 0, 0, 955, 1023, 1022, 942, 952, 0, 0, 349, - 256, 592, 714, 594, 593, 943, 0, 944, 948, 951, - 947, 945, 946, 0, 1037, 0, 0, 0, 0, 0, - 0, 910, 922, 0, 927, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 919, 920, 0, 0, 0, 0, 976, 0, 921, 0, - 0, 0, 0, 0, 510, 539, 0, 552, 0, 418, - 419, 971, 949, 953, 0, 0, 0, 0, 334, 517, - 536, 350, 504, 550, 355, 512, 529, 345, 467, 501, - 0, 0, 336, 534, 511, 447, 335, 0, 494, 378, - 395, 375, 465, 950, 0, 974, 978, 374, 1060, 972, - 544, 338, 0, 543, 464, 530, 535, 448, 441, 0, - 337, 532, 446, 440, 425, 385, 1061, 426, 427, 399, - 480, 438, 481, 400, 452, 451, 453, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 0, 0, - 0, 0, 574, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 707, - 969, 0, 711, 0, 546, 0, 0, 1044, 0, 0, - 0, 515, 0, 0, 428, 0, 0, 0, 973, 0, - 497, 470, 1057, 0, 0, 495, 436, 531, 482, 537, - 518, 545, 489, 483, 328, 519, 377, 449, 346, 348, - 739, 379, 382, 386, 387, 458, 459, 476, 503, 522, - 523, 524, 376, 360, 496, 361, 396, 362, 329, 368, - 366, 369, 505, 370, 331, 477, 528, 0, 392, 492, - 444, 332, 443, 478, 527, 526, 347, 554, 561, 562, - 652, 0, 567, 751, 752, 753, 576, 0, 484, 343, - 340, 0, 0, 0, 372, 479, 356, 358, 359, 357, - 473, 475, 581, 582, 583, 585, 0, 586, 587, 0, - 0, 0, 0, 588, 653, 669, 637, 606, 569, 661, - 603, 607, 608, 413, 414, 415, 672, 0, 0, 0, - 560, 429, 430, 0, 384, 383, 445, 333, 0, 0, - 422, 412, 485, 339, 380, 424, 417, 431, 432, 433, - 390, 323, 324, 745, 1041, 466, 674, 709, 710, 599, - 0, 1056, 1036, 1038, 1039, 1043, 1047, 1048, 1049, 1050, - 1051, 1053, 1055, 1059, 744, 0, 654, 668, 749, 667, - 741, 472, 0, 502, 665, 612, 0, 658, 631, 632, - 0, 659, 627, 663, 0, 601, 0, 570, 573, 602, - 687, 688, 689, 330, 572, 691, 692, 693, 694, 695, - 696, 697, 690, 1058, 635, 611, 638, 551, 614, 613, - 0, 0, 649, 977, 650, 651, 454, 455, 456, 457, - 1045, 675, 354, 571, 487, 488, 0, 636, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 639, 754, - 0, 698, 699, 0, 0, 565, 566, 389, 0, 584, - 397, 353, 471, 391, 549, 420, 0, 577, 643, 578, - 490, 491, 701, 706, 702, 703, 705, 725, 461, 411, - 416, 506, 423, 437, 493, 548, 469, 498, 351, 538, - 508, 442, 628, 656, 1067, 1040, 1066, 1068, 1069, 1065, - 1070, 1071, 1052, 931, 0, 984, 985, 1063, 1062, 1064, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 683, 682, 681, 680, 679, 678, 677, 676, 0, - 0, 625, 525, 367, 317, 363, 364, 371, 742, 738, - 743, 726, 729, 728, 704, 938, 325, 605, 435, 486, - 388, 670, 671, 0, 724, 1030, 993, 994, 995, 928, - 996, 990, 991, 929, 992, 1031, 982, 1027, 1028, 957, - 987, 997, 1026, 998, 1029, 958, 1032, 1072, 1073, 1004, - 988, 287, 1074, 1001, 1033, 1025, 1024, 999, 983, 1034, - 1035, 965, 960, 1002, 1003, 989, 1010, 1011, 1012, 1015, - 930, 1016, 1017, 1018, 1019, 1020, 1014, 1013, 979, 980, - 981, 1005, 1006, 1008, 1009, 986, 516, 961, 962, 963, - 964, 0, 0, 555, 556, 557, 580, 0, 558, 540, - 604, 398, 326, 520, 547, 740, 0, 0, 0, 0, - 0, 0, 0, 655, 666, 700, 0, 712, 713, 715, - 717, 1021, 719, 513, 514, 727, 0, 0, 421, 341, - 342, 462, 463, 500, 0, 1007, 722, 723, 720, 439, - 499, 521, 507, 975, 746, 595, 596, 747, 708, 327, - 0, 923, 468, 0, 0, 610, 644, 633, 718, 598, - 0, 0, 0, 0, 0, 0, 926, 0, 0, 0, - 381, 0, 0, 434, 648, 629, 640, 630, 474, 615, - 616, 617, 624, 393, 618, 748, 620, 590, 621, 591, - 622, 623, 966, 647, 597, 509, 450, 0, 664, 0, - 0, 1046, 1054, 0, 0, 0, 0, 0, 0, 0, - 0, 1042, 0, 0, 0, 0, 918, 0, 0, 955, - 1023, 1022, 942, 952, 0, 0, 349, 256, 592, 714, - 594, 593, 943, 0, 944, 948, 951, 947, 945, 946, - 0, 1037, 0, 0, 0, 0, 0, 0, 910, 922, - 0, 927, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 919, 920, 1814, - 0, 0, 0, 976, 0, 921, 0, 0, 0, 0, - 0, 510, 539, 0, 552, 0, 418, 419, 971, 949, - 953, 0, 0, 0, 0, 334, 517, 536, 350, 504, - 550, 355, 512, 529, 345, 467, 501, 0, 0, 336, - 534, 511, 447, 335, 0, 494, 378, 395, 375, 465, - 950, 0, 974, 978, 374, 1060, 972, 544, 338, 0, - 543, 464, 530, 535, 448, 441, 0, 337, 532, 446, - 440, 425, 385, 1061, 426, 427, 399, 480, 438, 481, - 400, 452, 451, 453, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 410, 0, 0, 0, 0, 0, 574, - 575, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 707, 969, 0, 711, - 0, 546, 0, 0, 1044, 0, 0, 0, 515, 0, - 0, 428, 0, 0, 0, 973, 0, 497, 470, 1057, - 0, 0, 495, 436, 531, 482, 537, 518, 545, 489, - 483, 328, 519, 377, 449, 346, 348, 739, 379, 382, - 386, 387, 458, 459, 476, 503, 522, 523, 524, 376, - 360, 496, 361, 396, 362, 329, 368, 366, 369, 505, - 370, 331, 477, 528, 0, 392, 492, 444, 332, 443, - 478, 527, 526, 347, 554, 561, 562, 652, 0, 567, - 751, 752, 753, 576, 0, 484, 343, 340, 0, 0, - 0, 372, 479, 356, 358, 359, 357, 473, 475, 581, - 582, 583, 585, 0, 586, 587, 0, 0, 0, 0, - 588, 653, 669, 637, 606, 569, 661, 603, 607, 608, - 413, 414, 415, 672, 0, 0, 0, 560, 429, 430, - 0, 384, 383, 445, 333, 0, 0, 422, 412, 485, - 339, 380, 424, 417, 431, 432, 433, 390, 323, 324, - 745, 1041, 466, 674, 709, 710, 599, 0, 1056, 1036, - 1038, 1039, 1043, 1047, 1048, 1049, 1050, 1051, 1053, 1055, - 1059, 744, 0, 654, 668, 749, 667, 741, 472, 0, - 502, 665, 612, 0, 658, 631, 632, 0, 659, 627, - 663, 0, 601, 0, 570, 573, 602, 687, 688, 689, - 330, 572, 691, 692, 693, 694, 695, 696, 697, 690, - 1058, 635, 611, 638, 551, 614, 613, 0, 0, 649, - 977, 650, 651, 454, 455, 456, 457, 1045, 675, 354, - 571, 487, 488, 0, 636, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 639, 754, 0, 698, 699, - 0, 0, 565, 566, 389, 0, 584, 397, 353, 471, - 391, 549, 420, 0, 577, 643, 578, 490, 491, 701, - 706, 702, 703, 705, 725, 461, 411, 416, 506, 423, - 437, 493, 548, 469, 498, 351, 538, 508, 442, 628, - 656, 1067, 1040, 1066, 1068, 1069, 1065, 1070, 1071, 1052, - 931, 0, 984, 985, 1063, 1062, 1064, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 683, 682, - 681, 680, 679, 678, 677, 676, 0, 0, 625, 525, - 367, 317, 363, 364, 371, 742, 738, 743, 726, 729, - 728, 704, 938, 325, 605, 435, 486, 388, 670, 671, - 0, 724, 1030, 993, 994, 995, 928, 996, 990, 991, - 929, 992, 1031, 982, 1027, 1028, 957, 987, 997, 1026, - 998, 1029, 958, 1032, 1072, 1073, 1004, 988, 287, 1074, - 1001, 1033, 1025, 1024, 999, 983, 1034, 1035, 965, 960, - 1002, 1003, 989, 1010, 1011, 1012, 1015, 930, 1016, 1017, - 1018, 1019, 1020, 1014, 1013, 979, 980, 981, 1005, 1006, - 1008, 1009, 986, 516, 961, 962, 963, 964, 0, 0, - 555, 556, 557, 580, 0, 558, 540, 604, 398, 326, - 520, 547, 740, 0, 0, 0, 0, 0, 0, 0, - 655, 666, 700, 0, 712, 713, 715, 717, 1021, 719, - 513, 514, 727, 0, 0, 421, 341, 342, 462, 463, - 500, 0, 1007, 722, 723, 720, 439, 499, 521, 507, - 0, 746, 595, 596, 747, 708, 327, 975, 923, 0, - 2633, 0, 0, 0, 0, 0, 468, 0, 0, 610, - 644, 633, 718, 598, 0, 0, 0, 0, 0, 0, - 926, 0, 0, 0, 381, 0, 0, 434, 648, 629, - 640, 630, 474, 615, 616, 617, 624, 393, 618, 748, - 620, 590, 621, 591, 622, 623, 966, 647, 597, 509, - 450, 0, 664, 0, 0, 1046, 1054, 0, 0, 0, - 0, 0, 0, 0, 0, 1042, 0, 0, 0, 0, - 918, 0, 0, 955, 1023, 1022, 942, 952, 0, 0, - 349, 256, 592, 714, 594, 593, 943, 0, 944, 948, - 951, 947, 945, 946, 0, 1037, 0, 0, 0, 0, - 0, 0, 910, 922, 0, 927, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 919, 920, 0, 0, 0, 0, 976, 0, 921, - 0, 0, 0, 0, 0, 510, 539, 0, 552, 0, - 418, 419, 971, 949, 953, 0, 0, 0, 0, 334, - 517, 536, 350, 504, 550, 355, 512, 529, 345, 467, - 501, 0, 0, 336, 534, 511, 447, 335, 0, 494, - 378, 395, 375, 465, 950, 0, 974, 978, 374, 1060, - 972, 544, 338, 0, 543, 464, 530, 535, 448, 441, - 0, 337, 532, 446, 440, 425, 385, 1061, 426, 427, - 399, 480, 438, 481, 400, 452, 451, 453, 401, 402, - 403, 404, 405, 406, 407, 408, 409, 410, 0, 0, - 0, 0, 0, 574, 575, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 707, 969, 0, 711, 0, 546, 0, 0, 1044, 0, - 0, 0, 515, 0, 0, 428, 0, 0, 0, 973, - 0, 497, 470, 1057, 0, 0, 495, 436, 531, 482, - 537, 518, 545, 489, 483, 328, 519, 377, 449, 346, - 348, 739, 379, 382, 386, 387, 458, 459, 476, 503, - 522, 523, 524, 376, 360, 496, 361, 396, 362, 329, - 368, 366, 369, 505, 370, 331, 477, 528, 0, 392, - 492, 444, 332, 443, 478, 527, 526, 347, 554, 561, - 562, 652, 0, 567, 751, 752, 753, 576, 0, 484, - 343, 340, 0, 0, 0, 372, 479, 356, 358, 359, - 357, 473, 475, 581, 582, 583, 585, 0, 586, 587, - 0, 0, 0, 0, 588, 653, 669, 637, 606, 569, - 661, 603, 607, 608, 413, 414, 415, 672, 0, 0, - 0, 560, 429, 430, 0, 384, 383, 445, 333, 0, - 0, 422, 412, 485, 339, 380, 424, 417, 431, 432, - 433, 390, 323, 324, 745, 1041, 466, 674, 709, 710, - 599, 0, 1056, 1036, 1038, 1039, 1043, 1047, 1048, 1049, - 1050, 1051, 1053, 1055, 1059, 744, 0, 654, 668, 749, - 667, 741, 472, 0, 502, 665, 612, 0, 658, 631, - 632, 0, 659, 627, 663, 0, 601, 0, 570, 573, - 602, 687, 688, 689, 330, 572, 691, 692, 693, 694, - 695, 696, 697, 690, 1058, 635, 611, 638, 551, 614, - 613, 0, 0, 649, 977, 650, 651, 454, 455, 456, - 457, 1045, 675, 354, 571, 487, 488, 0, 636, 0, - 0, 0, 0, 0, 0, 0, 0, 641, 642, 639, - 754, 0, 698, 699, 0, 0, 565, 566, 389, 0, - 584, 397, 353, 471, 391, 549, 420, 0, 577, 643, - 578, 490, 491, 701, 706, 702, 703, 705, 725, 461, - 411, 416, 506, 423, 437, 493, 548, 469, 498, 351, - 538, 508, 442, 628, 656, 1067, 1040, 1066, 1068, 1069, - 1065, 1070, 1071, 1052, 931, 0, 984, 985, 1063, 1062, - 1064, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 683, 682, 681, 680, 679, 678, 677, 676, - 0, 0, 625, 525, 367, 317, 363, 364, 371, 742, - 738, 743, 726, 729, 728, 704, 938, 325, 605, 435, - 486, 388, 670, 671, 0, 724, 1030, 993, 994, 995, - 928, 996, 990, 991, 929, 992, 1031, 982, 1027, 1028, - 957, 987, 997, 1026, 998, 1029, 958, 1032, 1072, 1073, - 1004, 988, 287, 1074, 1001, 1033, 1025, 1024, 999, 983, - 1034, 1035, 965, 960, 1002, 1003, 989, 1010, 1011, 1012, - 1015, 930, 1016, 1017, 1018, 1019, 1020, 1014, 1013, 979, - 980, 981, 1005, 1006, 1008, 1009, 986, 516, 961, 962, - 963, 964, 0, 0, 555, 556, 557, 580, 0, 558, - 540, 604, 398, 326, 520, 547, 740, 0, 0, 0, - 0, 0, 0, 0, 655, 666, 700, 0, 712, 713, - 715, 717, 1021, 719, 513, 514, 727, 0, 0, 421, - 341, 342, 462, 463, 500, 0, 1007, 722, 723, 720, - 439, 499, 521, 507, 975, 746, 595, 596, 747, 708, - 327, 0, 923, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 0, 926, 0, 0, - 0, 381, 0, 0, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 966, 647, 597, 509, 450, 0, 664, - 0, 0, 1046, 1054, 0, 0, 0, 0, 0, 0, - 0, 0, 1042, 0, 0, 0, 0, 918, 0, 0, - 955, 1023, 1022, 942, 952, 0, 0, 349, 256, 592, - 714, 594, 593, 943, 0, 944, 948, 951, 947, 945, - 946, 0, 1037, 0, 0, 0, 0, 0, 0, 910, - 922, 0, 927, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 919, 920, - 2175, 0, 0, 0, 976, 0, 921, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 971, - 949, 953, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 950, 0, 974, 978, 374, 1060, 972, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 1061, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 969, 0, - 711, 0, 546, 0, 0, 1044, 0, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 973, 0, 497, 470, - 1057, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 1041, 466, 674, 709, 710, 599, 0, 1056, - 1036, 1038, 1039, 1043, 1047, 1048, 1049, 1050, 1051, 1053, - 1055, 1059, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 1058, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 977, 650, 651, 454, 455, 456, 457, 1045, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 1067, 1040, 1066, 1068, 1069, 1065, 1070, 1071, - 1052, 931, 0, 984, 985, 1063, 1062, 1064, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 938, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 1030, 993, 994, 995, 928, 996, 990, - 991, 929, 992, 1031, 982, 1027, 1028, 957, 987, 997, - 1026, 998, 1029, 958, 1032, 1072, 1073, 1004, 988, 287, - 1074, 1001, 1033, 1025, 1024, 999, 983, 1034, 1035, 965, - 960, 1002, 1003, 989, 1010, 1011, 1012, 1015, 930, 1016, - 1017, 1018, 1019, 1020, 1014, 1013, 979, 980, 981, 1005, - 1006, 1008, 1009, 986, 516, 961, 962, 963, 964, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 1021, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 1007, 722, 723, 720, 439, 499, 521, - 507, 975, 746, 595, 596, 747, 708, 327, 0, 923, - 468, 0, 0, 610, 644, 633, 718, 598, 0, 0, - 0, 0, 0, 0, 926, 0, 0, 0, 381, 0, - 0, 434, 648, 629, 640, 630, 474, 615, 616, 617, - 624, 393, 618, 748, 620, 590, 621, 591, 622, 623, - 966, 647, 597, 509, 450, 0, 664, 0, 0, 1046, - 1054, 0, 0, 0, 0, 0, 0, 0, 0, 1042, - 0, 0, 0, 0, 918, 0, 0, 955, 1023, 1022, - 942, 952, 0, 0, 349, 256, 592, 714, 594, 593, - 943, 0, 944, 948, 951, 947, 945, 946, 0, 1037, - 0, 0, 0, 0, 0, 0, 910, 922, 0, 927, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 919, 920, 0, 0, 0, - 0, 976, 0, 921, 0, 0, 0, 0, 0, 510, - 539, 0, 552, 0, 418, 419, 971, 949, 953, 0, - 0, 0, 0, 334, 517, 536, 350, 504, 550, 355, - 512, 529, 345, 467, 501, 0, 0, 336, 534, 511, - 447, 335, 0, 494, 378, 395, 375, 465, 950, 0, - 974, 978, 374, 1060, 972, 544, 338, 0, 543, 464, - 530, 535, 448, 441, 0, 337, 532, 446, 440, 425, - 385, 1061, 426, 427, 399, 480, 438, 481, 400, 452, - 451, 453, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 0, 0, 0, 0, 0, 574, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 707, 969, 0, 711, 0, 546, - 0, 0, 1044, 0, 0, 0, 515, 0, 0, 428, - 0, 0, 0, 973, 0, 497, 470, 1057, 0, 0, - 495, 436, 531, 482, 537, 518, 545, 489, 483, 328, - 519, 377, 449, 346, 348, 739, 379, 382, 386, 387, - 458, 459, 476, 503, 522, 523, 524, 376, 360, 496, - 361, 396, 362, 329, 368, 366, 369, 505, 370, 331, - 477, 528, 0, 392, 492, 444, 332, 443, 478, 527, - 526, 347, 554, 561, 562, 652, 0, 567, 751, 752, - 753, 576, 0, 484, 343, 340, 0, 0, 0, 372, - 479, 356, 358, 359, 357, 473, 475, 581, 582, 583, - 585, 0, 586, 587, 0, 0, 0, 0, 588, 653, - 669, 637, 606, 569, 661, 603, 607, 608, 413, 414, - 415, 672, 0, 0, 0, 560, 429, 430, 0, 384, - 383, 445, 333, 0, 0, 422, 412, 485, 339, 380, - 424, 417, 431, 432, 433, 390, 323, 324, 745, 1041, - 466, 674, 709, 710, 599, 0, 1056, 1036, 1038, 1039, - 1043, 1047, 1048, 1049, 1050, 1051, 1053, 1055, 1059, 744, - 0, 654, 668, 749, 667, 741, 472, 0, 502, 665, - 612, 0, 658, 631, 632, 0, 659, 627, 663, 0, - 601, 0, 570, 573, 602, 687, 688, 689, 330, 572, - 691, 692, 693, 694, 695, 696, 697, 690, 1058, 635, - 611, 638, 551, 614, 613, 0, 0, 649, 977, 650, - 651, 454, 455, 456, 457, 1045, 675, 354, 571, 487, - 488, 0, 636, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 639, 754, 0, 698, 699, 0, 0, - 565, 566, 389, 0, 584, 397, 353, 471, 391, 549, - 420, 0, 577, 643, 578, 490, 491, 701, 706, 702, - 703, 705, 725, 461, 411, 416, 506, 423, 437, 493, - 548, 469, 498, 351, 538, 508, 442, 628, 656, 1067, - 1040, 1066, 1068, 1069, 1065, 1070, 1071, 1052, 931, 0, - 984, 985, 1063, 1062, 1064, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 683, 682, 681, 680, - 679, 678, 677, 676, 0, 0, 625, 525, 367, 317, - 363, 364, 371, 742, 738, 743, 726, 729, 728, 704, - 938, 325, 605, 435, 486, 388, 670, 671, 0, 724, - 1030, 993, 994, 995, 928, 996, 990, 991, 929, 992, - 1031, 982, 1027, 1028, 957, 987, 997, 1026, 998, 1029, - 958, 1032, 1072, 1073, 1004, 988, 287, 1074, 1001, 1033, - 1025, 1024, 999, 983, 1034, 1035, 965, 960, 1002, 1003, - 989, 1010, 1011, 1012, 1015, 930, 1016, 1017, 1018, 1019, - 1020, 1014, 1013, 979, 980, 981, 1005, 1006, 1008, 1009, - 986, 516, 961, 962, 963, 964, 0, 0, 555, 556, - 557, 580, 0, 558, 540, 604, 398, 326, 520, 547, - 740, 0, 0, 0, 0, 0, 0, 0, 655, 666, - 700, 0, 712, 713, 715, 717, 1021, 719, 513, 514, - 727, 0, 0, 421, 341, 342, 462, 463, 500, 0, - 1007, 722, 723, 720, 439, 499, 521, 507, 975, 746, - 595, 596, 747, 708, 327, 0, 923, 468, 0, 0, - 610, 644, 633, 718, 598, 0, 0, 0, 0, 0, - 0, 926, 0, 0, 0, 381, 0, 0, 434, 648, - 629, 640, 630, 474, 615, 616, 617, 624, 393, 618, - 748, 620, 590, 621, 591, 622, 623, 966, 647, 597, - 509, 450, 0, 664, 0, 0, 1046, 1054, 0, 0, - 0, 0, 0, 0, 0, 0, 1042, 0, 0, 0, - 0, 918, 0, 0, 955, 1023, 1022, 942, 952, 0, - 0, 349, 256, 592, 714, 594, 593, 943, 0, 944, - 948, 951, 947, 945, 946, 0, 1037, 0, 0, 0, - 0, 0, 0, 910, 922, 0, 927, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 919, 920, 0, 0, 0, 0, 976, 0, - 921, 0, 0, 0, 0, 0, 510, 539, 0, 552, - 0, 418, 419, 971, 949, 953, 0, 0, 0, 0, - 334, 517, 536, 350, 504, 550, 355, 512, 529, 345, - 467, 501, 0, 0, 336, 534, 511, 447, 335, 0, - 494, 378, 395, 375, 465, 950, 0, 974, 978, 374, - 1060, 972, 544, 338, 0, 543, 464, 530, 535, 448, - 441, 0, 337, 532, 446, 440, 425, 385, 1061, 426, - 427, 399, 480, 438, 481, 400, 452, 451, 453, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 0, 0, 0, 0, 574, 575, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 707, 969, 0, 711, 0, 546, 0, 0, 1044, - 0, 0, 0, 515, 0, 0, 428, 0, 0, 0, - 973, 0, 497, 470, 1057, 0, 0, 495, 436, 531, - 482, 537, 518, 545, 489, 483, 328, 519, 377, 449, - 346, 348, 739, 379, 382, 386, 387, 458, 459, 476, - 503, 522, 523, 524, 376, 360, 496, 361, 396, 362, - 329, 368, 366, 369, 505, 370, 331, 477, 528, 0, - 392, 492, 444, 332, 443, 478, 527, 526, 347, 554, - 561, 562, 652, 0, 567, 751, 752, 753, 576, 0, - 484, 343, 340, 0, 0, 0, 372, 479, 356, 358, - 359, 357, 473, 475, 581, 582, 583, 585, 0, 586, - 587, 0, 0, 0, 0, 588, 653, 669, 637, 606, - 569, 661, 603, 607, 608, 413, 414, 415, 672, 0, - 0, 0, 560, 429, 430, 0, 384, 383, 445, 333, - 0, 0, 422, 412, 485, 339, 380, 424, 417, 431, - 432, 433, 390, 323, 324, 745, 1041, 466, 674, 709, - 710, 599, 0, 1056, 1036, 1038, 1039, 1043, 1047, 1048, - 1049, 1050, 1051, 1053, 1055, 1059, 744, 0, 654, 668, - 749, 667, 741, 472, 0, 502, 665, 612, 0, 658, - 631, 632, 0, 659, 627, 663, 0, 601, 0, 570, - 573, 602, 687, 688, 689, 330, 572, 691, 692, 693, - 694, 695, 696, 697, 690, 1058, 635, 611, 638, 551, - 614, 613, 0, 0, 649, 977, 650, 651, 454, 455, - 456, 457, 1045, 675, 354, 571, 487, 488, 0, 636, - 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, - 639, 754, 0, 698, 699, 0, 0, 565, 566, 389, - 0, 584, 397, 353, 471, 391, 549, 420, 0, 577, - 643, 578, 490, 491, 701, 706, 702, 703, 705, 725, - 461, 411, 416, 506, 423, 437, 493, 548, 469, 498, - 351, 538, 508, 442, 628, 656, 1067, 1040, 1066, 1068, - 1069, 1065, 1070, 1071, 1052, 931, 0, 984, 985, 1063, - 1062, 1064, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 683, 682, 681, 680, 679, 678, 677, - 676, 0, 0, 625, 525, 367, 317, 363, 364, 371, - 742, 738, 743, 726, 729, 728, 704, 938, 325, 605, - 435, 486, 388, 670, 671, 0, 724, 1030, 993, 994, - 995, 928, 996, 990, 991, 929, 992, 1031, 982, 1027, - 1028, 957, 987, 997, 1026, 998, 1029, 958, 1032, 1072, - 1073, 1004, 988, 287, 1074, 1001, 1033, 1025, 1024, 999, - 983, 1034, 1035, 965, 960, 1002, 1003, 989, 1010, 1011, - 1012, 1015, 930, 1016, 1017, 1018, 1019, 1020, 1014, 1013, - 979, 980, 981, 1005, 1006, 1008, 1009, 986, 516, 961, - 962, 963, 964, 0, 0, 555, 556, 557, 580, 0, - 558, 540, 604, 398, 326, 520, 547, 740, 0, 0, - 0, 0, 0, 0, 0, 655, 666, 700, 0, 712, - 713, 715, 717, 1021, 719, 513, 514, 727, 0, 0, - 421, 341, 342, 462, 463, 500, 0, 4183, 722, 4184, - 4185, 439, 499, 521, 507, 975, 746, 595, 596, 747, - 708, 327, 0, 923, 468, 0, 0, 610, 644, 633, - 718, 598, 0, 0, 0, 0, 0, 0, 926, 0, - 0, 0, 381, 0, 0, 434, 648, 629, 640, 630, - 474, 615, 616, 617, 624, 393, 618, 748, 620, 590, - 621, 591, 622, 623, 966, 647, 597, 509, 450, 0, - 664, 0, 0, 1046, 1054, 0, 0, 0, 0, 0, - 0, 0, 0, 1042, 0, 0, 0, 0, 918, 0, - 0, 955, 1023, 1022, 942, 952, 0, 0, 349, 256, - 592, 714, 594, 593, 3208, 0, 3209, 948, 951, 947, - 945, 946, 0, 1037, 0, 0, 0, 0, 0, 0, - 910, 922, 0, 927, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 919, - 920, 0, 0, 0, 0, 976, 0, 921, 0, 0, - 0, 0, 0, 510, 539, 0, 552, 0, 418, 419, - 971, 949, 953, 0, 0, 0, 0, 334, 517, 536, - 350, 504, 550, 355, 512, 529, 345, 467, 501, 0, - 0, 336, 534, 511, 447, 335, 0, 494, 378, 395, - 375, 465, 950, 0, 974, 978, 374, 1060, 972, 544, - 338, 0, 543, 464, 530, 535, 448, 441, 0, 337, - 532, 446, 440, 425, 385, 1061, 426, 427, 399, 480, - 438, 481, 400, 452, 451, 453, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 0, 0, 0, 0, - 0, 574, 575, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 707, 969, - 0, 711, 0, 546, 0, 0, 1044, 0, 0, 0, - 515, 0, 0, 428, 0, 0, 0, 973, 0, 497, - 470, 1057, 0, 0, 495, 436, 531, 482, 537, 518, - 545, 489, 483, 328, 519, 377, 449, 346, 348, 739, - 379, 382, 386, 387, 458, 459, 476, 503, 522, 523, - 524, 376, 360, 496, 361, 396, 362, 329, 368, 366, - 369, 505, 370, 331, 477, 528, 0, 392, 492, 444, - 332, 443, 478, 527, 526, 347, 554, 561, 562, 652, - 0, 567, 751, 752, 753, 576, 0, 484, 343, 340, - 0, 0, 0, 372, 479, 356, 358, 359, 357, 473, - 475, 581, 582, 583, 585, 0, 586, 587, 0, 0, - 0, 0, 588, 653, 669, 637, 606, 569, 661, 603, - 607, 608, 413, 414, 415, 672, 0, 0, 0, 560, - 429, 430, 0, 384, 383, 445, 333, 0, 0, 422, - 412, 485, 339, 380, 424, 417, 431, 432, 433, 390, - 323, 324, 745, 1041, 466, 674, 709, 710, 599, 0, - 1056, 1036, 1038, 1039, 1043, 1047, 1048, 1049, 1050, 1051, - 1053, 1055, 1059, 744, 0, 654, 668, 749, 667, 741, - 472, 0, 502, 665, 612, 0, 658, 631, 632, 0, - 659, 627, 663, 0, 601, 0, 570, 573, 602, 687, - 688, 689, 330, 572, 691, 692, 693, 694, 695, 696, - 697, 690, 1058, 635, 611, 638, 551, 614, 613, 0, - 0, 649, 977, 650, 651, 454, 455, 456, 457, 1045, - 675, 354, 571, 487, 488, 0, 636, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 639, 754, 0, - 698, 699, 0, 0, 565, 566, 389, 0, 584, 397, - 353, 471, 391, 549, 420, 0, 577, 643, 578, 490, - 491, 701, 706, 702, 703, 705, 725, 461, 411, 416, - 506, 423, 437, 493, 548, 469, 498, 351, 538, 508, - 442, 628, 656, 1067, 1040, 1066, 1068, 1069, 1065, 1070, - 1071, 1052, 931, 0, 984, 985, 1063, 1062, 1064, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 683, 682, 681, 680, 679, 678, 677, 676, 0, 0, - 625, 525, 367, 317, 363, 364, 371, 742, 738, 743, - 726, 729, 728, 704, 938, 325, 605, 435, 486, 388, - 670, 671, 0, 724, 1030, 993, 994, 995, 928, 996, - 990, 991, 929, 992, 1031, 982, 1027, 1028, 957, 987, - 997, 1026, 998, 1029, 958, 1032, 1072, 1073, 1004, 988, - 287, 1074, 1001, 1033, 1025, 1024, 999, 983, 1034, 1035, - 965, 960, 1002, 1003, 989, 1010, 1011, 1012, 1015, 930, - 1016, 1017, 1018, 1019, 1020, 1014, 1013, 979, 980, 981, - 1005, 1006, 1008, 1009, 986, 516, 961, 962, 963, 964, - 0, 0, 555, 556, 557, 580, 0, 558, 540, 604, - 398, 326, 520, 547, 740, 0, 0, 0, 0, 0, - 0, 0, 655, 666, 700, 0, 712, 713, 715, 717, - 1021, 719, 513, 514, 727, 0, 0, 421, 341, 342, - 462, 463, 500, 0, 1007, 722, 723, 720, 439, 499, - 521, 507, 975, 746, 595, 596, 747, 708, 327, 0, - 923, 468, 0, 0, 610, 644, 633, 718, 598, 0, - 0, 2015, 0, 0, 0, 926, 0, 0, 0, 381, - 0, 0, 434, 648, 629, 640, 630, 474, 615, 616, - 617, 624, 393, 618, 748, 620, 590, 621, 591, 622, - 623, 966, 647, 597, 509, 450, 0, 664, 0, 0, - 1046, 1054, 0, 0, 0, 0, 0, 0, 0, 0, - 1042, 0, 0, 0, 0, 918, 0, 0, 955, 1023, - 1022, 942, 952, 0, 0, 349, 256, 592, 714, 594, - 593, 943, 0, 944, 948, 951, 947, 945, 946, 0, - 1037, 0, 0, 0, 0, 0, 0, 0, 922, 0, - 927, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 919, 920, 0, 0, - 0, 0, 976, 0, 921, 0, 0, 0, 0, 0, - 510, 539, 0, 552, 0, 418, 419, 971, 949, 953, - 0, 0, 0, 0, 334, 517, 536, 350, 504, 550, - 355, 512, 529, 345, 467, 501, 0, 0, 336, 534, - 511, 447, 335, 0, 494, 378, 395, 375, 465, 950, - 0, 974, 978, 374, 1060, 972, 544, 338, 0, 543, - 464, 530, 535, 448, 441, 0, 337, 532, 446, 440, - 425, 385, 1061, 426, 427, 399, 480, 438, 481, 400, - 452, 451, 453, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 0, 0, 0, 0, 0, 574, 575, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 707, 969, 0, 711, 0, - 546, 0, 0, 1044, 0, 0, 0, 515, 0, 0, - 428, 0, 0, 0, 973, 0, 497, 470, 1057, 0, - 0, 495, 436, 531, 482, 537, 518, 545, 489, 483, - 328, 519, 377, 449, 346, 348, 739, 379, 382, 386, - 387, 458, 459, 476, 503, 522, 523, 524, 376, 360, - 496, 361, 396, 362, 329, 368, 366, 369, 505, 370, - 331, 477, 528, 0, 392, 492, 444, 332, 443, 478, - 527, 526, 347, 554, 2016, 2017, 652, 0, 567, 751, - 752, 753, 576, 0, 484, 343, 340, 0, 0, 0, - 372, 479, 356, 358, 359, 357, 473, 475, 581, 582, - 583, 585, 0, 586, 587, 0, 0, 0, 0, 588, - 653, 669, 637, 606, 569, 661, 603, 607, 608, 413, - 414, 415, 672, 0, 0, 0, 560, 429, 430, 0, - 384, 383, 445, 333, 0, 0, 422, 412, 485, 339, - 380, 424, 417, 431, 432, 433, 390, 323, 324, 745, - 1041, 466, 674, 709, 710, 599, 0, 1056, 1036, 1038, - 1039, 1043, 1047, 1048, 1049, 1050, 1051, 1053, 1055, 1059, - 744, 0, 654, 668, 749, 667, 741, 472, 0, 502, - 665, 612, 0, 658, 631, 632, 0, 659, 627, 663, - 0, 601, 0, 570, 573, 602, 687, 688, 689, 330, - 572, 691, 692, 693, 694, 695, 696, 697, 690, 1058, - 635, 611, 638, 551, 614, 613, 0, 0, 649, 977, - 650, 651, 454, 455, 456, 457, 1045, 675, 354, 571, - 487, 488, 0, 636, 0, 0, 0, 0, 0, 0, - 0, 0, 641, 642, 639, 754, 0, 698, 699, 0, - 0, 565, 566, 389, 0, 584, 397, 353, 471, 391, - 549, 420, 0, 577, 643, 578, 490, 491, 701, 706, - 702, 703, 705, 725, 461, 411, 416, 506, 423, 437, - 493, 548, 469, 498, 351, 538, 508, 442, 628, 656, - 1067, 1040, 1066, 1068, 1069, 1065, 1070, 1071, 1052, 931, - 0, 984, 985, 1063, 1062, 1064, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 683, 682, 681, - 680, 679, 678, 677, 676, 0, 0, 625, 525, 367, - 317, 363, 364, 371, 742, 738, 743, 726, 729, 728, - 704, 938, 325, 605, 435, 486, 388, 670, 671, 0, - 724, 1030, 993, 994, 995, 928, 996, 990, 991, 929, - 992, 1031, 982, 1027, 1028, 957, 987, 997, 1026, 998, - 1029, 958, 1032, 1072, 1073, 1004, 988, 287, 1074, 1001, - 1033, 1025, 1024, 999, 983, 1034, 1035, 965, 960, 1002, - 1003, 989, 1010, 1011, 1012, 1015, 930, 1016, 1017, 1018, - 1019, 1020, 1014, 1013, 979, 980, 981, 1005, 1006, 1008, - 1009, 986, 516, 961, 962, 963, 964, 0, 0, 555, - 556, 557, 580, 0, 558, 540, 604, 398, 326, 520, - 547, 740, 0, 0, 0, 0, 0, 0, 0, 655, - 666, 700, 0, 712, 713, 715, 717, 1021, 719, 513, - 514, 727, 0, 0, 421, 341, 342, 462, 463, 500, - 0, 1007, 722, 723, 720, 439, 499, 521, 507, 975, - 746, 595, 596, 747, 708, 327, 0, 923, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 0, 0, - 0, 0, 926, 0, 0, 0, 381, 0, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 966, 647, - 597, 509, 450, 0, 664, 0, 0, 1046, 1054, 0, - 0, 0, 0, 0, 0, 0, 0, 1042, 0, 0, - 0, 0, 1547, 0, 0, 955, 1023, 1022, 942, 952, - 0, 0, 349, 256, 592, 714, 594, 593, 943, 0, - 944, 948, 951, 947, 945, 946, 0, 1037, 0, 0, - 0, 0, 0, 0, 910, 922, 0, 927, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 919, 920, 0, 0, 0, 0, 976, - 0, 921, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 971, 949, 953, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 950, 0, 974, 978, - 374, 1060, 972, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 1061, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 969, 0, 711, 0, 546, 0, 0, - 1044, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 973, 0, 497, 470, 1057, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 1041, 466, 674, - 709, 710, 599, 0, 1056, 1036, 1038, 1039, 1043, 1047, - 1048, 1049, 1050, 1051, 1053, 1055, 1059, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 1058, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 977, 650, 651, 454, - 455, 456, 457, 1045, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 1067, 1040, 1066, - 1068, 1069, 1065, 1070, 1071, 1052, 931, 0, 984, 985, - 1063, 1062, 1064, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 938, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 1030, 993, - 994, 995, 928, 996, 990, 991, 929, 992, 1031, 982, - 1027, 1028, 957, 987, 997, 1026, 998, 1029, 958, 1032, - 1072, 1073, 1004, 988, 287, 1074, 1001, 1033, 1025, 1024, - 999, 983, 1034, 1035, 965, 960, 1002, 1003, 989, 1010, - 1011, 1012, 1015, 930, 1016, 1017, 1018, 1019, 1020, 1014, - 1013, 979, 980, 981, 1005, 1006, 1008, 1009, 986, 516, - 961, 962, 963, 964, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 1021, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 1007, 722, - 723, 720, 439, 499, 521, 507, 975, 746, 595, 596, - 747, 708, 327, 0, 923, 468, 0, 0, 610, 644, - 633, 718, 598, 0, 0, 0, 0, 0, 0, 926, - 0, 0, 0, 381, 0, 0, 434, 648, 629, 640, - 630, 474, 615, 616, 617, 624, 393, 618, 748, 620, - 590, 621, 591, 622, 623, 966, 647, 597, 509, 450, - 0, 664, 0, 0, 1046, 1054, 0, 0, 0, 0, - 0, 0, 0, 0, 1042, 0, 0, 0, 0, 918, - 0, 0, 955, 1023, 1022, 942, 952, 0, 0, 349, - 256, 592, 714, 594, 593, 943, 0, 944, 948, 951, - 947, 945, 946, 0, 1037, 0, 0, 0, 0, 0, - 0, 0, 922, 0, 927, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 919, 920, 0, 0, 0, 0, 976, 0, 921, 0, - 0, 0, 0, 0, 510, 539, 0, 552, 0, 418, - 419, 971, 949, 953, 0, 0, 0, 0, 334, 517, - 536, 350, 504, 550, 355, 512, 529, 345, 467, 501, - 0, 0, 336, 534, 511, 447, 335, 0, 494, 378, - 395, 375, 465, 950, 0, 974, 978, 374, 1060, 972, - 544, 338, 0, 543, 464, 530, 535, 448, 441, 0, - 337, 532, 446, 440, 425, 385, 1061, 426, 427, 399, - 480, 438, 481, 400, 452, 451, 453, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 0, 0, - 0, 0, 574, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 707, - 969, 0, 711, 0, 546, 0, 0, 1044, 0, 0, - 0, 515, 0, 0, 428, 0, 0, 0, 973, 0, - 497, 470, 1057, 0, 0, 495, 436, 531, 482, 537, - 518, 545, 489, 483, 328, 519, 377, 449, 346, 348, - 739, 379, 382, 386, 387, 458, 459, 476, 503, 522, - 523, 524, 376, 360, 496, 361, 396, 362, 329, 368, - 366, 369, 505, 370, 331, 477, 528, 0, 392, 492, - 444, 332, 443, 478, 527, 526, 347, 554, 561, 562, - 652, 0, 567, 751, 752, 753, 576, 0, 484, 343, - 340, 0, 0, 0, 372, 479, 356, 358, 359, 357, - 473, 475, 581, 582, 583, 585, 0, 586, 587, 0, - 0, 0, 0, 588, 653, 669, 637, 606, 569, 661, - 603, 607, 608, 413, 414, 415, 672, 0, 0, 0, - 560, 429, 430, 0, 384, 383, 445, 333, 0, 0, - 422, 412, 485, 339, 380, 424, 417, 431, 432, 433, - 390, 323, 324, 745, 1041, 466, 674, 709, 710, 599, - 0, 1056, 1036, 1038, 1039, 1043, 1047, 1048, 1049, 1050, - 1051, 1053, 1055, 1059, 744, 0, 654, 668, 749, 667, - 741, 472, 0, 502, 665, 612, 0, 658, 631, 632, - 0, 659, 627, 663, 0, 601, 0, 570, 573, 602, - 687, 688, 689, 330, 572, 691, 692, 693, 694, 695, - 696, 697, 690, 1058, 635, 611, 638, 551, 614, 613, - 0, 0, 649, 977, 650, 651, 454, 455, 456, 457, - 1045, 675, 354, 571, 487, 488, 0, 636, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 639, 754, - 0, 698, 699, 0, 0, 565, 566, 389, 0, 584, - 397, 353, 471, 391, 549, 420, 0, 577, 643, 578, - 490, 491, 701, 706, 702, 703, 705, 725, 461, 411, - 416, 506, 423, 437, 493, 548, 469, 498, 351, 538, - 508, 442, 628, 656, 1067, 1040, 1066, 1068, 1069, 1065, - 1070, 1071, 1052, 931, 0, 984, 985, 1063, 1062, 1064, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 683, 682, 681, 680, 679, 678, 677, 676, 0, - 0, 625, 525, 367, 317, 363, 364, 371, 742, 738, - 743, 726, 729, 728, 704, 938, 325, 605, 435, 486, - 388, 670, 671, 0, 724, 1030, 993, 994, 995, 928, - 996, 990, 991, 929, 992, 1031, 982, 1027, 1028, 957, - 987, 997, 1026, 998, 1029, 958, 1032, 1072, 1073, 1004, - 988, 287, 1074, 1001, 1033, 1025, 1024, 999, 983, 1034, - 1035, 965, 960, 1002, 1003, 989, 1010, 1011, 1012, 1015, - 930, 1016, 1017, 1018, 1019, 1020, 1014, 1013, 979, 980, - 981, 1005, 1006, 1008, 1009, 986, 516, 961, 962, 963, - 964, 0, 0, 555, 556, 557, 580, 0, 558, 540, - 604, 398, 326, 520, 547, 740, 0, 0, 0, 0, - 0, 0, 0, 655, 666, 700, 0, 712, 713, 715, - 717, 1021, 719, 513, 514, 727, 0, 0, 421, 341, - 342, 462, 463, 500, 0, 1007, 722, 723, 720, 439, - 499, 521, 507, 0, 746, 595, 596, 747, 708, 327, - 0, 923, 192, 233, 191, 224, 193, 0, 0, 0, - 0, 0, 0, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 225, 0, 0, 0, 0, 0, 0, 217, - 0, 381, 0, 226, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 619, 620, 590, 621, - 591, 622, 623, 161, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 147, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 0, 0, - 255, 0, 0, 0, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 0, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 190, - 222, 231, 223, 79, 143, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 0, 248, 0, 0, 0, 515, - 0, 0, 428, 145, 216, 215, 564, 0, 497, 470, - 260, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 268, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 144, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 684, 685, 686, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 541, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 251, 657, - 660, 589, 261, 0, 654, 668, 626, 667, 262, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 159, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 259, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 74, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 266, 344, 267, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 69, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 263, 52, 249, 252, 254, 253, 0, - 70, 655, 666, 700, 9, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 164, 264, 595, 596, 265, 708, 327, 192, 233, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 468, - 0, 0, 610, 644, 633, 718, 598, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 381, 0, 0, - 434, 648, 629, 640, 630, 474, 615, 616, 617, 624, - 393, 618, 748, 620, 590, 621, 591, 622, 623, 161, - 647, 597, 509, 450, 0, 664, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 0, 0, 255, 0, 0, 0, - 0, 0, 0, 349, 256, 592, 714, 594, 593, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 352, 2840, - 2843, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 510, 539, - 0, 552, 0, 418, 419, 0, 0, 0, 0, 0, - 0, 0, 334, 517, 536, 350, 504, 550, 355, 512, - 529, 345, 467, 501, 0, 0, 336, 534, 511, 447, - 335, 0, 494, 378, 395, 375, 465, 0, 0, 533, - 563, 374, 553, 0, 544, 338, 0, 543, 464, 530, - 535, 448, 441, 0, 337, 532, 446, 440, 425, 385, - 579, 426, 427, 399, 480, 438, 481, 400, 452, 451, - 453, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 0, 0, 0, 0, 574, 575, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 707, 0, 0, 711, 2844, 546, 0, - 0, 0, 2839, 0, 2838, 515, 2836, 2841, 428, 0, - 0, 0, 564, 0, 497, 470, 750, 0, 0, 495, - 436, 531, 482, 537, 518, 545, 489, 483, 328, 519, - 377, 449, 346, 348, 739, 379, 382, 386, 387, 458, - 459, 476, 503, 522, 523, 524, 376, 360, 496, 361, - 396, 362, 329, 368, 366, 369, 505, 370, 331, 477, - 528, 2842, 392, 492, 444, 332, 443, 478, 527, 526, - 347, 554, 561, 562, 652, 0, 567, 751, 752, 753, - 576, 0, 484, 343, 340, 0, 0, 0, 372, 479, - 356, 358, 359, 357, 473, 475, 581, 582, 583, 585, - 0, 586, 587, 0, 0, 0, 0, 588, 653, 669, - 637, 606, 569, 661, 603, 607, 608, 413, 414, 415, - 672, 0, 0, 0, 560, 429, 430, 0, 384, 383, - 445, 333, 0, 0, 422, 412, 485, 339, 380, 424, - 417, 431, 432, 433, 390, 323, 324, 745, 373, 466, - 674, 709, 710, 599, 0, 662, 600, 609, 365, 634, - 646, 645, 460, 559, 0, 657, 660, 589, 744, 0, - 654, 668, 749, 667, 741, 472, 0, 502, 665, 612, - 0, 658, 631, 632, 0, 659, 627, 663, 0, 601, - 0, 570, 573, 602, 687, 688, 689, 330, 572, 691, - 692, 693, 694, 695, 696, 697, 690, 542, 635, 611, - 638, 551, 614, 613, 0, 0, 649, 568, 650, 651, - 454, 455, 456, 457, 394, 675, 354, 571, 487, 488, - 0, 636, 0, 0, 0, 0, 0, 0, 0, 0, - 641, 642, 639, 754, 0, 698, 699, 0, 0, 565, - 566, 389, 0, 584, 397, 353, 471, 391, 549, 420, - 0, 577, 643, 578, 490, 491, 701, 706, 702, 703, - 705, 725, 461, 411, 416, 506, 423, 437, 493, 548, - 469, 498, 351, 538, 508, 442, 628, 656, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 310, - 311, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 683, 682, 681, 680, 679, - 678, 677, 676, 0, 0, 625, 525, 367, 317, 363, - 364, 371, 742, 738, 743, 726, 729, 728, 704, 0, - 325, 605, 435, 486, 388, 670, 671, 0, 724, 269, - 270, 271, 272, 273, 274, 275, 276, 318, 277, 278, - 279, 280, 281, 282, 283, 288, 289, 290, 291, 292, - 293, 294, 295, 673, 286, 287, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 0, 0, 0, 0, 319, 730, 731, 732, 733, 734, - 0, 0, 320, 321, 322, 0, 0, 284, 285, 312, - 516, 313, 314, 315, 316, 0, 0, 555, 556, 557, - 580, 0, 558, 540, 604, 398, 326, 520, 547, 740, - 0, 0, 0, 0, 0, 0, 0, 655, 666, 700, - 0, 712, 713, 715, 717, 716, 719, 513, 514, 727, - 0, 0, 421, 341, 342, 462, 463, 500, 0, 721, - 722, 723, 720, 439, 499, 521, 507, 0, 746, 595, - 596, 747, 708, 327, 468, 0, 0, 610, 644, 633, - 718, 598, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 381, 0, 0, 434, 648, 629, 640, 630, - 474, 615, 616, 617, 624, 393, 618, 748, 620, 590, - 621, 591, 622, 623, 0, 647, 597, 509, 450, 0, - 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1568, 0, - 0, 255, 0, 0, 942, 952, 0, 0, 349, 256, - 592, 714, 594, 593, 943, 0, 944, 948, 951, 947, - 945, 946, 0, 352, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 510, 539, 0, 552, 0, 418, 419, - 0, 949, 0, 0, 0, 0, 0, 334, 517, 536, - 350, 504, 550, 355, 512, 529, 345, 467, 501, 0, - 0, 336, 534, 511, 447, 335, 0, 494, 378, 395, - 375, 465, 950, 0, 533, 563, 374, 553, 0, 544, - 338, 0, 543, 464, 530, 535, 448, 441, 0, 337, - 532, 446, 440, 425, 385, 579, 426, 427, 399, 480, - 438, 481, 400, 452, 451, 453, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 0, 0, 0, 0, - 0, 574, 575, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 707, 0, - 0, 711, 0, 546, 0, 0, 0, 0, 0, 0, - 515, 0, 0, 428, 0, 0, 0, 564, 0, 497, - 470, 750, 0, 0, 495, 436, 531, 482, 537, 518, - 545, 489, 483, 328, 519, 377, 449, 346, 348, 739, - 379, 382, 386, 387, 458, 459, 476, 503, 522, 523, - 524, 376, 360, 496, 361, 396, 362, 329, 368, 366, - 369, 505, 370, 331, 477, 528, 0, 392, 492, 444, - 332, 443, 478, 527, 526, 347, 554, 561, 562, 652, - 0, 567, 751, 752, 753, 576, 0, 484, 343, 340, - 0, 0, 0, 372, 479, 356, 358, 359, 357, 473, - 475, 581, 582, 583, 585, 0, 586, 587, 0, 0, - 0, 0, 588, 653, 669, 637, 606, 569, 661, 603, - 607, 608, 413, 414, 415, 672, 0, 0, 0, 560, - 429, 430, 0, 384, 383, 445, 333, 0, 0, 422, - 412, 485, 339, 380, 424, 417, 431, 432, 433, 390, - 323, 324, 745, 373, 466, 674, 709, 710, 599, 0, - 662, 600, 609, 365, 634, 646, 645, 460, 559, 0, - 657, 660, 589, 744, 0, 654, 668, 749, 667, 741, - 472, 0, 502, 665, 612, 0, 658, 631, 632, 0, - 659, 627, 663, 0, 601, 0, 570, 573, 602, 687, - 688, 689, 330, 572, 691, 692, 693, 694, 695, 696, - 697, 690, 542, 635, 611, 638, 551, 614, 613, 0, - 0, 649, 568, 650, 651, 454, 455, 456, 457, 394, - 675, 354, 571, 487, 488, 0, 636, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 639, 754, 0, - 698, 699, 0, 0, 565, 566, 389, 0, 584, 397, - 353, 471, 391, 549, 420, 0, 577, 643, 578, 490, - 491, 701, 706, 702, 703, 705, 725, 461, 411, 416, - 506, 423, 437, 493, 548, 469, 498, 351, 538, 508, - 442, 628, 656, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 310, 311, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 683, 682, 681, 680, 679, 678, 677, 676, 0, 0, - 625, 525, 367, 317, 363, 364, 371, 742, 738, 743, - 726, 729, 728, 704, 0, 325, 605, 435, 486, 388, - 670, 671, 0, 724, 269, 270, 271, 272, 273, 274, - 275, 276, 318, 277, 278, 279, 280, 281, 282, 283, - 288, 289, 290, 291, 292, 293, 294, 295, 673, 286, - 287, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 0, 0, 0, 0, 319, - 730, 731, 732, 733, 734, 0, 0, 320, 321, 322, - 0, 0, 284, 285, 312, 516, 313, 314, 315, 316, - 0, 0, 555, 556, 557, 580, 0, 558, 540, 604, - 398, 326, 520, 547, 740, 0, 0, 0, 0, 0, - 0, 0, 655, 666, 700, 0, 712, 713, 715, 717, - 716, 719, 513, 514, 727, 0, 0, 421, 341, 342, - 462, 463, 500, 0, 721, 722, 723, 720, 439, 499, - 521, 507, 0, 746, 595, 596, 747, 708, 327, 192, - 233, 191, 224, 193, 0, 0, 0, 0, 0, 0, - 468, 774, 0, 610, 644, 633, 718, 598, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 381, 0, - 0, 434, 648, 629, 640, 630, 474, 615, 616, 617, - 624, 393, 618, 748, 620, 590, 621, 591, 622, 623, - 0, 647, 597, 509, 450, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 781, 0, 0, 0, - 0, 0, 0, 0, 780, 0, 0, 255, 0, 0, - 0, 0, 0, 0, 349, 256, 592, 714, 594, 593, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 510, - 539, 0, 552, 0, 418, 419, 0, 0, 0, 0, - 0, 0, 0, 334, 517, 536, 350, 504, 550, 355, - 512, 529, 345, 467, 501, 0, 0, 336, 534, 511, - 447, 335, 0, 494, 378, 395, 375, 465, 0, 0, - 533, 563, 374, 553, 0, 544, 338, 0, 543, 464, - 530, 535, 448, 441, 0, 337, 532, 446, 440, 425, - 385, 579, 426, 427, 399, 480, 438, 481, 400, 452, - 451, 453, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 0, 0, 0, 0, 0, 574, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 778, 779, 0, 707, 0, 0, 711, 0, 546, - 0, 0, 0, 0, 0, 0, 515, 0, 0, 428, - 0, 0, 0, 564, 0, 497, 470, 750, 0, 0, - 495, 436, 531, 482, 537, 518, 545, 489, 483, 328, - 519, 377, 449, 346, 348, 739, 379, 382, 386, 387, - 458, 459, 476, 503, 522, 523, 524, 376, 360, 496, - 361, 396, 362, 329, 368, 366, 369, 505, 370, 331, - 477, 528, 0, 392, 492, 444, 332, 443, 478, 527, - 526, 347, 554, 561, 562, 652, 0, 567, 751, 752, - 753, 576, 0, 484, 343, 340, 0, 0, 0, 372, - 479, 356, 358, 359, 357, 473, 475, 581, 582, 583, - 585, 0, 586, 587, 0, 0, 0, 0, 588, 653, - 669, 637, 606, 569, 661, 603, 607, 608, 413, 414, - 415, 672, 0, 0, 0, 560, 429, 430, 0, 384, - 383, 445, 333, 0, 0, 422, 412, 485, 339, 380, - 424, 417, 431, 432, 433, 390, 323, 324, 745, 373, - 466, 674, 709, 710, 599, 0, 662, 600, 609, 365, - 634, 646, 645, 460, 559, 0, 657, 660, 589, 744, - 0, 654, 668, 749, 667, 741, 472, 0, 502, 665, - 612, 0, 658, 631, 632, 0, 659, 627, 663, 0, - 601, 0, 570, 573, 602, 687, 688, 689, 330, 572, - 691, 692, 693, 694, 695, 696, 697, 690, 542, 635, - 611, 638, 551, 614, 613, 0, 0, 649, 568, 650, - 651, 454, 455, 456, 457, 775, 777, 354, 571, 487, - 488, 790, 636, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 639, 754, 0, 698, 699, 0, 0, - 565, 566, 389, 0, 584, 397, 353, 471, 391, 549, - 420, 0, 577, 643, 578, 490, 491, 701, 706, 702, - 703, 705, 725, 461, 411, 416, 506, 423, 437, 493, - 548, 469, 498, 351, 538, 508, 442, 628, 656, 0, - 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, - 310, 311, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 683, 682, 681, 680, - 679, 678, 677, 676, 0, 0, 625, 525, 367, 317, - 363, 364, 371, 742, 738, 743, 726, 729, 728, 704, - 0, 325, 605, 435, 486, 388, 670, 671, 0, 724, - 269, 270, 271, 272, 273, 274, 275, 276, 318, 277, - 278, 279, 280, 281, 282, 283, 288, 289, 290, 291, - 292, 293, 294, 295, 673, 286, 287, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 0, 0, 0, 0, 319, 730, 731, 732, 733, - 734, 0, 0, 320, 321, 322, 0, 0, 284, 285, - 312, 516, 313, 314, 315, 316, 0, 0, 555, 556, - 557, 580, 0, 558, 540, 604, 398, 326, 520, 547, - 740, 0, 0, 0, 0, 0, 0, 0, 655, 666, - 700, 0, 712, 713, 715, 717, 716, 719, 513, 514, - 727, 0, 0, 421, 341, 342, 462, 463, 500, 0, - 721, 722, 723, 720, 439, 499, 521, 507, 0, 746, - 595, 596, 747, 708, 327, 468, 0, 0, 610, 644, - 633, 718, 598, 0, 1276, 0, 0, 0, 0, 0, - 0, 0, 0, 381, 0, 0, 434, 648, 629, 640, - 630, 474, 615, 616, 617, 624, 393, 618, 748, 620, - 590, 621, 591, 622, 623, 0, 647, 597, 509, 450, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 0, 0, 0, 0, 0, 0, 349, - 256, 592, 714, 594, 593, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 510, 539, 0, 552, 0, 2991, - 2992, 1261, 0, 0, 0, 0, 0, 0, 334, 517, - 536, 350, 504, 550, 355, 512, 529, 345, 467, 501, - 0, 0, 2985, 2988, 2989, 2990, 2993, 0, 2998, 2994, - 2995, 2996, 2997, 0, 0, 2981, 2982, 2983, 2984, 1259, - 2965, 2986, 0, 2966, 464, 2967, 2968, 2969, 2970, 1263, - 2971, 2972, 2973, 2974, 2975, 2978, 2979, 2976, 2977, 2999, - 3000, 3001, 3002, 3003, 3004, 3005, 3006, 3008, 3007, 3009, - 3010, 3011, 3012, 3013, 3014, 3015, 3016, 1287, 1289, 1291, - 1293, 1296, 574, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 707, - 0, 0, 711, 0, 546, 0, 0, 0, 0, 0, - 0, 515, 0, 0, 428, 0, 0, 0, 2980, 0, - 497, 470, 750, 0, 0, 495, 436, 531, 482, 537, - 518, 545, 489, 483, 328, 519, 377, 449, 346, 348, - 739, 379, 382, 386, 387, 458, 459, 476, 503, 522, - 523, 524, 376, 360, 496, 361, 396, 362, 329, 368, - 366, 369, 505, 370, 331, 477, 528, 0, 392, 492, - 444, 332, 443, 478, 527, 526, 347, 554, 561, 562, - 652, 0, 567, 751, 752, 753, 576, 0, 484, 343, - 340, 0, 0, 0, 372, 479, 356, 358, 359, 357, - 473, 475, 581, 582, 583, 585, 0, 586, 587, 0, - 0, 0, 0, 588, 653, 669, 637, 606, 569, 661, - 603, 607, 608, 413, 414, 415, 672, 0, 0, 0, - 560, 429, 430, 0, 384, 383, 445, 333, 0, 0, - 422, 412, 485, 339, 380, 424, 417, 431, 432, 433, - 390, 323, 324, 745, 373, 466, 674, 709, 710, 599, - 0, 662, 600, 609, 365, 634, 646, 645, 460, 559, - 0, 657, 660, 589, 744, 0, 654, 668, 749, 667, - 741, 472, 0, 502, 665, 612, 0, 658, 631, 632, - 0, 659, 627, 663, 0, 601, 0, 570, 573, 602, - 687, 688, 689, 330, 572, 691, 692, 693, 694, 695, - 696, 697, 690, 542, 635, 611, 638, 551, 614, 613, - 0, 0, 649, 568, 650, 651, 454, 455, 456, 457, - 394, 675, 354, 571, 487, 488, 0, 636, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 639, 754, - 0, 698, 699, 0, 0, 565, 566, 389, 0, 584, - 397, 353, 471, 391, 549, 420, 0, 577, 643, 578, - 490, 491, 701, 706, 702, 703, 705, 725, 461, 411, - 416, 506, 423, 437, 493, 548, 469, 498, 351, 538, - 508, 442, 628, 656, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 310, 311, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 683, 682, 681, 680, 679, 678, 677, 676, 0, - 0, 625, 525, 367, 317, 363, 364, 371, 742, 738, - 743, 726, 729, 728, 704, 0, 325, 2987, 435, 486, - 388, 670, 671, 0, 724, 269, 270, 271, 272, 273, - 274, 275, 276, 318, 277, 278, 279, 280, 281, 282, - 283, 288, 289, 290, 291, 292, 293, 294, 295, 673, - 286, 287, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 0, 0, 0, 0, - 319, 730, 731, 732, 733, 734, 0, 0, 320, 321, - 322, 0, 0, 284, 285, 312, 516, 313, 314, 315, - 316, 0, 0, 555, 556, 557, 580, 0, 558, 540, - 604, 398, 326, 520, 547, 740, 0, 0, 0, 0, - 0, 0, 0, 655, 666, 700, 0, 712, 713, 715, - 717, 716, 719, 513, 514, 727, 0, 0, 421, 341, - 342, 462, 463, 500, 0, 721, 722, 723, 720, 439, - 499, 521, 507, 0, 746, 595, 596, 747, 708, 2964, - 468, 0, 0, 610, 644, 633, 718, 598, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 381, 0, - 0, 434, 648, 629, 640, 630, 474, 615, 616, 617, - 624, 393, 618, 748, 620, 590, 621, 591, 622, 623, - 0, 647, 597, 509, 450, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, - 0, 0, 0, 0, 349, 256, 592, 714, 594, 593, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, - 2840, 2843, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 510, - 539, 0, 552, 0, 418, 419, 0, 0, 0, 0, - 0, 0, 0, 334, 517, 536, 350, 504, 550, 355, - 512, 529, 345, 467, 501, 0, 0, 336, 534, 511, - 447, 335, 0, 494, 378, 395, 375, 465, 0, 0, - 533, 563, 374, 553, 0, 544, 338, 0, 543, 464, - 530, 535, 448, 441, 0, 337, 532, 446, 440, 425, - 385, 579, 426, 427, 399, 480, 438, 481, 400, 452, - 451, 453, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 0, 0, 0, 0, 0, 574, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 707, 0, 0, 711, 2844, 546, - 0, 0, 0, 2839, 0, 2838, 515, 2836, 2841, 428, - 0, 0, 0, 564, 0, 497, 470, 750, 0, 0, - 495, 436, 531, 482, 537, 518, 545, 489, 483, 328, - 519, 377, 449, 346, 348, 739, 379, 382, 386, 387, - 458, 459, 476, 503, 522, 523, 524, 376, 360, 496, - 361, 396, 362, 329, 368, 366, 369, 505, 370, 331, - 477, 528, 2842, 392, 492, 444, 332, 443, 478, 527, - 526, 347, 554, 561, 562, 652, 0, 567, 751, 752, - 753, 576, 0, 484, 343, 340, 0, 0, 0, 372, - 479, 356, 358, 359, 357, 473, 475, 581, 582, 583, - 585, 0, 586, 587, 0, 0, 0, 0, 588, 653, - 669, 637, 606, 569, 661, 603, 607, 608, 413, 414, - 415, 672, 0, 0, 0, 560, 429, 430, 0, 384, - 383, 445, 333, 0, 0, 422, 412, 485, 339, 380, - 424, 417, 431, 432, 433, 390, 323, 324, 745, 373, - 466, 674, 709, 710, 599, 0, 662, 600, 609, 365, - 634, 646, 645, 460, 559, 0, 657, 660, 589, 744, - 0, 654, 668, 749, 667, 741, 472, 0, 502, 665, - 612, 0, 658, 631, 632, 0, 659, 627, 663, 0, - 601, 0, 570, 573, 602, 687, 688, 689, 330, 572, - 691, 692, 693, 694, 695, 696, 697, 690, 542, 635, - 611, 638, 551, 614, 613, 0, 0, 649, 568, 650, - 651, 454, 455, 456, 457, 394, 675, 354, 571, 487, - 488, 0, 636, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 639, 754, 0, 698, 699, 0, 0, - 565, 566, 389, 0, 584, 397, 353, 471, 391, 549, - 420, 0, 577, 643, 578, 490, 491, 701, 706, 702, - 703, 705, 725, 461, 411, 416, 506, 423, 437, 493, - 548, 469, 498, 351, 538, 508, 442, 628, 656, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 310, 311, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 683, 682, 681, 680, - 679, 678, 677, 676, 0, 0, 625, 525, 367, 317, - 363, 364, 371, 742, 738, 743, 726, 729, 728, 704, - 0, 325, 605, 435, 486, 388, 670, 671, 0, 724, - 269, 270, 271, 272, 273, 274, 275, 276, 318, 277, - 278, 279, 280, 281, 282, 283, 288, 289, 290, 291, - 292, 293, 294, 295, 673, 286, 287, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 0, 0, 0, 0, 319, 730, 731, 732, 733, - 734, 0, 0, 320, 321, 322, 0, 0, 284, 285, - 312, 516, 313, 314, 315, 316, 0, 0, 555, 556, - 557, 580, 0, 558, 540, 604, 398, 326, 520, 547, - 740, 0, 0, 0, 0, 0, 0, 0, 655, 666, - 700, 0, 712, 713, 715, 717, 716, 719, 513, 514, - 727, 0, 0, 421, 341, 342, 462, 463, 500, 0, - 721, 722, 723, 720, 439, 499, 521, 507, 0, 746, - 595, 596, 747, 708, 327, 468, 0, 0, 610, 644, - 633, 718, 598, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 381, 0, 0, 434, 648, 629, 640, - 630, 474, 615, 616, 617, 624, 393, 618, 748, 620, - 590, 621, 591, 622, 623, 0, 647, 597, 509, 450, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 0, 0, 0, 0, 0, 0, 349, - 256, 592, 714, 594, 593, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 352, 0, 2861, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 510, 539, 0, 552, 0, 418, - 419, 0, 0, 0, 0, 0, 0, 0, 334, 517, - 536, 350, 504, 550, 355, 512, 529, 345, 467, 501, - 0, 0, 336, 534, 511, 447, 335, 0, 494, 378, - 395, 375, 465, 0, 0, 533, 563, 374, 553, 0, - 544, 338, 0, 543, 464, 530, 535, 448, 441, 0, - 337, 532, 446, 440, 425, 385, 579, 426, 427, 399, - 480, 438, 481, 400, 452, 451, 453, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 0, 0, - 0, 0, 574, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 707, - 0, 0, 711, 2860, 546, 0, 0, 0, 2866, 2863, - 2865, 515, 0, 2864, 428, 0, 0, 0, 564, 0, - 497, 470, 750, 0, 2858, 495, 436, 531, 482, 537, - 518, 545, 489, 483, 328, 519, 377, 449, 346, 348, - 739, 379, 382, 386, 387, 458, 459, 476, 503, 522, - 523, 524, 376, 360, 496, 361, 396, 362, 329, 368, - 366, 369, 505, 370, 331, 477, 528, 0, 392, 492, - 444, 332, 443, 478, 527, 526, 347, 554, 561, 562, - 652, 0, 567, 751, 752, 753, 576, 0, 484, 343, - 340, 0, 0, 0, 372, 479, 356, 358, 359, 357, - 473, 475, 581, 582, 583, 585, 0, 586, 587, 0, - 0, 0, 0, 588, 653, 669, 637, 606, 569, 661, - 603, 607, 608, 413, 414, 415, 672, 0, 0, 0, - 560, 429, 430, 0, 384, 383, 445, 333, 0, 0, - 422, 412, 485, 339, 380, 424, 417, 431, 432, 433, - 390, 323, 324, 745, 373, 466, 674, 709, 710, 599, - 0, 662, 600, 609, 365, 634, 646, 645, 460, 559, - 0, 657, 660, 589, 744, 0, 654, 668, 749, 667, - 741, 472, 0, 502, 665, 612, 0, 658, 631, 632, - 0, 659, 627, 663, 0, 601, 0, 570, 573, 602, - 687, 688, 689, 330, 572, 691, 692, 693, 694, 695, - 696, 697, 690, 542, 635, 611, 638, 551, 614, 613, - 0, 0, 649, 568, 650, 651, 454, 455, 456, 457, - 394, 675, 354, 571, 487, 488, 0, 636, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 639, 754, - 0, 698, 699, 0, 0, 565, 566, 389, 0, 584, - 397, 353, 471, 391, 549, 420, 0, 577, 643, 578, - 490, 491, 701, 706, 702, 703, 705, 725, 461, 411, - 416, 506, 423, 437, 493, 548, 469, 498, 351, 538, - 508, 442, 628, 656, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 310, 311, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 683, 682, 681, 680, 679, 678, 677, 676, 0, - 0, 625, 525, 367, 317, 363, 364, 371, 742, 738, - 743, 726, 729, 728, 704, 0, 325, 605, 435, 486, - 388, 670, 671, 0, 724, 269, 270, 271, 272, 273, - 274, 275, 276, 318, 277, 278, 279, 280, 281, 282, - 283, 288, 289, 290, 291, 292, 293, 294, 295, 673, - 286, 287, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 0, 0, 0, 0, - 319, 730, 731, 732, 733, 734, 0, 0, 320, 321, - 322, 0, 0, 284, 285, 312, 516, 313, 314, 315, - 316, 0, 0, 555, 556, 557, 580, 0, 558, 540, - 604, 398, 326, 520, 547, 740, 0, 0, 0, 0, - 0, 0, 0, 655, 666, 700, 0, 712, 713, 715, - 717, 716, 719, 513, 514, 727, 0, 0, 421, 341, - 342, 462, 463, 500, 0, 721, 722, 723, 720, 439, - 499, 521, 507, 0, 746, 595, 596, 747, 708, 327, - 468, 0, 0, 610, 644, 633, 718, 598, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 381, 0, - 0, 434, 648, 629, 640, 630, 474, 615, 616, 617, - 624, 393, 618, 748, 620, 590, 621, 591, 622, 623, - 0, 647, 597, 509, 450, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, - 0, 0, 0, 0, 349, 256, 592, 714, 594, 593, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, - 0, 2861, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 510, - 539, 0, 552, 0, 418, 419, 0, 0, 0, 0, - 0, 0, 0, 334, 517, 536, 350, 504, 550, 355, - 512, 529, 345, 467, 501, 0, 0, 336, 534, 511, - 447, 335, 0, 494, 378, 395, 375, 465, 0, 0, - 533, 563, 374, 553, 0, 544, 338, 0, 543, 464, - 530, 535, 448, 441, 0, 337, 532, 446, 440, 425, - 385, 579, 426, 427, 399, 480, 438, 481, 400, 452, - 451, 453, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 0, 0, 0, 0, 0, 574, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 707, 0, 0, 711, 2860, 546, - 0, 0, 0, 2866, 2863, 2865, 515, 0, 2864, 428, - 0, 0, 0, 564, 0, 497, 470, 750, 0, 0, - 495, 436, 531, 482, 537, 518, 545, 489, 483, 328, - 519, 377, 449, 346, 348, 739, 379, 382, 386, 387, - 458, 459, 476, 503, 522, 523, 524, 376, 360, 496, - 361, 396, 362, 329, 368, 366, 369, 505, 370, 331, - 477, 528, 0, 392, 492, 444, 332, 443, 478, 527, - 526, 347, 554, 561, 562, 652, 0, 567, 751, 752, - 753, 576, 0, 484, 343, 340, 0, 0, 0, 372, - 479, 356, 358, 359, 357, 473, 475, 581, 582, 583, - 585, 0, 586, 587, 0, 0, 0, 0, 588, 653, - 669, 637, 606, 569, 661, 603, 607, 608, 413, 414, - 415, 672, 0, 0, 0, 560, 429, 430, 0, 384, - 383, 445, 333, 0, 0, 422, 412, 485, 339, 380, - 424, 417, 431, 432, 433, 390, 323, 324, 745, 373, - 466, 674, 709, 710, 599, 0, 662, 600, 609, 365, - 634, 646, 645, 460, 559, 0, 657, 660, 589, 744, - 0, 654, 668, 749, 667, 741, 472, 0, 502, 665, - 612, 0, 658, 631, 632, 0, 659, 627, 663, 0, - 601, 0, 570, 573, 602, 687, 688, 689, 330, 572, - 691, 692, 693, 694, 695, 696, 697, 690, 542, 635, - 611, 638, 551, 614, 613, 0, 0, 649, 568, 650, - 651, 454, 455, 456, 457, 394, 675, 354, 571, 487, - 488, 0, 636, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 639, 754, 0, 698, 699, 0, 0, - 565, 566, 389, 0, 584, 397, 353, 471, 391, 549, - 420, 0, 577, 643, 578, 490, 491, 701, 706, 702, - 703, 705, 725, 461, 411, 416, 506, 423, 437, 493, - 548, 469, 498, 351, 538, 508, 442, 628, 656, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 310, 311, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 683, 682, 681, 680, - 679, 678, 677, 676, 0, 0, 625, 525, 367, 317, - 363, 364, 371, 742, 738, 743, 726, 729, 728, 704, - 0, 325, 605, 435, 486, 388, 670, 671, 0, 724, - 269, 270, 271, 272, 273, 274, 275, 276, 318, 277, - 278, 279, 280, 281, 282, 283, 288, 289, 290, 291, - 292, 293, 294, 295, 673, 286, 287, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 0, 0, 0, 0, 319, 730, 731, 732, 733, - 734, 0, 0, 320, 321, 322, 0, 0, 284, 285, - 312, 516, 313, 314, 315, 316, 0, 0, 555, 556, - 557, 580, 0, 558, 540, 604, 398, 326, 520, 547, - 740, 0, 0, 0, 0, 0, 0, 0, 655, 666, - 700, 0, 712, 713, 715, 717, 716, 719, 513, 514, - 727, 0, 0, 421, 341, 342, 462, 463, 500, 0, - 721, 722, 723, 720, 439, 499, 521, 507, 0, 746, - 595, 596, 747, 708, 327, 192, 233, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 468, 0, 0, 610, - 644, 633, 718, 598, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 381, 0, 0, 434, 648, 629, - 640, 630, 474, 615, 616, 617, 624, 393, 618, 748, - 620, 590, 621, 591, 622, 623, 161, 647, 597, 509, - 450, 0, 664, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 229, 3065, 0, 255, 0, 0, 0, 0, 0, 0, - 349, 256, 592, 714, 594, 593, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 352, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 510, 539, 0, 552, 0, - 418, 419, 0, 0, 0, 0, 0, 0, 0, 334, - 517, 536, 350, 504, 550, 355, 512, 529, 345, 467, - 501, 0, 0, 336, 534, 511, 447, 335, 0, 494, - 378, 395, 375, 465, 0, 0, 533, 563, 374, 553, - 0, 544, 338, 0, 543, 464, 530, 535, 448, 441, - 0, 337, 532, 446, 440, 425, 385, 579, 426, 427, - 399, 480, 438, 481, 400, 452, 451, 453, 401, 402, - 403, 404, 405, 406, 407, 408, 409, 410, 0, 0, - 0, 0, 0, 574, 575, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 707, 0, 0, 711, 0, 546, 0, 0, 0, 0, - 0, 0, 515, 0, 0, 428, 0, 0, 0, 564, - 0, 497, 470, 750, 0, 0, 495, 436, 531, 482, - 537, 518, 545, 489, 483, 328, 519, 377, 449, 346, - 348, 739, 379, 382, 386, 387, 458, 459, 476, 503, - 522, 523, 524, 376, 360, 496, 361, 396, 362, 329, - 368, 366, 369, 505, 370, 331, 477, 528, 0, 392, - 492, 444, 332, 443, 478, 527, 526, 347, 554, 561, - 562, 652, 0, 567, 751, 752, 753, 576, 0, 484, - 343, 340, 0, 0, 0, 372, 479, 356, 358, 359, - 357, 473, 475, 581, 582, 583, 585, 0, 586, 587, - 0, 0, 0, 0, 588, 653, 669, 637, 606, 569, - 661, 603, 607, 608, 413, 414, 415, 672, 0, 0, - 0, 560, 429, 430, 0, 384, 383, 445, 333, 0, - 0, 422, 412, 485, 339, 380, 424, 417, 431, 432, - 433, 390, 323, 324, 745, 373, 466, 674, 709, 710, - 599, 0, 662, 600, 609, 365, 634, 646, 645, 460, - 559, 0, 657, 660, 589, 744, 0, 654, 668, 749, - 667, 741, 472, 0, 502, 665, 612, 0, 658, 631, - 632, 0, 659, 627, 663, 0, 601, 0, 570, 573, - 602, 687, 688, 689, 330, 572, 691, 692, 693, 694, - 695, 696, 697, 690, 542, 635, 611, 638, 551, 614, - 613, 0, 0, 649, 568, 650, 651, 454, 455, 456, - 457, 394, 675, 354, 571, 487, 488, 0, 636, 0, - 0, 0, 0, 0, 0, 0, 0, 641, 642, 639, - 754, 0, 698, 699, 0, 0, 565, 566, 389, 0, - 584, 397, 353, 471, 391, 549, 420, 0, 577, 643, - 578, 490, 491, 701, 706, 702, 703, 705, 725, 461, - 411, 416, 506, 423, 437, 493, 548, 469, 498, 351, - 538, 508, 442, 628, 656, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 310, 311, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 683, 682, 681, 680, 679, 678, 677, 676, - 0, 0, 625, 525, 367, 317, 363, 364, 371, 742, - 738, 743, 726, 729, 728, 704, 0, 325, 605, 435, - 486, 388, 670, 671, 0, 724, 269, 270, 271, 272, - 273, 274, 275, 276, 318, 277, 278, 279, 280, 281, - 282, 283, 288, 289, 290, 291, 292, 293, 294, 295, - 673, 286, 287, 296, 297, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, 0, 0, 0, - 0, 319, 730, 731, 732, 733, 734, 0, 0, 320, - 321, 322, 0, 0, 284, 285, 312, 516, 313, 314, - 315, 316, 0, 0, 555, 556, 557, 580, 0, 558, - 540, 604, 398, 326, 520, 547, 740, 0, 0, 0, - 0, 0, 0, 0, 655, 666, 700, 0, 712, 713, - 715, 717, 716, 719, 513, 514, 727, 0, 0, 421, - 341, 342, 462, 463, 500, 0, 721, 722, 723, 720, - 439, 499, 521, 507, 0, 746, 595, 596, 747, 708, - 327, 192, 233, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 468, 0, 0, 610, 644, 633, 718, 598, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 381, 0, 0, 434, 648, 629, 640, 630, 474, 615, - 616, 617, 624, 393, 618, 748, 620, 590, 621, 591, - 622, 623, 161, 647, 597, 509, 450, 0, 664, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 229, 2771, 0, 255, - 0, 0, 0, 0, 0, 0, 349, 256, 592, 714, - 594, 593, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 352, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 510, 539, 0, 552, 0, 418, 419, 0, 0, - 0, 0, 0, 0, 0, 334, 517, 536, 350, 504, - 550, 355, 512, 529, 345, 467, 501, 0, 0, 336, - 534, 511, 447, 335, 0, 494, 378, 395, 375, 465, - 0, 0, 533, 563, 374, 553, 0, 544, 338, 0, - 543, 464, 530, 535, 448, 441, 0, 337, 532, 446, - 440, 425, 385, 579, 426, 427, 399, 480, 438, 481, - 400, 452, 451, 453, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 410, 0, 0, 0, 0, 0, 574, - 575, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 707, 0, 0, 711, - 0, 546, 0, 0, 0, 0, 0, 0, 515, 0, - 0, 428, 0, 0, 0, 564, 0, 497, 470, 750, - 0, 0, 495, 436, 531, 482, 537, 518, 545, 489, - 483, 328, 519, 377, 449, 346, 348, 739, 379, 382, - 386, 387, 458, 459, 476, 503, 522, 523, 524, 376, - 360, 496, 361, 396, 362, 329, 368, 366, 369, 505, - 370, 331, 477, 528, 0, 392, 492, 444, 332, 443, - 478, 527, 526, 347, 554, 561, 562, 652, 0, 567, - 751, 752, 753, 576, 0, 484, 343, 340, 0, 0, - 0, 372, 479, 356, 358, 359, 357, 473, 475, 581, - 582, 583, 585, 0, 586, 587, 0, 0, 0, 0, - 588, 653, 669, 637, 606, 569, 661, 603, 607, 608, - 413, 414, 415, 672, 0, 0, 0, 560, 429, 430, - 0, 384, 383, 445, 333, 0, 0, 422, 412, 485, - 339, 380, 424, 417, 431, 432, 433, 390, 323, 324, - 745, 373, 466, 674, 709, 710, 599, 0, 662, 600, - 609, 365, 634, 646, 645, 460, 559, 0, 657, 660, - 589, 744, 0, 654, 668, 749, 667, 741, 472, 0, - 502, 665, 612, 0, 658, 631, 632, 0, 659, 627, - 663, 0, 601, 0, 570, 573, 602, 687, 688, 689, - 330, 572, 691, 692, 693, 694, 695, 696, 697, 690, - 542, 635, 611, 638, 551, 614, 613, 0, 0, 649, - 568, 650, 651, 454, 455, 456, 457, 394, 675, 354, - 571, 487, 488, 0, 636, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 639, 754, 0, 698, 699, - 0, 0, 565, 566, 389, 0, 584, 397, 353, 471, - 391, 549, 420, 0, 577, 643, 578, 490, 491, 701, - 706, 702, 703, 705, 725, 461, 411, 416, 506, 423, - 437, 493, 548, 469, 498, 351, 538, 508, 442, 628, - 656, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 310, 311, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 683, 682, - 681, 680, 679, 678, 677, 676, 0, 0, 625, 525, - 367, 317, 363, 364, 371, 742, 738, 743, 726, 729, - 728, 704, 0, 325, 605, 435, 486, 388, 670, 671, - 0, 724, 269, 270, 271, 272, 273, 274, 275, 276, - 318, 277, 278, 279, 280, 281, 282, 283, 288, 289, - 290, 291, 292, 293, 294, 295, 673, 286, 287, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 0, 0, 0, 0, 319, 730, 731, - 732, 733, 734, 0, 0, 320, 321, 322, 0, 0, - 284, 285, 312, 516, 313, 314, 315, 316, 0, 0, - 555, 556, 557, 580, 0, 558, 540, 604, 398, 326, - 520, 547, 740, 0, 0, 0, 0, 0, 0, 0, - 655, 666, 700, 0, 712, 713, 715, 717, 716, 719, - 513, 514, 727, 0, 0, 421, 341, 342, 462, 463, - 500, 0, 721, 722, 723, 720, 439, 499, 521, 507, - 0, 746, 595, 596, 747, 708, 327, 468, 0, 0, - 610, 644, 633, 718, 598, 0, 0, 0, 0, 0, - 2459, 0, 0, 0, 0, 381, 0, 0, 434, 648, - 629, 640, 630, 474, 615, 616, 617, 624, 393, 618, - 748, 620, 590, 621, 591, 622, 623, 0, 647, 597, - 509, 450, 0, 664, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 0, 0, 2460, 0, 0, - 0, 349, 256, 592, 714, 594, 593, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 352, 0, 0, 1492, - 0, 1493, 1491, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 510, 539, 0, 552, - 0, 418, 419, 0, 0, 0, 0, 0, 0, 0, - 334, 517, 536, 350, 504, 550, 355, 512, 529, 345, - 467, 501, 0, 0, 336, 534, 511, 447, 335, 0, - 494, 378, 395, 375, 465, 0, 0, 533, 563, 374, - 553, 0, 544, 338, 0, 543, 464, 530, 535, 448, - 441, 0, 337, 532, 446, 440, 425, 385, 579, 426, - 427, 399, 480, 438, 481, 400, 452, 451, 453, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 0, 0, 0, 0, 574, 575, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 707, 0, 0, 711, 0, 546, 0, 0, 0, - 0, 0, 0, 515, 0, 0, 428, 0, 0, 0, - 564, 0, 497, 470, 750, 0, 0, 495, 436, 531, - 482, 537, 518, 545, 489, 483, 328, 519, 377, 449, - 346, 348, 739, 379, 382, 386, 387, 458, 459, 476, - 503, 522, 523, 524, 376, 360, 496, 361, 396, 362, - 329, 368, 366, 369, 505, 370, 331, 477, 528, 0, - 392, 492, 444, 332, 443, 478, 527, 526, 347, 554, - 561, 562, 652, 0, 567, 751, 752, 753, 576, 0, - 484, 343, 340, 0, 0, 0, 372, 479, 356, 358, - 359, 357, 473, 475, 581, 582, 583, 585, 0, 586, - 587, 0, 0, 0, 0, 588, 653, 669, 637, 606, - 569, 661, 603, 607, 608, 413, 414, 415, 672, 0, - 0, 0, 560, 429, 430, 0, 384, 383, 445, 333, - 0, 0, 422, 412, 485, 339, 380, 424, 417, 431, - 432, 433, 390, 323, 324, 745, 373, 466, 674, 709, - 710, 599, 0, 662, 600, 609, 365, 634, 646, 645, - 460, 559, 0, 657, 660, 589, 744, 0, 654, 668, - 749, 667, 741, 472, 0, 502, 665, 612, 0, 658, - 631, 632, 0, 659, 627, 663, 0, 601, 0, 570, - 573, 602, 687, 688, 689, 330, 572, 691, 692, 693, - 694, 695, 696, 697, 690, 542, 635, 611, 638, 551, - 614, 613, 0, 0, 649, 568, 650, 651, 454, 455, - 456, 457, 394, 675, 354, 571, 487, 488, 0, 636, - 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, - 639, 754, 0, 698, 699, 0, 0, 565, 566, 389, - 0, 584, 397, 353, 471, 391, 549, 420, 0, 577, - 643, 578, 490, 491, 701, 706, 702, 703, 705, 725, - 461, 411, 416, 506, 423, 437, 493, 548, 469, 498, - 351, 538, 508, 442, 628, 656, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 310, 311, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 683, 682, 681, 680, 679, 678, 677, - 676, 0, 0, 625, 525, 367, 317, 363, 364, 371, - 742, 738, 743, 726, 729, 728, 704, 0, 325, 605, - 435, 486, 388, 670, 671, 0, 724, 269, 270, 271, - 272, 273, 274, 275, 276, 318, 277, 278, 279, 280, - 281, 282, 283, 288, 289, 290, 291, 292, 293, 294, - 295, 673, 286, 287, 296, 297, 298, 299, 300, 301, - 302, 303, 304, 305, 306, 307, 308, 309, 0, 0, - 0, 0, 319, 730, 731, 732, 733, 734, 0, 0, - 320, 321, 322, 0, 0, 284, 285, 312, 516, 313, - 314, 315, 316, 0, 0, 555, 556, 557, 580, 0, - 558, 540, 604, 398, 326, 520, 547, 740, 0, 0, - 0, 0, 0, 0, 0, 655, 666, 700, 0, 712, - 713, 715, 717, 716, 719, 513, 514, 727, 0, 0, - 421, 341, 342, 462, 463, 500, 0, 721, 722, 723, - 720, 439, 499, 521, 507, 0, 746, 595, 596, 747, - 708, 327, 468, 0, 0, 610, 644, 633, 718, 598, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 381, 1183, 0, 434, 648, 629, 640, 630, 474, 615, - 616, 617, 624, 393, 618, 748, 620, 590, 621, 591, - 622, 623, 0, 647, 597, 509, 450, 0, 664, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, - 1190, 1191, 0, 0, 0, 0, 349, 256, 592, 714, - 594, 593, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1194, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 510, 539, 0, 552, 0, 418, 419, 0, 0, - 0, 0, 0, 0, 0, 334, 517, 1177, 350, 504, - 550, 355, 512, 529, 345, 467, 501, 0, 0, 336, - 534, 511, 447, 335, 0, 494, 378, 395, 375, 465, - 0, 0, 533, 563, 374, 553, 855, 544, 338, 854, - 543, 464, 530, 535, 448, 441, 0, 337, 532, 446, - 440, 425, 385, 579, 426, 427, 399, 480, 438, 481, - 400, 452, 451, 453, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 410, 0, 0, 0, 0, 0, 574, - 575, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 707, 0, 0, 711, - 0, 546, 0, 0, 0, 0, 0, 0, 515, 0, - 0, 428, 0, 0, 0, 564, 0, 497, 470, 750, - 0, 0, 495, 436, 531, 482, 537, 518, 545, 1181, - 483, 328, 519, 377, 449, 346, 348, 739, 379, 382, - 386, 387, 458, 459, 476, 503, 522, 523, 524, 376, - 360, 496, 361, 396, 362, 329, 368, 366, 369, 505, - 370, 331, 477, 528, 0, 392, 492, 444, 332, 443, - 478, 527, 526, 347, 554, 561, 562, 652, 0, 567, - 751, 752, 753, 576, 0, 484, 343, 340, 0, 0, - 0, 372, 479, 356, 358, 359, 357, 473, 475, 581, - 582, 583, 585, 0, 586, 587, 0, 0, 0, 0, - 588, 653, 669, 637, 606, 569, 661, 603, 607, 608, - 413, 414, 415, 672, 0, 0, 0, 560, 429, 430, - 0, 384, 383, 445, 333, 0, 0, 422, 412, 485, - 339, 380, 424, 417, 431, 432, 433, 390, 323, 324, - 745, 373, 466, 674, 709, 710, 599, 0, 662, 600, - 609, 365, 634, 646, 645, 460, 559, 0, 657, 660, - 589, 744, 0, 654, 668, 749, 667, 741, 472, 0, - 502, 665, 612, 0, 658, 631, 632, 0, 659, 627, - 663, 0, 601, 0, 570, 573, 602, 687, 688, 689, - 330, 572, 691, 692, 693, 694, 695, 696, 1182, 690, - 542, 635, 611, 638, 551, 614, 613, 0, 0, 649, - 1185, 650, 651, 454, 455, 456, 457, 394, 675, 1180, - 571, 487, 488, 0, 636, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 639, 754, 0, 698, 699, - 0, 0, 565, 566, 389, 0, 584, 397, 353, 471, - 391, 549, 420, 0, 577, 643, 578, 490, 491, 701, - 706, 702, 703, 705, 725, 1192, 1178, 1188, 1179, 423, - 437, 493, 548, 469, 498, 351, 538, 508, 1189, 628, - 656, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 310, 311, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 683, 682, - 681, 680, 679, 678, 677, 676, 0, 0, 625, 525, - 367, 317, 363, 364, 371, 742, 738, 743, 726, 729, - 728, 704, 0, 325, 605, 435, 486, 388, 670, 671, - 0, 724, 269, 270, 271, 272, 273, 274, 275, 276, - 318, 277, 278, 279, 280, 281, 282, 283, 288, 289, - 290, 291, 292, 293, 294, 295, 673, 286, 287, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 0, 0, 0, 0, 319, 730, 731, - 732, 733, 734, 0, 0, 320, 321, 322, 0, 0, - 284, 285, 312, 516, 313, 314, 315, 316, 0, 0, - 555, 556, 557, 580, 0, 558, 540, 604, 398, 326, - 520, 547, 740, 0, 0, 0, 0, 0, 0, 0, - 655, 666, 700, 0, 712, 713, 715, 717, 716, 719, - 513, 514, 727, 0, 0, 421, 341, 342, 462, 463, - 500, 0, 721, 722, 723, 720, 1176, 499, 521, 507, - 0, 746, 595, 596, 747, 708, 327, 468, 0, 0, - 610, 644, 633, 718, 598, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 381, 0, 0, 434, 648, - 629, 640, 630, 474, 615, 616, 617, 624, 393, 618, - 748, 620, 590, 621, 591, 622, 623, 0, 647, 597, - 509, 450, 0, 664, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 1190, 1191, 0, 0, 0, - 0, 349, 256, 592, 714, 594, 593, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1194, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 510, 539, 0, 552, - 0, 418, 419, 0, 0, 0, 0, 0, 0, 0, - 334, 517, 536, 350, 504, 550, 355, 512, 529, 345, - 467, 501, 0, 0, 336, 534, 511, 447, 335, 0, - 494, 378, 395, 375, 465, 0, 0, 533, 563, 374, - 553, 855, 544, 338, 854, 543, 464, 530, 535, 448, - 441, 0, 337, 532, 446, 440, 425, 385, 579, 426, - 427, 399, 480, 438, 481, 400, 452, 451, 453, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 0, 0, 0, 0, 574, 575, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 707, 0, 0, 711, 0, 546, 0, 0, 0, - 0, 0, 0, 515, 0, 0, 428, 0, 0, 0, - 564, 0, 497, 470, 750, 0, 0, 495, 436, 531, - 482, 537, 518, 545, 489, 483, 328, 519, 377, 449, - 346, 348, 739, 379, 382, 386, 387, 458, 459, 476, - 503, 522, 523, 524, 376, 360, 496, 361, 396, 362, - 329, 368, 366, 369, 505, 370, 331, 477, 528, 0, - 392, 492, 444, 332, 443, 478, 527, 526, 347, 554, - 561, 562, 652, 0, 567, 751, 752, 753, 576, 0, - 484, 343, 340, 0, 0, 0, 372, 479, 356, 358, - 359, 357, 473, 475, 581, 582, 583, 585, 0, 586, - 587, 0, 0, 0, 0, 588, 653, 669, 637, 606, - 569, 661, 603, 607, 608, 413, 414, 415, 672, 0, - 0, 0, 560, 429, 430, 0, 384, 383, 445, 333, - 0, 0, 422, 412, 485, 339, 380, 424, 417, 431, - 432, 433, 390, 323, 324, 745, 373, 466, 674, 709, - 710, 599, 0, 662, 600, 609, 365, 634, 646, 645, - 460, 559, 0, 657, 660, 589, 744, 0, 654, 668, - 749, 667, 741, 472, 0, 502, 665, 612, 0, 658, - 631, 632, 0, 659, 627, 663, 0, 601, 0, 570, - 573, 602, 687, 688, 689, 330, 572, 691, 692, 693, - 694, 695, 696, 697, 690, 542, 635, 611, 638, 551, - 614, 613, 0, 0, 649, 568, 650, 651, 454, 455, - 456, 457, 394, 675, 354, 571, 487, 488, 0, 636, - 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, - 639, 754, 0, 698, 699, 0, 0, 565, 566, 389, - 0, 584, 397, 353, 471, 391, 549, 420, 0, 577, - 643, 578, 490, 491, 701, 706, 702, 703, 705, 725, - 1192, 2406, 1188, 2407, 423, 437, 493, 548, 469, 498, - 351, 538, 508, 1189, 628, 656, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 310, 311, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 683, 682, 681, 680, 679, 678, 677, - 676, 0, 0, 625, 525, 367, 317, 363, 364, 371, - 742, 738, 743, 726, 729, 728, 704, 0, 325, 605, - 435, 486, 388, 670, 671, 0, 724, 269, 270, 271, - 272, 273, 274, 275, 276, 318, 277, 278, 279, 280, - 281, 282, 283, 288, 289, 290, 291, 292, 293, 294, - 295, 673, 286, 287, 296, 297, 298, 299, 300, 301, - 302, 303, 304, 305, 306, 307, 308, 309, 0, 0, - 0, 0, 319, 730, 731, 732, 733, 734, 0, 0, - 320, 321, 322, 0, 0, 284, 285, 312, 516, 313, - 314, 315, 316, 0, 0, 555, 556, 557, 580, 0, - 558, 540, 604, 398, 326, 520, 547, 740, 0, 0, - 0, 0, 0, 0, 0, 655, 666, 700, 0, 712, - 713, 715, 717, 716, 719, 513, 514, 727, 0, 0, - 421, 341, 342, 462, 463, 500, 0, 721, 722, 723, - 720, 439, 499, 521, 507, 0, 746, 595, 596, 747, - 708, 327, 192, 233, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 381, 0, 0, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 161, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1722, 0, 0, - 255, 0, 0, 0, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 0, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 0, 0, 0, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 564, 0, 497, 470, - 750, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 0, 657, - 660, 589, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 0, 746, 595, 596, 747, 708, 327, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 3503, 0, - 0, 0, 0, 0, 0, 0, 381, 0, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 0, 647, - 597, 509, 450, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, - 0, 0, 349, 256, 592, 714, 594, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 0, 0, 0, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 0, 0, 533, 563, - 374, 553, 0, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 579, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3506, 0, 0, 0, - 0, 3505, 707, 0, 0, 711, 0, 546, 0, 0, - 0, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 564, 0, 497, 470, 750, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 373, 466, 674, - 709, 710, 599, 0, 662, 600, 609, 365, 634, 646, - 645, 460, 559, 0, 657, 660, 589, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 542, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 568, 650, 651, 454, - 455, 456, 457, 394, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 311, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 0, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 269, 270, - 271, 272, 273, 274, 275, 276, 318, 277, 278, 279, - 280, 281, 282, 283, 288, 289, 290, 291, 292, 293, - 294, 295, 673, 286, 287, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 0, - 0, 0, 0, 319, 730, 731, 732, 733, 734, 0, - 0, 320, 321, 322, 0, 0, 284, 285, 312, 516, - 313, 314, 315, 316, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 716, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 721, 722, - 723, 720, 439, 499, 521, 507, 0, 746, 595, 596, - 747, 708, 327, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 381, 1777, 0, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 0, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 0, 0, 1775, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 1773, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 0, 0, 0, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 564, 0, 497, 470, - 750, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 0, 657, - 660, 589, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 0, 746, 595, 596, 747, 708, 327, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 381, 1771, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 0, 647, - 597, 509, 450, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 0, 0, 1775, 0, - 0, 0, 349, 256, 592, 714, 594, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 1773, 0, 0, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 0, 0, 533, 563, - 374, 553, 0, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 579, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 711, 0, 546, 0, 0, - 0, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 564, 0, 497, 470, 750, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 373, 466, 674, - 709, 710, 599, 0, 662, 600, 609, 365, 634, 646, - 645, 460, 559, 0, 657, 660, 589, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 542, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 568, 650, 651, 454, - 455, 456, 457, 394, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 311, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 0, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 269, 270, - 271, 272, 273, 274, 275, 276, 318, 277, 278, 279, - 280, 281, 282, 283, 288, 289, 290, 291, 292, 293, - 294, 295, 673, 286, 287, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 0, - 0, 0, 0, 319, 730, 731, 732, 733, 734, 0, - 0, 320, 321, 322, 0, 0, 284, 285, 312, 516, - 313, 314, 315, 316, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 716, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 721, 722, - 723, 720, 439, 499, 521, 507, 0, 746, 595, 596, - 747, 708, 327, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 381, 0, 0, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 0, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 4841, 0, - 255, 1023, 0, 0, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 0, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 0, 0, 0, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 564, 0, 497, 470, - 750, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 0, 657, - 660, 589, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 0, 746, 595, 596, 747, 708, 327, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 381, 0, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 0, 647, - 597, 509, 450, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 0, 0, 1775, 0, - 0, 0, 349, 256, 592, 714, 594, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 1773, 0, 0, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 0, 0, 533, 563, - 374, 553, 0, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 579, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 711, 0, 546, 0, 0, - 0, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 564, 0, 497, 470, 750, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 373, 466, 674, - 709, 710, 599, 0, 662, 600, 609, 365, 634, 646, - 645, 460, 559, 0, 657, 660, 589, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 542, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 568, 650, 651, 454, - 455, 456, 457, 394, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 311, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 0, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 269, 270, - 271, 272, 273, 274, 275, 276, 318, 277, 278, 279, - 280, 281, 282, 283, 288, 289, 290, 291, 292, 293, - 294, 295, 673, 286, 287, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 0, - 0, 0, 0, 319, 730, 731, 732, 733, 734, 0, - 0, 320, 321, 322, 0, 0, 284, 285, 312, 516, - 313, 314, 315, 316, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 716, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 721, 722, - 723, 720, 439, 499, 521, 507, 0, 746, 595, 596, - 747, 708, 327, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 381, 0, 0, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 0, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 0, 0, 1775, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 2052, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 0, 0, 0, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 564, 0, 497, 470, - 750, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 0, 657, - 660, 589, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 0, 746, 595, 596, 747, 708, 327, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 0, 0, - 0, 2296, 0, 0, 0, 0, 381, 0, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 0, 647, - 597, 509, 450, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 0, 0, 2298, 0, - 0, 0, 349, 256, 592, 714, 594, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 0, 0, 0, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 0, 0, 533, 563, - 374, 553, 0, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 579, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 711, 0, 546, 0, 0, - 0, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 564, 0, 497, 470, 750, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 373, 466, 674, - 709, 710, 599, 0, 662, 600, 609, 365, 634, 646, - 645, 460, 559, 0, 657, 660, 589, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 542, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 568, 650, 651, 454, - 455, 456, 457, 394, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 311, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 0, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 269, 270, - 271, 272, 273, 274, 275, 276, 318, 277, 278, 279, - 280, 281, 282, 283, 288, 289, 290, 291, 292, 293, - 294, 295, 673, 286, 287, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 0, - 0, 0, 0, 319, 730, 731, 732, 733, 734, 0, - 0, 320, 321, 322, 0, 0, 284, 285, 312, 516, - 313, 314, 315, 316, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 716, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 721, 722, - 723, 720, 439, 499, 521, 507, 0, 746, 595, 596, - 747, 708, 327, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 2459, 0, 0, 0, - 0, 381, 0, 0, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 0, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 0, 0, 2460, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 0, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 0, 0, 0, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 564, 0, 497, 470, - 750, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 0, 657, - 660, 589, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 0, 746, 595, 596, 747, 708, 327, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 381, 0, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 0, 647, - 597, 509, 450, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 0, 0, 3721, 3723, - 0, 0, 349, 256, 592, 714, 594, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 0, 0, 0, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 0, 0, 533, 563, - 374, 553, 0, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 579, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 711, 0, 546, 0, 0, - 0, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 564, 0, 497, 470, 750, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 373, 466, 674, - 709, 710, 599, 0, 662, 600, 609, 365, 634, 646, - 645, 460, 559, 0, 657, 660, 589, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 542, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 568, 650, 651, 454, - 455, 456, 457, 394, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 311, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 0, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 269, 270, - 271, 272, 273, 274, 275, 276, 318, 277, 278, 279, - 280, 281, 282, 283, 288, 289, 290, 291, 292, 293, - 294, 295, 673, 286, 287, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 0, - 0, 0, 0, 319, 730, 731, 732, 733, 734, 0, - 0, 320, 321, 322, 0, 0, 284, 285, 312, 516, - 313, 314, 315, 316, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 716, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 721, 722, - 723, 720, 439, 499, 521, 507, 0, 746, 595, 596, - 747, 708, 327, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 381, 0, 0, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 0, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3371, 0, 0, - 255, 0, 0, 3375, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 0, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 0, 0, 0, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 564, 0, 497, 470, - 750, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 0, 657, - 660, 589, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 0, 746, 595, 596, 747, 708, 327, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 381, 2947, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 0, 647, - 597, 509, 450, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 0, 0, 1775, 0, - 0, 0, 349, 256, 592, 714, 594, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 0, 0, 0, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 0, 0, 533, 563, - 374, 553, 0, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 579, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 711, 0, 546, 0, 0, - 0, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 564, 0, 497, 470, 750, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 373, 466, 674, - 709, 710, 599, 0, 662, 600, 609, 365, 634, 646, - 645, 460, 559, 0, 657, 660, 589, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 542, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 568, 650, 651, 454, - 455, 456, 457, 394, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 311, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 0, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 269, 270, - 271, 272, 273, 274, 275, 276, 318, 277, 278, 279, - 280, 281, 282, 283, 288, 289, 290, 291, 292, 293, - 294, 295, 673, 286, 287, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 0, - 0, 0, 0, 319, 730, 731, 732, 733, 734, 0, - 0, 320, 321, 322, 0, 0, 284, 285, 312, 516, - 313, 314, 315, 316, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 716, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 721, 722, - 723, 720, 439, 499, 521, 507, 0, 746, 595, 596, - 747, 708, 327, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1150, 381, 0, 0, 434, 648, 629, 640, 630, 1148, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 0, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 0, 0, 0, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 0, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 1149, 0, 0, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 564, 0, 497, 470, - 750, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 0, 657, - 660, 589, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 0, 746, 595, 596, 747, 708, 327, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 381, 0, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 0, 647, - 597, 509, 450, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 1023, 0, 0, 0, - 0, 0, 349, 256, 592, 714, 594, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 0, 0, 0, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 0, 0, 533, 563, - 374, 553, 0, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 579, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 711, 0, 546, 0, 0, - 0, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 564, 0, 497, 470, 750, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 373, 466, 674, - 709, 710, 599, 0, 662, 600, 609, 365, 634, 646, - 645, 460, 559, 0, 657, 660, 589, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 542, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 568, 650, 651, 454, - 455, 456, 457, 394, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 311, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 0, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 269, 270, - 271, 272, 273, 274, 275, 276, 318, 277, 278, 279, - 280, 281, 282, 283, 288, 289, 290, 291, 292, 293, - 294, 295, 673, 286, 287, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 0, - 0, 0, 0, 319, 730, 731, 732, 733, 734, 0, - 0, 320, 321, 322, 0, 0, 284, 285, 312, 516, - 313, 314, 315, 316, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 716, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 721, 722, - 723, 720, 439, 499, 521, 507, 0, 746, 595, 596, - 747, 708, 327, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 381, 0, 0, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 0, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4815, 0, 0, - 255, 0, 0, 0, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 0, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 0, 0, 0, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 564, 0, 497, 470, - 750, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 0, 657, - 660, 589, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 0, 746, 595, 596, 747, 708, 327, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 381, 0, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 0, 647, - 597, 509, 450, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 0, 0, 4516, 0, - 0, 0, 349, 256, 592, 714, 594, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 0, 0, 0, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 0, 0, 533, 563, - 374, 553, 0, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 579, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 711, 0, 546, 0, 0, - 0, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 564, 0, 497, 470, 750, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 373, 466, 674, - 709, 710, 599, 0, 662, 600, 609, 365, 634, 646, - 645, 460, 559, 0, 657, 660, 589, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 542, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 568, 650, 651, 454, - 455, 456, 457, 394, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 311, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 0, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 269, 270, - 271, 272, 273, 274, 275, 276, 318, 277, 278, 279, - 280, 281, 282, 283, 288, 289, 290, 291, 292, 293, - 294, 295, 673, 286, 287, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 0, - 0, 0, 0, 319, 730, 731, 732, 733, 734, 0, - 0, 320, 321, 322, 0, 0, 284, 285, 312, 516, - 313, 314, 315, 316, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 716, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 721, 722, - 723, 720, 439, 499, 521, 507, 0, 746, 595, 596, - 747, 708, 327, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 381, 0, 0, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 0, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2066, 0, 0, - 255, 0, 0, 0, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 0, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 0, 0, 0, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 564, 0, 497, 470, - 750, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 0, 657, - 660, 589, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 0, 746, 595, 596, 747, 708, 327, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 381, 0, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 0, 647, - 597, 509, 450, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4536, 0, 255, 0, 0, 0, 0, - 0, 0, 349, 256, 592, 714, 594, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 0, 0, 0, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 0, 0, 533, 563, - 374, 553, 0, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 579, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 711, 0, 546, 0, 0, - 0, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 564, 0, 497, 470, 750, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 373, 466, 674, - 709, 710, 599, 0, 662, 600, 609, 365, 634, 646, - 645, 460, 559, 0, 657, 660, 589, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 542, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 568, 650, 651, 454, - 455, 456, 457, 394, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 311, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 0, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 269, 270, - 271, 272, 273, 274, 275, 276, 318, 277, 278, 279, - 280, 281, 282, 283, 288, 289, 290, 291, 292, 293, - 294, 295, 673, 286, 287, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 0, - 0, 0, 0, 319, 730, 731, 732, 733, 734, 0, - 0, 320, 321, 322, 0, 0, 284, 285, 312, 516, - 313, 314, 315, 316, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 716, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 721, 722, - 723, 720, 439, 499, 521, 507, 0, 746, 595, 596, - 747, 708, 327, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 381, 0, 0, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 0, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 0, 0, 0, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 0, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 0, 0, 4529, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 564, 0, 497, 470, - 750, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 0, 657, - 660, 589, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 0, 746, 595, 596, 747, 708, 327, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 381, 0, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 0, 647, - 597, 509, 450, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, - 0, 0, 349, 256, 592, 714, 594, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 4324, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 0, 0, 0, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 0, 0, 533, 563, - 374, 553, 0, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 579, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 711, 0, 546, 0, 0, - 0, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 564, 0, 497, 470, 750, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 373, 466, 674, - 709, 710, 599, 0, 662, 600, 609, 365, 634, 646, - 645, 460, 559, 0, 657, 660, 589, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 542, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 568, 650, 651, 454, - 455, 456, 457, 394, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 311, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 0, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 269, 270, - 271, 272, 273, 274, 275, 276, 318, 277, 278, 279, - 280, 281, 282, 283, 288, 289, 290, 291, 292, 293, - 294, 295, 673, 286, 287, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 0, - 0, 0, 0, 319, 730, 731, 732, 733, 734, 0, - 0, 320, 321, 322, 0, 0, 284, 285, 312, 516, - 313, 314, 315, 316, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 716, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 721, 722, - 723, 720, 439, 499, 521, 507, 0, 746, 595, 596, - 747, 708, 327, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 381, 0, 0, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 0, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 0, 0, 3757, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 0, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 0, 0, 0, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 564, 0, 497, 470, - 750, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 0, 657, - 660, 589, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 0, 746, 595, 596, 747, 708, 327, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 381, 0, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 0, 647, - 597, 509, 450, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 0, 0, 4247, 0, - 0, 0, 349, 256, 592, 714, 594, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 0, 0, 0, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 0, 0, 533, 563, - 374, 553, 0, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 579, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 711, 0, 546, 0, 0, - 0, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 564, 0, 497, 470, 750, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 373, 466, 674, - 709, 710, 599, 0, 662, 600, 609, 365, 634, 646, - 645, 460, 559, 0, 657, 660, 589, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 542, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 568, 650, 651, 454, - 455, 456, 457, 394, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 311, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 0, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 269, 270, - 271, 272, 273, 274, 275, 276, 318, 277, 278, 279, - 280, 281, 282, 283, 288, 289, 290, 291, 292, 293, - 294, 295, 673, 286, 287, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 0, - 0, 0, 0, 319, 730, 731, 732, 733, 734, 0, - 0, 320, 321, 322, 0, 0, 284, 285, 312, 516, - 313, 314, 315, 316, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 716, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 721, 722, - 723, 720, 439, 499, 521, 507, 0, 746, 595, 596, - 747, 708, 327, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 381, 0, 0, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 0, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1722, 0, 0, - 255, 0, 0, 0, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 0, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 0, 0, 0, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 564, 0, 497, 470, - 750, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 0, 657, - 660, 589, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 0, 746, 595, 596, 747, 708, 327, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 381, 0, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 0, 647, - 597, 509, 450, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 0, 0, 3098, 0, - 0, 0, 349, 256, 592, 714, 594, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 0, 0, 0, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 0, 0, 533, 563, - 374, 553, 0, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 579, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 711, 0, 546, 0, 0, - 0, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 564, 0, 497, 470, 750, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 373, 466, 674, - 709, 710, 599, 0, 662, 600, 609, 365, 634, 646, - 645, 460, 559, 0, 657, 660, 589, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 542, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 568, 650, 651, 454, - 455, 456, 457, 394, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 311, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 0, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 269, 270, - 271, 272, 273, 274, 275, 276, 318, 277, 278, 279, - 280, 281, 282, 283, 288, 289, 290, 291, 292, 293, - 294, 295, 673, 286, 287, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 0, - 0, 0, 0, 319, 730, 731, 732, 733, 734, 0, - 0, 320, 321, 322, 0, 0, 284, 285, 312, 516, - 313, 314, 315, 316, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 716, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 721, 722, - 723, 720, 439, 499, 521, 507, 0, 746, 595, 596, - 747, 708, 327, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 381, 0, 0, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 0, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 0, 0, 3375, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 0, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 0, 0, 0, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 564, 0, 497, 470, - 750, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 0, 657, - 660, 589, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 0, 746, 595, 596, 747, 708, 327, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 381, 0, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 0, 647, - 597, 509, 450, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, - 0, 0, 349, 256, 592, 714, 594, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 0, 0, 0, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 0, 0, 533, 563, - 374, 553, 0, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 579, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 711, 0, 546, 0, 0, - 0, 4082, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 564, 0, 497, 470, 750, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 373, 466, 674, - 709, 710, 599, 0, 662, 600, 609, 365, 634, 646, - 645, 460, 559, 0, 657, 660, 589, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 542, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 568, 650, 651, 454, - 455, 456, 457, 394, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 311, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 0, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 269, 270, - 271, 272, 273, 274, 275, 276, 318, 277, 278, 279, - 280, 281, 282, 283, 288, 289, 290, 291, 292, 293, - 294, 295, 673, 286, 287, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 0, - 0, 0, 0, 319, 730, 731, 732, 733, 734, 0, - 0, 320, 321, 322, 0, 0, 284, 285, 312, 516, - 313, 314, 315, 316, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 716, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 721, 722, - 723, 720, 439, 499, 521, 507, 0, 746, 595, 596, - 747, 708, 327, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 381, 0, 0, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 0, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 0, 0, 0, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3792, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 0, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 0, 0, 0, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 564, 0, 497, 470, - 750, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 0, 657, - 660, 589, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 0, 746, 595, 596, 747, 708, 327, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 4031, 0, - 0, 0, 0, 0, 0, 0, 381, 0, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 0, 647, - 597, 509, 450, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, - 0, 0, 349, 256, 592, 714, 594, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 0, 0, 0, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 0, 0, 533, 563, - 374, 553, 0, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 579, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 711, 0, 546, 0, 0, - 0, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 564, 0, 497, 470, 750, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 373, 466, 674, - 709, 710, 599, 0, 662, 600, 609, 365, 634, 646, - 645, 460, 559, 0, 657, 660, 589, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 542, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 568, 650, 651, 454, - 455, 456, 457, 394, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 311, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 0, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 269, 270, - 271, 272, 273, 274, 275, 276, 318, 277, 278, 279, - 280, 281, 282, 283, 288, 289, 290, 291, 292, 293, - 294, 295, 673, 286, 287, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 0, - 0, 0, 0, 319, 730, 731, 732, 733, 734, 0, - 0, 320, 321, 322, 0, 0, 284, 285, 312, 516, - 313, 314, 315, 316, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 716, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 721, 722, - 723, 720, 439, 499, 521, 507, 0, 746, 595, 596, - 747, 708, 327, 468, 0, 0, 610, 644, 633, 718, - 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 381, 0, 0, 434, 648, 629, 640, 630, 474, - 615, 616, 617, 624, 393, 618, 748, 620, 590, 621, - 591, 622, 623, 0, 647, 597, 509, 450, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 0, 0, 0, 0, 0, 0, 349, 256, 592, - 714, 594, 593, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3901, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 510, 539, 0, 552, 0, 418, 419, 0, - 0, 0, 0, 0, 0, 0, 334, 517, 536, 350, - 504, 550, 355, 512, 529, 345, 467, 501, 0, 0, - 336, 534, 511, 447, 335, 0, 494, 378, 395, 375, - 465, 0, 0, 533, 563, 374, 553, 0, 544, 338, - 0, 543, 464, 530, 535, 448, 441, 0, 337, 532, - 446, 440, 425, 385, 579, 426, 427, 399, 480, 438, - 481, 400, 452, 451, 453, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 0, 0, 0, 0, - 574, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 707, 0, 0, - 711, 0, 546, 0, 0, 0, 0, 0, 0, 515, - 0, 0, 428, 0, 0, 0, 564, 0, 497, 470, - 750, 0, 0, 495, 436, 531, 482, 537, 518, 545, - 489, 483, 328, 519, 377, 449, 346, 348, 739, 379, - 382, 386, 387, 458, 459, 476, 503, 522, 523, 524, - 376, 360, 496, 361, 396, 362, 329, 368, 366, 369, - 505, 370, 331, 477, 528, 0, 392, 492, 444, 332, - 443, 478, 527, 526, 347, 554, 561, 562, 652, 0, - 567, 751, 752, 753, 576, 0, 484, 343, 340, 0, - 0, 0, 372, 479, 356, 358, 359, 357, 473, 475, - 581, 582, 583, 585, 0, 586, 587, 0, 0, 0, - 0, 588, 653, 669, 637, 606, 569, 661, 603, 607, - 608, 413, 414, 415, 672, 0, 0, 0, 560, 429, - 430, 0, 384, 383, 445, 333, 0, 0, 422, 412, - 485, 339, 380, 424, 417, 431, 432, 433, 390, 323, - 324, 745, 373, 466, 674, 709, 710, 599, 0, 662, - 600, 609, 365, 634, 646, 645, 460, 559, 0, 657, - 660, 589, 744, 0, 654, 668, 749, 667, 741, 472, - 0, 502, 665, 612, 0, 658, 631, 632, 0, 659, - 627, 663, 0, 601, 0, 570, 573, 602, 687, 688, - 689, 330, 572, 691, 692, 693, 694, 695, 696, 697, - 690, 542, 635, 611, 638, 551, 614, 613, 0, 0, - 649, 568, 650, 651, 454, 455, 456, 457, 394, 675, - 354, 571, 487, 488, 0, 636, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 639, 754, 0, 698, - 699, 0, 0, 565, 566, 389, 0, 584, 397, 353, - 471, 391, 549, 420, 0, 577, 643, 578, 490, 491, - 701, 706, 702, 703, 705, 725, 461, 411, 416, 506, - 423, 437, 493, 548, 469, 498, 351, 538, 508, 442, - 628, 656, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 310, 311, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 683, - 682, 681, 680, 679, 678, 677, 676, 0, 0, 625, - 525, 367, 317, 363, 364, 371, 742, 738, 743, 726, - 729, 728, 704, 0, 325, 605, 435, 486, 388, 670, - 671, 0, 724, 269, 270, 271, 272, 273, 274, 275, - 276, 318, 277, 278, 279, 280, 281, 282, 283, 288, - 289, 290, 291, 292, 293, 294, 295, 673, 286, 287, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 319, 730, - 731, 732, 733, 734, 0, 0, 320, 321, 322, 0, - 0, 284, 285, 312, 516, 313, 314, 315, 316, 0, - 0, 555, 556, 557, 580, 0, 558, 540, 604, 398, - 326, 520, 547, 740, 0, 0, 0, 0, 0, 0, - 0, 655, 666, 700, 0, 712, 713, 715, 717, 716, - 719, 513, 514, 727, 0, 0, 421, 341, 342, 462, - 463, 500, 0, 721, 722, 723, 720, 439, 499, 521, - 507, 0, 746, 595, 596, 747, 708, 327, 468, 0, - 0, 610, 644, 633, 718, 598, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 381, 0, 0, 434, - 648, 629, 640, 630, 474, 615, 616, 617, 624, 393, - 618, 748, 620, 590, 621, 591, 622, 623, 0, 647, - 597, 509, 450, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 255, 0, 0, 3762, 0, - 0, 0, 349, 256, 592, 714, 594, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 510, 539, 0, - 552, 0, 418, 419, 0, 0, 0, 0, 0, 0, - 0, 334, 517, 536, 350, 504, 550, 355, 512, 529, - 345, 467, 501, 0, 0, 336, 534, 511, 447, 335, - 0, 494, 378, 395, 375, 465, 0, 0, 533, 563, - 374, 553, 0, 544, 338, 0, 543, 464, 530, 535, - 448, 441, 0, 337, 532, 446, 440, 425, 385, 579, - 426, 427, 399, 480, 438, 481, 400, 452, 451, 453, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 0, 0, 0, 0, 574, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 711, 0, 546, 0, 0, - 0, 0, 0, 0, 515, 0, 0, 428, 0, 0, - 0, 564, 0, 497, 470, 750, 0, 0, 495, 436, - 531, 482, 537, 518, 545, 489, 483, 328, 519, 377, - 449, 346, 348, 739, 379, 382, 386, 387, 458, 459, - 476, 503, 522, 523, 524, 376, 360, 496, 361, 396, - 362, 329, 368, 366, 369, 505, 370, 331, 477, 528, - 0, 392, 492, 444, 332, 443, 478, 527, 526, 347, - 554, 561, 562, 652, 0, 567, 751, 752, 753, 576, - 0, 484, 343, 340, 0, 0, 0, 372, 479, 356, - 358, 359, 357, 473, 475, 581, 582, 583, 585, 0, - 586, 587, 0, 0, 0, 0, 588, 653, 669, 637, - 606, 569, 661, 603, 607, 608, 413, 414, 415, 672, - 0, 0, 0, 560, 429, 430, 0, 384, 383, 445, - 333, 0, 0, 422, 412, 485, 339, 380, 424, 417, - 431, 432, 433, 390, 323, 324, 745, 373, 466, 674, - 709, 710, 599, 0, 662, 600, 609, 365, 634, 646, - 645, 460, 559, 0, 657, 660, 589, 744, 0, 654, - 668, 749, 667, 741, 472, 0, 502, 665, 612, 0, - 658, 631, 632, 0, 659, 627, 663, 0, 601, 0, - 570, 573, 602, 687, 688, 689, 330, 572, 691, 692, - 693, 694, 695, 696, 697, 690, 542, 635, 611, 638, - 551, 614, 613, 0, 0, 649, 568, 650, 651, 454, - 455, 456, 457, 394, 675, 354, 571, 487, 488, 0, - 636, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 639, 754, 0, 698, 699, 0, 0, 565, 566, - 389, 0, 584, 397, 353, 471, 391, 549, 420, 0, - 577, 643, 578, 490, 491, 701, 706, 702, 703, 705, - 725, 461, 411, 416, 506, 423, 437, 493, 548, 469, - 498, 351, 538, 508, 442, 628, 656, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 311, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 683, 682, 681, 680, 679, 678, - 677, 676, 0, 0, 625, 525, 367, 317, 363, 364, - 371, 742, 738, 743, 726, 729, 728, 704, 0, 325, - 605, 435, 486, 388, 670, 671, 0, 724, 269, 270, - 271, 272, 273, 274, 275, 276, 318, 277, 278, 279, - 280, 281, 282, 283, 288, 289, 290, 291, 292, 293, - 294, 295, 673, 286, 287, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 0, - 0, 0, 0, 319, 730, 731, 732, 733, 734, 0, - 0, 320, 321, 322, 0, 0, 284, 285, 312, 516, - 313, 314, 315, 316, 0, 0, 555, 556, 557, 580, - 0, 558, 540, 604, 398, 326, 520, 547, 740, 0, - 0, 0, 0, 0, 0, 0, 655, 666, 700, 0, - 712, 713, 715, 717, 716, 719, 513, 514, 727, 0, - 0, 421, 341, 342, 462, 463, 500, 0, 721, 722, - 723, 720, 439, 499, 521, 507, 0, 746, 595, 596, - 747, 708, 327, 3690, 0, 0, 0, 0, 0, 468, - 0, 0, 610, 644, 633, 718, 598, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 381, 0, 0, - 434, 648, 629, 640, 630, 474, 615, 616, 617, 624, - 393, 618, 748, 620, 590, 621, 591, 622, 623, 0, - 647, 597, 509, 450, 0, 664, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, - 0, 0, 0, 349, 256, 592, 714, 594, 593, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 352, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 510, 539, - 0, 552, 0, 418, 419, 0, 0, 0, 0, 0, - 0, 0, 334, 517, 536, 350, 504, 550, 355, 512, - 529, 345, 467, 501, 0, 0, 336, 534, 511, 447, - 335, 0, 494, 378, 395, 375, 465, 0, 0, 533, - 563, 374, 553, 0, 544, 338, 0, 543, 464, 530, - 535, 448, 441, 0, 337, 532, 446, 440, 425, 385, - 579, 426, 427, 399, 480, 438, 481, 400, 452, 451, - 453, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 0, 0, 0, 0, 574, 575, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 707, 0, 0, 711, 0, 546, 0, - 0, 0, 0, 0, 0, 515, 0, 0, 428, 0, - 0, 0, 564, 0, 497, 470, 750, 0, 0, 495, - 436, 531, 482, 537, 518, 545, 489, 483, 328, 519, - 377, 449, 346, 348, 739, 379, 382, 386, 387, 458, - 459, 476, 503, 522, 523, 524, 376, 360, 496, 361, - 396, 362, 329, 368, 366, 369, 505, 370, 331, 477, - 528, 0, 392, 492, 444, 332, 443, 478, 527, 526, - 347, 554, 561, 562, 652, 0, 567, 751, 752, 753, - 576, 0, 484, 343, 340, 0, 0, 0, 372, 479, - 356, 358, 359, 357, 473, 475, 581, 582, 583, 585, - 0, 586, 587, 0, 0, 0, 0, 588, 653, 669, - 637, 606, 569, 661, 603, 607, 608, 413, 414, 415, - 672, 0, 0, 0, 560, 429, 430, 0, 384, 383, - 445, 333, 0, 0, 422, 412, 485, 339, 380, 424, - 417, 431, 432, 433, 390, 323, 324, 745, 373, 466, - 674, 709, 710, 599, 0, 662, 600, 609, 365, 634, - 646, 645, 460, 559, 0, 657, 660, 589, 744, 0, - 654, 668, 749, 667, 741, 472, 0, 502, 665, 612, - 0, 658, 631, 632, 0, 659, 627, 663, 0, 601, - 0, 570, 573, 602, 687, 688, 689, 330, 572, 691, - 692, 693, 694, 695, 696, 697, 690, 542, 635, 611, - 638, 551, 614, 613, 0, 0, 649, 568, 650, 651, - 454, 455, 456, 457, 394, 675, 354, 571, 487, 488, - 0, 636, 0, 0, 0, 0, 0, 0, 0, 0, - 641, 642, 639, 754, 0, 698, 699, 0, 0, 565, - 566, 389, 0, 584, 397, 353, 471, 391, 549, 420, - 0, 577, 643, 578, 490, 491, 701, 706, 702, 703, - 705, 725, 461, 411, 416, 506, 423, 437, 493, 548, - 469, 498, 351, 538, 508, 442, 628, 656, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 310, - 311, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 683, 682, 681, 680, 679, - 678, 677, 676, 0, 0, 625, 525, 367, 317, 363, - 364, 371, 742, 738, 743, 726, 729, 728, 704, 0, - 325, 605, 435, 486, 388, 670, 671, 0, 724, 269, - 270, 271, 272, 273, 274, 275, 276, 318, 277, 278, - 279, 280, 281, 282, 283, 288, 289, 290, 291, 292, - 293, 294, 295, 673, 286, 287, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 0, 0, 0, 0, 319, 730, 731, 732, 733, 734, - 0, 0, 320, 321, 322, 0, 0, 284, 285, 312, - 516, 313, 314, 315, 316, 0, 0, 555, 556, 557, - 580, 0, 558, 540, 604, 398, 326, 520, 547, 740, - 0, 0, 0, 0, 0, 0, 0, 655, 666, 700, - 0, 712, 713, 715, 717, 716, 719, 513, 514, 727, - 0, 0, 421, 341, 342, 462, 463, 500, 0, 721, - 722, 723, 720, 439, 499, 521, 507, 0, 746, 595, - 596, 747, 708, 327, 468, 0, 0, 610, 644, 633, - 718, 598, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 381, 0, 0, 434, 648, 629, 640, 630, - 474, 615, 616, 617, 624, 393, 618, 748, 620, 590, - 621, 591, 622, 623, 0, 647, 597, 509, 450, 0, - 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2369, 0, 0, 0, 0, + 0, 0, 0, 0, 2357, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2384, 2383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 255, 0, 0, 0, 0, 0, 0, 349, 256, - 592, 714, 594, 593, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3584, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 510, 539, 0, 552, 0, 418, 419, - 0, 0, 0, 0, 0, 0, 0, 334, 517, 536, - 350, 504, 550, 355, 512, 529, 345, 467, 501, 0, - 0, 336, 534, 511, 447, 335, 0, 494, 378, 395, - 375, 465, 0, 0, 533, 563, 374, 553, 0, 544, - 338, 0, 543, 464, 530, 535, 448, 441, 0, 337, - 532, 446, 440, 425, 385, 579, 426, 427, 399, 480, - 438, 481, 400, 452, 451, 453, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 0, 0, 0, 0, - 0, 574, 575, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 707, 0, - 0, 711, 0, 546, 0, 0, 0, 0, 0, 0, - 515, 0, 0, 428, 0, 0, 0, 564, 0, 497, - 470, 750, 0, 0, 495, 436, 531, 482, 537, 518, - 545, 489, 483, 328, 519, 377, 449, 346, 348, 739, - 379, 382, 386, 387, 458, 459, 476, 503, 522, 523, - 524, 376, 360, 496, 361, 396, 362, 329, 368, 366, - 369, 505, 370, 331, 477, 528, 0, 392, 492, 444, - 332, 443, 478, 527, 526, 347, 554, 561, 562, 652, - 0, 567, 751, 752, 753, 576, 0, 484, 343, 340, - 0, 0, 0, 372, 479, 356, 358, 359, 357, 473, - 475, 581, 582, 583, 585, 0, 586, 587, 0, 0, - 0, 0, 588, 653, 669, 637, 606, 569, 661, 603, - 607, 608, 413, 414, 415, 672, 0, 0, 0, 560, - 429, 430, 0, 384, 383, 445, 333, 0, 0, 422, - 412, 485, 339, 380, 424, 417, 431, 432, 433, 390, - 323, 324, 745, 373, 466, 674, 709, 710, 599, 0, - 662, 600, 609, 365, 634, 646, 645, 460, 559, 0, - 657, 660, 589, 744, 0, 654, 668, 749, 667, 741, - 472, 0, 502, 665, 612, 0, 658, 631, 632, 0, - 659, 627, 663, 0, 601, 0, 570, 573, 602, 687, - 688, 689, 330, 572, 691, 692, 693, 694, 695, 696, - 697, 690, 542, 635, 611, 638, 551, 614, 613, 0, - 0, 649, 568, 650, 651, 454, 455, 456, 457, 394, - 675, 354, 571, 487, 488, 0, 636, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 639, 754, 0, - 698, 699, 0, 0, 565, 566, 389, 0, 584, 397, - 353, 471, 391, 549, 420, 0, 577, 643, 578, 490, - 491, 701, 706, 702, 703, 705, 725, 461, 411, 416, - 506, 423, 437, 493, 548, 469, 498, 351, 538, 508, - 442, 628, 656, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 310, 311, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 683, 682, 681, 680, 679, 678, 677, 676, 0, 0, - 625, 525, 367, 317, 363, 364, 371, 742, 738, 743, - 726, 729, 728, 704, 0, 325, 605, 435, 486, 388, - 670, 671, 0, 724, 269, 270, 271, 272, 273, 274, - 275, 276, 318, 277, 278, 279, 280, 281, 282, 283, - 288, 289, 290, 291, 292, 293, 294, 295, 673, 286, - 287, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 0, 0, 0, 0, 319, - 730, 731, 732, 733, 734, 0, 0, 320, 321, 322, - 0, 0, 284, 285, 312, 516, 313, 314, 315, 316, - 0, 0, 555, 556, 557, 580, 0, 558, 540, 604, - 398, 326, 520, 547, 740, 0, 0, 0, 0, 0, - 0, 0, 655, 666, 700, 0, 712, 713, 715, 717, - 716, 719, 513, 514, 727, 0, 0, 421, 341, 342, - 462, 463, 500, 0, 721, 722, 723, 720, 439, 499, - 521, 507, 0, 746, 595, 596, 747, 708, 327, 468, - 0, 0, 610, 644, 633, 718, 598, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 381, 0, 0, - 434, 648, 629, 640, 630, 474, 615, 616, 617, 624, - 393, 618, 748, 620, 590, 621, 591, 622, 623, 0, - 647, 597, 509, 450, 0, 664, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 255, 0, 0, 1775, - 0, 0, 0, 349, 256, 592, 714, 594, 593, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 352, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 510, 539, - 0, 552, 0, 418, 419, 0, 0, 0, 0, 0, - 0, 0, 334, 517, 536, 350, 504, 550, 355, 512, - 529, 345, 467, 501, 0, 0, 336, 534, 511, 447, - 335, 0, 494, 378, 395, 375, 465, 0, 0, 533, - 563, 374, 553, 0, 544, 338, 0, 543, 464, 530, - 535, 448, 441, 0, 337, 532, 446, 440, 425, 385, - 579, 426, 427, 399, 480, 438, 481, 400, 452, 451, - 453, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 0, 0, 0, 0, 574, 575, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 707, 0, 0, 711, 0, 546, 0, - 0, 0, 0, 0, 0, 515, 0, 0, 428, 0, - 0, 0, 564, 0, 497, 470, 750, 0, 0, 495, - 436, 531, 482, 537, 518, 545, 489, 483, 328, 519, - 377, 449, 346, 348, 739, 379, 382, 386, 387, 458, - 459, 476, 503, 522, 523, 524, 376, 360, 496, 361, - 396, 362, 329, 368, 366, 369, 505, 370, 331, 477, - 528, 0, 392, 492, 444, 332, 443, 478, 527, 526, - 347, 554, 561, 562, 652, 0, 567, 751, 752, 753, - 576, 0, 484, 343, 340, 0, 0, 0, 372, 479, - 356, 358, 359, 357, 473, 475, 581, 582, 583, 585, - 0, 586, 587, 0, 0, 0, 0, 588, 653, 669, - 637, 606, 569, 661, 603, 607, 608, 413, 414, 415, - 672, 0, 0, 0, 560, 429, 430, 0, 384, 383, - 445, 333, 0, 0, 422, 412, 485, 339, 380, 424, - 417, 431, 432, 433, 390, 323, 324, 745, 373, 466, - 674, 709, 710, 599, 0, 662, 600, 609, 365, 634, - 646, 645, 460, 559, 0, 657, 660, 589, 744, 0, - 654, 668, 749, 667, 741, 472, 0, 502, 665, 612, - 0, 658, 631, 632, 0, 659, 627, 663, 0, 601, - 0, 570, 573, 602, 687, 688, 689, 330, 572, 691, - 692, 693, 694, 695, 696, 697, 690, 542, 635, 611, - 638, 551, 614, 613, 0, 0, 649, 568, 650, 651, - 454, 455, 456, 457, 394, 675, 354, 571, 487, 488, - 0, 636, 0, 0, 0, 0, 0, 0, 0, 0, - 641, 642, 639, 754, 0, 698, 699, 0, 0, 565, - 566, 389, 0, 584, 397, 353, 471, 391, 549, 420, - 0, 577, 643, 578, 490, 491, 701, 706, 702, 703, - 705, 725, 461, 411, 416, 506, 423, 437, 493, 548, - 469, 498, 351, 538, 508, 442, 628, 656, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 310, - 311, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 683, 682, 681, 680, 679, - 678, 677, 676, 0, 0, 625, 525, 367, 317, 363, - 364, 371, 742, 738, 743, 726, 729, 728, 704, 0, - 325, 605, 435, 486, 388, 670, 671, 0, 724, 269, - 270, 271, 272, 273, 274, 275, 276, 318, 277, 278, - 279, 280, 281, 282, 283, 288, 289, 290, 291, 292, - 293, 294, 295, 673, 286, 287, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 0, 0, 0, 0, 319, 730, 731, 732, 733, 734, - 0, 0, 320, 321, 322, 0, 0, 284, 285, 312, - 516, 313, 314, 315, 316, 0, 0, 555, 556, 557, - 580, 0, 558, 540, 604, 398, 326, 520, 547, 740, - 0, 0, 0, 0, 0, 0, 0, 655, 666, 700, - 0, 712, 713, 715, 717, 716, 719, 513, 514, 727, - 0, 0, 421, 341, 342, 462, 463, 500, 0, 721, - 722, 723, 720, 439, 499, 521, 507, 0, 746, 595, - 596, 747, 708, 327, 468, 0, 0, 610, 644, 633, - 718, 598, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 381, 0, 0, 434, 648, 629, 640, 630, - 474, 615, 616, 617, 624, 393, 618, 748, 620, 590, - 621, 591, 622, 623, 0, 647, 597, 509, 450, 0, - 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 255, 0, 0, 2298, 0, 0, 0, 349, 256, - 592, 714, 594, 593, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 510, 539, 0, 552, 0, 418, 419, - 0, 0, 0, 0, 0, 0, 0, 334, 517, 536, - 350, 504, 550, 355, 512, 529, 345, 467, 501, 0, - 0, 336, 534, 511, 447, 335, 0, 494, 378, 395, - 375, 465, 0, 0, 533, 563, 374, 553, 0, 544, - 338, 0, 543, 464, 530, 535, 448, 441, 0, 337, - 532, 446, 440, 425, 385, 579, 426, 427, 399, 480, - 438, 481, 400, 452, 451, 453, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 0, 0, 0, 0, - 0, 574, 575, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 707, 0, - 0, 711, 0, 546, 0, 0, 0, 0, 0, 0, - 515, 0, 0, 428, 0, 0, 0, 564, 0, 497, - 470, 750, 0, 0, 495, 436, 531, 482, 537, 518, - 545, 489, 483, 328, 519, 377, 449, 346, 348, 739, - 379, 382, 386, 387, 458, 459, 476, 503, 522, 523, - 524, 376, 360, 496, 361, 396, 362, 329, 368, 366, - 369, 505, 370, 331, 477, 528, 0, 392, 492, 444, - 332, 443, 478, 527, 526, 347, 554, 561, 562, 652, - 0, 567, 751, 752, 753, 576, 0, 484, 343, 340, - 0, 0, 0, 372, 479, 356, 358, 359, 357, 473, - 475, 581, 582, 583, 585, 0, 586, 587, 0, 0, - 0, 0, 588, 653, 669, 637, 606, 569, 661, 603, - 607, 608, 413, 414, 415, 672, 0, 0, 0, 560, - 429, 430, 0, 384, 383, 445, 333, 0, 0, 422, - 412, 485, 339, 380, 424, 417, 431, 432, 433, 390, - 323, 324, 745, 373, 466, 674, 709, 710, 599, 0, - 662, 600, 609, 365, 634, 646, 645, 460, 559, 0, - 657, 660, 589, 744, 0, 654, 668, 749, 667, 741, - 472, 0, 502, 665, 612, 0, 658, 631, 632, 0, - 659, 627, 663, 0, 601, 0, 570, 573, 602, 687, - 688, 689, 330, 572, 691, 692, 693, 694, 695, 696, - 697, 690, 542, 635, 611, 638, 551, 614, 613, 0, - 0, 649, 568, 650, 651, 454, 455, 456, 457, 394, - 675, 354, 571, 487, 488, 0, 636, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 639, 754, 0, - 698, 699, 0, 0, 565, 566, 389, 0, 584, 397, - 353, 471, 391, 549, 420, 0, 577, 643, 578, 490, - 491, 701, 706, 702, 703, 705, 725, 461, 411, 416, - 506, 423, 437, 493, 548, 469, 498, 351, 538, 508, - 442, 628, 656, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 310, 311, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 683, 682, 681, 680, 679, 678, 677, 676, 0, 0, - 625, 525, 367, 317, 363, 364, 371, 742, 738, 743, - 726, 729, 728, 704, 0, 325, 605, 435, 486, 388, - 670, 671, 0, 724, 269, 270, 271, 272, 273, 274, - 275, 276, 318, 277, 278, 279, 280, 281, 282, 283, - 288, 289, 290, 291, 292, 293, 294, 295, 673, 286, - 287, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 0, 0, 0, 0, 319, - 730, 731, 732, 733, 734, 0, 0, 320, 321, 322, - 0, 0, 284, 285, 312, 516, 313, 314, 315, 316, - 0, 0, 555, 556, 557, 580, 0, 558, 540, 604, - 398, 326, 520, 547, 740, 0, 0, 0, 0, 0, - 0, 0, 655, 666, 700, 0, 712, 713, 715, 717, - 716, 719, 513, 514, 727, 0, 0, 421, 341, 342, - 462, 463, 500, 0, 721, 722, 723, 720, 439, 499, - 521, 507, 0, 746, 595, 596, 747, 708, 327, 468, - 0, 0, 610, 644, 633, 718, 598, 0, 0, 3414, - 0, 0, 0, 0, 0, 0, 0, 381, 0, 0, - 434, 648, 629, 640, 630, 474, 615, 616, 617, 624, - 393, 618, 748, 620, 590, 621, 591, 622, 623, 0, - 647, 597, 509, 450, 0, 664, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, - 0, 0, 0, 349, 256, 592, 714, 594, 593, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 352, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 510, 539, - 0, 552, 0, 418, 419, 0, 0, 0, 0, 0, - 0, 0, 334, 517, 536, 350, 504, 550, 355, 512, - 529, 345, 467, 501, 0, 0, 336, 534, 511, 447, - 335, 0, 494, 378, 395, 375, 465, 0, 0, 533, - 563, 374, 553, 0, 544, 338, 0, 543, 464, 530, - 535, 448, 441, 0, 337, 532, 446, 440, 425, 385, - 579, 426, 427, 399, 480, 438, 481, 400, 452, 451, - 453, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 0, 0, 0, 0, 574, 575, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 707, 0, 0, 711, 0, 546, 0, - 0, 0, 0, 0, 0, 515, 0, 0, 428, 0, - 0, 0, 564, 0, 497, 470, 750, 0, 0, 495, - 436, 531, 482, 537, 518, 545, 489, 483, 328, 519, - 377, 449, 346, 348, 739, 379, 382, 386, 387, 458, - 459, 476, 503, 522, 523, 524, 376, 360, 496, 361, - 396, 362, 329, 368, 366, 369, 505, 370, 331, 477, - 528, 0, 392, 492, 444, 332, 443, 478, 527, 526, - 347, 554, 561, 562, 652, 0, 567, 751, 752, 753, - 576, 0, 484, 343, 340, 0, 0, 0, 372, 479, - 356, 358, 359, 357, 473, 475, 581, 582, 583, 585, - 0, 586, 587, 0, 0, 0, 0, 588, 653, 669, - 637, 606, 569, 661, 603, 607, 608, 413, 414, 415, - 672, 0, 0, 0, 560, 429, 430, 0, 384, 383, - 445, 333, 0, 0, 422, 412, 485, 339, 380, 424, - 417, 431, 432, 433, 390, 323, 324, 745, 373, 466, - 674, 709, 710, 599, 0, 662, 600, 609, 365, 634, - 646, 645, 460, 559, 0, 657, 660, 589, 744, 0, - 654, 668, 749, 667, 741, 472, 0, 502, 665, 612, - 0, 658, 631, 632, 0, 659, 627, 663, 0, 601, - 0, 570, 573, 602, 687, 688, 689, 330, 572, 691, - 692, 693, 694, 695, 696, 697, 690, 542, 635, 611, - 638, 551, 614, 613, 0, 0, 649, 568, 650, 651, - 454, 455, 456, 457, 394, 675, 354, 571, 487, 488, - 0, 636, 0, 0, 0, 0, 0, 0, 0, 0, - 641, 642, 639, 754, 0, 698, 699, 0, 0, 565, - 566, 389, 0, 584, 397, 353, 471, 391, 549, 420, - 0, 577, 643, 578, 490, 491, 701, 706, 702, 703, - 705, 725, 461, 411, 416, 506, 423, 437, 493, 548, - 469, 498, 351, 538, 508, 442, 628, 656, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 310, - 311, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 683, 682, 681, 680, 679, - 678, 677, 676, 0, 0, 625, 525, 367, 317, 363, - 364, 371, 742, 738, 743, 726, 729, 728, 704, 0, - 325, 605, 435, 486, 388, 670, 671, 0, 724, 269, - 270, 271, 272, 273, 274, 275, 276, 318, 277, 278, - 279, 280, 281, 282, 283, 288, 289, 290, 291, 292, - 293, 294, 295, 673, 286, 287, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 0, 0, 0, 0, 319, 730, 731, 732, 733, 734, - 0, 0, 320, 321, 322, 0, 0, 284, 285, 312, - 516, 313, 314, 315, 316, 0, 0, 555, 556, 557, - 580, 0, 558, 540, 604, 398, 326, 520, 547, 740, - 0, 0, 0, 0, 0, 0, 0, 655, 666, 700, - 0, 712, 713, 715, 717, 716, 719, 513, 514, 727, - 0, 0, 421, 341, 342, 462, 463, 500, 0, 721, - 722, 723, 720, 439, 499, 521, 507, 0, 746, 595, - 596, 747, 708, 327, 468, 0, 0, 610, 644, 633, - 718, 598, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 381, 0, 0, 434, 648, 629, 640, 630, - 474, 615, 616, 617, 624, 393, 618, 748, 620, 590, - 621, 591, 622, 623, 0, 647, 597, 509, 450, 0, - 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2376, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2352, 0, + 0, 0, 2351, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 255, 0, 0, 3307, 0, 0, 0, 349, 256, - 592, 714, 594, 593, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 510, 539, 0, 552, 0, 418, 419, - 0, 0, 0, 0, 0, 0, 0, 334, 517, 536, - 350, 504, 550, 355, 512, 529, 345, 467, 501, 0, - 0, 336, 534, 511, 447, 335, 0, 494, 378, 395, - 375, 465, 0, 0, 533, 563, 374, 553, 0, 544, - 338, 0, 543, 464, 530, 535, 448, 441, 0, 337, - 532, 446, 440, 425, 385, 579, 426, 427, 399, 480, - 438, 481, 400, 452, 451, 453, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 0, 0, 0, 0, - 0, 574, 575, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 707, 0, - 0, 711, 0, 546, 0, 0, 0, 0, 0, 0, - 515, 0, 0, 428, 0, 0, 0, 564, 0, 497, - 470, 750, 0, 0, 495, 436, 531, 482, 537, 518, - 545, 489, 483, 328, 519, 377, 449, 346, 348, 739, - 379, 382, 386, 387, 458, 459, 476, 503, 522, 523, - 524, 376, 360, 496, 361, 396, 362, 329, 368, 366, - 369, 505, 370, 331, 477, 528, 0, 392, 492, 444, - 332, 443, 478, 527, 526, 347, 554, 561, 562, 652, - 0, 567, 751, 752, 753, 576, 0, 484, 343, 340, - 0, 0, 0, 372, 479, 356, 358, 359, 357, 473, - 475, 581, 582, 583, 585, 0, 586, 587, 0, 0, - 0, 0, 588, 653, 669, 637, 606, 569, 661, 603, - 607, 608, 413, 414, 415, 672, 0, 0, 0, 560, - 429, 430, 0, 384, 383, 445, 333, 0, 0, 422, - 412, 485, 339, 380, 424, 417, 431, 432, 433, 390, - 323, 324, 745, 373, 466, 674, 709, 710, 599, 0, - 662, 600, 609, 365, 634, 646, 645, 460, 559, 0, - 657, 660, 589, 744, 0, 654, 668, 749, 667, 741, - 472, 0, 502, 665, 612, 0, 658, 631, 632, 0, - 659, 627, 663, 0, 601, 0, 570, 573, 602, 687, - 688, 689, 330, 572, 691, 692, 693, 694, 695, 696, - 697, 690, 542, 635, 611, 638, 551, 614, 613, 0, - 0, 649, 568, 650, 651, 454, 455, 456, 457, 394, - 675, 354, 571, 487, 488, 0, 636, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 639, 754, 0, - 698, 699, 0, 0, 565, 566, 389, 0, 584, 397, - 353, 471, 391, 549, 420, 0, 577, 643, 578, 490, - 491, 701, 706, 702, 703, 705, 725, 461, 411, 416, - 506, 423, 437, 493, 548, 469, 498, 351, 538, 508, - 442, 628, 656, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 310, 311, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 683, 682, 681, 680, 679, 678, 677, 676, 0, 0, - 625, 525, 367, 317, 363, 364, 371, 742, 738, 743, - 726, 729, 728, 704, 0, 325, 605, 435, 486, 388, - 670, 671, 0, 724, 269, 270, 271, 272, 273, 274, - 275, 276, 318, 277, 278, 279, 280, 281, 282, 283, - 288, 289, 290, 291, 292, 293, 294, 295, 673, 286, - 287, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 0, 0, 0, 0, 319, - 730, 731, 732, 733, 734, 0, 0, 320, 321, 322, - 0, 0, 284, 285, 312, 516, 313, 314, 315, 316, - 0, 0, 555, 556, 557, 580, 0, 558, 540, 604, - 398, 326, 520, 547, 740, 0, 0, 0, 0, 0, - 0, 0, 655, 666, 700, 0, 712, 713, 715, 717, - 716, 719, 513, 514, 727, 0, 0, 421, 341, 342, - 462, 463, 500, 0, 721, 722, 723, 720, 439, 499, - 521, 507, 0, 746, 595, 596, 747, 708, 327, 468, - 0, 0, 610, 644, 633, 718, 598, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 381, 0, 0, - 434, 648, 629, 640, 630, 474, 615, 616, 617, 624, - 393, 618, 748, 620, 590, 621, 591, 622, 623, 0, - 647, 597, 509, 450, 0, 664, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, - 0, 0, 0, 349, 256, 592, 714, 594, 593, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 352, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3288, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 510, 539, - 0, 552, 0, 418, 419, 0, 0, 0, 0, 0, - 0, 0, 334, 517, 536, 350, 504, 550, 355, 512, - 529, 345, 467, 501, 0, 0, 336, 534, 511, 447, - 335, 0, 494, 378, 395, 375, 465, 0, 0, 533, - 563, 374, 553, 0, 544, 338, 0, 543, 464, 530, - 535, 448, 441, 0, 337, 532, 446, 440, 425, 385, - 579, 426, 427, 399, 480, 438, 481, 400, 452, 451, - 453, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 0, 0, 0, 0, 574, 575, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 707, 0, 0, 711, 0, 546, 0, - 0, 0, 0, 0, 0, 515, 0, 0, 428, 0, - 0, 0, 564, 0, 497, 470, 750, 0, 0, 495, - 436, 531, 482, 537, 518, 545, 489, 483, 328, 519, - 377, 449, 346, 348, 739, 379, 382, 386, 387, 458, - 459, 476, 503, 522, 523, 524, 376, 360, 496, 361, - 396, 362, 329, 368, 366, 369, 505, 370, 331, 477, - 528, 0, 392, 492, 444, 332, 443, 478, 527, 526, - 347, 554, 561, 562, 652, 0, 567, 751, 752, 753, - 576, 0, 484, 343, 340, 0, 0, 0, 372, 479, - 356, 358, 359, 357, 473, 475, 581, 582, 583, 585, - 0, 586, 587, 0, 0, 0, 0, 588, 653, 669, - 637, 606, 569, 661, 603, 607, 608, 413, 414, 415, - 672, 0, 0, 0, 560, 429, 430, 0, 384, 383, - 445, 333, 0, 0, 422, 412, 485, 339, 380, 424, - 417, 431, 432, 433, 390, 323, 324, 745, 373, 466, - 674, 709, 710, 599, 0, 662, 600, 609, 365, 634, - 646, 645, 460, 559, 0, 657, 660, 589, 744, 0, - 654, 668, 749, 667, 741, 472, 0, 502, 665, 612, - 0, 658, 631, 632, 0, 659, 627, 663, 0, 601, - 0, 570, 573, 602, 687, 688, 689, 330, 572, 691, - 692, 693, 694, 695, 696, 697, 690, 542, 635, 611, - 638, 551, 614, 613, 0, 0, 649, 568, 650, 651, - 454, 455, 456, 457, 394, 675, 354, 571, 487, 488, - 0, 636, 0, 0, 0, 0, 0, 0, 0, 0, - 641, 642, 639, 754, 0, 698, 699, 0, 0, 565, - 566, 389, 0, 584, 397, 353, 471, 391, 549, 420, - 0, 577, 643, 578, 490, 491, 701, 706, 702, 703, - 705, 725, 461, 411, 416, 506, 423, 437, 493, 548, - 469, 498, 351, 538, 508, 442, 628, 656, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 310, - 311, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 683, 682, 681, 680, 679, - 678, 677, 676, 0, 0, 625, 525, 367, 317, 363, - 364, 371, 742, 738, 743, 726, 729, 728, 704, 0, - 325, 605, 435, 486, 388, 670, 671, 0, 724, 269, - 270, 271, 272, 273, 274, 275, 276, 318, 277, 278, - 279, 280, 281, 282, 283, 288, 289, 290, 291, 292, - 293, 294, 295, 673, 286, 287, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 0, 0, 0, 0, 319, 730, 731, 732, 733, 734, - 0, 0, 320, 321, 322, 0, 0, 284, 285, 312, - 516, 313, 314, 315, 316, 0, 0, 555, 556, 557, - 580, 0, 558, 540, 604, 398, 326, 520, 547, 740, - 0, 0, 0, 0, 0, 0, 0, 655, 666, 700, - 0, 712, 713, 715, 717, 716, 719, 513, 514, 727, - 0, 0, 421, 341, 342, 462, 463, 500, 0, 721, - 722, 723, 720, 439, 499, 521, 507, 0, 746, 595, - 596, 747, 708, 327, 468, 0, 0, 610, 644, 633, - 718, 598, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 381, 0, 0, 434, 648, 629, 640, 630, - 474, 615, 616, 617, 624, 393, 618, 748, 620, 590, - 621, 591, 622, 623, 0, 647, 597, 509, 450, 0, - 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2344, 2369, 0, 0, 0, + 0, 0, 0, 0, 0, 2357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 255, 0, 0, 3231, 0, 0, 0, 349, 256, - 592, 714, 594, 593, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 510, 539, 0, 552, 0, 418, 419, - 0, 0, 0, 0, 0, 0, 0, 334, 517, 536, - 350, 504, 550, 355, 512, 529, 345, 467, 501, 0, - 0, 336, 534, 511, 447, 335, 0, 494, 378, 395, - 375, 465, 0, 0, 533, 563, 374, 553, 0, 544, - 338, 0, 543, 464, 530, 535, 448, 441, 0, 337, - 532, 446, 440, 425, 385, 579, 426, 427, 399, 480, - 438, 481, 400, 452, 451, 453, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 0, 0, 0, 0, - 0, 574, 575, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 707, 0, - 0, 711, 0, 546, 0, 0, 0, 0, 0, 0, - 515, 0, 0, 428, 0, 0, 0, 564, 0, 497, - 470, 750, 0, 0, 495, 436, 531, 482, 537, 518, - 545, 489, 483, 328, 519, 377, 449, 346, 348, 739, - 379, 382, 386, 387, 458, 459, 476, 503, 522, 523, - 524, 376, 360, 496, 361, 396, 362, 329, 368, 366, - 369, 505, 370, 331, 477, 528, 0, 392, 492, 444, - 332, 443, 478, 527, 526, 347, 554, 561, 562, 652, - 0, 567, 751, 752, 753, 576, 0, 484, 343, 340, - 0, 0, 0, 372, 479, 356, 358, 359, 357, 473, - 475, 581, 582, 583, 585, 0, 586, 587, 0, 0, - 0, 0, 588, 653, 669, 637, 606, 569, 661, 603, - 607, 608, 413, 414, 415, 672, 0, 0, 0, 560, - 429, 430, 0, 384, 383, 445, 333, 0, 0, 422, - 412, 485, 339, 380, 424, 417, 431, 432, 433, 390, - 323, 324, 745, 373, 466, 674, 709, 710, 599, 0, - 662, 600, 609, 365, 634, 646, 645, 460, 559, 0, - 657, 660, 589, 744, 0, 654, 668, 749, 667, 741, - 472, 0, 502, 665, 612, 0, 658, 631, 632, 0, - 659, 627, 663, 0, 601, 0, 570, 573, 602, 687, - 688, 689, 330, 572, 691, 692, 693, 694, 695, 696, - 697, 690, 542, 635, 611, 638, 551, 614, 613, 0, - 0, 649, 568, 650, 651, 454, 455, 456, 457, 394, - 675, 354, 571, 487, 488, 0, 636, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 639, 754, 0, - 698, 699, 0, 0, 565, 566, 389, 0, 584, 397, - 353, 471, 391, 549, 420, 0, 577, 643, 578, 490, - 491, 701, 706, 702, 703, 705, 725, 461, 411, 416, - 506, 423, 437, 493, 548, 469, 498, 351, 538, 508, - 442, 628, 656, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 310, 311, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 683, 682, 681, 680, 679, 678, 677, 676, 0, 0, - 625, 525, 367, 317, 363, 364, 371, 742, 738, 743, - 726, 729, 728, 704, 0, 325, 605, 435, 486, 388, - 670, 671, 0, 724, 269, 270, 271, 272, 273, 274, - 275, 276, 318, 277, 278, 279, 280, 281, 282, 283, - 288, 289, 290, 291, 292, 293, 294, 295, 673, 286, - 287, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 0, 0, 0, 0, 319, - 730, 731, 732, 733, 734, 0, 0, 320, 321, 322, - 0, 0, 284, 285, 312, 516, 313, 314, 315, 316, - 0, 0, 555, 556, 557, 580, 0, 558, 540, 604, - 398, 326, 520, 547, 740, 0, 0, 0, 0, 0, - 0, 0, 655, 666, 700, 0, 712, 713, 715, 717, - 716, 719, 513, 514, 727, 0, 0, 421, 341, 342, - 462, 463, 500, 0, 721, 722, 723, 720, 439, 499, - 521, 507, 0, 746, 595, 596, 747, 708, 327, 468, - 0, 0, 610, 644, 633, 718, 598, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 381, 0, 0, - 434, 648, 629, 640, 630, 474, 615, 616, 617, 624, - 393, 618, 748, 620, 590, 621, 591, 622, 623, 0, - 647, 597, 509, 450, 0, 664, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, - 0, 0, 0, 349, 256, 592, 714, 594, 593, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 352, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2566, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 510, 539, - 0, 552, 0, 418, 419, 0, 0, 0, 0, 0, - 0, 0, 334, 517, 536, 350, 504, 550, 355, 512, - 529, 345, 467, 501, 0, 0, 336, 534, 511, 447, - 335, 0, 494, 378, 395, 375, 465, 0, 0, 533, - 563, 374, 553, 0, 544, 338, 0, 543, 464, 530, - 535, 448, 441, 0, 337, 532, 446, 440, 425, 385, - 579, 426, 427, 399, 480, 438, 481, 400, 452, 451, - 453, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 0, 0, 0, 0, 574, 575, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 707, 0, 0, 711, 0, 546, 0, - 0, 0, 0, 0, 0, 515, 0, 0, 428, 0, - 0, 0, 564, 0, 497, 470, 750, 0, 0, 495, - 436, 531, 482, 537, 518, 545, 489, 483, 328, 519, - 377, 449, 346, 348, 739, 379, 382, 386, 387, 458, - 459, 476, 503, 522, 523, 524, 376, 360, 496, 361, - 396, 362, 329, 368, 366, 369, 505, 370, 331, 477, - 528, 0, 392, 492, 444, 332, 443, 478, 527, 526, - 347, 554, 561, 562, 652, 0, 567, 751, 752, 753, - 576, 0, 484, 343, 340, 0, 0, 0, 372, 479, - 356, 358, 359, 357, 473, 475, 581, 582, 583, 585, - 0, 586, 587, 0, 0, 0, 0, 588, 653, 669, - 637, 606, 569, 661, 603, 607, 608, 413, 414, 415, - 672, 0, 0, 0, 560, 429, 430, 0, 384, 383, - 445, 333, 0, 0, 422, 412, 485, 339, 380, 424, - 417, 431, 432, 433, 390, 323, 324, 745, 373, 466, - 674, 709, 710, 599, 0, 662, 600, 609, 365, 634, - 646, 645, 460, 559, 0, 657, 660, 589, 744, 0, - 654, 668, 749, 667, 741, 472, 0, 502, 665, 612, - 0, 658, 631, 632, 0, 659, 627, 663, 0, 601, - 0, 570, 573, 602, 687, 688, 689, 330, 572, 691, - 692, 693, 694, 695, 696, 697, 690, 542, 635, 611, - 638, 551, 614, 613, 0, 0, 649, 568, 650, 651, - 454, 455, 456, 457, 394, 675, 354, 571, 487, 488, - 0, 636, 0, 0, 0, 0, 0, 0, 0, 0, - 641, 642, 639, 754, 0, 698, 699, 0, 0, 565, - 566, 389, 0, 584, 397, 353, 471, 391, 549, 420, - 0, 577, 643, 578, 490, 491, 701, 706, 702, 703, - 705, 725, 461, 411, 416, 506, 423, 437, 493, 548, - 469, 498, 351, 538, 508, 442, 628, 656, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 310, - 311, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 683, 682, 681, 680, 679, - 678, 677, 676, 0, 0, 625, 525, 367, 317, 363, - 364, 371, 742, 738, 743, 726, 729, 728, 704, 0, - 325, 605, 435, 486, 388, 670, 671, 0, 724, 269, - 270, 271, 272, 273, 274, 275, 276, 318, 277, 278, - 279, 280, 281, 282, 283, 288, 289, 290, 291, 292, - 293, 294, 295, 673, 286, 287, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 0, 0, 0, 0, 319, 730, 731, 732, 733, 734, - 0, 0, 320, 321, 322, 0, 0, 284, 285, 312, - 516, 313, 314, 315, 316, 0, 0, 555, 556, 557, - 580, 0, 558, 540, 604, 398, 326, 520, 547, 740, - 0, 0, 0, 0, 0, 0, 0, 655, 666, 700, - 0, 712, 713, 715, 717, 716, 719, 513, 514, 727, - 0, 0, 421, 341, 342, 462, 463, 500, 0, 721, - 722, 723, 720, 439, 499, 521, 507, 0, 746, 595, - 596, 747, 708, 327, 468, 0, 0, 610, 644, 633, - 718, 598, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 381, 0, 0, 434, 648, 629, 640, 630, - 474, 615, 616, 617, 624, 393, 618, 748, 620, 590, - 621, 591, 622, 623, 0, 647, 597, 509, 450, 0, - 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 255, 0, 0, 3081, 0, 0, 0, 349, 256, - 592, 714, 594, 593, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 510, 539, 0, 552, 0, 418, 419, - 0, 0, 0, 0, 0, 0, 0, 334, 517, 536, - 350, 504, 550, 355, 512, 529, 345, 467, 501, 0, - 0, 336, 534, 511, 447, 335, 0, 494, 378, 395, - 375, 465, 0, 0, 533, 563, 374, 553, 0, 544, - 338, 0, 543, 464, 530, 535, 448, 441, 0, 337, - 532, 446, 440, 425, 385, 579, 426, 427, 399, 480, - 438, 481, 400, 452, 451, 453, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 0, 0, 0, 0, - 0, 574, 575, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 707, 0, - 0, 711, 0, 546, 0, 0, 0, 0, 0, 0, - 515, 0, 0, 428, 0, 0, 0, 564, 0, 497, - 470, 750, 0, 0, 495, 436, 531, 482, 537, 518, - 545, 489, 483, 328, 519, 377, 449, 346, 348, 739, - 379, 382, 386, 387, 458, 459, 476, 503, 522, 523, - 524, 376, 360, 496, 361, 396, 362, 329, 368, 366, - 369, 505, 370, 331, 477, 528, 0, 392, 492, 444, - 332, 443, 478, 527, 526, 347, 554, 561, 562, 652, - 0, 567, 751, 752, 753, 576, 0, 484, 343, 340, - 0, 0, 0, 372, 479, 356, 358, 359, 357, 473, - 475, 581, 582, 583, 585, 0, 586, 587, 0, 0, - 0, 0, 588, 653, 669, 637, 606, 569, 661, 603, - 607, 608, 413, 414, 415, 672, 0, 0, 0, 560, - 429, 430, 0, 384, 383, 445, 333, 0, 0, 422, - 412, 485, 339, 380, 424, 417, 431, 432, 433, 390, - 323, 324, 745, 373, 466, 674, 709, 710, 599, 0, - 662, 600, 609, 365, 634, 646, 645, 460, 559, 0, - 657, 660, 589, 744, 0, 654, 668, 749, 667, 741, - 472, 0, 502, 665, 612, 0, 658, 631, 632, 0, - 659, 627, 663, 0, 601, 0, 570, 573, 602, 687, - 688, 689, 330, 572, 691, 692, 693, 694, 695, 696, - 697, 690, 542, 635, 611, 638, 551, 614, 613, 0, - 0, 649, 568, 650, 651, 454, 455, 456, 457, 394, - 675, 354, 571, 487, 488, 0, 636, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 639, 754, 0, - 698, 699, 0, 0, 565, 566, 389, 0, 584, 397, - 353, 471, 391, 549, 420, 0, 577, 643, 578, 490, - 491, 701, 706, 702, 703, 705, 725, 461, 411, 416, - 506, 423, 437, 493, 548, 469, 498, 351, 538, 508, - 442, 628, 656, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 310, 311, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 683, 682, 681, 680, 679, 678, 677, 676, 0, 0, - 625, 525, 367, 317, 363, 364, 371, 742, 738, 743, - 726, 729, 728, 704, 0, 325, 605, 435, 486, 388, - 670, 671, 0, 724, 269, 270, 271, 272, 273, 274, - 275, 276, 318, 277, 278, 279, 280, 281, 282, 283, - 288, 289, 290, 291, 292, 293, 294, 295, 673, 286, - 287, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 0, 0, 0, 0, 319, - 730, 731, 732, 733, 734, 0, 0, 320, 321, 322, - 0, 0, 284, 285, 312, 516, 313, 314, 315, 316, - 0, 0, 555, 556, 557, 580, 0, 558, 540, 604, - 398, 326, 520, 547, 740, 0, 0, 0, 0, 0, - 0, 0, 655, 666, 700, 0, 712, 713, 715, 717, - 716, 719, 513, 514, 727, 0, 0, 421, 341, 342, - 462, 463, 500, 0, 721, 722, 723, 720, 439, 499, - 521, 507, 0, 746, 595, 596, 747, 708, 327, 468, - 0, 0, 610, 644, 633, 718, 598, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 381, 0, 0, - 434, 648, 629, 640, 630, 474, 615, 616, 617, 624, - 393, 618, 748, 620, 590, 621, 591, 622, 623, 0, - 647, 597, 509, 450, 0, 664, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, - 0, 0, 0, 349, 256, 592, 714, 594, 593, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 352, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3028, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 510, 539, - 0, 552, 0, 418, 419, 0, 0, 0, 0, 0, - 0, 0, 334, 517, 536, 350, 504, 550, 355, 512, - 529, 345, 467, 501, 0, 0, 336, 534, 511, 447, - 335, 0, 494, 378, 395, 375, 465, 0, 0, 533, - 563, 374, 553, 0, 544, 338, 0, 543, 464, 530, - 535, 448, 441, 0, 337, 532, 446, 440, 425, 385, - 579, 426, 427, 399, 480, 438, 481, 400, 452, 451, - 453, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 0, 0, 0, 0, 574, 575, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 707, 0, 0, 711, 0, 546, 0, - 0, 0, 0, 0, 0, 515, 0, 0, 428, 0, - 0, 0, 564, 0, 497, 470, 750, 0, 0, 495, - 436, 531, 482, 537, 518, 545, 489, 483, 328, 519, - 377, 449, 346, 348, 739, 379, 382, 386, 387, 458, - 459, 476, 503, 522, 523, 524, 376, 360, 496, 361, - 396, 362, 329, 368, 366, 369, 505, 370, 331, 477, - 528, 0, 392, 492, 444, 332, 443, 478, 527, 526, - 347, 554, 561, 562, 652, 0, 567, 751, 752, 753, - 576, 0, 484, 343, 340, 0, 0, 0, 372, 479, - 356, 358, 359, 357, 473, 475, 581, 582, 583, 585, - 0, 586, 587, 0, 0, 0, 0, 588, 653, 669, - 637, 606, 569, 661, 603, 607, 608, 413, 414, 415, - 672, 0, 0, 0, 560, 429, 430, 0, 384, 383, - 445, 333, 0, 0, 422, 412, 485, 339, 380, 424, - 417, 431, 432, 433, 390, 323, 324, 745, 373, 466, - 674, 709, 710, 599, 0, 662, 600, 609, 365, 634, - 646, 645, 460, 559, 0, 657, 660, 589, 744, 0, - 654, 668, 749, 667, 741, 472, 0, 502, 665, 612, - 0, 658, 631, 632, 0, 659, 627, 663, 0, 601, - 0, 570, 573, 602, 687, 688, 689, 330, 572, 691, - 692, 693, 694, 695, 696, 697, 690, 542, 635, 611, - 638, 551, 614, 613, 0, 0, 649, 568, 650, 651, - 454, 455, 456, 457, 394, 675, 354, 571, 487, 488, - 0, 636, 0, 0, 0, 0, 0, 0, 0, 0, - 641, 642, 639, 754, 0, 698, 699, 0, 0, 565, - 566, 389, 0, 584, 397, 353, 471, 391, 549, 420, - 0, 577, 643, 578, 490, 491, 701, 706, 702, 703, - 705, 725, 461, 411, 416, 506, 423, 437, 493, 548, - 469, 498, 351, 538, 508, 442, 628, 656, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 310, - 311, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 683, 682, 681, 680, 679, - 678, 677, 676, 0, 0, 625, 525, 367, 317, 363, - 364, 371, 742, 738, 743, 726, 729, 728, 704, 0, - 325, 605, 435, 486, 388, 670, 671, 0, 724, 269, - 270, 271, 272, 273, 274, 275, 276, 318, 277, 278, - 279, 280, 281, 282, 283, 288, 289, 290, 291, 292, - 293, 294, 295, 673, 286, 287, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 0, 0, 0, 0, 319, 730, 731, 732, 733, 734, - 0, 0, 320, 321, 322, 0, 0, 284, 285, 312, - 516, 313, 314, 315, 316, 0, 0, 555, 556, 557, - 580, 0, 558, 540, 604, 398, 326, 520, 547, 740, - 0, 0, 0, 0, 0, 0, 0, 655, 666, 700, - 0, 712, 713, 715, 717, 716, 719, 513, 514, 727, - 0, 0, 421, 341, 342, 462, 463, 500, 0, 721, - 722, 723, 720, 439, 499, 521, 507, 0, 746, 595, - 596, 747, 708, 327, 468, 0, 0, 610, 644, 633, - 718, 598, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 381, 0, 0, 434, 648, 629, 640, 630, - 474, 615, 616, 617, 624, 393, 618, 748, 620, 590, - 621, 591, 622, 623, 0, 647, 597, 509, 450, 0, - 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 255, 0, 0, 3026, 0, 0, 0, 349, 256, - 592, 714, 594, 593, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 510, 539, 0, 552, 0, 418, 419, - 0, 0, 0, 0, 0, 0, 0, 334, 517, 536, - 350, 504, 550, 355, 512, 529, 345, 467, 501, 0, - 0, 336, 534, 511, 447, 335, 0, 494, 378, 395, - 375, 465, 0, 0, 533, 563, 374, 553, 0, 544, - 338, 0, 543, 464, 530, 535, 448, 441, 0, 337, - 532, 446, 440, 425, 385, 579, 426, 427, 399, 480, - 438, 481, 400, 452, 451, 453, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 0, 0, 0, 0, - 0, 574, 575, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 707, 0, - 0, 711, 0, 546, 0, 0, 0, 0, 0, 0, - 515, 0, 0, 428, 0, 0, 0, 564, 0, 497, - 470, 750, 0, 0, 495, 436, 531, 482, 537, 518, - 545, 489, 483, 328, 519, 377, 449, 346, 348, 739, - 379, 382, 386, 387, 458, 459, 476, 503, 522, 523, - 524, 376, 360, 496, 361, 396, 362, 329, 368, 366, - 369, 505, 370, 331, 477, 528, 0, 392, 492, 444, - 332, 443, 478, 527, 526, 347, 554, 561, 562, 652, - 0, 567, 751, 752, 753, 576, 0, 484, 343, 340, - 0, 0, 0, 372, 479, 356, 358, 359, 357, 473, - 475, 581, 582, 583, 585, 0, 586, 587, 0, 0, - 0, 0, 588, 653, 669, 637, 606, 569, 661, 603, - 607, 608, 413, 414, 415, 672, 0, 0, 0, 560, - 429, 430, 0, 384, 383, 445, 333, 0, 0, 422, - 412, 485, 339, 380, 424, 417, 431, 432, 433, 390, - 323, 324, 745, 373, 466, 674, 709, 710, 599, 0, - 662, 600, 609, 365, 634, 646, 645, 460, 559, 0, - 657, 660, 589, 744, 0, 654, 668, 749, 667, 741, - 472, 0, 502, 665, 612, 0, 658, 631, 632, 0, - 659, 627, 663, 0, 601, 0, 570, 573, 602, 687, - 688, 689, 330, 572, 691, 692, 693, 694, 695, 696, - 697, 690, 542, 635, 611, 638, 551, 614, 613, 0, - 0, 649, 568, 650, 651, 454, 455, 456, 457, 394, - 675, 354, 571, 487, 488, 0, 636, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 639, 754, 0, - 698, 699, 0, 0, 565, 566, 389, 0, 584, 397, - 353, 471, 391, 549, 420, 0, 577, 643, 578, 490, - 491, 701, 706, 702, 703, 705, 725, 461, 411, 416, - 506, 423, 437, 493, 548, 469, 498, 351, 538, 508, - 442, 628, 656, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 310, 311, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 683, 682, 681, 680, 679, 678, 677, 676, 0, 0, - 625, 525, 367, 317, 363, 364, 371, 742, 738, 743, - 726, 729, 728, 704, 0, 325, 605, 435, 486, 388, - 670, 671, 0, 724, 269, 270, 271, 272, 273, 274, - 275, 276, 318, 277, 278, 279, 280, 281, 282, 283, - 288, 289, 290, 291, 292, 293, 294, 295, 673, 286, - 287, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 0, 0, 0, 0, 319, - 730, 731, 732, 733, 734, 0, 0, 320, 321, 322, - 0, 0, 284, 285, 312, 516, 313, 314, 315, 316, - 0, 0, 555, 556, 557, 580, 0, 558, 540, 604, - 398, 326, 520, 547, 740, 0, 0, 0, 0, 0, - 0, 0, 655, 666, 700, 0, 712, 713, 715, 717, - 716, 719, 513, 514, 727, 0, 0, 421, 341, 342, - 462, 463, 500, 0, 721, 722, 723, 720, 439, 499, - 521, 507, 0, 746, 595, 596, 747, 708, 327, 2784, - 0, 0, 0, 0, 0, 468, 0, 0, 610, 644, - 633, 718, 598, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 381, 0, 0, 434, 648, 629, 640, - 630, 474, 615, 616, 617, 624, 393, 618, 748, 620, - 590, 621, 591, 622, 623, 0, 647, 597, 509, 450, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 0, 0, 0, 0, 0, 0, 349, - 256, 592, 714, 594, 593, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 510, 539, 0, 552, 0, 418, - 419, 0, 0, 0, 0, 0, 0, 0, 334, 517, - 536, 350, 504, 550, 355, 512, 529, 345, 467, 501, - 0, 0, 336, 534, 511, 447, 335, 0, 494, 378, - 395, 375, 465, 0, 0, 533, 563, 374, 553, 0, - 544, 338, 0, 543, 464, 530, 535, 448, 441, 0, - 337, 532, 446, 440, 425, 385, 579, 426, 427, 399, - 480, 438, 481, 400, 452, 451, 453, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 0, 0, - 0, 0, 574, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 707, - 0, 0, 711, 0, 546, 0, 0, 0, 0, 0, - 0, 515, 0, 0, 428, 0, 0, 0, 564, 0, - 497, 470, 750, 0, 0, 495, 436, 531, 482, 537, - 518, 545, 489, 483, 328, 519, 377, 449, 346, 348, - 739, 379, 382, 386, 387, 458, 459, 476, 503, 522, - 523, 524, 376, 360, 496, 361, 396, 362, 329, 368, - 366, 369, 505, 370, 331, 477, 528, 0, 392, 492, - 444, 332, 443, 478, 527, 526, 347, 554, 561, 562, - 652, 0, 567, 751, 752, 753, 576, 0, 484, 343, - 340, 0, 0, 0, 372, 479, 356, 358, 359, 357, - 473, 475, 581, 582, 583, 585, 0, 586, 587, 0, - 0, 0, 0, 588, 653, 669, 637, 606, 569, 661, - 603, 607, 608, 413, 414, 415, 672, 0, 0, 0, - 560, 429, 430, 0, 384, 383, 445, 333, 0, 0, - 422, 412, 485, 339, 380, 424, 417, 431, 432, 433, - 390, 323, 324, 745, 373, 466, 674, 709, 710, 599, - 0, 662, 600, 609, 365, 634, 646, 645, 460, 559, - 0, 657, 660, 589, 744, 0, 654, 668, 749, 667, - 741, 472, 0, 502, 665, 612, 0, 658, 631, 632, - 0, 659, 627, 663, 0, 601, 0, 570, 573, 602, - 687, 688, 689, 330, 572, 691, 692, 693, 694, 695, - 696, 697, 690, 542, 635, 611, 638, 551, 614, 613, - 0, 0, 649, 568, 650, 651, 454, 455, 456, 457, - 394, 675, 354, 571, 487, 488, 0, 636, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 639, 754, - 0, 698, 699, 0, 0, 565, 566, 389, 0, 584, - 397, 353, 471, 391, 549, 420, 0, 577, 643, 578, - 490, 491, 701, 706, 702, 703, 705, 725, 461, 411, - 416, 506, 423, 437, 493, 548, 469, 498, 351, 538, - 508, 442, 628, 656, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 310, 311, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 683, 682, 681, 680, 679, 678, 677, 676, 0, - 0, 625, 525, 367, 317, 363, 364, 371, 742, 738, - 743, 726, 729, 728, 704, 0, 325, 605, 435, 486, - 388, 670, 671, 0, 724, 269, 270, 271, 272, 273, - 274, 275, 276, 318, 277, 278, 279, 280, 281, 282, - 283, 288, 289, 290, 291, 292, 293, 294, 295, 673, - 286, 287, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 0, 0, 0, 0, - 319, 730, 731, 732, 733, 734, 0, 0, 320, 321, - 322, 0, 0, 284, 285, 312, 516, 313, 314, 315, - 316, 0, 0, 555, 556, 557, 580, 0, 558, 540, - 604, 398, 326, 520, 547, 740, 0, 0, 0, 0, - 0, 0, 0, 655, 666, 700, 0, 712, 713, 715, - 717, 716, 719, 513, 514, 727, 0, 0, 421, 341, - 342, 462, 463, 500, 0, 721, 722, 723, 720, 439, - 499, 521, 507, 0, 746, 595, 596, 747, 708, 327, - 468, 0, 0, 610, 644, 633, 718, 598, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 381, 0, - 0, 434, 648, 629, 640, 630, 474, 615, 616, 617, - 624, 393, 618, 748, 620, 590, 621, 591, 622, 623, - 0, 647, 597, 509, 450, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, - 0, 2239, 0, 0, 349, 256, 592, 714, 594, 593, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 510, - 539, 0, 552, 0, 418, 419, 0, 0, 0, 0, - 0, 0, 0, 334, 517, 536, 350, 504, 550, 355, - 512, 529, 345, 467, 501, 0, 0, 336, 534, 511, - 447, 335, 0, 494, 378, 395, 375, 465, 0, 0, - 533, 563, 374, 553, 0, 544, 338, 0, 543, 464, - 530, 535, 448, 441, 0, 337, 532, 446, 440, 425, - 385, 579, 426, 427, 399, 480, 438, 481, 400, 452, - 451, 453, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 0, 0, 0, 0, 0, 574, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 707, 0, 0, 711, 0, 546, - 0, 0, 0, 0, 0, 0, 515, 0, 0, 428, - 0, 0, 0, 564, 0, 497, 470, 750, 0, 0, - 495, 436, 531, 482, 537, 518, 545, 489, 483, 328, - 519, 377, 449, 346, 348, 739, 379, 382, 386, 387, - 458, 459, 476, 503, 522, 523, 524, 376, 360, 496, - 361, 396, 362, 329, 368, 366, 369, 505, 370, 331, - 477, 528, 0, 392, 492, 444, 332, 443, 478, 527, - 526, 347, 554, 561, 562, 652, 0, 567, 751, 752, - 753, 576, 0, 484, 343, 340, 0, 0, 0, 372, - 479, 356, 358, 359, 357, 473, 475, 581, 582, 583, - 585, 0, 586, 587, 0, 0, 0, 0, 588, 653, - 669, 637, 606, 569, 661, 603, 607, 608, 413, 414, - 415, 672, 0, 0, 0, 560, 429, 430, 0, 384, - 383, 445, 333, 0, 0, 422, 412, 485, 339, 380, - 424, 417, 431, 432, 433, 390, 323, 324, 745, 373, - 466, 674, 709, 710, 599, 0, 662, 600, 609, 365, - 634, 646, 645, 460, 559, 0, 657, 660, 589, 744, - 0, 654, 668, 749, 667, 741, 472, 0, 502, 665, - 612, 0, 658, 631, 632, 0, 659, 627, 663, 0, - 601, 0, 570, 573, 602, 687, 688, 689, 330, 572, - 691, 692, 693, 694, 695, 696, 697, 690, 542, 635, - 611, 638, 551, 614, 613, 0, 0, 649, 568, 650, - 651, 454, 455, 456, 457, 394, 675, 354, 571, 487, - 488, 0, 636, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 639, 754, 0, 698, 699, 0, 0, - 565, 566, 389, 0, 584, 397, 353, 471, 391, 549, - 420, 0, 577, 643, 578, 490, 491, 701, 706, 702, - 703, 705, 725, 461, 411, 416, 506, 423, 437, 493, - 548, 469, 498, 351, 538, 508, 442, 628, 656, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 310, 311, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 683, 682, 681, 680, - 679, 678, 677, 676, 0, 0, 625, 525, 367, 317, - 363, 364, 371, 742, 738, 743, 726, 729, 728, 704, - 0, 325, 605, 435, 486, 388, 670, 671, 0, 724, - 269, 270, 271, 272, 273, 274, 275, 276, 318, 277, - 278, 279, 280, 281, 282, 283, 288, 289, 290, 291, - 292, 293, 294, 295, 673, 286, 287, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 0, 0, 0, 0, 319, 730, 731, 732, 733, - 734, 0, 0, 320, 321, 322, 0, 0, 284, 285, - 312, 516, 313, 314, 315, 316, 0, 0, 555, 556, - 557, 580, 0, 558, 540, 604, 398, 326, 520, 547, - 740, 0, 0, 0, 0, 0, 0, 0, 655, 666, - 700, 0, 712, 713, 715, 717, 716, 719, 513, 514, - 727, 0, 0, 421, 341, 342, 462, 463, 500, 0, - 721, 722, 723, 720, 439, 499, 521, 507, 0, 746, - 595, 596, 747, 708, 327, 468, 0, 0, 610, 644, - 633, 718, 598, 0, 0, 1374, 0, 0, 0, 0, - 0, 0, 0, 381, 0, 0, 434, 648, 629, 640, - 630, 474, 615, 616, 617, 624, 393, 618, 748, 620, - 590, 621, 591, 622, 623, 0, 647, 597, 509, 450, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 0, 0, 0, 0, 0, 0, 349, - 256, 592, 714, 594, 593, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 510, 539, 0, 552, 0, 418, - 419, 0, 0, 0, 0, 0, 0, 0, 334, 517, - 536, 350, 504, 550, 355, 512, 529, 345, 467, 501, - 0, 0, 336, 534, 511, 447, 335, 0, 494, 378, - 395, 375, 465, 0, 0, 533, 563, 374, 553, 0, - 544, 338, 0, 543, 464, 530, 535, 448, 441, 0, - 337, 532, 446, 440, 425, 385, 579, 426, 427, 399, - 480, 438, 481, 400, 452, 451, 453, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 0, 0, - 0, 0, 574, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 707, - 0, 0, 711, 0, 546, 0, 0, 0, 0, 0, - 0, 515, 0, 0, 428, 0, 0, 0, 564, 0, - 497, 470, 750, 0, 0, 495, 436, 531, 482, 537, - 518, 545, 489, 483, 328, 519, 377, 449, 346, 348, - 739, 379, 382, 386, 387, 458, 459, 476, 503, 522, - 523, 524, 376, 360, 496, 361, 396, 362, 329, 368, - 366, 369, 505, 370, 331, 477, 528, 0, 392, 492, - 444, 332, 443, 478, 527, 526, 347, 554, 561, 562, - 652, 0, 567, 751, 752, 753, 576, 0, 484, 343, - 340, 0, 0, 0, 372, 479, 356, 358, 359, 357, - 473, 475, 581, 582, 583, 585, 0, 586, 587, 0, - 0, 0, 0, 588, 653, 669, 637, 606, 569, 661, - 603, 607, 608, 413, 414, 415, 672, 0, 0, 0, - 560, 429, 430, 0, 384, 383, 445, 333, 0, 0, - 422, 412, 485, 339, 380, 424, 417, 431, 432, 433, - 390, 323, 324, 745, 373, 466, 674, 709, 710, 599, - 0, 662, 600, 609, 365, 634, 646, 645, 460, 559, - 0, 657, 660, 589, 744, 0, 654, 668, 749, 667, - 741, 472, 0, 502, 665, 612, 0, 658, 631, 632, - 0, 659, 627, 663, 0, 601, 0, 570, 573, 602, - 687, 688, 689, 330, 572, 691, 692, 693, 694, 695, - 696, 697, 690, 542, 635, 611, 638, 551, 614, 613, - 0, 0, 649, 568, 650, 651, 454, 455, 456, 457, - 394, 675, 354, 571, 487, 488, 0, 636, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 639, 754, - 0, 698, 699, 0, 0, 565, 566, 389, 0, 584, - 397, 353, 471, 391, 549, 420, 0, 577, 643, 578, - 490, 491, 701, 706, 702, 703, 705, 725, 461, 411, - 416, 506, 423, 437, 493, 548, 469, 498, 351, 538, - 508, 442, 628, 656, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 310, 311, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 683, 682, 681, 680, 679, 678, 677, 676, 0, - 0, 625, 525, 367, 317, 363, 364, 371, 742, 738, - 743, 726, 729, 728, 2431, 0, 325, 605, 435, 486, - 388, 670, 671, 0, 724, 269, 270, 271, 272, 273, - 274, 275, 276, 318, 277, 278, 279, 280, 281, 282, - 283, 288, 289, 290, 291, 292, 293, 294, 295, 673, - 286, 287, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 0, 0, 0, 0, - 319, 730, 731, 732, 733, 734, 0, 0, 320, 321, - 322, 0, 0, 284, 285, 312, 516, 313, 314, 315, - 316, 0, 0, 555, 556, 557, 580, 0, 558, 540, - 604, 398, 326, 520, 547, 740, 0, 0, 0, 0, - 0, 0, 0, 655, 666, 700, 0, 712, 713, 715, - 717, 716, 719, 513, 514, 727, 0, 0, 421, 341, - 342, 462, 463, 500, 0, 721, 722, 723, 720, 439, - 499, 521, 507, 0, 746, 595, 596, 747, 708, 327, - 468, 0, 0, 610, 644, 633, 718, 598, 0, 2378, - 0, 0, 0, 0, 0, 0, 0, 0, 381, 0, - 0, 434, 648, 629, 640, 630, 474, 615, 616, 617, - 624, 393, 618, 748, 620, 590, 621, 591, 622, 623, - 0, 647, 597, 509, 450, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, - 0, 0, 0, 0, 349, 256, 592, 714, 594, 593, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 510, - 539, 0, 552, 0, 418, 419, 0, 0, 0, 0, - 0, 0, 0, 334, 517, 536, 350, 504, 550, 355, - 512, 529, 345, 467, 501, 0, 0, 336, 534, 511, - 447, 335, 0, 494, 378, 395, 375, 465, 0, 0, - 533, 563, 374, 553, 0, 544, 338, 0, 543, 464, - 530, 535, 448, 441, 0, 337, 532, 446, 440, 425, - 385, 579, 426, 427, 399, 480, 438, 481, 400, 452, - 451, 453, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 0, 0, 0, 0, 0, 574, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 707, 0, 0, 711, 0, 546, - 0, 0, 0, 0, 0, 0, 515, 0, 0, 428, - 0, 0, 0, 564, 0, 497, 470, 750, 0, 0, - 495, 436, 531, 482, 537, 518, 545, 489, 483, 328, - 519, 377, 449, 346, 348, 739, 379, 382, 386, 387, - 458, 459, 476, 503, 522, 523, 524, 376, 360, 496, - 361, 396, 362, 329, 368, 366, 369, 505, 370, 331, - 477, 528, 0, 392, 492, 444, 332, 443, 478, 527, - 526, 347, 554, 561, 562, 652, 0, 567, 751, 752, - 753, 576, 0, 484, 343, 340, 0, 0, 0, 372, - 479, 356, 358, 359, 357, 473, 475, 581, 582, 583, - 585, 0, 586, 587, 0, 0, 0, 0, 588, 653, - 669, 637, 606, 569, 661, 603, 607, 608, 413, 414, - 415, 672, 0, 0, 0, 560, 429, 430, 0, 384, - 383, 445, 333, 0, 0, 422, 412, 485, 339, 380, - 424, 417, 431, 432, 433, 390, 323, 324, 745, 373, - 466, 674, 709, 710, 599, 0, 662, 600, 609, 365, - 634, 646, 645, 460, 559, 0, 657, 660, 589, 744, - 0, 654, 668, 749, 667, 741, 472, 0, 502, 665, - 612, 0, 658, 631, 632, 0, 659, 627, 663, 0, - 601, 0, 570, 573, 602, 687, 688, 689, 330, 572, - 691, 692, 693, 694, 695, 696, 697, 690, 542, 635, - 611, 638, 551, 614, 613, 0, 0, 649, 568, 650, - 651, 454, 455, 456, 457, 394, 675, 354, 571, 487, - 488, 0, 636, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 639, 754, 0, 698, 699, 0, 0, - 565, 566, 389, 0, 584, 397, 353, 471, 391, 549, - 420, 0, 577, 643, 578, 490, 491, 701, 706, 702, - 703, 705, 725, 461, 411, 416, 506, 423, 437, 493, - 548, 469, 498, 351, 538, 508, 442, 628, 656, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 310, 311, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 683, 682, 681, 680, - 679, 678, 677, 676, 0, 0, 625, 525, 367, 317, - 363, 364, 371, 742, 738, 743, 726, 729, 728, 704, - 0, 325, 605, 435, 486, 388, 670, 671, 0, 724, - 269, 270, 271, 272, 273, 274, 275, 276, 318, 277, - 278, 279, 280, 281, 282, 283, 288, 289, 290, 291, - 292, 293, 294, 295, 673, 286, 287, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 0, 0, 0, 0, 319, 730, 731, 732, 733, - 734, 0, 0, 320, 321, 322, 0, 0, 284, 285, - 312, 516, 313, 314, 315, 316, 0, 0, 555, 556, - 557, 580, 0, 558, 540, 604, 398, 326, 520, 547, - 740, 0, 0, 0, 0, 0, 0, 0, 655, 666, - 700, 0, 712, 713, 715, 717, 716, 719, 513, 514, - 727, 0, 0, 421, 341, 342, 462, 463, 500, 0, - 721, 722, 723, 720, 439, 499, 521, 507, 0, 746, - 595, 596, 747, 708, 327, 468, 0, 0, 610, 644, - 633, 718, 598, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 381, 0, 0, 434, 648, 629, 640, - 630, 474, 615, 616, 617, 624, 393, 618, 748, 620, - 590, 621, 591, 622, 623, 0, 647, 597, 509, 450, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 0, 0, 1775, 0, 0, 0, 349, - 256, 592, 714, 594, 593, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 510, 539, 0, 552, 0, 418, - 419, 0, 0, 0, 0, 0, 0, 0, 334, 517, - 536, 350, 504, 550, 355, 512, 529, 345, 467, 501, - 0, 0, 336, 534, 511, 447, 335, 0, 494, 378, - 395, 375, 465, 0, 0, 533, 563, 374, 553, 0, - 544, 338, 0, 543, 464, 530, 535, 448, 441, 0, - 337, 532, 446, 440, 425, 385, 579, 426, 427, 399, - 480, 438, 481, 400, 452, 451, 453, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 0, 0, - 0, 0, 574, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 707, - 0, 0, 711, 0, 546, 0, 0, 0, 0, 0, - 0, 515, 0, 0, 428, 0, 0, 0, 564, 0, - 497, 470, 750, 0, 0, 495, 436, 531, 482, 537, - 518, 545, 1945, 483, 328, 519, 377, 449, 346, 348, - 739, 379, 382, 386, 387, 458, 459, 476, 503, 522, - 523, 524, 376, 360, 496, 361, 396, 362, 329, 368, - 366, 369, 505, 370, 331, 477, 528, 0, 392, 492, - 444, 332, 443, 478, 527, 526, 347, 554, 561, 562, - 652, 0, 567, 751, 752, 753, 576, 0, 484, 343, - 340, 0, 0, 0, 372, 479, 356, 358, 359, 357, - 473, 475, 581, 582, 583, 585, 0, 586, 587, 0, - 0, 0, 0, 588, 653, 669, 637, 606, 569, 661, - 603, 607, 608, 413, 414, 415, 672, 0, 0, 0, - 560, 429, 430, 0, 384, 383, 445, 333, 0, 0, - 422, 412, 485, 339, 380, 424, 417, 431, 432, 433, - 390, 323, 324, 745, 373, 466, 674, 709, 710, 599, - 0, 662, 600, 609, 365, 634, 646, 645, 460, 559, - 0, 657, 660, 589, 744, 0, 654, 668, 749, 667, - 741, 472, 0, 502, 665, 612, 0, 658, 631, 632, - 0, 659, 627, 663, 0, 601, 0, 570, 573, 602, - 687, 688, 689, 330, 572, 691, 692, 693, 694, 695, - 696, 697, 690, 542, 635, 611, 638, 551, 614, 613, - 0, 0, 649, 568, 650, 651, 454, 455, 456, 457, - 394, 675, 354, 571, 487, 488, 0, 636, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 639, 754, - 0, 698, 699, 0, 0, 565, 566, 389, 0, 584, - 397, 353, 471, 391, 549, 420, 0, 577, 643, 578, - 490, 491, 701, 706, 702, 703, 705, 725, 461, 411, - 416, 506, 423, 437, 493, 548, 469, 498, 351, 538, - 508, 442, 628, 656, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 310, 311, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 683, 682, 681, 680, 679, 678, 677, 676, 0, - 0, 625, 525, 367, 317, 363, 364, 371, 742, 738, - 743, 726, 729, 728, 704, 0, 325, 605, 435, 486, - 388, 670, 671, 0, 724, 269, 270, 271, 272, 273, - 274, 275, 276, 318, 277, 278, 279, 280, 281, 282, - 283, 288, 289, 290, 291, 292, 293, 294, 295, 673, - 286, 287, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 0, 0, 0, 0, - 319, 730, 731, 732, 733, 734, 0, 0, 320, 321, - 322, 0, 0, 284, 285, 312, 516, 313, 314, 315, - 316, 0, 0, 555, 556, 557, 580, 0, 558, 540, - 604, 398, 326, 520, 547, 740, 0, 0, 0, 0, - 0, 0, 0, 655, 666, 700, 0, 712, 713, 715, - 717, 716, 719, 513, 514, 727, 0, 0, 421, 341, - 342, 462, 463, 500, 0, 721, 722, 723, 720, 439, - 499, 521, 507, 0, 746, 595, 596, 747, 708, 327, - 468, 0, 0, 610, 644, 633, 718, 598, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 381, 0, - 0, 434, 648, 629, 640, 630, 474, 615, 616, 617, - 624, 393, 618, 748, 620, 590, 621, 591, 622, 623, - 0, 647, 597, 509, 450, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, - 0, 0, 0, 0, 349, 256, 592, 714, 594, 593, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 510, - 539, 0, 552, 0, 418, 419, 0, 0, 0, 0, - 0, 0, 0, 334, 517, 536, 350, 504, 550, 355, - 512, 529, 345, 467, 501, 0, 0, 336, 534, 511, - 447, 335, 0, 494, 378, 395, 375, 465, 0, 0, - 533, 563, 374, 553, 0, 544, 338, 0, 543, 464, - 530, 535, 448, 441, 0, 337, 532, 446, 440, 425, - 385, 579, 426, 427, 399, 480, 438, 481, 400, 452, - 451, 453, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 0, 0, 0, 0, 0, 574, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 707, 0, 0, 711, 0, 546, - 0, 0, 1806, 0, 0, 0, 515, 0, 0, 428, - 0, 0, 0, 564, 0, 497, 470, 750, 0, 0, - 495, 436, 531, 482, 537, 518, 545, 489, 483, 328, - 519, 377, 449, 346, 348, 739, 379, 382, 386, 387, - 458, 459, 476, 503, 522, 523, 524, 376, 360, 496, - 361, 396, 362, 329, 368, 366, 369, 505, 370, 331, - 477, 528, 0, 392, 492, 444, 332, 443, 478, 527, - 526, 347, 554, 561, 562, 652, 0, 567, 751, 752, - 753, 576, 0, 484, 343, 340, 0, 0, 0, 372, - 479, 356, 358, 359, 357, 473, 475, 581, 582, 583, - 585, 0, 586, 587, 0, 0, 0, 0, 588, 653, - 669, 637, 606, 569, 661, 603, 607, 608, 413, 414, - 415, 672, 0, 0, 0, 560, 429, 430, 0, 384, - 383, 445, 333, 0, 0, 422, 412, 485, 339, 380, - 424, 417, 431, 432, 433, 390, 323, 324, 745, 373, - 466, 674, 709, 710, 599, 0, 662, 600, 609, 365, - 634, 646, 645, 460, 559, 0, 657, 660, 589, 744, - 0, 654, 668, 749, 667, 741, 472, 0, 502, 665, - 612, 0, 658, 631, 632, 0, 659, 627, 663, 0, - 601, 0, 570, 573, 602, 687, 688, 689, 330, 572, - 691, 692, 693, 694, 695, 696, 697, 690, 542, 635, - 611, 638, 551, 614, 613, 0, 0, 649, 568, 650, - 651, 454, 455, 456, 457, 394, 675, 354, 571, 487, - 488, 0, 636, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 639, 754, 0, 698, 699, 0, 0, - 565, 566, 389, 0, 584, 397, 353, 471, 391, 549, - 420, 0, 577, 643, 578, 490, 491, 701, 706, 702, - 703, 705, 725, 461, 411, 416, 506, 423, 437, 493, - 548, 469, 498, 351, 538, 508, 442, 628, 656, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 310, 311, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 683, 682, 681, 680, - 679, 678, 677, 676, 0, 0, 625, 525, 367, 317, - 363, 364, 371, 742, 738, 743, 726, 729, 728, 704, - 0, 325, 605, 435, 486, 388, 670, 671, 0, 724, - 269, 270, 271, 272, 273, 274, 275, 276, 318, 277, - 278, 279, 280, 281, 282, 283, 288, 289, 290, 291, - 292, 293, 294, 295, 673, 286, 287, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 0, 0, 0, 0, 319, 730, 731, 732, 733, - 734, 0, 0, 320, 321, 322, 0, 0, 284, 285, - 312, 516, 313, 314, 315, 316, 0, 0, 555, 556, - 557, 580, 0, 558, 540, 604, 398, 326, 520, 547, - 740, 0, 0, 0, 0, 0, 0, 0, 655, 666, - 700, 0, 712, 713, 715, 717, 716, 719, 513, 514, - 727, 0, 0, 421, 341, 342, 462, 463, 500, 0, - 721, 722, 723, 720, 439, 499, 521, 507, 0, 746, - 595, 596, 747, 708, 327, 468, 0, 0, 610, 644, - 633, 718, 598, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1150, 381, 0, 0, 434, 648, 629, 640, - 630, 474, 615, 616, 617, 624, 393, 618, 748, 620, - 590, 621, 591, 622, 623, 0, 647, 597, 509, 450, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 0, 0, 0, 0, 0, 0, 349, - 256, 592, 714, 594, 593, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 510, 539, 0, 552, 0, 418, - 419, 0, 0, 0, 0, 0, 0, 0, 334, 517, - 536, 350, 504, 550, 355, 512, 529, 345, 467, 501, - 0, 0, 336, 534, 511, 447, 335, 0, 494, 378, - 395, 375, 465, 0, 0, 533, 563, 374, 553, 0, - 544, 338, 0, 543, 464, 530, 535, 448, 441, 0, - 337, 532, 446, 440, 425, 385, 579, 426, 427, 399, - 480, 438, 481, 400, 452, 451, 453, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 0, 0, - 0, 0, 574, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 707, - 0, 0, 711, 0, 546, 0, 0, 0, 0, 0, - 0, 515, 0, 0, 428, 0, 0, 0, 564, 0, - 497, 470, 750, 0, 0, 495, 436, 531, 482, 537, - 518, 545, 489, 483, 328, 519, 377, 449, 346, 348, - 739, 379, 382, 386, 387, 458, 459, 476, 503, 522, - 523, 524, 376, 360, 496, 361, 396, 362, 329, 368, - 366, 369, 505, 370, 331, 477, 528, 0, 392, 492, - 444, 332, 443, 478, 527, 526, 347, 554, 561, 562, - 652, 0, 567, 751, 752, 753, 576, 0, 484, 343, - 340, 0, 0, 0, 372, 479, 356, 358, 359, 357, - 473, 475, 581, 582, 583, 585, 0, 586, 587, 0, - 0, 0, 0, 588, 653, 669, 637, 606, 569, 661, - 603, 607, 608, 413, 414, 415, 672, 0, 0, 0, - 560, 429, 430, 0, 384, 383, 445, 333, 0, 0, - 422, 412, 485, 339, 380, 424, 417, 431, 432, 433, - 390, 323, 324, 745, 373, 466, 674, 709, 710, 599, - 0, 662, 600, 609, 365, 634, 646, 645, 460, 559, - 0, 657, 660, 589, 744, 0, 654, 668, 749, 667, - 741, 472, 0, 502, 665, 612, 0, 658, 631, 632, - 0, 659, 627, 663, 0, 601, 0, 570, 573, 602, - 687, 688, 689, 330, 572, 691, 692, 693, 694, 695, - 696, 697, 690, 542, 635, 611, 638, 551, 614, 613, - 0, 0, 649, 568, 650, 651, 454, 455, 456, 457, - 394, 675, 354, 571, 487, 488, 0, 636, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 639, 754, - 0, 698, 699, 0, 0, 565, 566, 389, 0, 584, - 397, 353, 471, 391, 549, 420, 0, 577, 643, 578, - 490, 491, 701, 706, 702, 703, 705, 725, 461, 411, - 416, 506, 423, 437, 493, 548, 469, 498, 351, 538, - 508, 442, 628, 656, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 310, 311, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 683, 682, 681, 680, 679, 678, 677, 676, 0, - 0, 625, 525, 367, 317, 363, 364, 371, 742, 738, - 743, 726, 729, 728, 704, 0, 325, 605, 435, 486, - 388, 670, 671, 0, 724, 269, 270, 271, 272, 273, - 274, 275, 276, 318, 277, 278, 279, 280, 281, 282, - 283, 288, 289, 290, 291, 292, 293, 294, 295, 673, - 286, 287, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 0, 0, 0, 0, - 319, 730, 731, 732, 733, 734, 0, 0, 320, 321, - 322, 0, 0, 284, 285, 312, 516, 313, 314, 315, - 316, 0, 0, 555, 556, 557, 580, 0, 558, 540, - 604, 398, 326, 520, 547, 740, 0, 0, 0, 0, - 0, 0, 0, 655, 666, 700, 0, 712, 713, 715, - 717, 716, 719, 513, 514, 727, 0, 0, 421, 341, - 342, 462, 463, 500, 0, 721, 722, 723, 720, 439, - 499, 521, 507, 0, 746, 595, 596, 747, 708, 327, - 468, 0, 0, 610, 644, 633, 718, 598, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 381, 0, - 0, 434, 648, 629, 640, 630, 474, 615, 616, 617, - 624, 393, 618, 748, 620, 590, 621, 591, 622, 623, - 0, 647, 597, 509, 450, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, - 0, 0, 0, 0, 349, 256, 592, 714, 594, 593, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 510, - 539, 0, 552, 0, 418, 419, 0, 0, 0, 0, - 0, 0, 0, 334, 517, 536, 350, 504, 550, 355, - 512, 529, 345, 467, 501, 0, 0, 336, 534, 511, - 447, 335, 0, 494, 378, 395, 375, 465, 0, 0, - 533, 563, 374, 553, 0, 544, 338, 0, 543, 464, - 530, 535, 448, 441, 0, 337, 532, 446, 440, 425, - 385, 579, 426, 427, 399, 480, 438, 481, 400, 452, - 451, 453, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 0, 0, 0, 0, 0, 574, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 707, 0, 771, 711, 0, 546, - 0, 0, 0, 0, 0, 0, 515, 0, 0, 428, - 0, 0, 0, 564, 0, 497, 470, 750, 0, 0, - 495, 436, 531, 482, 537, 518, 545, 489, 483, 328, - 519, 377, 449, 346, 348, 739, 379, 382, 386, 387, - 458, 459, 476, 503, 522, 523, 524, 376, 360, 496, - 361, 396, 362, 329, 368, 366, 369, 505, 370, 331, - 477, 528, 0, 392, 492, 444, 332, 443, 478, 527, - 526, 347, 554, 561, 562, 652, 0, 567, 751, 752, - 753, 576, 0, 484, 343, 340, 0, 0, 0, 372, - 479, 356, 358, 359, 357, 473, 475, 581, 582, 583, - 585, 0, 586, 587, 0, 0, 0, 0, 588, 653, - 669, 637, 606, 569, 661, 603, 607, 608, 413, 414, - 415, 672, 0, 0, 0, 560, 429, 430, 0, 384, - 383, 445, 333, 0, 0, 422, 412, 485, 339, 380, - 424, 417, 431, 432, 433, 390, 323, 324, 745, 373, - 466, 674, 709, 710, 599, 0, 662, 600, 609, 365, - 634, 646, 645, 460, 559, 0, 657, 660, 589, 744, - 0, 654, 668, 749, 667, 741, 472, 0, 502, 665, - 612, 0, 658, 631, 632, 0, 659, 627, 663, 0, - 601, 0, 570, 573, 602, 687, 688, 689, 330, 572, - 691, 692, 693, 694, 695, 696, 697, 690, 542, 635, - 611, 638, 551, 614, 613, 0, 0, 649, 568, 650, - 651, 454, 455, 456, 457, 394, 675, 354, 571, 487, - 488, 0, 636, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 639, 754, 0, 698, 699, 0, 0, - 565, 566, 389, 0, 584, 397, 353, 471, 391, 549, - 420, 0, 577, 643, 578, 490, 491, 701, 706, 702, - 703, 705, 725, 461, 411, 416, 506, 423, 437, 493, - 548, 469, 498, 351, 538, 508, 442, 628, 656, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 310, 311, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 683, 682, 681, 680, - 679, 678, 677, 676, 0, 0, 625, 525, 367, 317, - 363, 364, 371, 742, 738, 743, 726, 729, 728, 704, - 0, 325, 605, 435, 486, 388, 670, 671, 0, 724, - 269, 270, 271, 272, 273, 274, 275, 276, 318, 277, - 278, 279, 280, 281, 282, 283, 288, 289, 290, 291, - 292, 293, 294, 295, 673, 286, 287, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 0, 0, 0, 0, 319, 730, 731, 732, 733, - 734, 0, 0, 320, 321, 322, 0, 0, 284, 285, - 312, 516, 313, 314, 315, 316, 0, 0, 555, 556, - 557, 580, 0, 558, 540, 604, 398, 326, 520, 547, - 740, 0, 0, 0, 0, 0, 0, 0, 655, 666, - 700, 0, 712, 713, 715, 717, 716, 719, 513, 514, - 727, 0, 0, 421, 341, 342, 462, 463, 500, 0, - 721, 722, 723, 720, 439, 499, 521, 507, 0, 746, - 595, 596, 747, 708, 327, 468, 0, 0, 610, 644, - 633, 718, 598, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 381, 0, 0, 434, 648, 629, 640, - 630, 474, 615, 616, 617, 624, 393, 618, 748, 620, - 590, 621, 591, 622, 623, 0, 647, 597, 509, 450, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 0, 0, 0, 0, 0, 0, 349, - 256, 592, 714, 594, 593, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 510, 539, 0, 552, 0, 418, - 419, 0, 0, 0, 0, 0, 0, 0, 334, 517, - 536, 350, 504, 550, 355, 512, 529, 345, 467, 501, - 0, 0, 336, 534, 511, 447, 335, 0, 494, 378, - 395, 375, 465, 0, 0, 533, 563, 374, 553, 0, - 544, 338, 0, 543, 464, 530, 535, 448, 441, 0, - 337, 532, 446, 440, 425, 385, 579, 426, 427, 399, - 480, 438, 481, 400, 452, 451, 453, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 0, 0, - 0, 0, 574, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 707, - 0, 0, 711, 0, 546, 0, 0, 0, 0, 0, - 0, 515, 0, 0, 428, 0, 0, 0, 564, 0, - 497, 470, 750, 0, 0, 495, 436, 531, 482, 537, - 518, 545, 489, 483, 328, 519, 377, 449, 346, 348, - 739, 379, 382, 386, 387, 458, 459, 476, 503, 522, - 523, 524, 376, 360, 496, 361, 396, 362, 329, 368, - 366, 369, 505, 370, 331, 477, 528, 0, 392, 492, - 444, 332, 443, 478, 527, 526, 347, 554, 561, 562, - 652, 0, 567, 751, 752, 753, 576, 0, 484, 343, - 340, 0, 0, 0, 372, 479, 356, 358, 359, 357, - 473, 475, 581, 582, 583, 585, 0, 586, 587, 0, - 0, 0, 0, 588, 653, 669, 637, 606, 569, 661, - 603, 607, 608, 413, 414, 415, 672, 0, 0, 0, - 560, 429, 430, 0, 384, 383, 445, 333, 0, 0, - 422, 412, 485, 339, 380, 424, 417, 431, 432, 433, - 390, 323, 324, 745, 373, 466, 674, 709, 710, 599, - 0, 662, 600, 609, 365, 634, 646, 645, 460, 559, - 0, 657, 660, 589, 744, 0, 654, 668, 749, 667, - 741, 472, 0, 502, 665, 612, 0, 658, 631, 632, - 0, 659, 627, 663, 0, 601, 0, 570, 573, 602, - 687, 688, 689, 330, 572, 691, 692, 693, 694, 695, - 696, 697, 690, 542, 635, 611, 638, 551, 614, 613, - 0, 0, 649, 568, 650, 651, 454, 455, 456, 457, - 394, 675, 354, 571, 487, 488, 0, 636, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 639, 754, - 0, 698, 699, 0, 0, 565, 566, 389, 0, 584, - 397, 353, 471, 391, 549, 420, 0, 577, 643, 578, - 490, 491, 701, 706, 702, 703, 705, 725, 461, 411, - 416, 506, 423, 437, 493, 548, 469, 498, 351, 538, - 508, 442, 628, 656, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 310, 311, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 683, 682, 681, 680, 679, 678, 677, 676, 1153, - 0, 625, 525, 367, 317, 363, 364, 371, 742, 738, - 743, 726, 729, 728, 704, 0, 325, 605, 435, 486, - 388, 670, 671, 0, 724, 269, 270, 271, 272, 273, - 274, 275, 276, 318, 277, 278, 279, 280, 281, 282, - 283, 288, 289, 290, 291, 292, 293, 294, 295, 673, - 286, 287, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 0, 0, 0, 0, - 319, 730, 731, 732, 733, 734, 0, 0, 320, 321, - 322, 0, 0, 284, 285, 312, 516, 313, 314, 315, - 316, 0, 0, 555, 556, 557, 580, 0, 558, 540, - 604, 398, 326, 520, 547, 740, 0, 0, 0, 0, - 0, 0, 0, 655, 666, 700, 0, 712, 713, 715, - 717, 716, 719, 513, 514, 727, 0, 0, 421, 341, - 342, 462, 463, 500, 0, 721, 722, 723, 720, 439, - 499, 521, 507, 0, 746, 595, 596, 747, 708, 327, - 468, 0, 0, 610, 644, 633, 718, 598, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 381, 0, - 0, 434, 648, 629, 640, 630, 474, 615, 616, 617, - 624, 393, 618, 748, 620, 590, 621, 591, 622, 623, - 0, 647, 597, 509, 450, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, - 0, 0, 0, 0, 349, 256, 592, 714, 594, 593, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 510, - 539, 0, 552, 0, 418, 419, 0, 0, 0, 0, - 0, 0, 0, 334, 517, 536, 350, 504, 550, 355, - 512, 529, 345, 467, 501, 0, 0, 336, 534, 511, - 447, 335, 0, 494, 378, 395, 375, 465, 0, 0, - 533, 563, 374, 553, 0, 544, 338, 0, 543, 464, - 530, 535, 448, 441, 0, 337, 532, 446, 440, 425, - 385, 579, 426, 427, 399, 480, 438, 481, 400, 452, - 451, 453, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 0, 0, 0, 0, 0, 574, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 707, 0, 0, 711, 0, 546, - 0, 0, 0, 0, 0, 0, 515, 0, 0, 428, - 0, 0, 0, 564, 0, 497, 470, 750, 0, 0, - 495, 436, 531, 482, 537, 518, 545, 489, 483, 328, - 519, 377, 449, 346, 348, 739, 379, 382, 386, 387, - 458, 459, 476, 503, 522, 523, 524, 376, 360, 496, - 361, 396, 362, 329, 368, 366, 369, 505, 370, 331, - 477, 528, 0, 392, 492, 444, 332, 443, 478, 527, - 526, 347, 554, 561, 562, 652, 0, 567, 751, 752, - 753, 576, 0, 484, 343, 340, 0, 0, 0, 372, - 479, 356, 358, 359, 357, 473, 475, 581, 582, 583, - 585, 0, 586, 587, 0, 0, 0, 0, 588, 653, - 669, 637, 606, 569, 661, 603, 607, 608, 413, 414, - 415, 672, 0, 0, 0, 560, 429, 430, 0, 384, - 383, 445, 333, 0, 0, 422, 412, 485, 339, 380, - 424, 417, 431, 432, 433, 390, 323, 324, 745, 373, - 466, 674, 709, 710, 599, 0, 662, 600, 609, 365, - 634, 646, 645, 460, 559, 0, 657, 660, 589, 744, - 0, 654, 668, 749, 667, 741, 472, 0, 502, 665, - 612, 0, 658, 631, 632, 0, 659, 627, 663, 0, - 601, 0, 570, 573, 602, 687, 688, 689, 330, 572, - 691, 692, 693, 694, 695, 696, 697, 690, 542, 635, - 611, 638, 551, 614, 613, 0, 0, 649, 568, 650, - 651, 454, 455, 456, 457, 394, 675, 354, 571, 487, - 488, 0, 636, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 639, 754, 0, 698, 699, 0, 0, - 565, 566, 389, 0, 584, 397, 353, 471, 391, 549, - 420, 0, 577, 643, 578, 490, 491, 701, 706, 702, - 703, 705, 725, 461, 411, 416, 506, 423, 437, 493, - 548, 469, 498, 351, 538, 508, 442, 628, 656, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 310, 311, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 683, 682, 681, 680, - 679, 678, 677, 676, 0, 0, 625, 525, 367, 317, - 363, 364, 371, 742, 738, 743, 726, 729, 728, 704, - 0, 325, 605, 435, 486, 388, 670, 671, 0, 724, - 269, 270, 271, 272, 273, 274, 275, 276, 318, 277, - 278, 279, 280, 281, 282, 283, 288, 289, 290, 291, - 292, 293, 294, 295, 673, 286, 287, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 0, 0, 0, 0, 319, 730, 731, 732, 733, - 734, 0, 0, 320, 321, 322, 0, 0, 284, 285, - 312, 516, 313, 314, 315, 316, 0, 0, 555, 556, - 557, 580, 0, 558, 540, 604, 398, 326, 520, 547, - 740, 0, 0, 0, 0, 0, 0, 0, 655, 666, - 700, 0, 712, 713, 715, 717, 716, 719, 513, 514, - 727, 0, 0, 421, 341, 342, 462, 463, 500, 0, - 721, 722, 723, 720, 439, 499, 521, 507, 0, 746, - 595, 596, 747, 708, 327, 468, 0, 0, 610, 644, - 633, 718, 598, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 381, 0, 0, 434, 648, 629, 640, - 630, 474, 615, 616, 617, 624, 393, 618, 748, 620, - 590, 621, 591, 622, 623, 0, 647, 597, 509, 450, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 0, 0, 0, 0, 0, 0, 349, - 256, 592, 714, 594, 593, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 510, 539, 0, 552, 0, 418, - 419, 0, 0, 0, 0, 0, 0, 0, 334, 517, - 536, 350, 504, 550, 355, 512, 529, 345, 467, 501, - 0, 0, 336, 534, 511, 447, 335, 0, 494, 378, - 395, 375, 465, 0, 0, 533, 563, 374, 553, 0, - 544, 338, 0, 543, 464, 530, 535, 448, 441, 0, - 337, 532, 446, 440, 425, 385, 579, 426, 427, 399, - 480, 438, 481, 400, 452, 451, 453, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 0, 0, - 0, 0, 574, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 707, - 0, 0, 711, 0, 546, 0, 0, 0, 0, 0, - 0, 515, 0, 0, 428, 0, 0, 0, 564, 0, - 497, 470, 750, 0, 0, 495, 436, 531, 482, 537, - 518, 545, 489, 483, 328, 519, 377, 449, 346, 348, - 739, 379, 382, 386, 387, 458, 459, 476, 503, 522, - 523, 524, 376, 360, 496, 361, 396, 362, 329, 368, - 366, 369, 505, 370, 331, 477, 528, 0, 392, 3693, - 444, 332, 443, 478, 527, 526, 347, 554, 561, 562, - 652, 0, 567, 751, 752, 753, 576, 0, 484, 343, - 340, 0, 0, 0, 372, 479, 356, 358, 359, 357, - 473, 475, 581, 582, 583, 585, 0, 586, 587, 0, - 0, 0, 0, 588, 653, 669, 637, 606, 569, 661, - 603, 607, 608, 413, 414, 415, 672, 0, 0, 0, - 560, 429, 430, 0, 384, 383, 445, 333, 0, 0, - 422, 412, 485, 339, 380, 424, 417, 431, 432, 433, - 390, 323, 324, 745, 373, 466, 674, 709, 710, 599, - 0, 662, 600, 609, 365, 634, 646, 645, 460, 559, - 0, 657, 660, 589, 744, 0, 654, 668, 749, 667, - 741, 472, 0, 502, 665, 612, 0, 658, 631, 632, - 0, 659, 627, 663, 0, 601, 0, 570, 573, 602, - 687, 688, 689, 330, 572, 691, 692, 693, 694, 695, - 696, 697, 690, 542, 635, 611, 638, 551, 614, 613, - 0, 0, 649, 568, 650, 651, 454, 455, 456, 457, - 394, 675, 354, 571, 487, 488, 0, 636, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 639, 754, - 0, 698, 699, 0, 0, 565, 566, 389, 0, 584, - 397, 353, 471, 391, 549, 420, 0, 577, 643, 578, - 490, 491, 701, 706, 702, 703, 705, 725, 461, 411, - 416, 506, 423, 437, 493, 548, 469, 498, 351, 538, - 508, 442, 628, 656, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 310, 311, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 683, 682, 681, 680, 679, 678, 677, 676, 0, - 0, 625, 525, 367, 317, 363, 364, 371, 742, 738, - 743, 726, 729, 728, 704, 0, 325, 605, 435, 486, - 388, 670, 671, 0, 724, 269, 270, 271, 272, 273, - 274, 275, 276, 318, 277, 278, 279, 280, 281, 282, - 283, 288, 289, 290, 291, 292, 293, 294, 295, 673, - 286, 287, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 0, 0, 0, 0, - 319, 730, 731, 732, 733, 734, 0, 0, 320, 321, - 322, 0, 0, 284, 285, 312, 516, 313, 314, 315, - 316, 0, 0, 555, 556, 557, 580, 0, 558, 540, - 604, 398, 326, 520, 547, 740, 0, 0, 0, 0, - 0, 0, 0, 655, 666, 700, 0, 712, 713, 715, - 717, 716, 719, 513, 514, 727, 0, 0, 421, 341, - 342, 462, 463, 500, 0, 721, 722, 723, 720, 439, - 499, 521, 507, 0, 746, 595, 596, 747, 708, 327, - 468, 0, 0, 610, 644, 633, 718, 598, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 381, 0, - 0, 434, 648, 629, 640, 630, 474, 615, 616, 617, - 624, 393, 618, 748, 620, 590, 621, 591, 622, 623, - 0, 647, 597, 509, 450, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, - 0, 0, 0, 0, 349, 256, 592, 714, 594, 593, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 510, - 539, 0, 552, 0, 418, 419, 0, 0, 0, 0, - 0, 0, 0, 334, 517, 536, 350, 504, 550, 355, - 512, 2223, 345, 467, 501, 0, 0, 336, 534, 511, - 447, 335, 0, 494, 378, 395, 375, 465, 0, 0, - 533, 563, 374, 553, 0, 544, 338, 0, 543, 464, - 530, 535, 448, 441, 0, 337, 532, 446, 440, 425, - 385, 579, 426, 427, 399, 480, 438, 481, 400, 452, - 451, 453, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 0, 0, 0, 0, 0, 574, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 707, 0, 0, 711, 0, 546, - 0, 0, 0, 0, 0, 0, 515, 0, 0, 428, - 0, 0, 0, 564, 0, 497, 470, 750, 0, 0, - 495, 436, 531, 482, 537, 518, 545, 489, 483, 328, - 519, 377, 449, 346, 348, 739, 379, 382, 386, 387, - 458, 459, 476, 503, 522, 523, 524, 376, 360, 496, - 361, 396, 362, 329, 368, 366, 369, 505, 370, 331, - 477, 528, 0, 392, 492, 444, 332, 443, 478, 527, - 526, 347, 554, 561, 562, 652, 0, 567, 751, 752, - 753, 576, 0, 484, 343, 340, 0, 0, 0, 372, - 479, 356, 358, 359, 357, 473, 475, 581, 582, 583, - 585, 0, 586, 587, 0, 0, 0, 0, 588, 653, - 669, 637, 606, 569, 661, 603, 607, 608, 413, 414, - 415, 672, 0, 0, 0, 560, 429, 430, 0, 384, - 383, 445, 333, 0, 0, 422, 412, 485, 339, 380, - 424, 417, 431, 432, 433, 390, 323, 324, 745, 373, - 466, 674, 709, 710, 599, 0, 662, 600, 609, 365, - 634, 646, 645, 460, 559, 0, 657, 660, 589, 744, - 0, 654, 668, 749, 667, 741, 472, 0, 502, 665, - 612, 0, 658, 631, 632, 0, 659, 627, 663, 0, - 601, 0, 570, 573, 602, 687, 688, 689, 330, 572, - 691, 692, 693, 694, 695, 696, 697, 690, 542, 635, - 611, 638, 551, 614, 613, 0, 0, 649, 568, 650, - 651, 454, 455, 456, 457, 394, 675, 354, 571, 487, - 488, 0, 636, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 639, 754, 0, 698, 699, 0, 0, - 565, 566, 389, 0, 584, 397, 353, 471, 391, 549, - 420, 0, 577, 643, 578, 490, 491, 701, 706, 702, - 703, 705, 725, 461, 411, 416, 506, 423, 437, 493, - 548, 469, 498, 351, 538, 508, 442, 628, 656, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 310, 311, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 683, 682, 681, 680, - 679, 678, 677, 676, 0, 0, 625, 525, 367, 317, - 363, 364, 371, 742, 738, 743, 726, 729, 728, 704, - 0, 325, 605, 435, 486, 388, 670, 671, 0, 724, - 269, 270, 271, 272, 273, 274, 275, 276, 318, 277, - 278, 279, 280, 281, 282, 283, 288, 289, 290, 291, - 292, 293, 294, 295, 673, 286, 287, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 0, 0, 0, 0, 319, 730, 731, 732, 733, - 734, 0, 0, 320, 321, 322, 0, 0, 284, 285, - 312, 516, 313, 314, 315, 316, 0, 0, 555, 556, - 557, 580, 0, 558, 540, 604, 398, 326, 520, 547, - 740, 0, 0, 0, 0, 0, 0, 0, 655, 666, - 700, 0, 712, 713, 715, 717, 716, 719, 513, 514, - 727, 0, 0, 421, 341, 342, 462, 463, 500, 0, - 721, 722, 723, 720, 439, 499, 521, 507, 0, 746, - 595, 596, 747, 708, 327, 468, 0, 0, 610, 644, - 633, 718, 598, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 381, 0, 0, 434, 648, 629, 640, - 630, 474, 615, 616, 617, 624, 393, 618, 748, 620, - 590, 621, 591, 622, 623, 0, 647, 597, 509, 450, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 0, 0, 0, 0, 0, 0, 349, - 256, 592, 714, 594, 593, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 510, 539, 0, 552, 0, 418, - 419, 0, 0, 0, 0, 0, 0, 0, 334, 517, - 1754, 350, 504, 550, 355, 512, 529, 345, 467, 501, - 0, 0, 336, 534, 511, 447, 335, 0, 494, 378, - 395, 375, 465, 0, 0, 533, 563, 374, 553, 0, - 544, 338, 0, 543, 464, 530, 535, 448, 441, 0, - 337, 532, 446, 440, 425, 385, 579, 426, 427, 399, - 480, 438, 481, 400, 452, 451, 453, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 0, 0, - 0, 0, 574, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 707, - 0, 0, 711, 0, 546, 0, 0, 0, 0, 0, - 0, 515, 0, 0, 428, 0, 0, 0, 564, 0, - 497, 470, 750, 0, 0, 495, 436, 531, 482, 537, - 518, 545, 489, 483, 328, 519, 377, 449, 346, 348, - 739, 379, 382, 386, 387, 458, 459, 476, 503, 522, - 523, 524, 376, 360, 496, 361, 396, 362, 329, 368, - 366, 369, 505, 370, 331, 477, 528, 0, 392, 492, - 444, 332, 443, 478, 527, 526, 347, 554, 561, 562, - 652, 0, 567, 751, 752, 753, 576, 0, 484, 343, - 340, 0, 0, 0, 372, 479, 356, 358, 359, 357, - 473, 475, 581, 582, 583, 585, 0, 586, 587, 0, - 0, 0, 0, 588, 653, 669, 637, 606, 569, 661, - 603, 607, 608, 413, 414, 415, 672, 0, 0, 0, - 560, 429, 430, 0, 384, 383, 445, 333, 0, 0, - 422, 412, 485, 339, 380, 424, 417, 431, 432, 433, - 390, 323, 324, 745, 373, 466, 674, 709, 710, 599, - 0, 662, 600, 609, 365, 634, 646, 645, 460, 559, - 0, 657, 660, 589, 744, 0, 654, 668, 749, 667, - 741, 472, 0, 502, 665, 612, 0, 658, 631, 632, - 0, 659, 627, 663, 0, 601, 0, 570, 573, 602, - 687, 688, 689, 330, 572, 691, 692, 693, 694, 695, - 696, 697, 690, 542, 635, 611, 638, 551, 614, 613, - 0, 0, 649, 568, 650, 651, 454, 455, 456, 457, - 394, 675, 354, 571, 487, 488, 0, 636, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 639, 754, - 0, 698, 699, 0, 0, 565, 566, 389, 0, 584, - 397, 353, 471, 391, 549, 420, 0, 577, 643, 578, - 490, 491, 701, 706, 702, 703, 705, 725, 461, 411, - 416, 506, 423, 437, 493, 548, 469, 498, 351, 538, - 508, 442, 628, 656, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 310, 311, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 683, 682, 681, 680, 679, 678, 677, 676, 0, - 0, 625, 525, 367, 317, 363, 364, 371, 742, 738, - 743, 726, 729, 728, 704, 0, 325, 605, 435, 486, - 388, 670, 671, 0, 724, 269, 270, 271, 272, 273, - 274, 275, 276, 318, 277, 278, 279, 280, 281, 282, - 283, 288, 289, 290, 291, 292, 293, 294, 295, 673, - 286, 287, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 0, 0, 0, 0, - 319, 730, 731, 732, 733, 734, 0, 0, 320, 321, - 322, 0, 0, 284, 285, 312, 516, 313, 314, 315, - 316, 0, 0, 555, 556, 557, 580, 0, 558, 540, - 604, 398, 326, 520, 547, 740, 0, 0, 0, 0, - 0, 0, 0, 655, 666, 700, 0, 712, 713, 715, - 717, 716, 719, 513, 514, 727, 0, 0, 421, 341, - 342, 462, 463, 500, 0, 721, 722, 723, 720, 439, - 499, 521, 507, 0, 746, 595, 596, 747, 708, 327, - 468, 0, 0, 610, 644, 633, 718, 598, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 381, 0, - 0, 434, 648, 629, 640, 630, 474, 615, 616, 617, - 624, 393, 618, 748, 620, 590, 621, 591, 622, 623, - 0, 647, 597, 509, 450, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, - 0, 0, 0, 0, 349, 256, 592, 714, 594, 593, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 510, - 539, 0, 552, 0, 418, 419, 0, 0, 0, 0, - 0, 0, 0, 334, 517, 1752, 350, 504, 550, 355, - 512, 529, 345, 467, 501, 0, 0, 336, 534, 511, - 447, 335, 0, 494, 378, 395, 375, 465, 0, 0, - 533, 563, 374, 553, 0, 544, 338, 0, 543, 464, - 530, 535, 448, 441, 0, 337, 532, 446, 440, 425, - 385, 579, 426, 427, 399, 480, 438, 481, 400, 452, - 451, 453, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 0, 0, 0, 0, 0, 574, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 707, 0, 0, 711, 0, 546, - 0, 0, 0, 0, 0, 0, 515, 0, 0, 428, - 0, 0, 0, 564, 0, 497, 470, 750, 0, 0, - 495, 436, 531, 482, 537, 518, 545, 489, 483, 328, - 519, 377, 449, 346, 348, 739, 379, 382, 386, 387, - 458, 459, 476, 503, 522, 523, 524, 376, 360, 496, - 361, 396, 362, 329, 368, 366, 369, 505, 370, 331, - 477, 528, 0, 392, 492, 444, 332, 443, 478, 527, - 526, 347, 554, 561, 562, 652, 0, 567, 751, 752, - 753, 576, 0, 484, 343, 340, 0, 0, 0, 372, - 479, 356, 358, 359, 357, 473, 475, 581, 582, 583, - 585, 0, 586, 587, 0, 0, 0, 0, 588, 653, - 669, 637, 606, 569, 661, 603, 607, 608, 413, 414, - 415, 672, 0, 0, 0, 560, 429, 430, 0, 384, - 383, 445, 333, 0, 0, 422, 412, 485, 339, 380, - 424, 417, 431, 432, 433, 390, 323, 324, 745, 373, - 466, 674, 709, 710, 599, 0, 662, 600, 609, 365, - 634, 646, 645, 460, 559, 0, 657, 660, 589, 744, - 0, 654, 668, 749, 667, 741, 472, 0, 502, 665, - 612, 0, 658, 631, 632, 0, 659, 627, 663, 0, - 601, 0, 570, 573, 602, 687, 688, 689, 330, 572, - 691, 692, 693, 694, 695, 696, 697, 690, 542, 635, - 611, 638, 551, 614, 613, 0, 0, 649, 568, 650, - 651, 454, 455, 456, 457, 394, 675, 354, 571, 487, - 488, 0, 636, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 639, 754, 0, 698, 699, 0, 0, - 565, 566, 389, 0, 584, 397, 353, 471, 391, 549, - 420, 0, 577, 643, 578, 490, 491, 701, 706, 702, - 703, 705, 725, 461, 411, 416, 506, 423, 437, 493, - 548, 469, 498, 351, 538, 508, 442, 628, 656, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 310, 311, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 683, 682, 681, 680, - 679, 678, 677, 676, 0, 0, 625, 525, 367, 317, - 363, 364, 371, 742, 738, 743, 726, 729, 728, 704, - 0, 325, 605, 435, 486, 388, 670, 671, 0, 724, - 269, 270, 271, 272, 273, 274, 275, 276, 318, 277, - 278, 279, 280, 281, 282, 283, 288, 289, 290, 291, - 292, 293, 294, 295, 673, 286, 287, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 0, 0, 0, 0, 319, 730, 731, 732, 733, - 734, 0, 0, 320, 321, 322, 0, 0, 284, 285, - 312, 516, 313, 314, 315, 316, 0, 0, 555, 556, - 557, 580, 0, 558, 540, 604, 398, 326, 520, 547, - 740, 0, 0, 0, 0, 0, 0, 0, 655, 666, - 700, 0, 712, 713, 715, 717, 716, 719, 513, 514, - 727, 0, 0, 421, 341, 342, 462, 463, 500, 0, - 721, 722, 723, 720, 439, 499, 521, 507, 0, 746, - 595, 596, 747, 708, 327, 468, 0, 0, 610, 644, - 633, 718, 598, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 381, 0, 0, 434, 648, 629, 640, - 630, 474, 615, 616, 617, 624, 393, 618, 748, 620, - 590, 621, 591, 622, 623, 0, 647, 597, 509, 450, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 0, 0, 0, 0, 0, 0, 349, - 256, 592, 714, 594, 593, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 510, 539, 0, 552, 0, 418, - 419, 0, 0, 0, 0, 0, 0, 0, 334, 517, - 536, 350, 504, 550, 355, 512, 1669, 345, 467, 501, - 0, 0, 336, 534, 511, 447, 335, 0, 494, 378, - 395, 375, 465, 0, 0, 533, 563, 374, 553, 0, - 544, 338, 0, 543, 464, 530, 535, 448, 441, 0, - 337, 532, 446, 440, 425, 385, 579, 426, 427, 399, - 480, 438, 481, 400, 452, 451, 453, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 0, 0, - 0, 0, 574, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 707, - 0, 0, 711, 0, 546, 0, 0, 0, 0, 0, - 0, 515, 0, 0, 428, 0, 0, 0, 564, 0, - 497, 470, 750, 0, 0, 495, 436, 531, 482, 537, - 518, 545, 489, 483, 328, 519, 377, 449, 346, 348, - 739, 379, 382, 386, 387, 458, 459, 476, 503, 522, - 523, 524, 376, 360, 496, 361, 396, 362, 329, 368, - 366, 369, 505, 370, 331, 477, 528, 0, 392, 492, - 444, 332, 443, 478, 527, 526, 347, 554, 561, 562, - 652, 0, 567, 751, 752, 753, 576, 0, 484, 343, - 340, 0, 0, 0, 372, 479, 356, 358, 359, 357, - 473, 475, 581, 582, 583, 585, 0, 586, 587, 0, - 0, 0, 0, 588, 653, 669, 637, 606, 569, 661, - 603, 607, 608, 413, 414, 415, 672, 0, 0, 0, - 560, 429, 430, 0, 384, 383, 445, 333, 0, 0, - 422, 412, 485, 339, 380, 424, 417, 431, 432, 433, - 390, 323, 324, 745, 373, 466, 674, 709, 710, 599, - 0, 662, 600, 609, 365, 634, 646, 645, 460, 559, - 0, 657, 660, 589, 744, 0, 654, 668, 749, 667, - 741, 472, 0, 502, 665, 612, 0, 658, 631, 632, - 0, 659, 627, 663, 0, 601, 0, 570, 573, 602, - 687, 688, 689, 330, 572, 691, 692, 693, 694, 695, - 696, 697, 690, 542, 635, 611, 638, 551, 614, 613, - 0, 0, 649, 568, 650, 651, 454, 455, 456, 457, - 394, 675, 354, 571, 487, 488, 0, 636, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 639, 754, - 0, 698, 699, 0, 0, 565, 566, 389, 0, 584, - 397, 353, 471, 391, 549, 420, 0, 577, 643, 578, - 490, 491, 701, 706, 702, 703, 705, 725, 461, 411, - 416, 506, 423, 437, 493, 548, 469, 498, 351, 538, - 508, 442, 628, 656, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 310, 311, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 683, 682, 681, 680, 679, 678, 677, 676, 0, - 0, 625, 525, 367, 317, 363, 364, 371, 742, 738, - 743, 726, 729, 728, 704, 0, 325, 605, 435, 486, - 388, 670, 671, 0, 724, 269, 270, 271, 272, 273, - 274, 275, 276, 318, 277, 278, 279, 280, 281, 282, - 283, 288, 289, 290, 291, 292, 293, 294, 295, 673, - 286, 287, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 0, 0, 0, 0, - 319, 730, 731, 732, 733, 734, 0, 0, 320, 321, - 322, 0, 0, 284, 285, 312, 516, 313, 314, 315, - 316, 0, 0, 555, 556, 557, 580, 0, 558, 540, - 604, 398, 326, 520, 547, 740, 0, 0, 0, 0, - 0, 0, 0, 655, 666, 700, 0, 712, 713, 715, - 717, 716, 719, 513, 514, 727, 0, 0, 421, 341, - 342, 462, 463, 500, 0, 721, 722, 723, 720, 439, - 499, 521, 507, 0, 746, 595, 596, 747, 708, 327, - 468, 0, 0, 610, 644, 633, 718, 598, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 381, 0, - 0, 434, 648, 629, 640, 630, 474, 615, 616, 617, - 624, 393, 618, 748, 620, 590, 621, 591, 622, 623, - 0, 647, 597, 509, 450, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, - 0, 0, 0, 0, 349, 256, 592, 714, 594, 593, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 510, - 539, 0, 552, 0, 418, 419, 0, 0, 0, 0, - 0, 0, 0, 334, 517, 536, 350, 504, 550, 355, - 512, 529, 345, 467, 501, 0, 0, 336, 534, 511, - 447, 335, 0, 494, 378, 395, 375, 465, 0, 0, - 533, 563, 374, 553, 0, 544, 338, 0, 543, 464, - 530, 535, 448, 441, 0, 337, 532, 446, 440, 425, - 385, 579, 426, 427, 399, 480, 438, 481, 400, 452, - 451, 453, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 0, 0, 0, 0, 0, 574, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 707, 0, 0, 711, 0, 546, - 0, 0, 0, 0, 0, 0, 515, 0, 0, 428, - 0, 0, 0, 564, 0, 497, 470, 750, 0, 0, - 495, 436, 531, 482, 537, 518, 545, 489, 483, 328, - 519, 377, 449, 346, 348, 905, 379, 382, 386, 387, - 458, 459, 476, 503, 522, 523, 524, 376, 360, 496, - 361, 396, 362, 329, 368, 366, 369, 505, 370, 331, - 477, 528, 0, 392, 492, 444, 332, 443, 478, 527, - 526, 347, 554, 561, 562, 652, 0, 567, 751, 752, - 753, 576, 0, 484, 343, 340, 0, 0, 0, 372, - 479, 356, 358, 359, 357, 473, 475, 581, 582, 583, - 585, 0, 586, 587, 0, 0, 0, 0, 588, 653, - 669, 637, 606, 569, 661, 603, 607, 608, 413, 414, - 415, 672, 0, 0, 0, 560, 429, 430, 0, 384, - 383, 445, 333, 0, 0, 422, 412, 485, 339, 380, - 424, 417, 431, 432, 433, 390, 323, 324, 745, 373, - 466, 674, 709, 710, 599, 0, 662, 600, 609, 365, - 634, 646, 645, 460, 559, 0, 657, 660, 589, 744, - 0, 654, 668, 749, 667, 741, 472, 0, 502, 665, - 612, 0, 658, 631, 632, 0, 659, 627, 663, 0, - 601, 0, 570, 573, 602, 687, 688, 689, 330, 572, - 691, 692, 693, 694, 695, 696, 697, 690, 542, 635, - 611, 638, 551, 614, 613, 0, 0, 649, 568, 650, - 651, 454, 455, 456, 457, 394, 675, 354, 571, 487, - 488, 0, 636, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 639, 754, 0, 698, 699, 0, 0, - 565, 566, 389, 0, 584, 397, 353, 471, 391, 549, - 420, 0, 577, 643, 578, 490, 491, 701, 706, 702, - 703, 705, 725, 461, 411, 416, 506, 423, 437, 493, - 548, 469, 498, 351, 538, 508, 442, 628, 656, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 310, 311, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 683, 682, 681, 680, - 679, 678, 677, 676, 0, 0, 625, 525, 367, 317, - 363, 364, 371, 742, 738, 743, 726, 729, 728, 704, - 0, 325, 605, 435, 486, 388, 670, 671, 0, 724, - 269, 270, 271, 272, 273, 274, 275, 276, 318, 277, - 278, 279, 280, 281, 282, 283, 288, 289, 290, 291, - 292, 293, 294, 295, 673, 286, 287, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 0, 0, 0, 0, 319, 730, 731, 732, 733, - 734, 0, 0, 320, 321, 322, 0, 0, 284, 285, - 312, 516, 313, 314, 315, 316, 0, 0, 555, 556, - 557, 580, 0, 558, 540, 604, 398, 326, 520, 547, - 740, 0, 0, 0, 0, 0, 0, 0, 655, 666, - 700, 0, 712, 713, 715, 717, 716, 719, 513, 514, - 727, 0, 0, 421, 341, 342, 462, 463, 500, 0, - 721, 722, 723, 720, 439, 499, 521, 507, 0, 746, - 595, 596, 747, 708, 327, 468, 0, 0, 610, 644, - 633, 718, 598, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 381, 0, 0, 434, 648, 629, 640, - 630, 474, 615, 616, 617, 624, 393, 618, 748, 620, - 590, 621, 591, 622, 623, 0, 647, 597, 509, 450, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 0, 0, 0, 0, 0, 0, 349, - 256, 592, 714, 594, 593, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 510, 539, 0, 552, 0, 418, - 419, 0, 0, 0, 0, 0, 0, 0, 334, 517, - 536, 350, 504, 550, 355, 512, 529, 345, 467, 501, - 0, 0, 336, 534, 511, 447, 335, 0, 494, 378, - 395, 375, 465, 0, 0, 533, 563, 374, 553, 0, - 544, 338, 0, 543, 464, 530, 535, 448, 441, 0, - 337, 532, 446, 440, 425, 385, 579, 426, 427, 399, - 480, 438, 481, 400, 452, 451, 453, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 0, 0, - 0, 0, 574, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 707, - 0, 0, 711, 0, 546, 0, 0, 0, 0, 0, - 0, 515, 0, 0, 428, 0, 0, 0, 564, 0, - 497, 470, 750, 0, 0, 495, 436, 531, 482, 537, - 518, 545, 857, 483, 328, 519, 377, 449, 346, 348, - 739, 379, 382, 386, 387, 458, 459, 476, 503, 522, - 523, 524, 376, 360, 496, 361, 396, 362, 329, 368, - 366, 369, 505, 370, 331, 477, 528, 0, 392, 492, - 444, 332, 443, 478, 527, 526, 347, 554, 561, 562, - 652, 0, 567, 751, 752, 753, 576, 0, 484, 343, - 340, 0, 0, 0, 372, 479, 356, 358, 359, 357, - 473, 475, 581, 582, 583, 585, 0, 586, 587, 0, - 0, 0, 0, 588, 653, 669, 637, 606, 569, 661, - 603, 607, 608, 413, 414, 415, 672, 0, 0, 0, - 560, 429, 430, 0, 384, 383, 445, 333, 0, 0, - 422, 412, 485, 339, 380, 424, 417, 431, 432, 433, - 390, 323, 324, 745, 373, 466, 674, 709, 710, 599, - 0, 662, 600, 609, 365, 634, 646, 645, 460, 559, - 0, 657, 660, 589, 744, 0, 654, 668, 749, 667, - 741, 472, 0, 502, 665, 612, 0, 658, 631, 632, - 0, 659, 627, 663, 0, 601, 0, 570, 573, 602, - 687, 688, 689, 330, 572, 691, 692, 693, 694, 695, - 696, 858, 690, 542, 635, 611, 638, 551, 614, 613, - 0, 0, 649, 568, 650, 651, 454, 455, 456, 457, - 394, 675, 354, 571, 487, 488, 0, 636, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 639, 754, - 0, 698, 699, 0, 0, 565, 566, 389, 0, 584, - 397, 353, 471, 391, 549, 420, 0, 577, 643, 578, - 490, 491, 701, 706, 702, 703, 705, 725, 461, 411, - 416, 506, 423, 437, 493, 548, 469, 498, 351, 538, - 508, 442, 628, 656, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 310, 311, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 683, 682, 681, 680, 679, 678, 677, 676, 0, - 0, 625, 525, 367, 317, 363, 364, 371, 742, 738, - 743, 726, 729, 728, 704, 0, 325, 605, 435, 486, - 388, 670, 671, 0, 724, 269, 270, 271, 272, 273, - 274, 275, 276, 318, 277, 278, 279, 280, 281, 282, - 283, 288, 289, 290, 291, 292, 293, 294, 295, 673, - 286, 287, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 0, 0, 0, 0, - 319, 730, 731, 732, 733, 734, 0, 0, 320, 321, - 322, 0, 0, 284, 285, 312, 516, 313, 314, 315, - 316, 0, 0, 555, 556, 557, 580, 0, 558, 540, - 604, 398, 326, 520, 547, 740, 0, 0, 0, 0, - 0, 0, 0, 655, 666, 700, 0, 712, 713, 715, - 717, 716, 719, 513, 514, 727, 0, 0, 421, 341, - 342, 462, 463, 500, 0, 721, 722, 723, 720, 439, - 499, 521, 507, 0, 746, 595, 596, 747, 708, 327, - 468, 0, 0, 610, 644, 633, 718, 598, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 381, 0, - 0, 434, 648, 629, 640, 630, 474, 615, 616, 617, - 624, 393, 618, 748, 620, 590, 621, 591, 622, 623, - 0, 647, 597, 509, 450, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, - 0, 0, 0, 0, 349, 256, 592, 714, 594, 593, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 510, - 539, 0, 552, 0, 418, 419, 0, 0, 0, 0, - 0, 0, 0, 334, 517, 536, 350, 504, 550, 355, - 512, 529, 345, 467, 501, 0, 0, 336, 534, 511, - 447, 335, 0, 494, 378, 395, 375, 465, 0, 0, - 533, 563, 374, 553, 0, 544, 338, 0, 543, 464, - 530, 535, 448, 441, 0, 337, 532, 446, 440, 425, - 385, 579, 426, 427, 399, 480, 438, 481, 400, 452, - 451, 453, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 0, 0, 0, 0, 0, 574, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 707, 0, 0, 711, 0, 546, - 0, 0, 0, 0, 0, 0, 515, 0, 0, 428, - 0, 0, 0, 564, 0, 497, 470, 750, 0, 0, - 495, 436, 531, 482, 537, 518, 545, 489, 483, 328, - 519, 377, 449, 346, 348, 739, 379, 382, 386, 387, - 458, 459, 476, 503, 522, 523, 524, 376, 360, 496, - 361, 396, 362, 329, 368, 366, 369, 505, 370, 331, - 477, 528, 0, 392, 492, 444, 332, 443, 478, 527, - 526, 347, 554, 561, 562, 652, 0, 567, 751, 752, - 753, 576, 0, 484, 343, 340, 0, 0, 0, 372, - 479, 356, 358, 359, 357, 473, 475, 581, 582, 583, - 585, 0, 586, 587, 0, 0, 0, 0, 588, 653, - 669, 637, 606, 569, 661, 603, 607, 608, 413, 414, - 415, 672, 0, 0, 0, 560, 429, 430, 0, 384, - 383, 445, 333, 0, 0, 422, 412, 485, 339, 380, - 424, 417, 431, 432, 433, 390, 323, 324, 745, 373, - 466, 674, 709, 710, 599, 0, 662, 600, 609, 365, - 634, 646, 645, 460, 559, 0, 657, 660, 589, 744, - 0, 654, 668, 749, 667, 741, 472, 0, 502, 665, - 612, 0, 658, 631, 632, 0, 659, 627, 663, 0, - 601, 0, 570, 573, 602, 687, 688, 689, 330, 572, - 691, 692, 693, 694, 695, 696, 697, 690, 542, 635, - 611, 638, 551, 614, 613, 0, 0, 649, 568, 650, - 651, 454, 455, 456, 457, 394, 675, 354, 571, 487, - 488, 0, 636, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 639, 754, 0, 698, 699, 0, 0, - 565, 566, 389, 0, 584, 397, 353, 471, 391, 549, - 420, 0, 577, 643, 578, 490, 491, 701, 706, 702, - 703, 705, 725, 461, 411, 416, 506, 423, 437, 493, - 548, 469, 498, 351, 538, 508, 442, 628, 656, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 310, 311, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 683, 682, 681, 680, - 679, 678, 677, 676, 0, 0, 625, 525, 367, 317, - 363, 364, 371, 742, 738, 743, 726, 729, 728, 795, - 0, 325, 605, 435, 486, 388, 670, 671, 0, 724, - 269, 270, 271, 272, 273, 274, 275, 276, 318, 277, - 278, 279, 280, 281, 282, 283, 288, 289, 290, 291, - 292, 293, 294, 295, 673, 286, 287, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 0, 0, 0, 0, 319, 730, 731, 732, 733, - 734, 0, 0, 320, 321, 322, 0, 0, 284, 285, - 312, 516, 313, 314, 315, 316, 0, 0, 555, 556, - 557, 580, 0, 558, 540, 604, 398, 326, 520, 547, - 740, 0, 0, 0, 0, 0, 0, 0, 655, 666, - 700, 0, 712, 713, 715, 717, 716, 719, 513, 514, - 727, 0, 0, 421, 341, 342, 462, 463, 500, 0, - 721, 722, 723, 720, 439, 499, 521, 507, 0, 746, - 595, 596, 747, 708, 327, + 0, 0, 0, 2385, } var yyPact = [...]int{ - 5106, -1000, -1000, -393, -1000, -1000, -1000, -1000, -1000, 19728, + 5287, -1000, -1000, -401, -1000, -1000, -1000, -1000, -1000, 19136, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 68113, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 545, + 68113, -398, -1000, 3530, 1152, -1000, -1000, -1000, -1000, 414, + 66653, 21348, 68113, 716, 702, 73953, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 66195, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 574, - 66195, -390, -1000, 3505, 1221, -1000, -1000, -1000, -1000, 360, - 64745, 21925, 66195, 789, 786, 71995, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1117, 1116, 5440, -1000, 73223, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1028, + 6228, 72493, 14733, -238, -1000, 2165, -20, 3343, 495, 18, + 16, 693, 1361, 1377, 1379, 1246, 68113, 1321, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 1184, 1182, 5567, -1000, 71270, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1087, 5893, 70545, - 15355, -247, -1000, 2283, -44, 3357, 576, 21, 11, 774, - 1404, 1423, 1599, 1549, 66195, 1368, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 6034, 38171, 67383, 1224, 3951, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 5136, 37908, 65470, 1251, 4010, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 330, 1115, 1224, 27210, + 184, 183, 2165, 3489, -112, 5446, -1000, 2578, 5287, 229, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 712, 1180, 1251, 27747, 189, 186, 2283, 3551, - -123, 3315, -1000, 2137, 5106, 226, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 15355, 15355, 19728, - -443, 19728, 15355, 66195, 66195, -1000, -1000, -1000, -1000, -390, - 64745, 1087, 5893, 15355, 3357, 576, 21, 11, 774, -1000, + -1000, 14733, 14733, 19136, -437, 19136, 14733, 68113, 68113, -1000, + -1000, -1000, -1000, -398, 66653, 1028, 6228, 14733, 3343, 495, + 18, 16, 693, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -112, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -123, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -9411,15 +9680,15 @@ var yyPact = [...]int{ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 183, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 186, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 4010, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 3951, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -9431,500 +9700,506 @@ var yyPact = [...]int{ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 414, -1000, 2146, -1000, -1000, + -1000, -1000, -1000, -1000, 445, -1000, 2064, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 3007, 3826, 2144, 3356, -1000, - -1000, -1000, -1000, -1000, 2283, 4221, 64020, -1000, -1000, 4202, - -1000, 66195, 158, 66195, 269, 2487, -1000, 680, 703, 675, - 963, 481, 2143, -1000, -1000, -1000, -1000, -1000, -1000, 3495, - 984, 4200, -1000, 66195, 66195, 66195, 3843, 66195, 66195, 436, - 4107, -1000, 30, -156, -379, 3862, 2288, 2288, 4181, 4181, - 4106, 4104, 1032, 1031, 1028, 2288, 852, -1000, 2369, 2369, - 2369, 2369, 2288, 664, 1024, 4118, 4118, 157, 2369, 171, - 2288, 2288, 171, 2288, 2288, 627, -1000, 2347, 650, 326, - -310, -1000, -1000, -1000, -1000, 2369, 2369, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 4078, 4072, -1000, 361, 1021, -1000, - 6171, 4018, 1947, 1203, 3856, -1000, -1000, 3825, -1000, 493, - 838, 505, 872, 573, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 426, -1000, 4088, -1000, -1000, 467, -1000, -1000, 477, - -1000, -1000, -1000, 179, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -59, -1000, -1000, 1502, 2559, - 15355, 2553, -1000, 5158, 2256, -1000, -1000, -1000, 10259, 18990, - 18990, 18990, 18990, 66195, -1000, -1000, 3669, 15355, 3822, 3818, - 3817, 3812, -1000, -1000, -1000, -1000, -1000, -1000, 3810, 2126, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2638, - -1000, -1000, -1000, 18263, -1000, 3802, 3798, 3797, 3795, 3793, - 3792, 3790, 3789, 3788, 3787, 3786, 3785, 3784, 3783, 3779, - 3580, 21189, 3775, 3351, 3349, 3774, 3773, 3772, 3348, 3770, - 3769, 3767, 3580, 3580, 3764, 3763, 3761, 3759, 3758, 3753, - 3752, 3751, 3749, 3748, 3747, 3746, 3744, 3742, 3740, 3739, - 3738, 3734, 3730, 3728, 3727, 3726, 3724, 3723, 3722, 3720, - 3719, 3718, 3712, 3711, 3708, 3706, 3705, 3703, 3701, 3697, - 3682, 3680, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 3029, 3779, 2062, 3341, -1000, -1000, + -1000, -1000, -1000, 2165, 4166, 65923, -1000, -1000, 4144, -1000, + 68113, 163, 68113, 299, 2443, -1000, 861, 753, 711, 856, + 443, 2059, -1000, -1000, -1000, -1000, -1000, -1000, 3550, 876, + 4143, -1000, 68113, 68113, 68113, 3791, 68113, 68113, 449, 4051, + -1000, 11, -128, -375, -379, 3809, 2253, 2253, 4113, 4113, + 4050, 4046, 930, 928, 923, 2253, 807, -1000, 2360, 2360, + 2360, 2360, 2253, 566, 910, 4054, 4054, 206, 2360, 96, + 2253, 2253, 96, 2253, 2253, 595, -1000, 2410, 633, 247, + -305, -1000, -1000, -1000, -1000, 2360, 2360, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 4017, 4016, -1000, 606, 905, -1000, + 6332, 3959, 1692, 1155, 3808, -1000, -1000, 3775, -1000, 460, + 544, 487, 892, 531, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 375, -1000, 4023, -1000, -1000, 450, -1000, -1000, 427, + -1000, -1000, -1000, 117, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -39, -1000, -1000, 1454, 2598, + 14733, 2618, -1000, 6060, 2210, -1000, -1000, -1000, 9602, 18393, + 18393, 18393, 18393, 68113, -1000, -1000, 3667, 14733, 3773, 3772, + 3770, 3769, -1000, -1000, -1000, -1000, -1000, -1000, 3768, 2040, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2636, + -1000, -1000, -1000, 17661, -1000, 3767, 3766, 3765, 3764, 3762, + 3761, 3760, 3757, 3752, 3751, 3748, 3747, 3745, 3743, 3741, + 3562, 20607, 3736, 3338, 3337, 3735, 3734, 3733, 3334, 3732, + 3730, 3729, 3562, 3562, 3728, 3727, 3726, 3725, 3723, 3722, + 3721, 3720, 3719, 3718, 3717, 3716, 3715, 3714, 3712, 3711, + 3710, 3709, 3707, 3706, 3705, 3703, 3702, 3701, 3700, 3698, + 3696, 3695, 3694, 3693, 3692, 3689, 3688, 3687, 3686, 3685, + 3684, 3683, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 2014, -1000, 3679, 4232, 3622, - -1000, 4068, 4065, 4053, 4039, -303, 3678, 2936, -1000, -1000, - 140, 66195, 66195, 315, 66195, -321, 436, 677, -140, -141, - 666, -142, 1160, -1000, 568, -1000, -1000, 1460, -1000, 1349, - 69820, 1137, -1000, -1000, 66195, 1086, 1086, 1086, -340, 1086, - 66195, 294, 1214, 1353, 1086, 1086, 1086, 1086, 1114, 1086, - 4103, 1178, 1176, 1166, 1163, 1086, -74, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 2486, 2477, 3930, 1051, 64020, 64020, - 66195, -1000, 1975, 66195, -1000, 3648, 1331, -1000, -1000, -1000, - -1000, 45158, -343, 1087, 1087, 66195, 1087, 66195, 486, 212, - 66195, 1087, 1087, 1087, 66195, 1099, -378, 44, 69095, 68370, - 3021, 361, 1018, 1013, 1986, 2374, -1000, 2399, 66195, 66195, - 2399, 2399, 31383, 30658, -1000, 66195, -1000, 4232, 3622, 3559, - 2251, 3558, 3622, -144, 1087, 1087, -352, 1087, 1087, 1087, - 1087, 1087, 357, 1087, 1087, 1087, 1087, 1087, 66195, 66195, - 63295, 1087, 665, 1087, 1087, 1087, 13167, 2137, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1850, -1000, 3682, 4186, 3564, + -1000, 4013, 3989, 3987, 3981, -296, 3681, 2954, -1000, -1000, + 107, 68113, 68113, 327, 68113, -318, 449, 618, -125, -126, + 616, -127, 1130, -1000, 513, -1000, -1000, 1396, -1000, 1313, + 71763, 1086, -1000, -1000, 68113, 1024, 1024, 1024, -341, 296, + 1024, 68113, 262, 1176, 1248, 1024, 1024, 1024, 1024, 1097, + 1024, 4044, 1110, 1108, 1107, 1106, 1024, -65, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 2442, 2433, 3874, 962, 65923, + 65923, 68113, -1000, 1832, 68113, -1000, 3651, 1274, -1000, -1000, + -1000, -1000, 45471, -342, 289, 1028, 1028, 68113, 1028, 68113, + 371, 219, 68113, 1028, 1028, 1028, 68113, 1038, -387, 54, + 71033, 70303, 3195, 606, 902, 901, 1864, 2348, -1000, 2279, + 68113, 68113, 2279, 2279, 30871, 30141, -1000, 68113, -1000, 4186, + 3564, 3552, 1674, 3551, 3564, -129, 1028, 1028, -346, 288, + 1028, 1028, 1028, 1028, 1028, 407, 1028, 1028, 1028, 1028, + 1028, 68113, 68113, 65193, 1028, 614, 1028, 1028, 1028, 12530, + 2578, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 19136, 2563, 2674, 228, -8, -359, + 320, -1000, -1000, 68113, 3932, 2190, -1000, -1000, -1000, 3639, + 3631, -1000, 3634, 3634, 3634, 3634, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 3634, 3634, 3637, 3680, + -1000, -1000, 3632, 3632, 3632, 3631, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 19728, 2658, 2578, 225, -27, -359, 305, -1000, -1000, - 66195, 3978, 2199, -1000, -1000, -1000, 3637, 3626, -1000, 3630, - 3630, 3630, 3630, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 3630, 3630, 3633, 3677, -1000, -1000, 3627, - 3627, 3627, 3626, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1464, 3631, - 3632, 3632, 3631, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 1359, 3635, 3636, 3636, 3635, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 66195, 4228, -1000, -1000, 15355, 66195, 4007, 4232, 3983, - 4118, 4175, 1046, 2728, -1000, -363, 66195, 388, -1000, 2125, - 2935, 3345, -1000, 481, -1000, 661, 481, -1000, 691, 691, - 2289, -1000, 1653, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 66195, -59, 1223, -1000, -1000, -1000, 3295, 1983, -1000, 3676, - 645, -1000, -1000, -1000, -1000, 66195, 4118, -159, 4102, 2288, - 2527, 2450, -1000, -1000, -1000, 1011, 4181, 18990, 18990, -1000, - -1000, 15355, -1000, 249, 62570, 2369, 2288, 2288, -1000, -1000, - 66195, -1000, -1000, -1000, 2369, 66195, 2369, 2369, 4181, 2369, - -1000, -1000, -1000, 2288, 2288, -1000, -1000, 15355, -1000, -1000, - 2369, 2369, -1000, -1000, 4181, 66195, 178, 4181, 4181, 153, - -1000, -1000, 66195, -1000, 2288, 3342, -1000, 66195, 66195, 1086, - 66195, -1000, 66195, 66195, -1000, -1000, -1000, 773, 1815, 1861, - -1000, 483, 6555, 52414, 361, 52414, 66195, -1000, -1000, -1000, - -1000, -1000, -1000, 160, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 68113, 4182, -1000, -1000, 14733, 68113, + 3950, 4186, 3938, 4054, 4102, 950, 2806, -1000, -366, 68113, + 413, -1000, 2028, 2952, 3330, -1000, 443, -1000, 779, 443, + -1000, 770, 770, 2273, -1000, 1621, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 68113, -39, 738, -1000, -1000, -1000, 3275, + 1859, -1000, 3679, 600, -1000, -1000, -1000, -1000, 68113, 4054, + -146, 4043, 2253, 2452, 2440, 2253, -1000, -1000, -1000, 898, + 4113, 18393, 18393, -1000, -1000, 14733, -1000, 329, 64463, 2360, + 2253, 2253, -1000, -1000, 68113, -1000, -1000, -1000, 2360, 68113, + 2360, 2360, 4113, 2360, -1000, -1000, -1000, 2253, 2253, -1000, + -1000, 14733, -1000, -1000, 2360, 2360, -1000, -1000, 4113, 68113, + 108, 4113, 4113, 80, -1000, -1000, 68113, -1000, 2253, 3321, + -1000, 68113, 68113, 1024, 68113, -1000, 68113, 68113, -1000, -1000, + -1000, 808, 1612, 1649, -1000, 441, 5045, 54237, 606, 54237, + 68113, -1000, -1000, -1000, -1000, -1000, -1000, 102, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 449, -1000, - 15355, 15355, 15355, 15355, -1000, 892, 17536, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 18990, 18990, 18990, 18990, 18990, 18990, - 18990, 18990, 18990, 18990, 18990, 18990, 18990, 18990, 18990, 3667, - 2428, 18990, 18990, 18990, 18990, 316, 33558, 2251, 3382, 1978, - 352, 2256, 2256, 2256, 2256, 15355, -1000, 2511, 2559, 15355, - 15355, 15355, 15355, 40808, 66195, -1000, -1000, 10259, 4515, 15355, - 15355, 4991, 18990, 15355, 4037, 15355, 15355, 15355, 3557, 8056, - 66195, 15355, -1000, 3556, 3555, -1000, -1000, 2814, 15355, -1000, - -1000, 15355, -1000, -1000, 15355, 18990, 15355, -1000, 15355, 15355, - 15355, -1000, -1000, 3842, 3842, 1185, 4037, 4037, 4037, 2406, - 15355, 15355, 4037, 4037, 4037, 2390, 4037, 4037, 4037, 4037, - 4037, 4037, 4037, 4037, 4037, 4037, 4037, 4037, 4037, 3552, - 3549, 3548, 3545, 15355, 3543, 15355, 15355, 15355, 15355, 15355, - 14628, 4118, -247, -1000, 12440, 3983, 4118, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -305, 3675, 66195, - 3340, 3337, -400, -402, 1484, -402, 2124, -1000, -323, 1393, - 329, 66195, -1000, 3336, 2930, 66195, 3325, 2928, 257, 232, - 66195, 66195, 66195, 24, 1400, 1340, 1356, -1000, -1000, 66195, - 67645, -1000, 66195, 2520, 66195, 66195, 1086, 66195, 4033, -1000, - 66195, 66195, 1086, 1086, 1086, -1000, 60395, 3324, 52414, 66195, - 66195, 361, 66195, 66195, 66195, 1086, 1086, 1086, 1086, 66195, - -1000, 3948, 52414, 3943, 3440, 3673, 1051, 1051, -1000, 66195, - 1975, 4031, 66195, 1099, -1000, 2037, -1000, -1000, -1000, -1000, - 34283, 34283, 29208, 34283, -1000, 213, 66195, 66195, 66195, 6368, - 66195, 444, 4017, 1206, 60395, 61845, 4071, -1000, 52414, 66195, - 66195, 1951, -1000, 1134, 45158, -1000, 66195, 1834, -1000, 35, - -1000, 15, 44, 2399, 44, 2399, 1132, -1000, 756, 631, - 28472, 694, 52414, 9521, -1000, -1000, 2399, 2399, 9521, 9521, - 2190, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1950, -1000, - 261, 4118, -1000, -1000, -1000, -1000, -1000, 2925, 61120, 66195, - 1087, 66195, 60395, 52414, 361, 66195, 1087, 66195, 66195, 66195, - 66195, 66195, -1000, 3672, 2097, -1000, 4016, 66195, 1087, 66195, - 66195, 66195, 1855, -1000, -1000, 27022, 2096, -1000, -1000, 2502, - -1000, 15355, 19728, -280, 15355, 19728, 19728, 15355, 19728, -1000, - 15355, 2098, -1000, -1000, 633, -1000, -1000, 2924, -1000, 2920, - -1000, -1000, -1000, -1000, -1000, 3320, 3320, -1000, 2915, -1000, - -1000, -1000, -1000, 3631, 2913, -1000, -1000, 2912, -1000, -1000, - -1000, -1000, -175, 3542, 1502, -1000, 3311, 4118, -1000, -252, - 4172, 15355, 1487, 3670, 1087, -1000, 182, -414, 2473, 2471, - 2464, 4096, 66195, -1000, 4101, -1000, -1000, 481, -1000, -1000, - -1000, 691, 714, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 2082, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 5775, -124, -125, 1913, -1000, 66195, 66195, - -1000, 66195, -1000, -172, -1000, -1000, 2907, 4120, 66195, 4181, - 66195, -353, 4181, 4181, 66195, -348, 361, -1000, 2256, 2256, - 2559, 66195, 66195, 66195, 3841, 66195, 206, 66195, 4181, 4181, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2369, 4181, 4181, - 1960, 2288, 2369, -1000, -1000, 2369, -414, -1000, 2369, -1000, - -1000, -1000, -414, 2073, -414, 66195, -1000, -1000, -1000, -1000, - -1000, 483, 52414, 56764, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 1903, -1000, -1000, -1000, 1130, 306, 2286, -1000, -1000, - 228, 236, 275, 1265, 2559, -1000, 2531, 2544, -1000, 910, - -1000, -1000, -1000, -1000, 3669, -1000, -1000, -1000, 3509, 2745, - 2549, -1000, 2320, 2320, 2280, 2280, 2280, 2280, 2280, 2575, - 2575, 2256, 2256, -1000, -1000, -1000, 10259, 3667, 18990, 18990, - 18990, 18990, 1218, 1218, 4299, 5319, -1000, -1000, 2192, 2192, - -1000, -1000, -1000, -1000, 15355, 200, 2501, -1000, 15355, 2873, - 2063, 2830, 2040, 2279, -1000, 3626, 15355, 2068, 5115, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 454, -1000, 14733, 14733, 14733, 14733, -1000, 868, + 16929, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 18393, 18393, + 18393, 18393, 18393, 18393, 18393, 18393, 18393, 18393, 18393, 18393, + 18393, 18393, 18393, 3666, 2395, 18393, 18393, 18393, 18393, 346, + 33061, 1674, 3412, 1835, 360, 2210, 2210, 2210, 2210, 14733, + -1000, 2501, 2598, 14733, 14733, 14733, 14733, 41091, 68113, -1000, + -1000, 9602, 4681, 14733, 14733, 5484, 18393, 14733, 3979, 14733, + 14733, 14733, 3548, 7384, 68113, 14733, -1000, 3547, 3546, -1000, + -1000, 2739, 14733, -1000, -1000, 14733, -1000, -1000, 14733, 18393, + 14733, -1000, 14733, 14733, 14733, -1000, -1000, 3837, 3837, 1064, + 3979, 3979, 3979, 2368, 14733, 14733, 3979, 3979, 3979, 2346, + 3979, 3979, 3979, 3979, 3979, 3979, 3979, 3979, 3979, 3979, + 3979, 3979, 3979, 3545, 3544, 3541, 3540, 14733, 3539, 14733, + 14733, 14733, 14733, 14733, 14001, 4054, -238, -1000, 11798, 3938, + 4054, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -300, 3678, 68113, 3317, 3312, -406, -408, 1353, -408, + 2027, -1000, -319, 1348, 309, 68113, -1000, 3311, 2950, 68113, + 3306, 2946, 249, 237, 68113, 68113, 68113, -6, 1354, 1299, + 1318, -1000, -1000, 68113, 69573, -1000, 68113, 2507, 68113, 68113, + 1024, 1024, 68113, 3975, -1000, 68113, 68113, 1024, 1024, 1024, + -1000, 62273, 3305, 54237, 68113, 68113, 606, 68113, 68113, 68113, + 1024, 1024, 1024, 1024, 68113, -1000, 3893, 54237, 3883, 3526, + 3676, 962, 962, -1000, 68113, 1832, 3974, 68113, 1038, -1000, + 2061, -1000, -1000, -1000, -1000, 33791, 33791, 28681, 33791, -1000, + 225, 68113, 68113, 68113, 68113, 6545, 68113, 463, 3958, 1153, + 62273, 63733, 4012, -1000, 54237, 68113, 68113, 1775, -1000, 1084, + 45471, -1000, 68113, 1727, -1000, -10, -1000, -21, 54, 2279, + 54, 2279, 1083, -1000, 797, 622, 27940, 731, 54237, 8859, + -1000, -1000, 2279, 2279, 8859, 8859, 2085, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 1772, -1000, 266, 4054, -1000, -1000, + -1000, -1000, -1000, 2942, 63003, 68113, 1028, 1028, 68113, 62273, + 54237, 606, 68113, 1028, 68113, 68113, 68113, 68113, 68113, -1000, + 3670, 2019, -1000, 3957, 68113, 1028, 68113, 68113, 68113, 1587, + -1000, -1000, 26480, 2003, -1000, -1000, 2463, -1000, 14733, 19136, + -281, 14733, 19136, 19136, 14733, 19136, -1000, 14733, 2074, -1000, + -1000, 5195, -1000, -1000, 2936, -1000, 2934, -1000, -1000, -1000, + -1000, -1000, 3302, 3302, -1000, 2925, -1000, -1000, -1000, -1000, + 3635, 2923, -1000, -1000, 2919, -1000, -1000, -1000, -1000, -165, + 3538, 1454, -1000, 3298, 4054, -1000, -245, 4097, 14733, 1505, + 3668, 1028, -1000, 188, -416, 2430, 2429, 2428, 4028, 68113, + -1000, 4037, -1000, -1000, 443, -1000, -1000, -1000, 770, 507, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1992, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 3532, - 3531, 2768, 4199, 5389, 3530, 15355, -1000, -1000, 2278, 2277, - 2275, -1000, 2699, 13901, -1000, -1000, -1000, 3529, 2066, 3528, - -1000, -1000, -1000, 3524, 2270, 1681, 3519, 3005, 3518, 3517, - 3516, 3515, 1884, 1879, 1873, -1000, -1000, -1000, -1000, 15355, - 15355, 15355, 15355, 3514, 2269, 2264, 15355, 15355, 15355, 15355, - 3513, 15355, 15355, 15355, 15355, 15355, 15355, 15355, 15355, 15355, - 15355, 66195, 15355, 15355, 233, 233, 233, 233, 3346, 233, - 1945, 1821, 3328, 3322, 2046, 1871, 1869, -1000, -1000, 2255, - -1000, 2559, -1000, -1000, 4172, -1000, 3666, 2906, 1856, -1000, - -1000, -387, 3201, 1129, 66195, -324, 66195, 1129, 66195, 66195, - 2457, 1129, 66195, -325, 3310, -1000, -1000, 3309, -1000, -1000, - 66195, 66195, 66195, 66195, -148, 4006, 3995, -1000, -1000, 1389, - 1337, 1437, -1000, 66195, -1000, 3306, 4015, 4100, 1165, 66195, - -132, 66195, 3664, 3663, 66195, 66195, 66195, 341, -1000, -1000, - 66195, 1792, -1000, 306, -66, 793, 1533, 3840, 1112, 4227, - 66195, 66195, 66195, 66195, 4029, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 3855, -248, -1000, 26297, 66195, 66195, 3440, - 3440, -1000, 3662, 2253, -1000, 59670, 45158, 45158, 45158, 45158, - 45158, 45158, 45158, -1000, 3907, 3877, 3658, -1000, 3903, 3882, - 3880, 672, 3901, 3634, 3648, -1000, 53139, -1000, -1000, -1000, - 2251, 2248, -1000, 2258, 1339, 15355, 4064, 4027, 3648, 1852, - -1000, -1000, -1000, 4174, 1268, 1075, 1075, 1311, 944, 4173, - 24100, -1000, 2357, 1606, 1127, 3963, 487, -1000, 2357, -170, - 1050, 2357, 2357, 2357, 2357, 2357, 2357, 2357, 971, 953, - 2357, 2357, 2357, 2357, 2357, 2357, 2357, 2357, 2357, 2357, - 2357, 1419, 2357, 2357, 2357, 2357, 2357, -1000, 2357, 3654, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1001, 895, -1000, - -1000, 325, 361, 1125, 61, 51, 339, 4061, 532, -1000, - 526, 1792, 785, 4058, 571, 66195, 66195, 1458, 1725, 2399, - 44, 33, -1000, -1000, 1834, 9521, 1834, 9521, 2903, -1000, - -1000, 1123, -1000, -1000, 1533, -1000, 66195, 66195, -1000, -1000, - 3653, 2453, -1000, -1000, 21189, -1000, 9521, 9521, -1000, -1000, - 37183, 66195, -1000, -61, -1000, -42, 4172, -1000, -331, -1000, - -1000, 66195, -1000, 66195, 1517, -1000, 1793, 1533, 3854, 66195, - 1517, 1517, 1517, -1000, -1000, 22650, 66195, 66195, -1000, 3305, - -1000, 4198, -331, 4181, 13167, -1000, 45158, -1000, -1000, 58939, - -1000, 58214, 2482, -1000, 19728, 2543, 218, -1000, 300, -365, - 217, 2479, 216, 2559, -1000, -1000, 3512, 3511, 3508, 2239, - -1000, 2238, 3507, -1000, 2236, 2206, 2897, -1000, 139, 4172, - 3300, 3983, -221, 1789, -1000, 2632, -1000, -248, -1000, 25561, - -1000, 66195, 66195, 66195, 3292, 2696, 4026, 2956, -363, 15355, - 57489, 15355, 1314, 2054, 263, -1000, -1000, -1000, 66195, 3295, - -1000, 2205, -1000, -1000, -1000, -1000, 2896, -1000, -1000, 2288, - 66195, -1000, -1000, 2053, 66195, 45883, -1000, -1000, -1000, 66195, - -1000, 361, -1000, 52414, -1000, 2288, -1000, -1000, 4181, -1000, - -1000, 15355, 15355, 4181, 2288, 2288, -1000, 2369, -1000, 66195, - -1000, -414, 56764, 1638, -1000, 1122, 2051, 2044, -1000, 52414, - 473, 52414, -1000, -1000, 4143, -1000, 66195, 3993, -1000, -1000, - -1000, 3201, 2452, -413, 66195, -1000, -1000, -1000, -1000, -1000, - 2198, -1000, 1218, 1218, 4299, 4552, -1000, 18990, -1000, 18990, - -1000, -1000, -1000, -1000, 3307, -1000, 2366, -1000, 15355, 2528, - 316, 15355, 316, 2148, 32833, 40808, -149, 3992, 3294, 66195, - 15355, -1000, -1000, 15355, 15355, 18990, -1000, 3290, -1000, -1000, - -1000, -1000, 15355, 15355, 2750, -1000, 66195, -1000, -1000, -1000, - -1000, 32833, -1000, 18990, -1000, -1000, -1000, -1000, 15355, 15355, - 15355, 1819, 1819, 3273, 2196, 233, 233, 233, 3256, 3251, - 3223, 2195, 233, 3219, 3183, 3162, 3148, 3142, 3123, 3105, - 3095, 3091, 3077, 2183, 3073, 2026, -1000, 3650, -1000, -1000, - -1000, 233, -1000, 233, 15355, 233, 15355, 233, 233, 15355, - 2656, 16809, 12440, -1000, 3983, 606, 1774, 2895, 3291, 148, - -1000, 2451, -1000, 569, -1000, 66195, 4197, -1000, 2042, 3286, - 56039, -1000, 1394, 66195, -1000, -1000, 4196, 4195, -1000, -1000, - 66195, 66195, 66195, -1000, -1000, -1000, 1334, -1000, 3279, -1000, - 397, 328, 2802, 4219, 2508, 3274, 363, 1525, 22650, 3648, - 3649, 3648, 250, 2357, 727, 732, 52414, 995, -1000, 55314, - 2710, 2448, 3853, 1680, 3977, 66195, 54589, 3646, 1276, 1168, - 3645, 4025, 742, 633, -1000, 3980, 1513, -1000, 3643, -1000, - 2141, 3926, -1000, 1750, -1000, 2447, 2139, 2133, 2445, -1000, - -1000, 5106, -1000, 66195, 66195, 1854, -1000, 2032, 1942, 3839, - 3852, 3839, -1000, 3839, -1000, -1000, -1000, -1000, 3893, 3272, - -1000, 3892, -1000, 3890, -1000, 3878, -1000, -1000, -1000, -1000, - -1000, -1000, 45158, -1000, -1000, 1339, -1000, 4099, 1309, 1309, - 1309, 3501, 36458, 742, 633, 4023, 6650, 947, 3296, -1000, - 66195, -1000, -1000, -1000, 1073, -1000, 1309, 1086, 66195, 2591, - 1309, 2589, 3641, -1000, -1000, 66195, 66195, 66195, 66195, -1000, - -1000, 66195, -1000, 66195, 66195, 66195, 66195, 66195, 53864, -1000, - 66195, 66195, -1000, 66195, 2587, 66195, 2586, 3976, -1000, 2357, - 2357, 1277, -1000, -1000, 761, -1000, 53864, 2894, 2893, 2892, - 2890, 3270, 3269, 3239, 2357, 2357, 2889, 3234, 53139, 3233, - 1516, 2886, 2883, 2881, 2868, 3232, 1452, -1000, 3231, 2861, - 2776, 2771, 66195, 3639, 3132, -1000, -1000, 2802, 3230, 3638, - 2880, 3229, 1172, 361, 3227, 3851, 250, 2357, 531, 66195, - 2444, 2443, 732, 807, 807, 792, -69, 29933, -1000, -1000, - -1000, 66195, 66195, 9521, -1000, -1000, -24, -52, -1000, -1000, - -1000, -1000, 52414, 3220, 694, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 3983, -1000, -1000, -1000, 66195, 1056, 3500, 1764, - -1000, -1000, -1000, 633, 3637, 3630, 3630, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 3630, 3630, 3633, -1000, - -1000, 3627, 3627, 3627, 3626, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 1464, 3631, 3632, 3632, 3631, -1000, + 5751, -113, -121, 1768, -1000, 68113, 68113, -1000, 68113, -1000, + -162, -1000, -1000, 2910, 4055, 68113, 4113, 68113, -348, 4113, + 4113, 68113, -355, 4113, 606, -1000, 2210, 2210, 2598, 68113, + 68113, 68113, 3790, 68113, 208, 68113, 4113, 4113, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 2360, 4113, 4113, 1909, 2253, + 2360, -1000, -1000, 2360, -416, -1000, 2360, -1000, -1000, -1000, + -416, 1988, -416, 68113, -1000, -1000, -1000, -1000, -1000, 441, + 54237, 58617, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1766, + -1000, -1000, -1000, 1080, 353, 2272, -1000, -1000, 227, 241, + 317, 1189, 2598, -1000, 2514, 2530, -1000, 920, -1000, -1000, + -1000, -1000, 3667, -1000, -1000, -1000, 3065, 4198, 2534, -1000, + 2354, 2354, 2188, 2188, 2188, 2188, 2188, 2338, 2338, 2210, + 2210, -1000, -1000, -1000, 9602, 3666, 18393, 18393, 18393, 18393, + 1142, 1142, 6430, 6416, -1000, -1000, 2199, 2199, -1000, -1000, + -1000, -1000, 14733, 207, 2459, -1000, 14733, 2816, 2108, 2808, + 1745, 2271, -1000, 3631, 14733, 1970, 5965, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 66195, -1000, 4179, -1000, 1752, -1000, -1000, 2031, -1000, 2516, - -395, 19728, 2293, 2266, -1000, 15355, 19728, 15355, -286, 503, - -293, -1000, -1000, -1000, -1000, 3212, -1000, -1000, -1000, 2875, - -1000, 2874, -1000, 223, 259, 3983, 273, -1000, 4226, 15355, - 3950, -1000, -1000, 1513, 2132, 3924, 1750, 4232, 2130, -1000, - -1000, -1000, -1000, 4092, -1000, -1000, -1000, -1000, -1000, 195, - -422, -423, 188, 3210, 66195, 2871, -1000, -1000, -1000, -1000, - 4181, 2288, 4181, 45883, 2288, 2341, -1000, -1000, -1000, -1000, - 1533, -1000, 4181, -1000, 2559, 2559, -414, 4181, 4181, 2288, - -1000, -1000, 4192, 52414, 361, 2225, 51689, -1000, 447, 1870, - 741, 3209, -1000, 1161, 147, 3206, 3201, -1000, -1000, -1000, - -1000, 18990, 2256, -1000, -1000, -1000, 2559, 15355, 3493, 2707, - 3492, 3491, -1000, 3630, 3630, -1000, 3626, 3627, 3626, 2192, - 2192, 3490, -1000, 3625, -1000, 3992, -1000, 2119, 2675, 3053, - 5075, -1000, 3022, 3018, 15355, -1000, 3488, 4468, 2019, 1770, - 2999, -81, -205, 233, 233, -1000, -1000, -1000, -1000, 233, - 233, 233, 233, -1000, 233, 233, 233, 233, 233, 233, - 233, 233, 233, 233, 233, 233, 15355, 1047, -1000, -1000, - 1813, -1000, 1795, -1000, -1000, 2919, -103, -315, -109, -316, - -1000, -1000, 3487, 1733, -1000, -1000, -1000, -1000, -1000, 4991, - 1701, 800, 800, 3201, 3199, 66195, 3197, -326, 66195, -1000, - -424, -427, -327, 66195, 3196, 66195, 66195, 71, 2494, 2593, - -1000, 3194, -1000, -1000, 50964, 66195, 66195, 66920, 893, 66195, - 66195, 3193, -1000, -1000, 3621, -177, 3620, -136, 3190, 3486, - 1676, -1000, -1000, 66195, -1000, -1000, -1000, 3483, 4022, 23375, - 4021, 2857, -1000, -1000, -1000, 35733, 66195, 807, -1000, -1000, - -1000, 911, 499, 2864, 718, -1000, 66195, 708, 564, 3939, - 2442, 3189, 66195, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 3977, -1000, 1187, -414, 66195, 724, 43708, - 20464, -1000, 3482, 66195, -1000, 66195, 50233, 23375, -1000, 2357, - 23375, 3482, 681, 2386, -1000, 2566, -248, 12440, 3547, 66195, - -248, 66195, 12440, -1000, 66195, -1000, 66195, 15355, 3480, -1000, - 1046, 1639, 152, 45158, 66195, -1000, 48058, 15355, -1000, -1000, - 15355, 3619, -1000, 15355, -1000, -1000, -1000, 3479, -1000, -1000, - -1000, -1000, -1000, -1000, 3618, 3940, -1000, -1000, -1000, -1000, - 1660, 46608, -1000, 2431, -1000, -1000, 681, -1000, 3482, -1000, - 1850, 24825, 822, 516, 514, -1000, 896, -1000, -1000, 1045, - 3960, 633, -1000, 66195, -1000, 66195, -1000, 66195, 66195, 1086, - 15355, 3960, 66195, 1119, -1000, 1433, 715, 867, 1085, 1085, - 1650, -1000, 3992, -1000, -1000, 1647, -1000, -1000, -1000, -1000, - 66195, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 32833, 32833, - 4051, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 3179, 3177, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 3537, 3536, 2802, + 4137, 6289, 3535, 14733, -1000, -1000, 2269, 2259, 2258, -1000, + 2708, 13269, -1000, -1000, -1000, 3533, 1956, 3532, -1000, -1000, + -1000, 3531, 2256, 1627, 3523, 4616, 3519, 3518, 3517, 3516, + 1763, 1757, 1755, -1000, -1000, -1000, -1000, 14733, 14733, 14733, + 14733, 3515, 2250, 2247, 14733, 14733, 14733, 14733, 3514, 14733, + 14733, 14733, 14733, 14733, 14733, 14733, 14733, 14733, 14733, 68113, + 14733, 14733, 212, 212, 212, 212, 3376, 212, 2075, 1972, + 3356, 3351, 2103, 1746, 1739, -1000, -1000, 2245, -1000, 2598, + -1000, -1000, 4097, -298, 3665, 2904, 1732, -1000, -1000, -393, + 3205, 1074, 68113, -320, 68113, 1074, 68113, 68113, 2427, 1074, + 68113, -321, 3297, -1000, -1000, 3294, -1000, -1000, 68113, 68113, + 68113, 68113, -135, 3949, 3945, -1000, -1000, 1338, 1311, 1341, + -1000, 68113, -1000, 3293, 3955, 4036, 1133, 68113, 68113, -118, + 68113, 3663, 3661, 68113, 68113, 68113, 399, -1000, -1000, 68113, + 1545, -1000, 353, -53, 735, 1504, 3788, 1085, 4181, 68113, + 68113, 68113, 68113, 3973, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 3806, -239, -1000, 25750, 68113, 68113, 3526, 3526, + -1000, 3660, 2244, -1000, 61543, 45471, 45471, 45471, 45471, 45471, + 45471, 45471, -1000, 3851, 3824, 3659, -1000, 3842, 3839, 3829, + 556, 3849, 3815, 3651, -1000, 54967, -1000, -1000, -1000, 1674, + 2242, -1000, 2249, 1242, 14733, 4008, 3904, 3971, 3651, 1728, + -1000, -1000, -1000, 4099, 1298, 987, 987, 1261, 816, 4098, + 23538, -1000, 2162, 1421, 1070, 3911, 458, -1000, 2162, -155, + 954, 2162, 2162, 2162, 2162, 2162, 2162, 2162, 866, 844, + 2162, 2162, 2162, 2162, 2162, 2162, 2162, 2162, 2162, 2162, + 2162, 1362, 2162, 2162, 2162, 2162, 2162, -1000, 2162, 3657, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 883, 832, -1000, + -1000, 335, 606, 1069, 69, 67, 396, 4004, 490, -1000, + 509, 1545, 818, 4001, 528, 68113, 68113, 1719, 1532, 2279, + 54, -31, -1000, -1000, 1727, 8859, 1727, 8859, 2903, -1000, + -1000, 1068, -1000, -1000, 1504, -1000, 68113, 68113, -1000, -1000, + 3655, 2424, -1000, -1000, 20607, -1000, 8859, 8859, -1000, -1000, + 37441, 68113, -1000, -48, -1000, -27, 4097, -1000, -336, -1000, + -1000, 68113, -1000, 68113, 68113, 1480, -1000, 1715, 1504, 3804, + 68113, 1480, 1480, 1480, -1000, -1000, 22078, 68113, 68113, -1000, + 3290, -1000, 4134, -336, 4113, 12530, -1000, 45471, -1000, -1000, + 60807, -1000, 60077, 2450, -1000, 19136, 2654, 218, -1000, 316, + -362, 217, 2489, 216, 2598, -1000, -1000, 3512, 3511, 3508, + 2240, -1000, 2230, 3507, -1000, 2227, 2225, 2901, -1000, 91, + 4097, 3286, 3938, -211, 1713, -1000, 2778, -1000, -239, -1000, + 25009, -1000, 68113, 68113, 68113, 3284, 2757, 3970, 2970, -366, + 14733, 59347, 14733, 1245, 1932, 278, -1000, -1000, -1000, 68113, + 3275, -1000, 2224, -1000, -1000, -1000, -1000, 2900, -1000, -1000, + 2253, 68113, -1000, -1000, 1738, 68113, 47661, -1000, -1000, -1000, + -1000, 68113, -1000, 606, -1000, 54237, -1000, 2253, -1000, -1000, + 4113, -1000, -1000, 14733, 14733, 4113, 2253, 2253, -1000, 2360, + -1000, 68113, -1000, -416, 58617, 1625, -1000, 1066, 1931, 1928, + -1000, 54237, 452, 54237, -1000, -1000, 4067, -1000, 68113, 3943, + -1000, -1000, -1000, 3205, 2423, -413, 68113, -1000, -1000, -1000, + -1000, -1000, 2223, -1000, 1142, 1142, 6430, 6248, -1000, 18393, + -1000, 18393, -1000, -1000, -1000, -1000, 3332, -1000, 2347, -1000, + 14733, 2553, 346, 14733, 346, 2186, 32331, 41091, -136, 3942, + 3325, 68113, 14733, -1000, -1000, 14733, 14733, 18393, -1000, 3320, + -1000, -1000, -1000, -1000, 14733, 14733, 2694, -1000, 68113, -1000, + -1000, -1000, -1000, 32331, -1000, 18393, -1000, -1000, -1000, -1000, + 14733, 14733, 14733, 1701, 1701, 3304, 2222, 212, 212, 212, + 3300, 3267, 3263, 2214, 212, 3258, 3245, 3235, 3192, 3187, + 3175, 3159, 3135, 3109, 3070, 2191, 3048, 2091, -1000, 3654, + -1000, -1000, -1000, 212, -1000, 212, 14733, 212, 14733, 212, + 212, 14733, 2690, 16197, 11798, -1000, 3938, -1000, 3653, 953, + 1708, 2899, 3272, 133, -1000, 2420, -1000, 520, -1000, 68113, + 4133, -1000, 1919, 3251, 57887, -1000, 1320, 68113, -1000, -1000, + 4132, 4130, -1000, -1000, 68113, 68113, 68113, -1000, -1000, -1000, + 1303, -1000, 3246, -1000, 388, 358, 2766, 4164, 4162, 2491, + 3244, 422, 1590, 22078, 3651, 3652, 3651, 231, 2162, 647, + 795, 54237, 893, -1000, 57157, 2697, 2419, 3802, 1159, 3931, + 68113, 56427, 3648, 1471, 1092, 3646, 3969, 669, 5195, -1000, + 3936, 1467, -1000, 3645, -1000, 2185, 3870, -1000, 1693, -1000, + 2411, 2169, 2168, 2408, -1000, -1000, 5287, -1000, 68113, 68113, + 1583, -1000, 1899, 1977, 3787, 3801, 3787, -1000, 3787, -1000, + -1000, -1000, -1000, 3845, 3243, -1000, 3843, -1000, 3841, -1000, + 3832, -1000, -1000, -1000, -1000, -1000, -1000, 45471, -1000, -1000, + 1242, -1000, 4031, 1253, 1253, 1253, 3506, 36711, 35981, -1000, + -1000, 669, 5195, 3967, 74702, 791, 3554, -1000, 68113, -1000, + -1000, -1000, 1055, -1000, 1253, 1024, 68113, 2565, 1253, 2561, + 3644, -1000, -1000, 68113, 68113, 68113, 68113, -1000, -1000, 68113, + -1000, 68113, 68113, 68113, 68113, 68113, 55697, -1000, 68113, 68113, + -1000, 68113, 2560, 68113, 2555, 3917, -1000, 2162, 2162, 1216, + -1000, -1000, 792, -1000, 55697, 2890, 2883, 2882, 2878, 3238, + 3237, 3233, 2162, 2162, 2876, 3231, 54967, 3229, 1572, 2875, + 2868, 2864, 2867, 3228, 1602, -1000, 3227, 2799, 2752, 2748, + 68113, 3643, 3148, -1000, -1000, 2766, 3226, 3641, 2861, 3221, + 1141, 606, 3220, 3800, 231, 2162, 488, 68113, 2402, 2399, + 795, 749, 749, 712, -56, 29411, -1000, -1000, -1000, 68113, + 68113, 8859, -1000, -1000, -22, -28, -1000, -1000, -1000, -1000, + 54237, 3219, 731, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 3938, -1000, -1000, -1000, -1000, 68113, 1004, 3505, 1707, -1000, + -1000, -1000, 5195, 3639, 3634, 3634, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 3634, 3634, 3637, -1000, -1000, + 3632, 3632, 3632, 3631, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 1359, 3635, 3636, 3636, 3635, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 68113, + -1000, 4111, -1000, 1700, -1000, -1000, 1898, -1000, 2508, -402, + 19136, 2453, 2370, -1000, 14733, 19136, 14733, -283, 474, -288, + -1000, -1000, -1000, -1000, 3215, -1000, -1000, -1000, 2854, -1000, + 2853, -1000, 243, 251, 3938, 310, -1000, 4169, 14733, 3908, + -1000, -1000, 1467, 2154, 3868, 1693, 4186, 2144, -1000, -1000, + -1000, -1000, 4027, -1000, -1000, -1000, -1000, -1000, 203, -422, + -423, 198, 3213, 68113, 2847, -1000, -1000, -1000, -1000, 4113, + 2253, 4113, 47661, 2253, 2319, -1000, -1000, -1000, -1000, 1504, + -1000, 4113, -1000, 2598, 2598, -416, 4113, 4113, 2253, -1000, + -1000, 4129, 54237, 606, 2116, 53507, -1000, 446, 1624, 766, + 3210, -1000, 1105, 132, 3206, 3205, -1000, -1000, -1000, -1000, + 18393, 2210, -1000, -1000, -1000, 2598, 14733, 3503, 2741, 3497, + 3496, -1000, 3634, 3634, -1000, 3631, 3632, 3631, 2199, 2199, + 3495, -1000, 3629, -1000, 3942, -1000, 2134, 2688, 3032, 6076, + -1000, 3028, 2917, 14733, -1000, 3493, 5695, 1870, 1767, 2912, + -75, -195, 212, 212, -1000, -1000, -1000, -1000, 212, 212, + 212, 212, -1000, 212, 212, 212, 212, 212, 212, 212, + 212, 212, 212, 212, 212, 14733, 951, -1000, -1000, 1957, + -1000, 1779, -1000, -1000, 2906, -104, -309, -108, -311, -1000, + -1000, 355, 3491, 5484, 1675, 777, 777, 3205, 3204, 68113, + 3203, -322, 68113, -1000, -424, -425, -323, 68113, 3202, 68113, + 68113, 87, 2479, 2585, -1000, 3198, -1000, -1000, 52777, 68113, + 68113, 68843, 829, 68113, 68113, 3194, -1000, -1000, 3625, -1000, + 3624, -166, 3623, -120, 3193, 3490, 1667, -1000, -1000, 68113, + -1000, -1000, -1000, 3485, 3964, 22808, 3962, 2964, -1000, -1000, + -1000, 35251, 68113, 749, -1000, -1000, -1000, 899, 435, 2841, + 733, -1000, 68113, 667, 519, 3885, 2398, 3191, 68113, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 3931, + -1000, 1151, -416, 68113, 645, 44011, 19877, -1000, 3555, 68113, + -1000, 68113, 52041, 22808, -1000, 2162, 22808, 3555, 654, 2285, + -1000, 2550, -239, 11798, 3468, 68113, -239, 68113, 11798, -1000, + 68113, -1000, 68113, 14733, 3473, -1000, 950, 1492, 156, 45471, + 68113, -1000, 49851, 14733, -1000, -1000, 14733, 3621, -1000, 14733, + -1000, -1000, -1000, 3471, -1000, -1000, -1000, -1000, -1000, -1000, + 3620, 3909, -1000, -1000, -1000, -1000, 1663, 48391, -1000, 2391, + -1000, -1000, 1648, 46931, -1000, 2388, -1000, -1000, 654, -1000, + 3555, -1000, 1908, 24268, 786, 627, 613, -1000, 858, -1000, + -1000, 949, 3906, 5195, -1000, 68113, -1000, 68113, -1000, 68113, + 68113, 1024, 14733, 3906, 68113, 1059, -1000, 1385, 755, 643, + 1016, 1016, 1633, -1000, 3942, -1000, -1000, 1632, -1000, -1000, + -1000, -1000, 68113, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 32331, 32331, 3994, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 3188, 3185, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 66195, 2118, -1000, 2430, 3174, - -136, 8794, -1000, -1000, 1118, -1000, 3849, 1156, 2857, 35733, - 2426, 2399, 3171, 3165, 807, -1000, 3163, 3161, -1000, 2710, - 2423, 1151, 66195, -1000, 1524, 66195, 66195, -1000, 1787, -1000, - 2417, 1759, -1000, -1000, -1000, -1000, 1638, 3478, -1000, -1000, - 4098, -1000, -1000, -1000, -1000, -1000, 22650, 3973, 713, 4177, - 4171, 49508, -1000, -395, 2365, -1000, 2504, 211, 2436, 66195, - -1000, -1000, -1000, 3474, 3470, -254, 251, 4168, 4165, 4098, - -266, 3160, 438, -1000, -1000, 3966, 1790, -248, 4118, -1000, - 1410, -1000, -1000, -1000, -1000, -434, -1000, -1000, -1000, 4181, - -1000, 2288, 4181, 4181, -357, -1000, -1000, -1000, -1000, 4181, - 361, -1000, 1864, -1000, -1000, -1000, -1000, -1000, -1000, 285, - -1000, 66195, -1000, 1585, 138, -1000, 2559, -1000, 316, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 3159, - -1000, -1000, -1000, 15355, -1000, -1000, -1000, -1000, 2855, -1000, - -1000, 15355, 15355, -1000, 3469, 3158, 3467, 3149, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 2851, 4232, -1000, 4161, - 233, 15355, 233, 15355, 233, 2100, 3466, 3465, 2091, 3445, - 3436, -1000, 15355, 3435, 4991, 1252, 3146, 1252, -1000, -1000, - -1000, -1000, 66195, -1000, -1000, -1000, 66195, 4191, 35008, 1106, - -414, 750, 3617, -1000, 759, 2494, 1382, 3616, 3140, -1000, - 66195, 4190, 66195, 2802, 883, 2802, 957, 66195, -331, 46608, - -138, 2862, 8794, -1000, 3138, -1000, -152, 1525, 633, 1162, - 3482, 3424, 1582, -1000, -1000, -1000, -1000, 3482, -1000, 3133, - 299, -1000, -1000, -1000, 636, -1000, 2850, -1000, -1000, 2767, - 2020, 330, -1000, -1000, -1000, -1000, -1000, -1000, 2774, 66195, - 48783, 2774, 2836, 2414, -415, -1000, 3614, -1000, 2357, 2357, - 2357, 1106, 710, 66195, 2088, -1000, 2357, 2357, 3408, -1000, - -1000, 3945, 66195, 3401, -338, 3398, 4225, 1053, 2363, 2362, - -1000, 2848, 1343, -1000, 3397, 1534, -248, -1000, -1000, 1513, - -1000, -1000, -1000, 2412, 2559, -1000, 34283, 45158, 48058, 1691, - -1000, 2030, -1000, 2623, 2559, 66195, 2559, -1000, 47333, -1000, - 4156, 4155, 46608, 2087, 45883, 1053, -1000, 808, 2837, 18990, - 3613, 18990, 3612, 836, 3610, 2074, -1000, 66195, -1000, -1000, - 66195, 5047, 3607, -1000, 3606, 3831, 791, 3605, 3603, 66195, - 2844, -1000, 3960, 66195, 967, 3967, -1000, 587, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 898, -1000, 66195, -1000, - 66195, -1000, 2178, -1000, 32833, -1000, -1000, 2064, -1000, 3132, - 3128, -1000, -1000, 3394, 2559, -1000, 2283, 361, 1147, 66195, - -1000, 299, 3124, 9521, -1000, -1000, -1000, -1000, -1000, 3939, - 3121, 2774, 66195, -1000, 66195, 1524, 1524, 4232, 45158, 66195, - 12440, -1000, -1000, -1000, 4208, -1000, 2294, 66195, -1000, 15355, - 16082, -1000, 1080, 19728, -294, 502, -1000, -1000, -1000, -256, - 3114, -1000, -1000, 4153, 3112, 2957, -1000, 139, 3107, -1000, - 15355, -1000, -1000, -1000, -248, -1000, 1513, -1000, 3096, -1000, - -1000, -1000, 4181, -1000, -1000, 66195, -1000, 1533, -1000, -1000, - 1354, 978, -1000, 3387, 2449, -1000, 2820, -1000, 2796, 2789, - 233, -1000, 233, -1000, 233, 412, 15355, -1000, 2763, -1000, - 2724, -1000, -1000, 3093, -1000, -1000, -1000, 3092, -1000, -1000, - 2718, -1000, 3383, -1000, 3089, -1000, -1000, 3087, 3083, -328, - -1000, -1000, 561, 1106, -1000, 439, 66195, 899, -1000, 44433, - 8794, -416, 700, 66195, 4189, 3082, 2802, 3071, 2802, 66195, - 874, -1000, 2059, 4020, 3070, -1000, 3378, -1000, 3051, 3050, - -1000, -1000, 633, 4220, 4225, 23375, 4220, -1000, -1000, 4141, - -1000, 1994, 545, -1000, -1000, 2746, 749, -1000, -1000, 3049, - 795, -1000, 1524, -1000, -1000, 2407, 2670, 2998, 40808, 32833, - 33558, 3045, -1000, 66195, -1000, -1000, 43708, 2294, 2294, 6884, - 1106, 4087, 699, 611, 4219, 7273, -1000, 3600, 1428, 2292, - -1000, 2833, -1000, 2826, -1000, 66195, -1000, -1000, 1513, 15355, - 4181, 1691, 150, -1000, -1000, 2220, 2507, -1000, 42983, 2027, - 1993, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1428, 3296, - 4148, -1000, 4248, 66195, 3628, 66195, 3599, 2403, 18990, -1000, - 1045, 3921, -1000, -1000, 5047, -1000, -1000, 2584, 18990, -1000, - -1000, 3039, 33558, 1234, 2402, 2401, 1273, 3598, -1000, 909, - 4206, 2825, -1000, -1000, -1000, 1263, 3597, -1000, -272, 3596, - 2565, 2555, -1000, 66195, -1000, 40808, 40808, 1612, 1612, 40808, - 40808, 3595, 1085, -1000, -1000, 18990, -1000, -1000, -1000, 2398, - 5380, 5380, 5380, 5380, -1000, -1000, -1000, 2357, 2145, -1000, - -1000, -1000, -1000, -1000, 66195, 2024, -1000, -1000, -1000, 2836, - -1000, -1000, 1517, -1000, 4118, 1691, -1000, -1000, -1000, -1000, - -1000, 2559, 1806, 279, 3593, 3592, -1000, -395, 66195, 66195, - -259, 2824, -1000, 3038, 247, -1000, -1000, 223, -1000, 1502, - 1513, -1000, -1000, 2288, -262, 153, 32833, 2381, -1000, 3372, - 383, -160, -1000, -1000, -1000, -1000, -1000, -1000, 3369, -1000, - 886, -1000, -1000, -1000, 1502, 233, 233, 3368, 3367, -1000, - -1000, -1000, -1000, -1000, 66195, 66195, -1000, 66195, 3033, 2819, - -1000, -1000, 1965, -1000, -1000, -1000, 2541, 2537, 1933, 3333, - 2995, 66195, 685, 66195, -331, 3032, -331, 3031, 868, 2802, - -1000, -307, -1000, -1000, -1000, -1000, -153, -1000, -1000, 437, - -1000, -1000, -1000, 812, 2951, 2818, -1000, -1000, 541, -1000, - -1000, -1000, 2774, 3030, -1000, -1000, 136, -1000, 2364, 1932, - -1000, -1000, -1000, 636, -1000, -1000, -1000, 1044, -1000, 3482, - 7050, -1000, 1606, -1000, -1000, 66195, -1000, -1000, 1354, -1000, - 1044, 40083, 938, 2330, -1000, 2817, -1000, -1000, 1461, 2559, - 4232, -1000, -1000, 2535, 66195, -1000, -1000, -1000, 42258, 936, - -1000, 828, -1000, 1907, -1000, 1901, 41533, 2813, 3205, -1000, - 6943, 1202, -1000, -1000, 4299, -1000, -1000, -1000, -1000, -1000, - -1000, 3025, 3016, -1000, -1000, -1000, -1000, -1000, 2812, 3589, - -76, -1000, 4046, 3015, 3996, 15355, -1000, -1000, 3587, 1885, - 1882, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 1881, 1862, 40808, -1000, -1000, 4299, 5380, - 2642, -1000, 2357, 2357, 3014, 3012, 623, -1000, -1000, 2357, - 2357, 2357, 2357, 2357, 2357, 3586, 3011, 3010, 2357, 2357, - 2357, 2357, -1000, -1000, 2361, 2357, 2357, 32833, 2357, 2017, - 66195, -1000, -1000, -1000, -1000, -372, 3583, 15355, 15355, -1000, - -1000, -1000, 3582, -1000, -1000, 4147, -254, 4181, -264, 3009, - 220, 276, -1000, 3008, -1000, -154, 3915, -165, -1000, -1000, - 894, -249, 209, 203, 194, -1000, -1000, -1000, 15355, -1000, - -1000, -1000, -1000, 3002, -1000, -1000, -1000, -1000, -1000, 66195, - 3001, -1000, -1000, 134, -1000, 2358, -1000, 66195, 662, -1000, - -331, -1000, -331, 2802, 3000, -1000, 66195, 908, -1000, -1000, - -1000, -1000, 266, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 2998, 2997, -1000, -1000, 802, 4145, -1000, 7273, -1000, 2357, - 636, -1000, 802, 1812, -1000, 2357, 2357, -1000, 740, -1000, - 2261, -1000, 2779, -1000, 4118, 2455, 15355, 2535, -1000, -1000, - -1000, 734, -1000, 811, -1000, -1000, -1000, 1805, -1000, -1000, - -1000, 6943, 820, -1000, 1037, 3581, -1000, -1000, 3312, 15355, - 3580, 2357, 3188, 3578, 2713, -146, 40808, 3829, 3554, 3485, - 3013, 1798, -1000, -1000, 2770, 2766, -1000, -1000, 66195, 2740, - 2731, 2729, 2723, 2720, 2712, 66195, -1000, -1000, 2701, 2691, - 2688, 2671, 2601, 2667, 2663, -1000, 32833, 66195, -1000, -1000, - 3564, 1785, 1781, 66195, 2957, -256, -1000, -1000, 2996, -1000, - 1097, 253, 276, -1000, 4144, 234, 4137, 4136, 1485, 3912, - -1000, -1000, 2526, -1000, 219, 214, 207, -1000, -1000, -1000, - -1000, -1000, 2534, 2534, -331, 2995, 2993, -1000, 66195, -1000, - -1000, 2992, -331, 689, -1000, 394, -1000, -1000, -1000, 5380, - -1000, 4135, 947, -1000, 32833, -1000, -1000, -1000, 40083, 2294, - 2294, -1000, -1000, 2650, -1000, -1000, 4187, 2559, 2433, -1000, - -1000, 2633, -1000, -1000, -1000, 1772, -1000, 66195, 1246, 11713, - -1000, 2690, -1000, 66195, -1000, 15355, -275, 3848, -1000, 377, - 1762, 5380, 1612, 5380, 1612, 5380, 1612, 5380, 1612, 372, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1738, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 68113, 2117, -1000, + 2384, 3178, -120, 8127, -1000, -1000, 1057, -1000, 3799, 1102, + 2964, 35251, 2371, 2279, 3173, 3172, 749, -1000, 3171, 3169, + -1000, 2697, 2349, 1100, 68113, -1000, 1496, 68113, 68113, -1000, + 1607, -1000, 2342, 1594, -1000, -1000, -1000, -1000, 1625, 3463, + -1000, -1000, 4030, -1000, -1000, -1000, -1000, -1000, 22078, 3929, + 644, 4108, 4096, 51311, -1000, -402, 2228, -1000, 2541, 213, + 2448, 68113, -1000, -1000, -1000, 3454, 3453, -248, 263, 4094, + 4091, 4030, -264, 3168, 442, -1000, -1000, 3919, 1638, -239, + 4054, -1000, 1337, -1000, -1000, -1000, -1000, -428, -1000, -1000, + -1000, 4113, -1000, 2253, 4113, 4113, -356, -1000, -1000, -1000, + -1000, 4113, 606, -1000, 1598, -1000, -1000, -1000, -1000, -1000, + -1000, 336, -1000, 68113, -1000, 1613, 131, -1000, 2598, -1000, + 346, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 3167, -1000, -1000, -1000, 14733, -1000, -1000, -1000, -1000, + 2902, -1000, -1000, 14733, 14733, -1000, 3447, 3162, 3446, 3156, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 1729, 15355, -1000, -1000, 1707, -1000, -1000, -259, -1000, 3561, - 2612, 251, 239, 4133, -1000, 2957, 4131, 2957, 2957, -1000, - 215, 4217, 894, -1000, -1000, -1000, -1000, 2494, -1000, 2494, - -1000, -1000, -1000, -1000, -331, -1000, 2991, -1000, -1000, -1000, - 39358, 822, -1000, -1000, -1000, -1000, -1000, 4044, -1000, 4210, - -1000, -1000, 820, 7273, -1000, 11713, 1628, -1000, 2559, -1000, - 1085, -1000, 2680, -1000, -1000, -1000, -1000, 3847, 3846, 4185, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2880, 4186, + -1000, 4090, 212, 14733, 212, 14733, 212, 2115, 3444, 3436, + 2114, 3435, 3434, 3431, 1609, -1000, -1000, -1000, -1000, -1000, + -1000, 3429, 5484, 1230, 3153, 1230, -1000, -1000, -1000, -1000, + 68113, -1000, -1000, -1000, 68113, 4128, 34521, 1051, -416, 680, + 3619, -1000, 673, 2479, 1326, 3618, 3152, -1000, 68113, 4125, + 68113, 2766, 828, 2766, 881, 68113, -336, 48391, 46931, -123, + 2835, 8127, -1000, 3150, -1000, -141, 1590, 5195, 1121, 3555, + 3426, 1584, -1000, -1000, -1000, -1000, 3555, -1000, 3149, 351, + -1000, -1000, -1000, 608, -1000, 2829, -1000, -1000, 2717, 1740, + 369, -1000, -1000, -1000, -1000, -1000, -1000, 2814, 68113, 50581, + 2814, 2918, 2334, -417, -1000, 3617, -1000, 2162, 2162, 2162, + 1051, 638, 68113, 2110, -1000, 2162, 2162, 3416, -1000, -1000, + 3894, 68113, 3410, -357, 3407, 4168, 967, 2377, 2345, -1000, + 2821, 1289, -1000, 3402, 1538, -239, -1000, -1000, 1467, -1000, + -1000, -1000, 2332, 2598, -1000, 33791, 45471, 49851, 1549, -1000, + 1894, -1000, 2504, 2598, 68113, 2598, -1000, 49121, -1000, 4089, + 4088, 48391, 2109, 47661, 46931, 2094, 46201, 967, -1000, 782, + 2813, 18393, 3616, 18393, 3615, 804, 3614, 2086, -1000, 68113, + -1000, -1000, 68113, 5201, 3613, -1000, 3612, 3784, 773, 3611, + 3610, 68113, 2874, -1000, 3906, 68113, 943, 3928, -1000, 560, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 834, -1000, + 68113, -1000, 68113, -1000, 2082, -1000, 32331, -1000, -1000, 2077, + -1000, 3148, 3147, -1000, -1000, 3399, 2598, -1000, 2165, 606, + 1094, 68113, -1000, 351, 3146, 8859, -1000, -1000, -1000, -1000, + -1000, 3885, 3138, 2814, 68113, -1000, 68113, 1496, 1496, 4186, + 45471, 68113, 11798, -1000, -1000, -1000, 4150, -1000, 2614, 68113, + -1000, 14733, 15465, -1000, 995, 19136, -289, 473, -1000, -1000, + -1000, -250, 3136, -1000, -1000, 4085, 3132, 2996, -1000, 91, + 3128, -1000, 14733, -1000, -1000, -1000, -239, -1000, 1467, -1000, + 3113, -1000, -1000, -1000, 4113, -1000, -1000, 68113, -1000, 1504, + -1000, -1000, 1384, 872, -1000, 3396, 2344, -1000, 2865, -1000, + 2848, 2834, 212, -1000, 212, -1000, 212, 381, 14733, -1000, + 2830, -1000, 2825, -1000, -1000, 3112, -1000, -1000, -1000, 3107, + -1000, -1000, -1000, 14733, -1000, 3391, -1000, 3106, -1000, -1000, + 3100, 3099, -329, -1000, -1000, 511, 1051, -1000, 440, 68113, + 748, -1000, 44741, 8127, -418, 637, 68113, 4123, 3093, 2766, + 3084, 2766, 68113, 825, -1000, 2060, 2051, 3961, 3083, -1000, + 3388, -1000, 3082, 3081, -1000, -1000, 5195, 4167, 4168, 22808, + 4167, -1000, -1000, 4066, -1000, 1676, 504, -1000, -1000, 2715, + 821, -1000, -1000, 3080, 764, -1000, 1496, -1000, -1000, 2320, + 2646, 3020, 41091, 32331, 33061, 3079, -1000, 68113, -1000, -1000, + 44011, 2614, 2614, 6668, 1051, 4022, 628, 478, 4164, 74783, + -1000, 3609, 1382, 2313, -1000, 2811, -1000, 2809, -1000, 68113, + -1000, -1000, 1467, 14733, 4113, 1549, 151, -1000, -1000, 2101, + 2487, -1000, 43281, 2041, 2021, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1382, 3554, 4079, + -1000, 5530, 68113, 4991, 68113, 3608, 2318, 18393, -1000, 949, + 3864, -1000, -1000, 5201, -1000, -1000, 2576, 18393, -1000, -1000, + 3078, 3075, 3074, 33061, 1182, 2306, 2301, 1209, 3606, -1000, + 838, 4149, 2807, -1000, -1000, -1000, 1211, 3604, -1000, -272, + 3602, 2540, 2538, -1000, 68113, -1000, 41091, 41091, 1008, 1008, + 41091, 41091, 3599, 1016, -1000, -1000, 18393, -1000, -1000, -1000, + 2295, 5354, 5354, 5354, 5354, -1000, -1000, -1000, 2162, 1985, + -1000, -1000, -1000, -1000, -1000, 68113, 1884, -1000, -1000, -1000, + 2918, -1000, -1000, 1480, -1000, 4054, 1549, -1000, -1000, -1000, + -1000, -1000, 2598, 1595, 274, 3598, 3597, -1000, -402, 68113, + 68113, -252, 2805, -1000, 3071, 254, -1000, -1000, 243, -1000, + 1454, 1467, -1000, -1000, 2253, -255, 80, 32331, 2292, -1000, + 3387, 397, -147, -1000, -1000, -1000, -1000, -1000, -1000, 3379, + -1000, 888, -1000, -1000, -1000, 1454, 212, 212, 3369, 3366, + 2789, -1000, -1000, -1000, -1000, 68113, 68113, -1000, 68113, 3069, + 2798, -1000, -1000, 2014, -1000, -1000, -1000, 2527, 2526, 2010, + 3364, 3016, 68113, 623, 68113, -336, 3068, -336, 3066, 817, + 2766, -1000, -1000, -302, -1000, -1000, -1000, -1000, -143, -1000, + -1000, 455, -1000, -1000, -1000, 758, 2983, 2795, -1000, -1000, + 496, -1000, -1000, -1000, 2814, 3063, -1000, -1000, 128, -1000, + 2270, 2008, -1000, -1000, -1000, 608, -1000, -1000, -1000, 948, + -1000, 3555, 74615, -1000, 1421, -1000, -1000, 68113, -1000, -1000, + -1000, 1384, 2162, -1000, 948, 40361, 852, 2361, -1000, 2783, + -1000, -1000, 1430, 2598, 4186, -1000, -1000, 2523, 68113, -1000, + -1000, -1000, 42551, 836, -1000, 796, -1000, 2007, -1000, 2004, + 41821, 2776, 4759, -1000, 6781, 1122, -1000, -1000, 6430, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 3062, 3055, -1000, + -1000, -1000, -1000, -1000, 2773, 3596, -66, -1000, 3992, 3049, + 3946, 14733, -1000, -1000, 3595, 1993, 1979, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1921, + 1913, 41091, -1000, -1000, 6430, 5354, 2622, -1000, 2162, 2162, + 3046, 3044, 591, -1000, -1000, 2162, 2162, 2162, 2162, 2162, + 2162, 3575, 3040, 3038, 2162, 2162, 2162, 2162, -1000, -1000, + 2211, 2162, 2162, 32331, 2162, 1874, 68113, -1000, -1000, -1000, + -1000, -382, 3567, 14733, 14733, -1000, -1000, -1000, 3566, -1000, + -1000, 4078, -248, 4113, -259, 3037, 224, 313, -1000, 3031, + -1000, -144, 3857, -151, -1000, -1000, 751, -241, 209, 200, + 197, -1000, -1000, -1000, 14733, -1000, -1000, -1000, -1000, -1000, + 3030, -1000, -1000, -1000, -1000, -1000, 68113, 3024, -1000, -1000, + 127, -1000, 2208, -1000, 68113, 621, -1000, -336, -1000, -336, + 2766, 3022, -1000, 68113, 837, -1000, -1000, -1000, -1000, 323, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 3020, 3018, -1000, + -1000, 739, 4076, -1000, 74783, -1000, 2162, 608, -1000, -358, + 739, 1910, -1000, 2162, 2162, -1000, 660, -1000, 2260, -1000, + 2765, -1000, 4054, 2475, 14733, 2523, -1000, -1000, -1000, 656, + -1000, 768, -1000, -1000, -1000, 1868, -1000, -1000, -1000, 6781, + 784, -1000, 938, 3565, -1000, -1000, 3360, 14733, 3562, 2162, + 3357, 3560, 2782, -132, 41091, 3782, 3553, 3340, 3308, 1839, + -1000, -1000, 2764, 2759, -1000, -1000, 68113, 2751, 2740, 2735, + 2721, 2719, 2710, 68113, -1000, -1000, 2699, 2683, 2665, 2664, + 2617, 2661, 2657, -1000, 32331, 68113, -1000, -1000, 3559, 1820, + 1816, 68113, 2996, -250, -1000, -1000, 3017, -1000, 1033, 236, + 313, -1000, 4075, 253, 4074, 4072, 1450, 3855, -1000, -1000, + 2521, -1000, 220, 202, 189, -1000, -1000, -1000, -1000, -1000, + 2559, 2559, -336, 3016, 3015, -1000, 68113, -1000, -1000, 3014, + -336, 705, -1000, 432, -1000, -1000, -1000, 5354, -1000, 4064, + 791, -1000, 32331, -1000, 4162, -1000, -1000, 40361, 2614, 2614, + -1000, -1000, 2632, -1000, -1000, 4120, 2598, 2474, -1000, -1000, + 2607, -1000, -1000, -1000, 1758, -1000, 68113, 1150, 11066, -1000, + 2746, -1000, 68113, -1000, 14733, -275, 3797, -1000, 300, 1747, + 5354, 1008, 5354, 1008, 5354, 1008, 5354, 1008, 420, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1741, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1722, + 14733, -1000, -1000, 1714, -1000, -1000, -252, -1000, 3558, 2564, + 263, 246, 4063, -1000, 2996, 4059, 2996, 2996, -1000, 222, + 4156, 751, -1000, -1000, -1000, -1000, 2479, -1000, 2479, -1000, + -1000, -1000, -1000, -336, -1000, 3008, -1000, -1000, -1000, 39631, + 786, -1000, -1000, -1000, -1000, -1000, -1000, 3986, -1000, 4153, + -1000, -1000, 784, 74783, -1000, 11066, 1684, -1000, 2598, -1000, + 1016, -1000, 2722, -1000, -1000, -1000, -1000, 3794, 3534, 4117, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 3510, 3110, -1000, 66195, -1000, 4042, 32108, 241, -1000, - -1000, -1000, 2958, -1000, 2957, -1000, -1000, 2356, -162, -1000, - -1000, -1000, -1000, -312, -1000, 66195, 808, 66195, 3439, -1000, - 7273, 1616, -1000, 11713, -1000, -275, -1000, 4205, -1000, 4188, - 1236, 1236, 5380, 5380, 5380, 5380, 15355, -1000, -1000, -1000, - 66195, -1000, 1608, -1000, -1000, -1000, 2010, -1000, -1000, -1000, - -1000, 2955, -166, -1000, -1000, 2865, 1595, 3296, 1461, 66195, - 3129, -1000, -1000, -1000, -1000, -1000, -1000, 2692, 915, -1000, - 2835, 1456, -1000, 2348, -1000, 38633, 66195, -1000, -1000, -1000, - -1000, -1000, 1574, 15355, -1000, -1000, -1000, -1000, 66195, 10986, - -1000, 1995, 3920, 1567, -1000, -1000, 2559, 66195, 3097, -1000, - -1000, 15355, 1559, -1000, + -1000, 3556, 3240, -1000, 68113, -1000, 3984, 31601, 233, -1000, + -1000, -1000, 3006, -1000, 2996, -1000, -1000, 2160, -149, -1000, + -1000, -1000, -1000, -307, -1000, 68113, 782, 68113, 3383, -1000, + 74783, 1664, -1000, 11066, -1000, -275, -1000, 4148, -1000, 4121, + 1223, 1223, 5354, 5354, 5354, 5354, 14733, -1000, -1000, -1000, + 68113, -1000, 1659, -1000, -1000, -1000, 1867, -1000, -1000, -1000, + -1000, 2974, -152, -1000, -1000, 2916, 1651, 3554, 1430, 68113, + 3527, -1000, -1000, -1000, -1000, -1000, -1000, 2631, 842, -1000, + 3114, 1425, -1000, 2145, -1000, 38901, 68113, -1000, -1000, -1000, + -1000, -1000, 1645, 14733, -1000, -1000, -1000, -1000, 68113, 10334, + -1000, 1866, 3863, 1573, -1000, -1000, 2598, 68113, 3469, -1000, + -1000, 14733, 1559, -1000, } var yyPgo = [...]int{ - 0, 196, 68, 277, 202, 4967, 132, 282, 423, 306, - 283, 4966, 281, 275, 4965, 4963, 4962, 304, 301, 4960, - 4959, 4957, 4956, 4955, 4949, 4947, 4945, 4944, 4943, 4942, - 4941, 4940, 4938, 4937, 4936, 4935, 4934, 4933, 4932, 4931, - 4930, 4929, 4927, 4926, 4925, 4924, 4923, 4922, 4921, 4920, - 4915, 4914, 4913, 4912, 4911, 4910, 274, 4909, 4908, 4907, - 4906, 4902, 4901, 4900, 4899, 4897, 4896, 4895, 4894, 4893, - 4890, 4889, 4888, 4887, 4886, 4884, 4882, 4879, 4878, 4875, - 4874, 4873, 4872, 4871, 4870, 4869, 4868, 4867, 4863, 4861, - 4859, 4857, 4856, 4855, 4854, 4853, 278, 4852, 300, 4850, - 4849, 4848, 4847, 4846, 3953, 4842, 75, 47, 58, 4839, - 4838, 4836, 4834, 4831, 4828, 4827, 4826, 293, 4825, 4824, - 4823, 4822, 4820, 4819, 4817, 4815, 4814, 4813, 4812, 4806, - 4805, 239, 4804, 4803, 4801, 4800, 4799, 4794, 267, 4793, - 260, 4792, 200, 149, 4790, 4787, 4784, 4782, 4781, 4779, - 121, 134, 4778, 4775, 4774, 4772, 4771, 4768, 4766, 4764, - 4763, 4762, 4760, 4758, 4757, 4756, 273, 183, 97, 4755, - 62, 4749, 272, 231, 4747, 243, 4746, 173, 4743, 165, - 4741, 4740, 4739, 4738, 4737, 4736, 4735, 4734, 4732, 4731, - 4730, 4729, 4728, 4727, 4726, 4725, 4724, 4721, 4720, 4718, - 4716, 4714, 4712, 4711, 4710, 4694, 4693, 4692, 4691, 4690, - 64, 4689, 288, 4688, 92, 4687, 163, 4683, 116, 4681, - 199, 4680, 89, 4677, 4676, 102, 4675, 27, 38, 4673, - 245, 111, 126, 296, 4138, 291, 4669, 219, 4667, 4666, - 285, 198, 4665, 4664, 316, 4660, 244, 224, 190, 109, - 141, 4659, 157, 4658, 298, 56, 85, 266, 225, 151, - 4657, 4656, 112, 212, 145, 216, 6, 119, 4655, 4654, - 4653, 271, 4652, 195, 4648, 4647, 130, 4646, 4643, 237, - 4641, 4640, 269, 207, 4639, 127, 4638, 4633, 4627, 46, - 4626, 4609, 227, 229, 4608, 4607, 118, 4606, 4605, 76, - 215, 174, 4603, 91, 143, 187, 136, 4601, 3832, 144, - 99, 4600, 150, 124, 4598, 101, 4597, 4596, 4593, 4592, - 208, 4591, 4589, 169, 4580, 70, 4579, 4578, 4577, 90, - 4574, 96, 4573, 93, 80, 122, 120, 41, 4572, 74, - 4571, 4570, 4568, 4567, 4566, 4565, 4564, 4563, 4562, 4559, - 4556, 4555, 40, 4553, 4551, 4550, 4549, 8, 17, 19, - 4548, 32, 4547, 189, 4546, 4544, 182, 4543, 220, 4542, - 4541, 114, 106, 4540, 108, 4539, 206, 4537, 12, 33, - 84, 4536, 4535, 4533, 1271, 4532, 4531, 4530, 343, 4528, - 4525, 4524, 228, 4523, 4522, 4521, 497, 4519, 4518, 4517, - 4514, 4503, 4502, 197, 4498, 2, 242, 36, 4497, 153, - 159, 4496, 51, 37, 4495, 60, 171, 240, 156, 123, - 4493, 4492, 4491, 725, 233, 137, 50, 0, 125, 251, - 188, 4490, 4488, 4486, 287, 4485, 268, 295, 276, 79, - 297, 213, 4484, 4481, 88, 4480, 178, 34, 63, 158, - 333, 26, 262, 4473, 2352, 13, 211, 4472, 234, 4471, - 21, 20, 1, 155, 4469, 4467, 44, 289, 4465, 4464, - 4463, 152, 4462, 4461, 626, 87, 4460, 4457, 4441, 4428, - 4427, 45, 4426, 205, 23, 4425, 168, 4424, 270, 110, - 218, 161, 209, 204, 172, 256, 259, 98, 11, 4423, - 2304, 177, 129, 18, 4422, 9, 249, 4420, 179, 138, - 4415, 100, 4414, 280, 292, 235, 4413, 210, 14, 59, - 48, 35, 57, 15, 356, 78, 4412, 4410, 28, 61, - 4409, 65, 4408, 25, 4406, 4391, 54, 49, 4387, 72, - 7, 4385, 4384, 24, 22, 4382, 43, 246, 191, 142, - 113, 73, 4381, 4378, 184, 154, 4376, 164, 180, 170, - 4375, 52, 4372, 4367, 4365, 4361, 3857, 284, 4360, 4359, - 4358, 4357, 4356, 4355, 4354, 4352, 238, 4350, 94, 55, - 4349, 4348, 4346, 4345, 105, 147, 4344, 4342, 4341, 4340, - 39, 95, 4339, 16, 4336, 31, 29, 42, 4335, 66, - 4334, 4333, 4332, 4, 214, 4331, 4328, 5, 4327, 4326, - 3, 4324, 4323, 135, 4322, 115, 30, 185, 186, 4321, - 4320, 107, 217, 146, 4319, 4318, 128, 279, 4317, 230, - 4316, 166, 264, 294, 4315, 241, 4310, 4308, 4302, 4300, - 4299, 1491, 4298, 4297, 263, 77, 117, 4296, 247, 133, - 4294, 4292, 104, 181, 140, 139, 67, 103, 4290, 131, - 236, 4289, 221, 4288, 253, 4287, 4286, 4276, 4275, 194, - 4274, 4272, 4270, 4269, 222, 4268, 4267, 223, 258, 4265, - 4262, 340, 4261, 4259, 4258, 4256, 4255, 4253, 4251, 4250, - 4249, 4246, 290, 257, 4245, 4244, -} - -//line mysql_sql.y:15067 + 0, 209, 66, 282, 207, 4856, 125, 289, 409, 313, + 288, 4853, 286, 285, 4851, 4850, 4847, 312, 311, 4846, + 4845, 4842, 4841, 4840, 4839, 4838, 4837, 4836, 4835, 4834, + 4831, 4829, 4827, 4825, 4824, 4823, 4822, 4821, 4818, 4817, + 4816, 4815, 4814, 4811, 4809, 4807, 4804, 4799, 4797, 4796, + 4795, 4794, 4792, 4790, 4789, 4788, 4787, 4786, 280, 4785, + 4784, 4782, 4780, 4778, 4776, 4774, 4758, 4757, 4756, 4754, + 4753, 4752, 4751, 4750, 4749, 4748, 4747, 4743, 4742, 4740, + 4739, 4737, 4736, 4735, 4732, 4731, 4730, 4729, 4728, 4726, + 4725, 4724, 4720, 4719, 4718, 4716, 4715, 4714, 4713, 269, + 4712, 309, 4707, 4706, 4705, 4700, 4699, 4698, 3903, 4695, + 80, 46, 59, 4694, 4692, 4691, 4690, 4688, 4686, 4685, + 4684, 427, 4683, 4682, 4681, 4678, 4677, 4675, 4674, 4673, + 4672, 4670, 4669, 4668, 4667, 310, 4666, 4665, 4664, 4663, + 4662, 4661, 244, 4660, 260, 4659, 203, 157, 4657, 4656, + 4655, 4653, 4650, 4648, 124, 137, 4644, 4637, 4636, 4635, + 4633, 4631, 4630, 4629, 4628, 4626, 4625, 4624, 4623, 4622, + 271, 174, 95, 4621, 61, 4620, 362, 237, 4618, 249, + 4616, 176, 4614, 173, 4613, 4611, 4610, 4607, 4606, 4605, + 4604, 4603, 4601, 4600, 4599, 4598, 4597, 4596, 4594, 4593, + 4592, 4591, 4590, 4589, 4588, 4587, 4586, 4585, 4583, 4582, + 4581, 4580, 4579, 4576, 62, 4575, 293, 4573, 89, 4571, + 161, 4570, 119, 4569, 205, 4568, 93, 4567, 4565, 91, + 4563, 29, 40, 4562, 63, 97, 133, 291, 3317, 292, + 4561, 229, 4560, 4558, 283, 202, 4557, 4556, 316, 4555, + 246, 235, 197, 109, 144, 4554, 167, 4553, 296, 65, + 55, 274, 221, 151, 4552, 4551, 99, 212, 153, 217, + 6, 120, 4549, 4548, 4547, 276, 4546, 201, 4545, 4543, + 134, 4542, 4541, 239, 4540, 4538, 273, 210, 4537, 135, + 4536, 4533, 4531, 26, 4529, 4525, 236, 267, 4524, 4523, + 123, 4522, 4521, 110, 218, 154, 4520, 94, 149, 189, + 142, 4519, 3285, 152, 102, 4518, 139, 130, 4517, 104, + 4514, 4513, 4512, 4511, 214, 4510, 4506, 171, 4505, 88, + 4504, 4503, 4502, 84, 4501, 96, 4500, 92, 90, 129, + 122, 4499, 36, 126, 117, 4498, 4497, 52, 4496, 74, + 4495, 4494, 4492, 4491, 4489, 4488, 4484, 4483, 4482, 4481, + 4480, 4479, 42, 4478, 4476, 4475, 4473, 8, 13, 19, + 4471, 34, 4470, 194, 4469, 4466, 190, 4465, 224, 4464, + 4462, 115, 113, 4461, 112, 4460, 200, 4459, 9, 38, + 103, 4457, 4456, 4455, 462, 4453, 4451, 4449, 304, 4448, + 4443, 4439, 226, 4436, 4427, 4424, 506, 4422, 4421, 4420, + 4418, 4417, 4416, 168, 4414, 1, 248, 31, 4413, 155, + 164, 4412, 50, 39, 4411, 64, 148, 243, 166, 127, + 4410, 4409, 4408, 719, 233, 121, 56, 0, 131, 252, + 187, 4405, 4403, 4402, 290, 4401, 272, 287, 277, 85, + 299, 222, 4400, 4399, 78, 4398, 183, 35, 70, 184, + 454, 27, 319, 4396, 525, 12, 215, 4394, 238, 4393, + 22, 17, 2, 158, 4392, 4390, 45, 297, 4389, 4388, + 4387, 160, 4386, 4385, 180, 75, 4384, 4382, 4381, 4378, + 4377, 43, 4376, 213, 24, 4375, 147, 4374, 281, 111, + 231, 188, 211, 206, 182, 253, 264, 100, 14, 4373, + 1775, 181, 132, 23, 4372, 11, 261, 4371, 192, 234, + 4370, 159, 4369, 279, 298, 240, 4368, 216, 15, 60, + 48, 37, 58, 16, 457, 79, 4367, 4364, 28, 69, + 4363, 68, 4361, 21, 4360, 4359, 54, 49, 4339, 76, + 7, 4338, 4337, 20, 25, 4336, 47, 247, 193, 143, + 118, 77, 4335, 4333, 198, 186, 4331, 172, 175, 178, + 4330, 57, 4329, 4328, 4327, 4326, 3797, 284, 4324, 4323, + 4322, 4320, 4319, 4318, 4317, 4315, 227, 4312, 106, 51, + 4309, 4307, 4304, 4302, 101, 156, 4301, 4300, 4298, 4297, + 41, 98, 4296, 18, 4295, 32, 30, 44, 4293, 72, + 4292, 4290, 4288, 4, 219, 4285, 4284, 5, 4283, 4282, + 3, 4279, 4277, 146, 4271, 116, 33, 191, 262, 4270, + 4269, 108, 220, 141, 4266, 4265, 128, 275, 4264, 232, + 4263, 169, 263, 295, 4262, 241, 4260, 4259, 4257, 4256, + 4255, 1449, 4254, 4253, 268, 87, 114, 4252, 257, 140, + 4251, 4250, 105, 185, 136, 163, 73, 107, 4249, 138, + 242, 4248, 225, 4247, 255, 4245, 4244, 4243, 4239, 199, + 4237, 4236, 4233, 4225, 223, 4222, 4221, 228, 266, 4219, + 4218, 300, 4214, 4213, 4212, 4210, 4208, 4207, 4206, 4205, + 4203, 4202, 4200, 278, 250, 4199, 4198, +} + +//line mysql_sql.y:15225 type yySymType struct { union interface{} id int @@ -10504,6 +10779,21 @@ func (st *yySymType) minValueOptionUnion() *tree.MinValueOption { return v } +func (st *yySymType) mongodbOptionUnion() *tree.MongoDBOption { + v, _ := st.union.(*tree.MongoDBOption) + return v +} + +func (st *yySymType) mongodbOptionsUnion() tree.MongoDBOptions { + v, _ := st.union.(tree.MongoDBOptions) + return v +} + +func (st *yySymType) mongodbTableParamUnion() *tree.MongoDBTableParam { + v, _ := st.union.(*tree.MongoDBTableParam) + return v +} + func (st *yySymType) nullsPositionUnion() tree.NullsPosition { v, _ := st.union.(tree.NullsPosition) return v @@ -11060,272 +11350,275 @@ func (st *yySymType) zeroFillOptUnion() bool { } var yyR1 = [...]int{ - 0, 687, 690, 5, 5, 2, 6, 6, 3, 3, + 0, 698, 701, 5, 5, 2, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 156, 156, 418, 418, - 419, 419, 158, 414, 414, 413, 413, 159, 160, 161, - 665, 665, 666, 666, 664, 664, 162, 163, 201, 663, - 663, 663, 663, 663, 663, 663, 663, 203, 203, 203, - 203, 203, 203, 203, 536, 157, 157, 157, 157, 268, - 268, 269, 269, 172, 172, 173, 173, 207, 207, 207, - 207, 207, 207, 207, 147, 672, 672, 672, 673, 673, - 144, 184, 183, 186, 186, 185, 185, 182, 182, 178, - 181, 181, 180, 180, 179, 174, 176, 176, 175, 177, - 177, 145, 131, 146, 612, 612, 611, 611, 610, 610, - 562, 562, 563, 563, 405, 405, 405, 609, 609, 609, - 608, 608, 607, 607, 606, 606, 604, 604, 605, 603, - 602, 602, 602, 598, 598, 598, 594, 594, 596, 595, - 595, 597, 589, 589, 592, 592, 590, 590, 590, 590, - 593, 588, 588, 588, 587, 587, 130, 130, 130, 502, - 502, 129, 129, 517, 517, 517, 517, 517, 515, 515, - 515, 515, 515, 515, 514, 514, 513, 513, 518, 518, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 4, 4, 4, 4, 4, 4, 160, 160, 428, 428, + 429, 429, 162, 424, 424, 423, 423, 163, 164, 165, + 675, 675, 676, 676, 674, 674, 166, 167, 205, 673, + 673, 673, 673, 673, 673, 673, 673, 207, 207, 207, + 207, 207, 207, 207, 546, 161, 161, 161, 161, 272, + 272, 273, 273, 176, 176, 177, 177, 211, 211, 211, + 211, 211, 211, 211, 151, 682, 682, 682, 683, 683, + 148, 188, 187, 190, 190, 189, 189, 186, 186, 182, + 185, 185, 184, 184, 183, 178, 180, 180, 179, 181, + 181, 149, 135, 150, 622, 622, 621, 621, 620, 620, + 572, 572, 573, 573, 415, 415, 415, 619, 619, 619, + 618, 618, 617, 617, 616, 616, 614, 614, 615, 613, + 612, 612, 612, 608, 608, 608, 604, 604, 606, 605, + 605, 607, 599, 599, 602, 602, 600, 600, 600, 600, + 603, 598, 598, 598, 597, 597, 134, 134, 134, 512, + 512, 133, 133, 527, 527, 527, 527, 527, 525, 525, + 525, 525, 525, 525, 524, 524, 523, 523, 528, 528, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 122, 122, 122, 122, 122, 122, 122, 129, 127, + 127, 127, 128, 688, 688, 687, 687, 689, 689, 689, + 689, 690, 690, 125, 125, 125, 126, 522, 522, 522, + 123, 124, 124, 511, 511, 517, 517, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 118, 118, 118, 118, 118, 118, 118, 125, 123, - 123, 123, 124, 678, 678, 677, 677, 679, 679, 679, - 679, 680, 680, 121, 121, 121, 122, 512, 512, 512, - 119, 120, 120, 501, 501, 507, 507, 506, 506, 506, - 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, - 511, 511, 511, 509, 509, 508, 508, 510, 510, 109, - 109, 109, 109, 109, 109, 113, 114, 115, 115, 115, - 115, 112, 111, 500, 500, 500, 500, 500, 500, 500, - 500, 500, 110, 110, 110, 110, 110, 110, 97, 97, - 97, 97, 97, 96, 96, 98, 98, 98, 498, 498, - 497, 126, 126, 127, 675, 675, 674, 676, 676, 676, - 676, 128, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 135, 135, 135, 138, 138, 138, 137, 139, 117, - 117, 117, 117, 117, 117, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 638, 638, 638, 638, 638, 639, 639, 432, 433, - 691, 435, 431, 431, 431, 634, 634, 635, 636, 637, - 637, 637, 637, 132, 278, 278, 279, 279, 133, 280, - 280, 280, 134, 281, 281, 16, 277, 277, 535, 535, + 521, 521, 521, 519, 519, 518, 518, 520, 520, 113, + 113, 113, 113, 113, 113, 117, 118, 119, 119, 119, + 119, 116, 115, 510, 510, 510, 510, 510, 510, 510, + 510, 510, 114, 114, 114, 114, 114, 114, 100, 100, + 100, 100, 100, 99, 99, 101, 101, 101, 508, 508, + 507, 130, 130, 131, 685, 685, 684, 686, 686, 686, + 686, 132, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 139, 139, 139, 142, 142, 142, 141, 143, 121, + 121, 121, 121, 121, 121, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 648, 648, 648, 648, 648, 649, 649, 442, 443, + 702, 445, 441, 441, 441, 644, 644, 645, 646, 647, + 647, 647, 647, 136, 282, 282, 283, 283, 137, 284, + 284, 284, 138, 285, 285, 16, 281, 281, 545, 545, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 103, 103, 15, 95, 100, 100, 102, - 367, 367, 368, 362, 362, 369, 369, 206, 53, 53, - 53, 53, 53, 53, 101, 101, 101, 101, 370, 370, - 370, 376, 376, 377, 377, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 347, 347, 347, - 342, 342, 342, 342, 343, 343, 344, 344, 345, 345, - 345, 345, 346, 346, 424, 424, 371, 371, 371, 373, - 373, 372, 366, 364, 364, 364, 364, 364, 364, 364, - 365, 365, 365, 365, 365, 365, 365, 365, 374, 374, - 375, 375, 93, 99, 99, 99, 99, 651, 651, 94, - 94, 94, 662, 662, 566, 566, 446, 446, 445, 445, - 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, - 445, 445, 445, 445, 571, 572, 442, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 54, 55, 153, 153, 155, 155, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 216, 90, 91, - 92, 69, 63, 66, 67, 205, 208, 208, 208, 208, - 62, 62, 62, 487, 487, 61, 692, 692, 417, 417, - 78, 77, 65, 79, 80, 81, 82, 83, 84, 60, - 76, 76, 76, 76, 76, 76, 76, 76, 87, 583, - 583, 694, 694, 694, 85, 86, 565, 565, 565, 75, - 74, 73, 72, 71, 71, 59, 59, 58, 58, 64, - 190, 192, 68, 191, 191, 193, 193, 439, 439, 439, - 441, 441, 437, 693, 693, 531, 531, 440, 440, 57, - 57, 57, 57, 88, 438, 438, 416, 436, 436, 436, - 14, 14, 12, 19, 19, 19, 19, 19, 19, 19, + 13, 13, 13, 13, 106, 106, 107, 107, 107, 107, + 15, 98, 103, 103, 105, 377, 377, 378, 372, 372, + 379, 379, 210, 55, 55, 55, 55, 55, 55, 104, + 104, 104, 104, 380, 380, 380, 386, 386, 387, 387, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 357, 357, 357, 352, 352, 352, 352, 353, + 353, 354, 354, 355, 355, 355, 355, 356, 356, 434, + 434, 381, 381, 381, 383, 383, 382, 376, 374, 374, + 374, 374, 374, 374, 374, 375, 375, 375, 375, 375, + 375, 375, 375, 384, 384, 385, 385, 96, 102, 102, + 102, 102, 661, 661, 97, 97, 97, 672, 672, 576, + 576, 456, 456, 455, 455, 455, 455, 455, 455, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 581, + 582, 452, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 56, 57, 157, + 157, 159, 159, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 73, 220, 93, 94, 95, 71, 65, + 68, 69, 209, 212, 212, 212, 212, 64, 64, 64, + 497, 497, 63, 703, 703, 427, 427, 81, 80, 67, + 82, 83, 84, 85, 86, 87, 62, 79, 79, 79, + 79, 79, 79, 79, 79, 90, 593, 593, 705, 705, + 705, 88, 89, 575, 575, 575, 78, 77, 76, 75, + 74, 74, 61, 61, 60, 60, 66, 194, 196, 70, + 195, 195, 197, 197, 449, 449, 449, 451, 451, 447, + 704, 704, 541, 541, 450, 450, 59, 59, 59, 59, + 91, 448, 448, 426, 446, 446, 446, 14, 14, 12, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 52, 29, 28, 30, 32, 495, 495, - 492, 31, 22, 21, 21, 25, 24, 20, 20, 23, - 26, 27, 27, 10, 10, 10, 10, 17, 17, 18, - 241, 241, 309, 309, 645, 645, 641, 641, 642, 642, - 642, 643, 643, 644, 644, 695, 695, 695, 140, 577, - 577, 577, 577, 577, 577, 577, 577, 232, 8, 8, - 9, 9, 9, 11, 11, 104, 105, 105, 106, 106, - 106, 106, 108, 107, 107, 267, 267, 576, 576, 576, - 576, 576, 576, 499, 499, 499, 622, 622, 622, 623, - 266, 266, 259, 259, 578, 578, 463, 624, 624, 586, - 586, 585, 585, 584, 584, 264, 264, 271, 271, 271, - 272, 272, 265, 265, 244, 244, 167, 167, 600, 600, - 601, 601, 591, 591, 591, 591, 599, 599, 561, 561, - 352, 352, 407, 407, 408, 408, 230, 230, 231, 231, - 231, 231, 231, 231, 681, 681, 682, 683, 684, 684, - 685, 685, 685, 686, 686, 686, 686, 686, 631, 631, - 633, 633, 632, 263, 263, 256, 256, 257, 257, 257, - 258, 258, 255, 255, 254, 253, 253, 252, 250, 250, - 250, 251, 251, 251, 276, 276, 234, 234, 234, 233, - 233, 233, 233, 233, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 235, 238, 238, 239, - 239, 240, 240, 240, 240, 240, 240, 240, 240, 240, - 240, 385, 385, 386, 386, 386, 386, 386, 165, 165, - 570, 570, 384, 384, 236, 236, 237, 237, 237, 237, - 383, 383, 382, 249, 249, 248, 247, 247, 247, 242, - 242, 242, 242, 242, 243, 394, 394, 393, 393, 392, - 392, 392, 392, 392, 392, 395, 143, 164, 164, 166, - 275, 275, 261, 260, 391, 390, 390, 390, 390, 274, - 274, 273, 273, 262, 262, 246, 246, 246, 246, 389, - 245, 387, 671, 671, 670, 670, 669, 667, 667, 667, - 668, 668, 668, 668, 614, 614, 614, 614, 614, 425, - 425, 425, 430, 430, 428, 428, 428, 428, 428, 434, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 45, 51, 148, 148, 151, 151, - 149, 149, 150, 150, 154, 154, 152, 152, 42, 291, - 292, 43, 293, 293, 294, 294, 295, 295, 296, 297, - 298, 298, 298, 298, 479, 479, 41, 282, 282, 283, - 283, 284, 284, 285, 286, 286, 286, 290, 287, 288, - 288, 689, 689, 688, 40, 40, 33, 33, 211, 211, - 212, 212, 212, 214, 214, 348, 348, 348, 213, 213, - 215, 215, 215, 646, 648, 648, 650, 649, 649, 649, - 652, 652, 652, 652, 652, 653, 653, 653, 653, 654, - 654, 34, 187, 187, 187, 222, 222, 197, 657, 657, - 657, 656, 656, 537, 537, 658, 658, 659, 659, 411, - 411, 412, 412, 209, 210, 210, 199, 189, 221, 221, - 221, 221, 221, 223, 223, 311, 311, 188, 194, 195, - 196, 198, 200, 202, 202, 204, 647, 655, 655, 655, - 496, 496, 493, 494, 494, 491, 490, 490, 490, 661, - 661, 660, 660, 660, 426, 426, 35, 486, 486, 488, - 489, 489, 489, 489, 489, 489, 489, 489, 480, 480, - 480, 480, 39, 484, 484, 485, 485, 485, 485, 485, - 485, 485, 485, 485, 485, 485, 485, 485, 485, 485, - 485, 485, 485, 485, 485, 485, 485, 485, 485, 485, - 485, 481, 481, 483, 483, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 38, 38, 38, 220, 220, - 477, 477, 474, 474, 289, 289, 472, 472, 473, 473, - 471, 471, 471, 475, 475, 47, 89, 48, 49, 50, - 46, 476, 476, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 270, 270, 229, 229, 229, 229, - 229, 229, 227, 227, 227, 227, 228, 228, 225, 225, - 226, 226, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 169, 168, 168, 168, - 168, 168, 171, 171, 410, 410, 409, 409, 170, 349, - 349, 44, 322, 322, 553, 553, 548, 548, 548, 548, - 548, 568, 568, 568, 549, 549, 549, 550, 550, 550, - 552, 552, 552, 551, 551, 551, 551, 551, 567, 567, - 569, 569, 569, 519, 519, 520, 520, 520, 523, 523, - 540, 540, 541, 541, 539, 539, 546, 546, 545, 545, - 544, 544, 543, 543, 542, 542, 542, 542, 534, 534, - 533, 533, 521, 521, 521, 521, 521, 522, 522, 522, - 532, 532, 538, 538, 381, 381, 380, 380, 331, 331, - 332, 332, 379, 379, 333, 334, 334, 335, 335, 336, - 217, 217, 218, 218, 329, 329, 330, 330, 330, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, - 378, 378, 378, 378, 620, 620, 621, 338, 338, 350, - 350, 350, 350, 350, 350, 337, 337, 339, 339, 310, - 310, 308, 308, 300, 300, 300, 300, 300, 300, 219, - 219, 219, 299, 299, 299, 299, 299, 299, 301, 301, - 302, 302, 303, 303, 303, 307, 307, 306, 306, 306, - 306, 304, 304, 305, 305, 305, 305, 305, 305, 504, - 504, 617, 617, 618, 618, 613, 613, 613, 616, 616, - 616, 616, 616, 616, 616, 616, 616, 616, 619, 619, - 619, 615, 615, 312, 404, 404, 404, 427, 427, 427, - 427, 429, 403, 403, 403, 328, 328, 327, 327, 325, - 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 505, 505, 505, 503, 503, 443, - 443, 444, 444, 361, 360, 360, 360, 360, 360, 358, - 359, 357, 357, 357, 357, 357, 354, 354, 353, 353, - 353, 355, 355, 355, 355, 355, 482, 482, 351, 351, - 341, 341, 341, 340, 340, 340, 547, 450, 450, 450, - 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, - 450, 450, 450, 452, 452, 452, 452, 452, 452, 452, - 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, - 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, - 452, 356, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 402, 402, 402, - 402, 402, 402, 402, 402, 453, 453, 459, 459, 630, - 630, 629, 313, 313, 313, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 323, 323, 323, 528, 528, 528, - 528, 529, 529, 529, 529, 530, 530, 530, 526, 526, - 527, 527, 464, 465, 465, 574, 574, 575, 575, 524, - 524, 525, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 582, 582, 582, - 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 397, 397, 397, 397, 397, 640, 640, - 640, 625, 625, 625, 626, 626, 626, 626, 626, 626, - 626, 626, 626, 626, 626, 626, 627, 627, 627, 627, - 627, 627, 627, 627, 627, 627, 627, 627, 627, 627, - 627, 627, 627, 628, 628, 628, 628, 399, 399, 399, - 399, 399, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 466, 466, 467, 467, 579, 579, 579, 579, 579, 579, - 580, 580, 581, 581, 581, 581, 573, 573, 573, 573, - 573, 573, 573, 573, 573, 573, 573, 573, 573, 573, - 573, 573, 573, 573, 573, 573, 573, 573, 573, 573, - 573, 573, 573, 573, 573, 451, 396, 396, 396, 468, - 460, 460, 461, 461, 462, 462, 454, 454, 454, 454, - 454, 455, 455, 457, 457, 457, 457, 457, 457, 457, - 457, 457, 457, 457, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 456, 456, 458, 458, 470, - 470, 470, 469, 469, 469, 469, 469, 469, 469, 326, - 326, 326, 326, 448, 448, 448, 447, 447, 447, 447, - 447, 447, 447, 447, 447, 447, 447, 447, 315, 315, - 315, 315, 315, 319, 319, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, 321, 320, - 320, 320, 320, 320, 320, 318, 318, 318, 318, 318, - 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, - 316, 316, 316, 316, 316, 316, 316, 316, 316, 141, - 142, 142, 317, 324, 324, 324, 324, 324, 324, 324, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, - 324, 406, 406, 554, 554, 557, 557, 555, 555, 556, - 558, 558, 558, 559, 559, 559, 560, 560, 560, 564, - 564, 415, 415, 415, 423, 423, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 421, 421, - 421, 421, 421, 421, 421, 421, 421, 420, 420, 420, - 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, - 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, - 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, - 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, - 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, - 420, + 19, 54, 29, 30, 28, 31, 33, 505, 505, 502, + 32, 22, 21, 21, 25, 24, 20, 20, 23, 26, + 27, 27, 10, 10, 10, 10, 17, 17, 18, 245, + 245, 313, 313, 655, 655, 651, 651, 652, 652, 652, + 653, 653, 654, 654, 706, 706, 706, 144, 587, 587, + 587, 587, 587, 587, 587, 587, 236, 8, 8, 9, + 9, 9, 11, 11, 108, 109, 109, 110, 110, 110, + 110, 112, 111, 111, 271, 271, 586, 586, 586, 586, + 586, 586, 509, 509, 509, 632, 632, 632, 633, 270, + 270, 263, 263, 588, 588, 473, 634, 634, 596, 596, + 595, 595, 594, 594, 268, 268, 275, 275, 275, 276, + 276, 269, 269, 248, 248, 171, 171, 610, 610, 611, + 611, 601, 601, 601, 601, 609, 609, 571, 571, 362, + 362, 417, 417, 418, 418, 234, 234, 235, 235, 235, + 235, 235, 235, 691, 691, 692, 693, 694, 694, 695, + 695, 696, 696, 696, 697, 697, 697, 697, 697, 641, + 641, 643, 643, 642, 267, 267, 260, 260, 261, 261, + 261, 262, 262, 259, 259, 258, 257, 257, 256, 254, + 254, 254, 255, 255, 255, 280, 280, 238, 238, 238, + 237, 237, 237, 237, 237, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 239, 242, 242, + 243, 243, 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 395, 395, 396, 396, 396, 396, 396, 169, + 169, 580, 580, 394, 394, 240, 240, 241, 241, 241, + 241, 393, 393, 392, 253, 253, 252, 251, 251, 251, + 246, 246, 246, 246, 246, 247, 404, 404, 403, 403, + 402, 402, 402, 402, 402, 402, 405, 147, 168, 168, + 170, 279, 279, 265, 264, 401, 400, 400, 400, 400, + 278, 278, 277, 277, 266, 266, 250, 250, 250, 250, + 399, 249, 397, 681, 681, 680, 680, 679, 677, 677, + 677, 678, 678, 678, 678, 624, 624, 624, 624, 624, + 435, 435, 435, 440, 440, 438, 438, 438, 438, 438, + 444, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 46, 47, 53, 152, + 152, 155, 155, 153, 153, 154, 154, 158, 158, 156, + 156, 43, 295, 296, 44, 297, 297, 298, 298, 299, + 299, 300, 301, 302, 302, 302, 302, 489, 489, 42, + 286, 286, 287, 287, 288, 288, 289, 290, 290, 290, + 294, 291, 292, 292, 700, 700, 699, 41, 41, 34, + 34, 215, 215, 216, 216, 216, 218, 218, 358, 358, + 358, 217, 217, 219, 219, 219, 656, 658, 658, 660, + 659, 659, 659, 662, 662, 662, 662, 662, 663, 663, + 663, 663, 664, 664, 35, 191, 191, 191, 226, 226, + 201, 667, 667, 667, 666, 666, 547, 547, 668, 668, + 669, 669, 421, 421, 422, 422, 213, 214, 214, 203, + 193, 225, 225, 225, 225, 225, 227, 227, 315, 315, + 192, 198, 199, 200, 202, 204, 206, 206, 208, 657, + 665, 665, 665, 506, 506, 503, 504, 504, 501, 500, + 500, 500, 671, 671, 670, 670, 670, 436, 436, 36, + 496, 496, 498, 499, 499, 499, 499, 499, 499, 499, + 499, 490, 490, 490, 490, 40, 494, 494, 495, 495, + 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, + 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, + 495, 495, 495, 495, 491, 491, 493, 493, 488, 488, + 488, 488, 488, 488, 488, 488, 488, 488, 39, 39, + 39, 224, 224, 487, 487, 484, 484, 293, 293, 482, + 482, 483, 483, 481, 481, 481, 485, 485, 49, 92, + 50, 51, 52, 48, 486, 486, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 274, 274, 233, + 233, 233, 233, 233, 233, 231, 231, 231, 231, 232, + 232, 229, 229, 230, 230, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 173, 172, 172, 172, 172, 172, 175, 175, 420, 420, + 419, 419, 174, 359, 359, 45, 326, 326, 563, 563, + 558, 558, 558, 558, 558, 578, 578, 578, 559, 559, + 559, 560, 560, 560, 562, 562, 562, 561, 561, 561, + 561, 561, 577, 577, 579, 579, 579, 529, 529, 530, + 530, 530, 533, 533, 550, 550, 551, 551, 549, 549, + 556, 556, 555, 555, 554, 554, 553, 553, 552, 552, + 552, 552, 544, 544, 543, 543, 531, 531, 531, 531, + 531, 532, 532, 532, 542, 542, 548, 548, 391, 391, + 390, 390, 335, 335, 336, 336, 389, 389, 337, 338, + 338, 339, 339, 340, 221, 221, 222, 222, 341, 342, + 342, 343, 343, 344, 345, 345, 346, 346, 333, 333, + 334, 334, 334, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 630, 630, + 631, 348, 348, 360, 360, 360, 360, 360, 360, 347, + 347, 349, 349, 314, 314, 312, 312, 304, 304, 304, + 304, 304, 304, 223, 223, 223, 303, 303, 303, 303, + 303, 303, 305, 305, 306, 306, 307, 307, 307, 311, + 311, 310, 310, 310, 310, 308, 308, 309, 309, 309, + 309, 309, 309, 514, 514, 627, 627, 628, 628, 623, + 623, 623, 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 629, 629, 629, 625, 625, 316, 414, 414, + 414, 437, 437, 437, 437, 439, 413, 413, 413, 332, + 332, 331, 331, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, + 515, 515, 515, 513, 513, 453, 453, 454, 454, 371, + 370, 370, 370, 370, 370, 368, 369, 367, 367, 367, + 367, 367, 364, 364, 363, 363, 363, 365, 365, 365, + 365, 365, 492, 492, 361, 361, 351, 351, 351, 350, + 350, 350, 557, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 462, + 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, + 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, + 462, 462, 462, 462, 462, 462, 462, 366, 411, 411, + 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, + 411, 411, 411, 412, 412, 412, 412, 412, 412, 412, + 412, 463, 463, 469, 469, 640, 640, 639, 317, 317, + 317, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 327, 327, 327, 538, 538, 538, 538, 539, 539, 539, + 539, 540, 540, 540, 536, 536, 537, 537, 474, 475, + 475, 584, 584, 585, 585, 534, 534, 535, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 592, 592, 592, 407, 407, 407, 407, + 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, + 407, 407, 407, 407, 650, 650, 650, 635, 635, 635, + 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, + 636, 636, 637, 637, 637, 637, 637, 637, 637, 637, + 637, 637, 637, 637, 637, 637, 637, 637, 637, 638, + 638, 638, 638, 409, 409, 409, 409, 409, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 476, 476, 477, 477, + 589, 589, 589, 589, 589, 589, 590, 590, 591, 591, + 591, 591, 583, 583, 583, 583, 583, 583, 583, 583, + 583, 583, 583, 583, 583, 583, 583, 583, 583, 583, + 583, 583, 583, 583, 583, 583, 583, 583, 583, 583, + 583, 461, 406, 406, 406, 478, 470, 470, 471, 471, + 472, 472, 464, 464, 464, 464, 464, 465, 465, 467, + 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, + 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, + 459, 466, 466, 468, 468, 480, 480, 480, 479, 479, + 479, 479, 479, 479, 479, 330, 330, 330, 330, 458, + 458, 458, 457, 457, 457, 457, 457, 457, 457, 457, + 457, 457, 457, 457, 319, 319, 319, 319, 319, 323, + 323, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 324, 324, 324, 324, 324, + 324, 322, 322, 322, 322, 322, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 145, 146, 146, 321, 328, + 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 416, 416, 564, + 564, 567, 567, 565, 565, 566, 568, 568, 568, 569, + 569, 569, 570, 570, 570, 574, 574, 425, 425, 425, + 433, 433, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 430, 430, + 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, + 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, + 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, + 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, + 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, + 430, 430, } var yyR2 = [...]int{ @@ -11377,175 +11670,178 @@ var yyR2 = [...]int{ 1, 1, 1, 3, 1, 3, 1, 4, 4, 0, 1, 2, 4, 0, 3, 4, 1, 1, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 6, 8, 10, 7, 4, 4, 3, - 1, 3, 3, 1, 3, 1, 6, 7, 4, 4, - 7, 8, 6, 6, 8, 6, 11, 10, 3, 3, - 3, 1, 1, 1, 3, 2, 4, 5, 5, 6, - 5, 5, 3, 2, 2, 1, 3, 4, 3, 7, - 5, 8, 2, 2, 1, 3, 2, 0, 1, 1, + 1, 1, 1, 1, 6, 8, 6, 8, 5, 5, + 10, 7, 4, 4, 3, 1, 3, 3, 1, 3, + 1, 6, 7, 4, 4, 7, 8, 6, 6, 8, + 6, 11, 10, 3, 3, 3, 1, 1, 1, 3, + 2, 4, 5, 5, 6, 5, 5, 3, 2, 2, + 1, 3, 4, 3, 7, 5, 8, 2, 2, 1, + 3, 2, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 0, 1, 2, 1, 3, 2, 1, 2, 2, + 1, 2, 3, 2, 2, 3, 5, 4, 4, 4, + 4, 3, 3, 1, 1, 3, 3, 7, 7, 7, + 8, 8, 0, 4, 7, 6, 6, 0, 3, 0, + 2, 0, 1, 1, 1, 1, 4, 2, 2, 3, + 3, 4, 5, 3, 4, 4, 2, 2, 2, 3, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 1, 0, 1, 2, 1, - 3, 2, 1, 2, 2, 1, 2, 3, 2, 2, - 3, 5, 4, 4, 4, 4, 3, 3, 1, 1, - 3, 3, 7, 7, 7, 8, 8, 0, 4, 7, - 6, 6, 0, 3, 0, 2, 0, 1, 1, 1, - 1, 4, 2, 2, 3, 3, 4, 5, 3, 4, - 4, 2, 2, 2, 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 5, 0, + 2, 0, 2, 5, 7, 8, 5, 5, 7, 9, + 8, 8, 11, 5, 1, 3, 3, 3, 5, 4, + 3, 3, 3, 4, 5, 6, 5, 2, 5, 5, + 0, 2, 7, 0, 1, 0, 1, 5, 5, 3, + 3, 2, 4, 4, 4, 4, 4, 1, 1, 1, + 3, 3, 1, 1, 1, 6, 0, 1, 1, 1, + 1, 5, 5, 0, 1, 1, 3, 3, 3, 4, + 7, 7, 5, 4, 7, 8, 3, 3, 4, 2, + 3, 4, 4, 3, 0, 2, 2, 0, 2, 2, + 1, 1, 1, 1, 0, 1, 5, 5, 6, 4, + 3, 1, 3, 1, 1, 3, 5, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 5, 0, 2, 0, 2, 5, 7, 8, - 5, 5, 7, 9, 8, 8, 11, 1, 3, 3, - 3, 5, 4, 3, 3, 3, 4, 5, 6, 5, - 2, 5, 5, 0, 2, 7, 0, 1, 0, 1, - 5, 5, 3, 3, 2, 4, 4, 4, 4, 4, - 1, 1, 1, 3, 3, 1, 1, 1, 6, 0, - 1, 1, 1, 1, 5, 5, 0, 1, 1, 3, - 3, 3, 4, 7, 7, 5, 4, 7, 8, 3, - 3, 4, 2, 3, 4, 4, 3, 0, 2, 2, - 0, 2, 2, 1, 1, 1, 1, 0, 1, 5, - 5, 6, 4, 3, 1, 3, 1, 1, 3, 5, - 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 4, 5, 5, 4, 4, 4, 1, 3, 1, + 4, 6, 6, 4, 4, 4, 4, 4, 3, 6, + 3, 5, 1, 1, 2, 2, 11, 8, 9, 1, + 3, 2, 4, 0, 2, 0, 1, 1, 1, 1, + 0, 1, 0, 1, 0, 1, 1, 5, 2, 1, + 4, 1, 5, 4, 4, 2, 4, 1, 2, 5, + 5, 5, 1, 2, 8, 1, 2, 7, 5, 13, + 10, 1, 0, 2, 1, 3, 2, 1, 5, 4, + 4, 2, 0, 5, 4, 0, 1, 3, 3, 1, + 3, 1, 3, 1, 3, 4, 0, 1, 0, 1, + 1, 3, 1, 1, 0, 4, 0, 4, 4, 3, + 5, 1, 3, 2, 1, 0, 10, 0, 2, 0, + 2, 0, 4, 7, 4, 0, 2, 0, 2, 0, + 2, 0, 4, 1, 3, 1, 1, 7, 4, 6, + 8, 4, 6, 0, 1, 4, 8, 0, 6, 0, + 4, 0, 4, 6, 1, 1, 1, 1, 1, 2, + 3, 1, 3, 6, 0, 3, 0, 1, 2, 4, + 4, 0, 5, 0, 1, 3, 1, 3, 3, 0, + 1, 1, 0, 2, 2, 0, 2, 3, 3, 3, + 1, 3, 3, 3, 3, 1, 2, 2, 1, 2, + 2, 1, 2, 2, 1, 2, 2, 7, 0, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 2, 0, 4, 7, 6, 6, 3, + 5, 0, 2, 0, 2, 1, 3, 1, 2, 3, + 5, 0, 1, 2, 1, 3, 1, 1, 1, 1, + 4, 4, 4, 3, 4, 3, 2, 2, 2, 2, + 2, 3, 2, 3, 2, 3, 2, 4, 1, 3, + 4, 0, 2, 1, 3, 1, 1, 2, 2, 3, + 0, 1, 2, 4, 1, 3, 1, 3, 2, 3, + 1, 4, 3, 0, 1, 1, 2, 5, 2, 2, + 2, 0, 2, 3, 3, 0, 1, 3, 1, 3, + 0, 1, 2, 1, 1, 0, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 4, 5, 4, 4, 4, 1, 3, - 1, 4, 6, 6, 4, 4, 4, 4, 4, 3, - 6, 3, 5, 1, 1, 2, 2, 11, 8, 9, - 1, 3, 2, 4, 0, 2, 0, 1, 1, 1, - 1, 0, 1, 0, 1, 0, 1, 1, 5, 2, - 1, 4, 1, 5, 4, 4, 2, 4, 1, 2, - 5, 5, 5, 1, 2, 8, 1, 2, 7, 5, - 13, 10, 1, 0, 2, 1, 3, 2, 1, 5, - 4, 4, 2, 0, 5, 4, 0, 1, 3, 3, - 1, 3, 1, 3, 1, 3, 4, 0, 1, 0, - 1, 1, 3, 1, 1, 0, 4, 0, 4, 4, - 3, 5, 1, 3, 2, 1, 0, 10, 0, 2, - 0, 2, 0, 4, 7, 4, 0, 2, 0, 2, - 0, 2, 0, 4, 1, 3, 1, 1, 7, 4, - 6, 8, 4, 6, 0, 1, 3, 8, 0, 6, - 0, 4, 6, 1, 1, 1, 1, 1, 2, 3, - 1, 3, 6, 0, 3, 0, 1, 2, 4, 4, - 0, 5, 0, 1, 3, 1, 3, 3, 0, 1, - 1, 0, 2, 2, 0, 2, 3, 3, 3, 1, - 3, 3, 3, 3, 1, 2, 2, 1, 2, 2, - 1, 2, 2, 1, 2, 2, 7, 0, 1, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 2, 0, 4, 7, 6, 6, 3, 5, - 0, 2, 0, 2, 1, 3, 1, 2, 3, 5, - 0, 1, 2, 1, 3, 1, 1, 1, 1, 4, - 4, 4, 3, 4, 3, 2, 2, 2, 2, 2, - 3, 2, 3, 2, 3, 2, 4, 1, 3, 4, - 0, 2, 1, 3, 1, 1, 2, 2, 3, 0, - 1, 2, 4, 1, 3, 1, 3, 2, 3, 1, - 4, 3, 0, 1, 1, 2, 5, 2, 2, 2, - 0, 2, 3, 3, 0, 1, 3, 1, 3, 0, - 1, 2, 1, 1, 0, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 6, 6, 10, 0, + 3, 0, 2, 0, 4, 1, 1, 0, 2, 0, + 2, 7, 1, 1, 9, 1, 3, 0, 1, 1, + 3, 1, 3, 0, 1, 1, 1, 0, 2, 14, + 1, 3, 0, 1, 1, 3, 1, 1, 2, 4, + 1, 1, 1, 1, 0, 1, 2, 9, 9, 7, + 8, 1, 2, 3, 3, 3, 0, 4, 1, 1, + 1, 1, 1, 0, 1, 1, 1, 1, 1, 4, + 1, 1, 1, 3, 3, 4, 3, 3, 0, 1, + 1, 1, 0, 2, 7, 8, 10, 8, 2, 2, + 8, 0, 3, 3, 0, 3, 0, 3, 0, 3, + 0, 5, 1, 3, 0, 3, 3, 0, 2, 9, + 8, 0, 2, 2, 3, 3, 0, 2, 0, 2, + 4, 5, 4, 4, 4, 6, 4, 8, 5, 1, + 0, 2, 2, 1, 3, 2, 1, 3, 2, 1, + 3, 2, 0, 1, 3, 4, 3, 1, 1, 4, + 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 11, 0, 2, 3, 3, + 2, 2, 3, 1, 1, 3, 3, 3, 3, 3, + 3, 4, 2, 2, 3, 3, 3, 3, 1, 1, + 3, 3, 3, 3, 1, 3, 3, 4, 0, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 6, 8, + 10, 0, 4, 1, 1, 0, 3, 0, 1, 0, + 1, 1, 2, 4, 4, 4, 0, 1, 8, 2, + 4, 4, 4, 9, 0, 2, 8, 9, 5, 5, + 8, 7, 8, 12, 12, 13, 13, 0, 4, 0, + 3, 3, 3, 2, 2, 0, 3, 3, 3, 4, + 4, 0, 3, 0, 2, 11, 9, 9, 9, 6, + 11, 8, 6, 9, 7, 10, 7, 6, 9, 11, + 2, 2, 9, 4, 5, 3, 0, 4, 1, 3, + 0, 3, 6, 0, 2, 10, 0, 2, 0, 2, + 0, 3, 2, 4, 3, 0, 2, 1, 0, 2, + 3, 0, 2, 3, 0, 2, 1, 0, 3, 2, + 4, 3, 0, 1, 0, 1, 1, 0, 6, 0, + 3, 5, 0, 4, 0, 3, 1, 3, 4, 5, + 0, 3, 1, 3, 2, 3, 1, 2, 0, 4, + 6, 5, 0, 2, 0, 2, 4, 5, 4, 5, + 1, 5, 6, 5, 0, 3, 0, 1, 1, 3, + 3, 3, 0, 4, 1, 3, 3, 3, 4, 0, + 4, 1, 3, 3, 1, 1, 1, 1, 4, 0, + 4, 1, 3, 3, 1, 1, 1, 1, 0, 1, + 1, 3, 2, 3, 3, 3, 4, 4, 3, 3, + 3, 3, 4, 4, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, + 3, 3, 3, 3, 3, 1, 5, 4, 1, 3, + 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 5, 0, 3, 3, + 6, 5, 3, 1, 1, 1, 0, 5, 5, 5, + 5, 6, 0, 1, 1, 3, 1, 1, 1, 1, + 1, 7, 9, 7, 9, 2, 1, 7, 9, 7, + 9, 8, 5, 0, 1, 0, 1, 1, 1, 1, + 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 1, 3, 1, 3, + 5, 1, 1, 1, 1, 1, 1, 3, 5, 0, + 1, 1, 2, 1, 2, 2, 1, 1, 2, 2, + 2, 2, 2, 3, 3, 2, 2, 1, 5, 6, + 4, 2, 1, 1, 1, 5, 4, 1, 7, 5, + 0, 1, 1, 1, 2, 0, 1, 1, 2, 5, + 0, 1, 1, 2, 2, 3, 3, 1, 1, 2, + 2, 2, 0, 1, 2, 2, 2, 0, 4, 7, + 3, 3, 0, 3, 0, 3, 1, 1, 1, 1, + 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, + 1, 1, 3, 5, 2, 2, 2, 2, 4, 1, + 1, 2, 5, 6, 8, 6, 3, 6, 6, 1, + 1, 1, 1, 1, 1, 3, 9, 1, 4, 4, + 4, 4, 5, 4, 5, 7, 9, 5, 7, 9, + 5, 5, 7, 7, 9, 7, 7, 7, 9, 7, + 7, 0, 2, 0, 1, 1, 2, 4, 1, 2, + 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, + 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 1, 1, 1, 2, 5, 0, 1, 3, 0, + 1, 0, 2, 0, 2, 0, 1, 6, 8, 8, + 6, 6, 5, 5, 5, 6, 6, 6, 6, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 8, 1, 1, 1, 4, 6, 4, 6, + 8, 6, 6, 4, 5, 4, 4, 4, 3, 4, + 6, 6, 7, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 6, 10, 0, 3, 0, 2, - 0, 4, 1, 1, 0, 2, 0, 2, 7, 1, - 1, 9, 1, 3, 0, 1, 1, 3, 1, 3, - 0, 1, 1, 1, 0, 2, 14, 1, 3, 0, - 1, 1, 3, 1, 1, 2, 4, 1, 1, 1, - 1, 0, 1, 2, 9, 9, 7, 8, 1, 2, - 3, 3, 3, 0, 4, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 4, 1, 1, 1, - 3, 3, 4, 3, 3, 0, 1, 1, 1, 0, - 2, 7, 8, 10, 8, 2, 2, 8, 0, 3, - 3, 0, 3, 0, 3, 0, 3, 0, 5, 1, - 3, 0, 3, 3, 0, 2, 9, 8, 0, 2, - 2, 3, 3, 0, 2, 0, 2, 4, 5, 4, - 4, 4, 6, 4, 8, 5, 1, 0, 2, 2, - 1, 3, 2, 1, 3, 2, 1, 3, 2, 0, - 1, 3, 4, 3, 1, 1, 4, 1, 3, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, - 1, 1, 11, 0, 2, 3, 3, 2, 2, 3, - 1, 1, 3, 3, 3, 3, 3, 3, 4, 2, - 2, 3, 3, 3, 3, 1, 1, 3, 3, 3, - 3, 1, 3, 3, 4, 0, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 6, 8, 10, 0, 4, - 1, 1, 0, 3, 0, 1, 0, 1, 1, 2, - 4, 4, 4, 0, 1, 8, 2, 4, 4, 4, - 9, 0, 2, 8, 9, 5, 5, 8, 7, 8, - 12, 12, 13, 13, 0, 4, 0, 3, 3, 3, - 2, 2, 0, 3, 3, 3, 4, 4, 0, 3, - 0, 2, 11, 9, 9, 6, 11, 8, 6, 9, - 7, 10, 7, 6, 9, 11, 2, 2, 9, 4, - 5, 3, 0, 4, 1, 3, 0, 3, 6, 0, - 2, 10, 0, 2, 0, 2, 0, 3, 2, 4, - 3, 0, 2, 1, 0, 2, 3, 0, 2, 3, - 0, 2, 1, 0, 3, 2, 4, 3, 0, 1, - 0, 1, 1, 0, 6, 0, 3, 5, 0, 4, - 0, 3, 1, 3, 4, 5, 0, 3, 1, 3, - 2, 3, 1, 2, 0, 4, 6, 5, 0, 2, - 0, 2, 4, 5, 4, 5, 1, 5, 6, 5, - 0, 3, 0, 1, 1, 3, 3, 3, 0, 4, - 1, 3, 3, 3, 4, 0, 4, 1, 3, 3, - 1, 1, 1, 1, 0, 1, 1, 3, 2, 3, - 3, 3, 4, 4, 3, 3, 3, 3, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 5, 4, 1, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 3, 3, 5, 0, 3, 3, 6, 5, 3, 1, - 1, 1, 0, 5, 5, 5, 5, 6, 0, 1, - 1, 3, 1, 1, 1, 1, 1, 7, 9, 7, - 9, 2, 1, 7, 9, 7, 9, 8, 5, 0, - 1, 0, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 3, 1, 3, 5, 1, 1, 1, - 1, 1, 1, 3, 5, 0, 1, 1, 2, 1, - 2, 2, 1, 1, 2, 2, 2, 3, 3, 2, - 2, 1, 5, 6, 4, 2, 1, 1, 1, 5, - 4, 1, 7, 5, 0, 1, 1, 1, 2, 0, - 1, 1, 2, 5, 0, 1, 1, 2, 2, 3, - 3, 1, 1, 2, 2, 2, 0, 1, 2, 2, - 2, 0, 4, 7, 3, 3, 0, 3, 0, 3, - 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 1, 1, 1, 1, 3, 5, 2, 2, - 2, 2, 4, 1, 1, 2, 5, 6, 8, 6, - 3, 6, 6, 1, 1, 1, 1, 1, 1, 3, - 9, 1, 4, 4, 4, 4, 5, 4, 5, 7, - 9, 5, 7, 9, 5, 5, 7, 7, 9, 7, - 7, 7, 9, 7, 7, 0, 2, 0, 1, 1, - 2, 4, 1, 2, 2, 1, 2, 2, 1, 2, - 2, 2, 2, 2, 0, 1, 1, 1, 2, 2, - 2, 2, 2, 2, 2, 1, 1, 1, 2, 5, - 0, 1, 3, 0, 1, 0, 2, 0, 2, 0, - 1, 6, 8, 8, 6, 6, 5, 5, 5, 6, - 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 8, 1, 1, 1, - 4, 6, 4, 6, 8, 6, 6, 4, 5, 4, - 4, 4, 3, 4, 6, 6, 7, 4, 1, 1, + 1, 1, 1, 2, 2, 8, 8, 6, 4, 2, + 3, 2, 4, 2, 2, 4, 6, 2, 2, 4, + 6, 4, 2, 4, 4, 4, 0, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 8, - 8, 6, 4, 2, 3, 2, 4, 2, 2, 4, - 6, 2, 2, 4, 6, 4, 2, 4, 4, 4, - 0, 1, 2, 3, 1, 1, 1, 1, 1, 1, - 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 0, 1, 1, 3, 0, 1, 1, 3, + 1, 3, 3, 3, 3, 2, 1, 1, 1, 3, + 4, 3, 4, 3, 4, 3, 4, 3, 4, 1, + 3, 4, 4, 5, 4, 5, 3, 4, 5, 6, + 1, 0, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 1, 1, 1, 2, 3, 1, 1, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 3, 2, 2, 2, + 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 0, 1, 1, 3, - 0, 1, 1, 3, 1, 3, 3, 3, 3, 2, - 1, 1, 1, 3, 4, 3, 4, 3, 4, 3, - 4, 3, 4, 1, 3, 4, 4, 5, 4, 5, - 3, 4, 5, 6, 1, 0, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 1, 1, 1, 2, 3, 1, - 1, 1, 4, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 3, 2, 2, 2, 2, 1, 2, 2, 2, 2, - 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 4, 4, 1, 2, - 3, 5, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 4, 4, 1, 2, 3, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 3, 0, 1, 0, 3, 0, 3, 3, - 0, 3, 5, 0, 3, 5, 0, 1, 1, 0, - 1, 1, 2, 2, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 0, + 1, 0, 3, 0, 3, 3, 0, 3, 5, 0, + 3, 5, 0, 1, 1, 0, 1, 1, 2, 2, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -11594,501 +11890,507 @@ var yyR2 = [...]int{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, + 1, 1, } var yyChk = [...]int{ - -1000, -687, -690, -5, -1, -2, -4, -142, -109, 716, - -7, -16, -144, -145, -8, -140, -10, -11, -12, -200, - -14, -116, -135, -137, -139, -138, -56, -13, -132, -133, - -134, -96, -97, -118, -126, -129, -130, -131, -146, -141, - -143, -230, -147, -156, -157, -207, -160, -162, -163, -195, - -196, -224, 706, -110, -111, -112, -113, -114, -115, -36, - -35, -34, -33, -187, -197, -201, -203, -158, -51, 623, - 712, 519, -9, -631, 572, -17, -18, -104, -19, 265, - 292, -431, -432, -433, -435, -691, -57, -58, -59, -71, - -72, -73, -74, -75, -85, -86, -87, -60, -61, -62, - -65, -63, -78, -77, -79, -80, -81, -82, -83, -84, - -64, -68, -190, -191, -192, -193, -88, -66, -89, -67, - -205, -208, -159, -90, -91, -92, -69, -54, -55, -70, - -94, -93, -99, -95, -100, -189, -199, -15, -206, -101, - -53, -103, -102, 266, 337, 285, -98, 80, -119, -120, - -121, -122, -123, -124, -125, -127, -128, 444, 450, 506, - 705, 65, -231, -234, 743, 744, 747, 608, 610, 310, - 178, 179, 181, 182, 186, 189, -37, -38, -39, -40, - -41, -42, -44, -43, -46, -47, -45, -48, -49, -50, - 261, 16, 14, 18, 58, -20, -23, -21, -24, -22, - -31, -32, -30, -26, -28, -188, -194, -27, -198, -25, - -202, -204, -161, -52, -29, 287, 286, 41, 353, 354, - 355, 448, 262, 264, 17, 34, 45, 423, -233, 89, - 609, 263, -235, 15, 750, -6, -3, -2, -174, -178, - -182, -185, -186, -183, -184, -4, -142, 124, 277, 707, - -427, 440, 708, 710, 709, 92, 100, -420, -422, 519, - 292, 444, 450, 705, 744, 747, 608, 610, 310, 625, - 626, 627, 628, 629, 630, 631, 632, 634, 635, 636, - 637, 638, 639, 640, 683, 684, 650, 651, 641, 642, - 643, 644, 645, 646, 647, 648, 652, 653, 654, 655, - 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, - 575, 576, 685, 687, 688, 689, 690, 604, 633, 670, - 678, 679, 680, 421, 422, 616, 702, 749, 304, 328, - 473, 334, 341, 407, 178, 196, 192, 220, 211, 413, - 360, 729, 730, 359, 609, 187, 308, 346, 309, 99, - 181, 558, 114, 531, 502, 184, 366, 369, 367, 368, - 323, 325, 327, 605, 606, 434, 330, 603, 329, 331, - 333, 607, 364, 424, 207, 201, 322, 306, 199, 311, - 414, 43, 312, 405, 404, 225, 313, 314, 620, 527, - 420, 533, 338, 56, 500, 200, 326, 530, 701, 229, - 233, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 549, 411, 393, 394, 395, 550, 416, 169, 170, - 535, 728, 410, 552, 415, 224, 227, 228, 284, 401, - 402, 417, 418, 419, 46, 618, 296, 553, 231, 739, - 223, 218, 561, 342, 340, 406, 222, 195, 217, 307, - 69, 235, 234, 236, 496, 497, 498, 499, 315, 316, - 438, 548, 731, 732, 214, 202, 425, 188, 25, 556, - 291, 532, 451, 370, 51, 371, 317, 335, 343, 365, - 230, 232, 298, 303, 358, 412, 619, 504, 505, 302, - 540, 541, 339, 554, 198, 295, 324, 290, 557, 740, - 733, 189, 453, 318, 182, 332, 551, 742, 560, 68, - 164, 194, 185, 723, 724, 281, 686, 179, 300, 305, - 703, 741, 319, 320, 321, 602, 345, 344, 336, 186, - 215, 297, 221, 205, 193, 216, 180, 299, 559, 165, - 699, 423, 483, 213, 210, 301, 274, 704, 555, 534, - 183, 487, 167, 208, 347, 693, 694, 695, 698, 439, - 400, 348, 349, 206, 288, 525, 526, 352, 493, 388, - 467, 503, 474, 468, 252, 253, 356, 537, 539, 226, - 696, 372, 373, 374, 529, 375, 377, 378, 383, 443, - 60, 62, 101, 104, 103, 745, 746, 67, 32, 429, - 432, 465, 469, 390, 700, 617, 387, 391, 392, 433, - 28, 485, 455, 489, 488, 52, 53, 54, 57, 58, - 59, 61, 63, 64, 55, 601, 448, 462, 562, 48, - 50, 458, 459, 30, 435, 484, 507, 386, 486, 518, - 49, 516, 517, 538, 29, 437, 436, 66, 47, 492, - 494, 495, 350, 384, 446, 713, 563, 441, 457, 461, - 442, 389, 431, 463, 71, 454, 714, 449, 447, 385, - 621, 622, 396, 649, 426, 501, 598, 597, 596, 595, - 594, 593, 592, 591, 353, 354, 355, 470, 471, 472, - 482, 475, 476, 477, 478, 479, 480, 481, 521, 522, - 715, 542, 544, 545, 614, 546, 543, 269, 748, 427, - 428, 272, 717, 718, 102, 719, 721, 720, 31, 722, - 738, 735, 736, 737, 624, 547, 611, 725, 613, 612, - 671, 672, 673, 674, 675, -510, -508, -427, 609, 310, - 705, 450, 608, 610, 444, 423, 744, 747, 58, 448, - 292, 353, 354, 355, 519, 421, -293, -427, 748, -98, - -18, -17, -9, -104, -233, -234, -695, 258, 260, 459, - -308, 271, -427, -436, 26, 500, -117, 501, 266, 267, - 89, 81, -427, -10, -131, -8, -140, -96, -230, -631, - 506, -434, -427, 353, 353, 614, -434, 271, 271, 727, - 505, 546, 614, 728, 739, 541, 434, 103, 104, 723, - 724, 30, 271, 445, 298, 539, 537, 538, 542, 543, - 544, 545, -76, -583, -565, 534, 533, -440, 526, 532, + -1000, -698, -701, -5, -1, -2, -4, -146, -113, 717, + -7, -16, -148, -149, -8, -144, -10, -11, -12, -204, + -14, -120, -139, -141, -143, -142, -58, -13, -136, -137, + -138, -99, -100, -122, -130, -133, -134, -135, -150, -145, + -147, -234, -151, -160, -161, -211, -164, -166, -167, -199, + -200, -228, 706, -114, -115, -116, -117, -118, -119, -37, + -36, -35, -34, -191, -201, -205, -207, -162, -53, 623, + 712, 519, -9, -641, 572, -17, -18, -108, -19, 265, + 292, -441, -442, -443, -445, -702, -59, -60, -61, -74, + -75, -76, -77, -78, -88, -89, -90, -62, -63, -64, + -67, -65, -81, -80, -82, -83, -84, -85, -86, -87, + -66, -70, -194, -195, -196, -197, -91, -68, -92, -69, + -209, -212, -163, -93, -94, -95, -71, -56, -57, -72, + -73, -97, -96, -102, -98, -103, -193, -203, -15, -210, + -104, -55, -106, -107, -105, 266, 337, 285, -101, 80, + -123, -124, -125, -126, -127, -128, -129, -131, -132, 444, + 450, 506, 705, 65, -235, -238, 748, 749, 752, 608, + 610, 310, 178, 179, 181, 182, 186, 189, -38, -39, + -40, -41, -42, -43, -45, -44, -48, -49, -46, -47, + -50, -51, -52, 261, 16, 14, 18, 58, -20, -23, + -21, -24, -22, -32, -33, -31, -26, -28, -192, -198, + -27, -202, -25, -206, -208, -165, -54, -29, -30, 287, + 286, 41, 353, 354, 355, 448, 262, 264, 17, 34, + 45, 423, -237, 89, 609, 263, -239, 15, 755, -6, + -3, -2, -178, -182, -186, -189, -190, -187, -188, -4, + -146, 124, 277, 707, -437, 440, 708, 710, 709, 92, + 100, -430, -432, 519, 292, 444, 450, 705, 749, 752, + 608, 610, 310, 625, 626, 627, 628, 629, 630, 631, + 632, 634, 635, 636, 637, 638, 639, 640, 683, 684, + 650, 651, 641, 642, 643, 644, 645, 646, 647, 648, + 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, + 662, 663, 664, 665, 575, 576, 685, 687, 688, 689, + 690, 604, 633, 670, 678, 679, 680, 421, 422, 616, + 702, 754, 304, 328, 473, 334, 341, 407, 178, 196, + 192, 220, 211, 413, 360, 730, 731, 359, 609, 187, + 308, 346, 309, 99, 181, 558, 114, 531, 502, 184, + 366, 369, 367, 368, 323, 325, 327, 605, 606, 434, + 330, 603, 329, 331, 333, 607, 364, 424, 207, 201, + 322, 306, 199, 311, 414, 43, 312, 405, 404, 225, + 313, 314, 620, 527, 420, 533, 338, 56, 500, 200, + 326, 530, 701, 229, 233, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 549, 411, 393, 394, 395, + 550, 416, 169, 170, 535, 729, 736, 737, 738, 739, + 410, 552, 415, 224, 227, 228, 284, 401, 402, 417, + 418, 419, 46, 618, 296, 553, 231, 744, 223, 218, + 561, 342, 340, 406, 222, 195, 217, 307, 69, 235, + 234, 236, 496, 497, 498, 499, 315, 316, 438, 548, + 732, 733, 214, 202, 425, 188, 25, 556, 291, 532, + 451, 370, 51, 371, 317, 335, 343, 365, 230, 232, + 298, 303, 358, 412, 619, 504, 505, 302, 540, 541, + 339, 554, 198, 295, 324, 290, 557, 745, 734, 189, + 453, 318, 182, 332, 551, 747, 560, 68, 164, 194, + 185, 724, 725, 281, 686, 179, 300, 305, 703, 746, + 319, 320, 321, 602, 345, 344, 336, 186, 215, 297, + 221, 205, 193, 216, 180, 299, 559, 165, 699, 423, + 483, 213, 210, 301, 274, 704, 555, 534, 183, 487, + 167, 208, 347, 693, 694, 695, 698, 439, 400, 348, + 349, 206, 288, 525, 526, 352, 493, 388, 467, 503, + 474, 468, 252, 253, 356, 537, 539, 226, 696, 372, + 373, 374, 529, 375, 377, 378, 383, 443, 60, 62, + 101, 104, 103, 750, 751, 67, 32, 429, 432, 465, + 469, 390, 700, 617, 387, 391, 392, 433, 28, 485, + 455, 489, 488, 52, 53, 54, 57, 58, 59, 61, + 63, 64, 55, 601, 448, 462, 562, 48, 50, 458, + 459, 30, 435, 484, 507, 386, 486, 518, 49, 516, + 517, 538, 29, 437, 436, 66, 47, 492, 494, 495, + 350, 384, 446, 713, 563, 441, 457, 461, 442, 389, + 431, 463, 71, 454, 714, 449, 447, 385, 621, 622, + 396, 649, 426, 501, 598, 597, 596, 595, 594, 593, + 592, 591, 353, 354, 355, 470, 471, 472, 482, 475, + 476, 477, 478, 479, 480, 481, 521, 522, 715, 716, + 542, 544, 545, 614, 546, 543, 269, 753, 427, 428, + 272, 718, 719, 102, 720, 722, 721, 31, 723, 743, + 740, 741, 742, 624, 547, 611, 726, 613, 612, 671, + 672, 673, 674, 675, -520, -518, -437, 609, 310, 705, + 450, 608, 610, 444, 423, 749, 752, 58, 448, 292, + 353, 354, 355, 519, 421, -297, -437, 753, -101, -18, + -17, -9, -108, -237, -238, -706, 258, 260, 459, -312, + 271, -437, -446, 26, 500, -121, 501, 266, 267, 89, + 81, -437, -10, -135, -8, -144, -99, -234, -641, 506, + -444, -437, 353, 353, 614, -444, 271, 271, 728, 505, + 546, 614, 729, 736, 744, 541, 434, 103, 104, 724, + 725, 30, 271, 445, 298, 539, 537, 538, 542, 543, + 544, 545, -79, -593, -575, 534, 533, -450, 526, 532, 524, 536, 527, 422, 378, 375, 623, 377, 382, 261, - 717, 606, 600, -415, 467, 503, 562, 563, 446, 504, - 549, 551, 528, 114, 212, 209, -429, 302, 481, -427, - -566, 277, -514, -486, 303, -513, -488, -516, -489, 35, + 718, 606, 600, -425, 467, 503, 562, 563, 446, 504, + 549, 551, 528, 114, 212, 209, -439, 302, 481, -437, + -576, 277, -524, -496, 303, -523, -498, -526, -499, 35, 261, 263, 262, 623, 299, 18, 448, 273, 16, 15, 449, 285, 28, 29, 31, 17, 450, 452, 32, 453, 456, 457, 458, 45, 462, 463, 292, 92, 100, 95, - 671, 672, 673, 674, 675, 310, -292, -427, -462, -454, - 121, -457, -449, -450, -452, -405, -604, -447, 89, 150, - 151, 158, 122, 751, -451, -547, 39, 124, 629, 633, - 670, 573, -397, -398, -399, -400, -401, -402, 615, -427, - -605, -603, 95, 105, 107, 111, 112, 110, 108, 172, - 203, 109, 96, 173, -234, 92, -625, 639, 645, -421, - 662, 687, 688, 689, 690, 661, 65, -573, -581, 270, - -579, 171, 209, 288, 205, 16, 156, 493, 206, 678, + 671, 672, 673, 674, 675, 310, -296, -437, -472, -464, + 121, -467, -459, -460, -462, -415, -614, -457, 89, 150, + 151, 158, 122, 756, -461, -557, 39, 124, 629, 633, + 670, 573, -407, -408, -409, -410, -411, -412, 615, -437, + -615, -613, 95, 105, 107, 111, 112, 110, 108, 172, + 203, 109, 96, 173, -238, 92, -635, 639, 645, -431, + 662, 687, 688, 689, 690, 661, 65, -583, -591, 270, + -589, 171, 209, 288, 205, 16, 156, 493, 206, 678, 679, 680, 636, 658, 575, 576, 685, 640, 650, 665, 631, 632, 634, 626, 627, 628, 630, 641, 643, 657, - -582, 653, 663, 664, 649, 681, 682, 735, 683, 684, + -592, 653, 663, 664, 649, 681, 682, 740, 683, 684, 666, 667, 668, 677, 676, 669, 671, 672, 673, 674, - 675, 721, 94, 93, 656, 655, 642, 637, 638, 644, + 675, 722, 94, 93, 656, 655, 642, 637, 638, 644, 625, 635, 646, 654, 659, 660, 432, 114, 433, 434, 565, 424, 84, 435, 277, 500, 74, 436, 437, 438, 439, 440, 572, 441, 75, 442, 431, 292, 483, 443, 208, 226, 578, 577, 579, 569, 566, 564, 567, 568, - 570, 571, 647, 648, 652, -164, -166, 691, -681, -388, - -682, 6, 7, 8, 9, -683, 173, -672, 502, 619, - 95, 565, 271, 346, 421, 19, 727, 382, 607, 727, - 382, 607, 360, 183, 180, -500, 183, 120, 189, 188, - 275, 183, -500, -427, 186, 727, 185, 723, 728, 614, - 356, -476, -211, 421, 483, 375, 101, 302, -480, -477, - 605, -567, 350, 346, 322, 272, 117, -212, 282, 281, - 115, 565, 270, 460, 341, 60, 62, -244, 51, 276, - 42, -308, -633, 599, -632, -427, -641, -642, 258, 259, - 260, 42, 728, 272, 274, 271, 723, 614, 302, 421, - 565, 483, 101, 375, 271, -641, 739, 180, 549, 551, - 502, 302, 481, 44, -507, 493, -506, -508, 550, 561, - 93, 94, 548, -415, 114, 525, 525, -681, -388, -231, - -234, -143, -631, 607, 727, 614, 728, 272, 421, 483, - 302, 273, 271, 602, 605, 274, 565, 270, 353, 445, - 298, 375, 382, 101, 185, 723, -238, -239, -240, 254, - 255, 256, 73, 259, 257, 70, 35, 36, 37, -1, - 128, 750, -454, -454, -6, 753, -6, -454, -427, -427, - 175, -315, -319, -316, -318, -317, 749, -321, -320, 209, - 210, 171, 213, 219, 215, 216, 217, 218, 220, 221, - 222, 223, 224, 227, 228, 225, 34, 226, 288, 205, - 206, 207, 208, -324, 192, 211, 617, 247, 193, 248, - 194, 249, 195, 250, 169, 170, 251, 196, 199, 200, - 201, 202, 198, 229, 230, 231, 232, 233, 234, 235, - 236, 238, 237, 239, 240, 241, 242, 243, 244, 245, - 246, 174, -277, 95, 35, 89, 174, 95, -681, -254, - -255, 11, -244, 19, -308, -299, 174, 751, -403, -427, - 502, 131, -117, 81, -117, 501, 81, -117, 501, 266, - -634, -635, -636, -638, 266, 501, 500, 267, 337, -138, - 174, 310, 19, -434, -434, -427, 87, -278, -279, -308, - -310, -308, -665, -664, 35, 614, -281, 26, 547, 730, - 732, 525, 740, 741, 742, 86, -439, 139, 143, -439, - -384, 20, -384, 26, 26, 300, 300, 300, -439, 340, - -692, -693, 19, 141, -437, -693, -437, -437, -439, -694, - 273, 535, 46, 301, 300, -256, -257, 24, -256, 529, - 525, -531, 530, 531, -441, -693, -440, -439, -439, -440, - -439, -439, 381, -439, 35, 376, 377, 271, 274, 565, - 375, 718, -692, -692, 34, 34, -488, 302, -514, -486, - 39, 86, 175, 275, 175, 86, 89, 446, 421, 483, - 447, 565, 271, 460, 274, 302, 461, 421, 483, 271, - 274, 565, 302, 421, 271, 274, 483, 302, 461, 421, - 524, 525, 274, 30, 451, 454, 455, 525, -587, 561, - 175, 120, 117, 119, -454, 138, -469, 131, 132, 133, - 134, 135, 136, 137, 145, 144, 157, 118, 150, 151, - 152, 153, 154, 155, 156, 146, 147, 148, 149, 141, - 121, 139, 143, 140, 123, 162, 161, -234, -454, -462, - 65, -452, -452, -452, -452, -427, -547, -459, -454, 89, - 89, 89, 89, 89, 174, 108, 95, 89, -454, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, -580, 89, 89, -466, -467, 89, 89, -447, - -403, 89, 95, 95, 89, 89, 89, 95, 89, 89, - 89, -467, -467, 89, 89, 89, 89, 89, 89, 89, + 570, 571, 647, 648, 652, -168, -170, 691, -691, -398, + -692, 6, 7, 8, 9, -693, 173, -682, 502, 619, + 95, 565, 271, 346, 421, 19, 728, 382, 607, 728, + 382, 607, 360, 183, 180, -510, 183, 120, 189, 188, + 275, 183, -510, -437, 186, 728, 185, 724, 729, 736, + 614, 356, -486, -215, 421, 483, 375, 101, 302, -490, + -487, 605, -577, 350, 346, 322, 272, 117, -216, 282, + 281, 115, 565, 270, 460, 341, 60, 62, -248, 51, + 276, 42, -312, -643, 599, -642, -437, -651, -652, 258, + 259, 260, 42, 729, 736, 272, 274, 271, 724, 614, + 302, 421, 565, 483, 101, 375, 271, -651, 744, 180, + 549, 551, 502, 302, 481, 44, -517, 493, -516, -518, + 550, 561, 93, 94, 548, -425, 114, 525, 525, -691, + -398, -235, -238, -147, -641, 607, 728, 614, 729, 736, + 272, 421, 483, 302, 273, 271, 602, 605, 274, 565, + 270, 353, 445, 298, 375, 382, 101, 185, 724, -242, + -243, -244, 254, 255, 256, 73, 259, 257, 70, 35, + 36, 37, -1, 128, 755, -464, -464, -6, 758, -6, + -464, -437, -437, 175, -319, -323, -320, -322, -321, 754, + -325, -324, 209, 210, 171, 213, 219, 215, 216, 217, + 218, 220, 221, 222, 223, 224, 227, 228, 225, 34, + 226, 288, 205, 206, 207, 208, -328, 192, 211, 617, + 247, 193, 248, 194, 249, 195, 250, 169, 170, 251, + 196, 199, 200, 201, 202, 198, 229, 230, 231, 232, + 233, 234, 235, 236, 238, 237, 239, 240, 241, 242, + 243, 244, 245, 246, 174, -281, 95, 35, 89, 174, + 95, -691, -258, -259, 11, -248, 19, -312, -303, 174, + 756, -413, -437, 502, 131, -121, 81, -121, 501, 81, + -121, 501, 266, -644, -645, -646, -648, 266, 501, 500, + 267, 337, -142, 174, 310, 19, -444, -444, -437, 87, + -282, -283, -312, -314, -312, -675, -674, 35, 614, -285, + 26, 547, 731, 733, 525, 739, 745, 746, 747, 86, + -449, 139, 143, -449, -394, 20, -394, 26, 26, 300, + 300, 300, -449, 340, -703, -704, 19, 141, -447, -704, + -447, -447, -449, -705, 273, 535, 46, 301, 300, -260, + -261, 24, -260, 529, 525, -541, 530, 531, -451, -704, + -450, -449, -449, -450, -449, -449, 381, -449, 35, 376, + 377, 271, 274, 565, 375, 719, -703, -703, 34, 34, + -498, 302, -524, -496, 39, 86, 175, 275, 175, 86, + 89, 446, 421, 483, 447, 565, 271, 460, 274, 302, + 461, 421, 483, 271, 274, 565, 302, 421, 271, 274, + 483, 302, 461, 421, 524, 525, 274, 30, 451, 454, + 455, 525, -597, 561, 175, 120, 117, 119, -464, 138, + -479, 131, 132, 133, 134, 135, 136, 137, 145, 144, + 157, 118, 150, 151, 152, 153, 154, 155, 156, 146, + 147, 148, 149, 141, 121, 139, 143, 140, 123, 162, + 161, -238, -464, -472, 65, -462, -462, -462, -462, -437, + -557, -469, -464, 89, 89, 89, 89, 89, 174, 108, + 95, 89, -464, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, -590, 89, 89, -476, + -477, 89, 89, -457, -413, 89, 95, 95, 89, 89, + 89, 95, 89, 89, 89, -477, -477, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, -255, 175, -254, 89, -254, -255, -235, -234, 35, - 36, 35, 36, 35, 36, 35, 36, -684, 714, 89, - 105, 745, 252, -268, -427, -269, -427, -172, 19, 751, - -427, 723, -664, 376, 614, 614, 376, 614, 261, 18, - 364, 58, 365, 554, 14, 187, 188, 189, -427, 186, - 275, -427, -474, 277, -474, -474, 729, -474, -291, -427, - 298, 445, 274, 602, 274, -212, -474, 19, -474, -474, - -474, -474, 273, -474, 26, 271, 271, 271, 271, -474, - 572, 131, 131, 63, -271, 294, -244, -244, -308, 175, - -633, -263, 89, -643, 191, -247, -246, -242, -243, -387, - -389, -245, 89, -308, -234, -427, 729, -566, -566, -308, - -566, -427, 277, -489, -566, 600, -416, -427, -566, -566, - -566, -367, -368, -308, -644, 276, 742, -678, -677, 552, - -680, 554, 180, -508, 180, -508, 92, -488, 302, 302, - 175, 131, 26, -509, 131, 142, -508, -508, -509, -509, - -337, 44, -426, 171, -427, 95, -337, 44, -675, -674, - -308, -255, -235, -234, 90, 90, 90, 614, -566, -566, - 729, -566, -566, -566, -566, -566, -567, -566, -566, -566, - -566, -566, -434, -282, -427, -293, 277, -566, 376, -566, - -566, -566, -236, -237, 152, -454, -427, -240, -3, -176, - -175, 125, 126, 128, 708, 440, 707, 711, 705, -508, - 44, -560, 165, 164, 89, -554, -556, 89, -555, 89, - -555, -555, -555, -555, -555, 89, 89, -557, 89, -557, - -557, -554, -558, 204, 89, -558, -559, 89, -559, -558, - -427, -535, 14, -460, -462, -427, 42, -255, -167, 42, - -257, 23, -264, 294, 101, -300, 734, -427, 206, 185, - 722, 38, 174, 105, 95, -138, -117, 81, -138, -117, - -117, 90, 175, -637, 111, 112, -639, 95, 224, 215, - -427, -136, 95, -603, -7, -13, -8, -140, -10, -12, - -56, -96, -230, 285, 608, 610, -606, -604, 175, 89, - -280, 175, 527, 26, -427, -256, 619, -153, 26, -439, - 19, 141, -439, -439, 19, 141, 302, -384, -452, -452, - -454, 421, 565, 271, -490, 302, -426, -692, -439, -439, - -417, -416, -441, -436, -441, -441, -384, -437, -439, -439, - -454, -441, -437, -384, -427, 525, -384, -384, -531, -416, - -439, 95, -438, -427, -438, -474, -416, -417, -417, 35, - 492, 86, 19, -515, 271, 565, 445, 298, 274, 421, - -513, -495, -492, -490, -488, -491, -490, -518, -403, 525, - -168, 508, 507, 352, -454, -454, -454, -454, 110, 121, - 400, 111, 112, -449, -470, 35, 348, 349, -450, -450, - -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, - -450, -452, -452, -458, -468, -547, 89, 141, 139, 143, - 140, 123, -452, -452, -450, -450, -313, -315, 164, 165, - -339, -426, 171, 90, 175, -454, -630, -629, 125, -454, - -454, -454, -454, -481, -483, -403, 89, -427, -450, -626, - -627, 580, 581, 582, 583, 584, 585, 586, 587, 588, - 589, 590, 436, 431, 437, 435, 424, 443, 438, 439, - 208, 597, 598, 591, 592, 593, 594, 595, 596, -460, - -460, -454, -626, -450, -460, -396, 36, 35, -462, -462, - -462, 90, -454, -640, 398, 397, 399, -259, -427, -460, - 90, 90, 90, 105, -462, -462, -460, -450, -460, -460, - -460, -460, -627, -627, -628, 288, 205, 207, 206, -396, - -396, -396, -396, 152, -462, -462, -396, -396, -396, -396, - 152, -396, -396, -396, -396, -396, -396, -396, -396, -396, - -396, -396, -396, -396, 90, 90, 90, 90, -454, 90, - -454, -454, -454, -454, -454, 152, -462, -256, -166, -585, - -584, -454, 44, -167, -257, -685, 715, 89, -403, -673, - 95, 95, 751, -172, 174, 19, 271, -172, 174, 723, - 185, -172, 565, 19, -427, 95, 105, -427, 95, 105, - 271, 565, 271, 565, -308, -308, -308, 555, 556, 184, - 188, 187, -427, 186, -427, -427, 121, -427, -427, -474, - -427, 38, -293, -282, -474, -474, -474, -648, -427, 96, - 95, -496, -493, -490, -427, -427, -486, -427, -416, -308, - -474, -474, -474, -474, -308, -348, 57, 58, 59, -490, - -213, 60, 61, -576, 65, -230, 89, 34, 89, -271, - -271, -632, 38, -262, -427, -644, 87, -390, -391, -392, - -393, -395, -394, 72, 76, 78, 82, 73, 74, 75, - 528, 79, 84, 77, -425, -430, 38, -427, 95, -425, - -234, -249, -248, -247, -425, 89, -427, -308, -308, -362, - -369, -363, -370, 294, 268, 429, 430, 264, 262, 11, - 263, -378, 341, -475, 573, -343, -344, 81, 45, -346, + 89, 89, 89, 89, 89, -259, 175, -258, 89, -258, + -259, -239, -238, 35, 36, 35, 36, 35, 36, 35, + 36, -694, 714, 89, 105, 750, 252, -272, -437, -273, + -437, -176, 19, 756, -437, 724, -674, 376, 614, 614, + 376, 614, 261, 18, 364, 58, 365, 554, 14, 187, + 188, 189, -437, 186, 275, -437, -484, 277, -484, -484, + 730, 502, -484, -295, -437, 298, 445, 274, 602, 274, + -216, -484, 19, -484, -484, -484, -484, 273, -484, 26, + 271, 271, 271, 271, -484, 572, 131, 131, 63, -275, + 294, -248, -248, -312, 175, -643, -267, 89, -653, 191, + -251, -250, -246, -247, -397, -399, -249, 89, -312, -238, + -437, 730, 502, -576, -576, -312, -576, -437, 277, -499, + -576, 600, -426, -437, -576, -576, -576, -377, -378, -312, + -654, 276, 747, -688, -687, 552, -690, 554, 180, -518, + 180, -518, 92, -498, 302, 302, 175, 131, 26, -519, + 131, 142, -518, -518, -519, -519, -347, 44, -436, 171, + -437, 95, -347, 44, -685, -684, -312, -259, -239, -238, + 90, 90, 90, 614, -576, -576, 730, 502, -576, -576, + -576, -576, -576, -577, -576, -576, -576, -576, -576, -444, + -286, -437, -297, 277, -576, 376, -576, -576, -576, -240, + -241, 152, -464, -437, -244, -3, -180, -179, 125, 126, + 128, 708, 440, 707, 711, 705, -518, 44, -570, 165, + 164, 89, -564, -566, 89, -565, 89, -565, -565, -565, + -565, -565, 89, 89, -567, 89, -567, -567, -564, -568, + 204, 89, -568, -569, 89, -569, -568, -437, -545, 14, + -470, -472, -437, 42, -259, -171, 42, -261, 23, -268, + 294, 101, -304, 735, -437, 206, 185, 723, 38, 174, + 105, 95, -142, -121, 81, -142, -121, -121, 90, 175, + -647, 111, 112, -649, 95, 224, 215, -437, -140, 95, + -613, -7, -13, -8, -144, -10, -12, -58, -99, -234, + 285, 608, 610, -616, -614, 175, 89, -284, 175, 527, + 26, -437, -260, 619, -157, 26, -449, 19, 141, -449, + -449, 19, 141, -449, 302, -394, -462, -462, -464, 421, + 565, 271, -500, 302, -436, -703, -449, -449, -427, -426, + -451, -446, -451, -451, -394, -447, -449, -449, -464, -451, + -447, -394, -437, 525, -394, -394, -541, -426, -449, 95, + -448, -437, -448, -484, -426, -427, -427, 35, 492, 86, + 19, -525, 271, 565, 445, 298, 274, 421, -523, -505, + -502, -500, -498, -501, -500, -528, -413, 525, -172, 508, + 507, 352, -464, -464, -464, -464, 110, 121, 400, 111, + 112, -459, -480, 35, 348, 349, -460, -460, -460, -460, + -460, -460, -460, -460, -460, -460, -460, -460, -460, -462, + -462, -468, -478, -557, 89, 141, 139, 143, 140, 123, + -462, -462, -460, -460, -317, -319, 164, 165, -349, -436, + 171, 90, 175, -464, -640, -639, 125, -464, -464, -464, + -464, -491, -493, -413, 89, -437, -460, -636, -637, 580, + 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, + 436, 431, 437, 435, 424, 443, 438, 439, 208, 597, + 598, 591, 592, 593, 594, 595, 596, -470, -470, -464, + -636, -460, -470, -406, 36, 35, -472, -472, -472, 90, + -464, -650, 398, 397, 399, -263, -437, -470, 90, 90, + 90, 105, -472, -472, -470, -460, -470, -470, -470, -470, + -637, -637, -638, 288, 205, 207, 206, -406, -406, -406, + -406, 152, -472, -472, -406, -406, -406, -406, 152, -406, + -406, -406, -406, -406, -406, -406, -406, -406, -406, -406, + -406, -406, 90, 90, 90, 90, -464, 90, -464, -464, + -464, -464, -464, 152, -472, -260, -170, -595, -594, -464, + 44, -171, -261, -695, 716, 89, -413, -683, 95, 95, + 756, -176, 174, 19, 271, -176, 174, 724, 185, -176, + 565, 19, -437, 95, 105, -437, 95, 105, 271, 565, + 271, 565, -312, -312, -312, 555, 556, 184, 188, 187, + -437, 186, -437, -437, 121, -437, -437, -484, -484, -437, + 38, -297, -286, -484, -484, -484, -658, -437, 96, 95, + -506, -503, -500, -437, -437, -496, -437, -426, -312, -484, + -484, -484, -484, -312, -358, 57, 58, 59, -500, -217, + 60, 61, -586, 65, -234, 89, 34, 89, -275, -275, + -642, 38, -266, -437, -654, 87, -400, -401, -402, -403, + -405, -404, 72, 76, 78, 82, 73, 74, 75, 528, + 79, 84, 77, -435, -440, 38, -437, 95, -435, -238, + -253, -252, -251, -435, 89, -437, -437, -312, -312, -372, + -379, -373, -380, 294, 268, 429, 430, 264, 262, 11, + 263, -388, 341, -485, 573, -353, -354, 81, 45, -356, 292, 469, 465, 304, 308, 99, 309, 502, 310, 273, 312, 313, 314, 329, 331, 284, 315, 316, 317, 493, - 318, 179, 330, 319, 320, 321, 447, -338, 6, 383, - 44, 55, 56, 517, 516, 621, 14, 305, -427, 472, - 610, 34, 39, 264, 268, 263, -648, -646, 34, -427, - 34, -496, -490, -427, -427, 175, 275, -247, -249, -508, - 175, 553, 555, 556, -678, -509, -678, -509, 275, 35, - 492, -512, 492, 35, -486, -506, 549, 551, -501, 95, - 493, -491, -511, 86, 171, -584, -509, -509, -511, -511, - 161, 175, -676, 554, 555, 258, -256, 105, -666, -664, - -427, 614, -427, -566, -310, -648, -495, -486, -427, -566, - -310, -310, -310, -429, -429, 89, 174, 39, -427, -566, - -427, -427, -427, -383, 175, -382, 19, -428, -427, 38, - 95, 174, -177, -175, 127, -454, -6, 707, -454, -6, - -6, -454, -6, -454, -564, 167, -315, 105, 105, -406, - 95, -406, 105, -558, 105, 105, 624, 90, 95, -256, - 692, -258, 23, -253, -252, -454, -577, 65, -232, 89, - -230, 34, 271, 89, -566, 185, 206, 733, -299, 131, - 131, 131, 27, -427, 26, -138, -117, -635, 174, 175, - -279, -262, -308, 623, 105, -155, 24, -427, -384, -427, - 729, -384, -384, -427, 729, 731, -489, -427, -427, -427, - -487, 87, -427, 754, 93, -417, -384, -384, -441, -384, - -384, 175, 25, -439, -441, -441, -299, -437, -299, 174, - -299, -416, -515, -494, -491, -517, 152, -427, -502, 175, - 14, 275, -661, -660, 484, 90, 175, -588, 276, 572, - 95, 751, 500, 252, 253, 110, 400, 111, 112, -547, - -462, -458, -452, -452, -450, -450, -456, 289, -456, 120, - -323, 170, 169, -323, -454, 752, -453, -629, 127, -454, - 38, 175, 38, 175, 87, 175, 90, -554, -454, 174, - 175, 90, 90, 19, 19, 141, 90, -454, 90, 90, - 90, 90, 19, 19, -454, 90, 174, 90, 90, 90, - 90, 87, 90, 175, 90, 90, 90, 90, 175, 175, - 175, -462, -462, -454, -462, 90, 90, 90, -454, -454, - -454, -462, 90, -454, -454, -454, -454, -454, -454, -454, - -454, -454, -454, -262, -454, -454, -525, 520, -525, -525, - -525, 90, -525, 90, 175, 90, 175, 90, 90, 175, - 175, 175, 175, 90, -258, 89, 105, 175, 746, -410, - -409, 95, -173, 275, -427, 723, -427, -173, -427, -427, - 131, -173, -427, 723, 95, 95, -308, -416, -308, -416, - 616, 42, 42, 185, 189, 189, 188, -427, 95, 39, - 26, 26, 339, -427, -148, 611, -292, 89, 89, -308, - -308, -308, -650, 470, -427, -662, 175, 44, -660, 565, - -209, 352, -478, 87, -220, 359, 19, 14, -308, -308, - -308, -308, -322, 38, -499, 86, -578, -463, -624, 691, - -266, 90, -259, -622, -623, -259, -265, -272, -427, -576, - -576, 89, 90, 175, 19, -241, -309, -427, -247, -246, - -246, -246, -246, -246, -246, 72, 83, 72, -260, 89, - 72, 77, 72, 77, 72, 77, 72, -392, 72, 83, - -263, -430, 175, 90, -671, -670, -669, -667, 80, 276, - 81, -460, 34, -553, 38, -263, 175, 23, 294, -307, - -424, -304, -306, 279, -444, -305, 282, -618, 280, 278, - 115, 283, 337, 116, 273, -424, -424, 279, -347, 275, - 38, -424, -365, 273, 403, 337, 280, 23, 294, -364, - 273, 116, -427, 279, 283, 280, 278, -423, 131, -415, - 161, 275, 46, 447, -423, 622, 294, -423, -423, -423, - -423, -423, -423, -423, 311, 311, -423, -423, -423, -423, - -423, -423, -423, -423, -423, -423, -423, 180, -423, -423, - -423, -423, -423, -423, 89, 306, 307, 339, 611, 125, - 624, 613, -489, 275, 540, 540, -651, 470, 34, 427, - 427, 428, -662, 423, 45, 34, -221, 421, -368, -366, - -438, 34, 34, -509, -677, -679, 557, 554, 560, -511, - -511, 105, 275, 89, 131, -511, -511, 44, -426, -674, - 561, 555, -258, -289, 725, -427, 86, -310, -283, -284, - -285, -286, -315, -403, 749, 210, 213, 215, 216, 217, - 218, 220, 221, 222, 223, 224, 227, 228, 225, 226, - 288, 205, 206, 207, 208, 192, 211, 617, 193, 194, - 195, 169, 170, 196, 199, 200, 201, 202, 198, 229, - 230, 231, 232, 233, 234, 235, 236, 238, 237, 239, - 240, 241, 242, 243, 244, 245, 246, -427, -293, 95, - 19, -289, -384, -237, -249, -427, 95, -427, 152, 128, - -6, 126, -181, -180, -179, 129, 705, 711, 128, 128, - 128, 90, 90, 90, 90, 175, 90, 90, 90, 175, - 90, 175, 105, -591, 530, -258, 95, -167, 666, 175, - -250, 40, 41, -578, -266, 90, -622, -308, -265, -427, - 95, 105, 95, 38, -219, 92, 100, 95, -300, -454, - -427, 95, -454, 206, 174, 502, -427, -604, 90, 105, - -439, -427, -439, 174, -427, -216, -218, -427, 95, -427, - -486, -426, -439, -384, -454, -454, -384, -439, -439, -441, - -427, -299, -517, 175, 275, 174, 174, -492, 450, -494, - 23, 14, -403, 42, -410, 131, 751, -427, 90, -456, - -456, 120, -452, -449, 90, 128, -454, 126, -313, -454, - -313, -314, -320, 171, 209, 288, 208, 207, 205, 164, - 165, -337, -483, 616, -250, 90, -427, -462, -454, -454, - -450, 90, -454, -454, 19, -427, -337, -450, -454, -454, - -454, -255, -255, 90, 90, -524, -525, -524, -524, 90, - 90, 90, 90, -524, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 175, 89, -525, -525, - -454, -525, -454, -525, -525, -454, 105, 107, 105, 107, - -584, -167, -686, 67, 713, 66, 492, 110, 342, 175, - 105, 95, 752, 175, 131, 421, -427, 19, 174, 95, - -427, 95, 19, 271, -427, 19, 19, -308, -308, -308, - 189, 95, -663, 346, 421, 565, 271, 421, 346, 565, - 271, -536, 105, -334, 14, -149, 125, 95, 458, -294, - -295, -296, -297, -298, 141, 176, 177, -283, -263, 89, - -263, -653, 532, 472, 482, -423, 375, -446, -445, 423, - 45, -571, 493, 478, 479, -493, 302, -416, 152, -659, - 102, 131, 86, 387, 391, 393, 395, 394, 392, 388, - 389, 390, -472, -473, -471, -475, -416, 95, -646, 89, - 89, -230, 38, 139, -220, 359, 19, 89, -333, 314, - 89, 38, -548, 372, -315, 43, 175, 89, 90, 175, - 65, 175, 131, 90, 175, 90, 175, 131, -1, -427, - -308, -241, -427, 19, 175, -645, 174, 86, -274, -273, - 86, 87, -275, 86, -273, -273, 72, -261, 95, 72, - 72, 72, -248, -669, -668, 26, -618, -618, -618, 90, - -335, 89, -336, -217, -427, 95, -548, -315, 38, -363, - 268, 263, -521, 339, 340, -522, -538, 342, -540, 89, - -312, -403, -305, -617, -618, -474, -427, 116, -617, 116, - 89, -312, -403, -403, -366, -403, -427, -427, -427, -427, - -373, -372, -403, -376, 35, -377, -427, -427, -427, -427, - 116, -427, 116, -342, 44, 52, 53, 54, -423, -423, - 212, -345, 44, 492, 494, 495, -376, 105, 105, 105, - 105, 95, 95, 95, -423, -423, 105, 95, -430, 95, - -619, 188, 48, 49, 105, 105, 105, 105, 44, 95, - -350, 44, 322, 326, 323, 324, 325, 95, 105, 44, - 105, 44, 105, 44, -427, 89, -620, -621, 95, -536, - 95, 89, 105, 95, 264, -489, 95, 86, -653, -423, - 427, -508, 131, 131, -446, -655, 99, 473, -655, -658, - 352, -223, 565, 35, -267, 268, 263, -646, -498, -497, - -403, -498, -511, 554, 558, 559, -494, -442, 95, -501, - -167, -308, -569, 332, 333, 90, 175, -315, -427, -386, - 21, 174, 124, -6, -177, -179, -454, -6, -454, 707, - 440, 708, 95, 105, 105, -599, 514, 509, 511, -167, - -600, 500, 14, -252, -251, 47, 90, 65, -255, 90, - 27, 752, 752, 752, 752, 95, -427, 105, -384, -439, - -384, -216, -439, -439, 141, -384, -299, -384, -384, -439, - 19, -491, -486, 152, 152, -427, 451, -502, 95, 471, - 95, 271, 752, 95, -410, -449, -454, 90, 38, 90, - 90, -555, -555, -554, -557, -554, -323, -323, 90, 89, - -250, 90, 90, 26, 90, 90, 90, 90, -454, 90, - 90, 175, 175, 90, -574, 574, -575, 651, -524, -524, - -524, -524, -524, -524, -524, -524, -524, -524, -524, -524, - -524, -524, -524, -524, -524, -524, -454, -465, -464, 294, - 90, 175, 90, 175, 90, 515, 720, 720, 515, 720, - 720, 90, 175, -626, 175, -418, 347, -418, -409, 95, - -427, 95, 723, -427, 752, 752, 723, -427, 95, -308, - -416, -270, 531, -227, 125, -228, 123, 46, 95, -427, - 19, -427, -427, 339, -427, 339, -427, -427, 95, 89, - -154, 624, 89, -151, 612, 95, 90, 175, -403, 90, - 38, -301, -302, -303, -312, -304, -306, 38, -654, 99, - -649, 95, -427, 96, -427, -655, 173, 425, 44, 474, - 475, 490, 420, 105, 105, 480, -647, -427, -222, 271, - 421, -222, -657, 56, 131, 95, -308, -471, -415, 161, - 313, -299, -427, 375, -381, -380, -427, 95, -301, -230, - -308, -308, 95, -301, -423, -301, -230, -549, 374, 23, - 105, 151, 116, -463, -586, -585, 65, -230, -259, -578, - -623, -584, -427, -427, -454, 90, -264, 87, 174, -249, - -309, -427, 152, -454, -454, 89, -454, 90, 89, 72, - 11, 21, 175, -335, 131, -549, -230, -533, 343, 89, - -531, 89, -531, 116, 388, -541, -539, 294, -371, 48, - 50, -315, -615, -427, -613, -615, -427, -613, -613, -474, - -454, -371, -312, 275, 34, 263, -374, 391, 385, 386, - 391, 393, 395, 394, -503, 338, 121, -503, 175, -250, - 175, -427, -337, -337, 34, 95, 95, -310, 90, 175, - 131, 95, -151, -150, -454, -231, -234, 275, 86, 271, - -654, -649, 131, -509, 95, 95, -655, 95, 95, -659, - 131, -311, 271, -416, 175, -267, -267, -384, 19, 175, - 131, -384, 90, -276, 26, -285, 44, 375, -385, 22, - 23, 152, 128, 126, 128, 128, -427, 90, 90, -561, - 693, -595, -597, 509, 23, 23, -276, -601, 698, 95, - 451, 48, 49, -232, 65, -230, -578, -256, 206, 95, - 752, -384, -439, -384, -384, 729, -384, -486, -502, 493, - -308, 175, 752, -313, -356, 95, -454, 90, -454, -454, - 90, 95, 90, 95, 90, -255, 23, -525, -454, -525, - -454, -525, 90, 175, 90, 90, 90, 175, 90, 90, - -454, 90, -626, -419, 206, 95, -419, -427, -427, 19, - -428, -225, 275, -299, -229, 370, 89, 366, -227, 185, - 89, 95, -427, 19, -427, -536, 339, -536, 339, 271, - -427, -289, -335, -152, 613, 105, -150, 95, -479, 618, - -296, -315, 269, -230, 90, 175, -230, 95, -652, 484, - -537, 380, 105, 44, 105, 173, 476, -572, -210, 99, - -310, 35, -267, -210, -656, 99, 131, 751, 89, -423, - -423, -423, -225, 375, -427, 90, 175, -423, -423, 90, - -226, 54, -427, 90, 728, 90, -331, 14, -550, 293, - 105, 151, 105, 151, 105, 17, 276, 90, -578, 131, - -425, -249, -427, -384, -645, 174, -105, -106, 125, -262, - -614, -427, 278, 23, 23, -336, 90, -218, -550, -523, - 344, 105, -450, 89, -450, 89, -532, 341, 89, 90, - 175, -427, -403, -328, -327, -325, 110, 121, 44, 465, - -326, 99, 161, 327, 330, 329, 305, 328, -361, -443, - 86, 686, 468, 385, 386, -475, 693, 604, 701, 38, - 278, 115, 116, 452, -444, 89, 89, 87, 347, 89, - 89, -615, 90, -371, -403, 44, -374, 44, -375, 409, - -484, -484, -484, -484, 338, -372, -427, 161, -337, 90, - -621, 95, 90, -489, 271, -427, -652, 95, -511, -657, - 95, -210, -310, -646, -255, -249, -497, -584, 17, -447, - -427, -454, -462, 735, 737, 738, 277, -6, 708, 440, - -352, 694, 95, 23, 95, -593, 95, -591, 95, -462, - -578, 95, -384, -427, -170, -349, -415, 310, 90, -355, - 141, 14, 90, 90, 90, -524, -524, -524, -527, -526, - -530, 515, 339, 523, -462, 90, 90, 95, 95, 90, - 90, 95, 95, 95, 723, 421, -225, 38, 458, 24, - 630, 371, -262, 367, 368, 369, -427, 95, -462, -231, - 751, 375, -427, 19, 95, -536, 95, -536, -427, 339, - 90, 38, 95, 90, 95, 95, -287, -315, -214, 14, - -331, -303, -214, 23, 14, 173, 424, 44, 105, 44, - 477, 95, -222, 131, 111, 112, -411, -412, 95, -481, - -337, -339, 95, -427, -380, -447, -447, -329, -230, 38, - -330, -378, -475, -225, 30, 375, -169, -333, -168, -334, - -329, 89, -551, 179, 105, 151, 105, 105, -498, -454, - -384, -384, -106, -108, 121, -427, 90, 90, 175, -551, - -540, 23, 90, -518, 90, -518, 89, 131, -450, -539, - -542, 65, -325, 110, -450, 95, -339, -340, 44, 326, - 322, 131, 131, -341, 44, 306, 307, -351, 89, 337, - 17, 105, 212, 89, 702, 89, 116, 116, -308, -481, - -481, -616, 387, 388, 389, 396, 391, 392, 390, 393, - 394, 395, -616, -481, -481, 89, -504, -503, -450, -484, - 131, -485, 284, 401, 402, 99, 14, 385, 386, 406, - 405, 404, 410, 411, 415, 416, 412, 414, 413, 417, - 418, 419, 407, 408, 409, 424, 435, -423, 161, -427, - 174, -656, -256, -384, -570, 14, 736, 89, 89, -427, - -427, -407, 695, 105, 95, 511, -599, -439, -562, 696, - -589, -531, -337, 131, 90, 79, 617, 619, 90, -529, - 123, 476, 480, -448, -451, 105, 107, 203, 173, -525, - -525, 90, 90, -427, -427, -308, 95, 105, 90, 120, - 120, 90, 90, -414, -413, 95, -427, 375, -427, -289, - 95, -289, 95, 339, -536, -2, 618, -215, 64, 561, - 95, 96, 471, 95, 96, 105, 424, -210, 95, 752, - 175, 131, 90, -537, -519, 294, -230, 175, -378, -415, - -427, -170, -519, -332, -379, -427, 95, -568, 188, 373, - 14, 105, 151, 105, -255, -107, 120, -108, -427, 278, - -552, 188, 373, -522, 90, 90, 90, -518, 105, 90, - -546, -543, 89, -378, 296, 141, 95, 95, 105, 89, - -579, 34, 95, 38, -454, -482, 89, 90, 90, 90, - 90, -481, 111, 112, -423, -423, 95, 95, 384, -423, - -423, -423, -423, -423, -423, 89, 95, 95, -423, -423, - -423, -423, 131, -423, -423, -337, -423, 174, -427, 738, - 89, -462, -462, 89, 23, -561, -384, -563, 697, 95, - -598, 514, -592, -590, 509, 510, 511, 512, 95, 618, - 69, 620, -528, -529, 480, -448, -451, 691, 521, 521, - 521, 95, -427, 95, 752, 175, 131, -427, 375, -289, - -289, -536, 95, -290, -427, 337, 493, -412, 95, -484, - -520, 346, 23, -378, -423, -537, -520, 90, 175, -423, - -423, 373, 105, 151, 105, -256, 126, -454, -107, 373, - -534, 345, 90, -546, -378, -545, -544, 344, 297, 89, - 90, -454, -466, -423, 90, 89, 90, -354, -353, 615, - -481, -484, 87, -484, 87, -484, 87, -484, 87, 90, - 105, 105, -427, 105, 105, 105, 105, 105, 105, -518, - 105, 105, 105, 105, 111, 112, 105, 105, -337, -427, - -165, 89, 90, 90, -408, -427, -593, -352, 95, -602, - 276, -596, -597, 513, -590, 23, 511, 23, 23, -171, - 175, 69, 120, 522, 522, 522, -227, -228, -227, -228, - -289, -413, 95, -427, 95, -289, -288, 38, 516, 451, - 23, -521, -337, -379, -447, -447, 105, 17, 18, 126, - 105, 90, 175, -427, 293, 89, -461, -455, -454, 293, - 90, -427, -454, -505, 704, 703, -360, -358, -359, 86, - 528, 335, 336, 90, -616, -616, -616, -616, -361, 90, - 90, 175, -460, 90, 175, -407, -609, 89, 105, -595, - -594, -596, 23, -593, 23, -593, -593, 518, 14, -528, - -227, -227, -289, 95, -403, 89, -533, 34, 16, -544, - -543, -461, 90, 175, -503, 90, -359, 86, -358, 86, - 18, 17, -484, -484, -484, -484, 89, 90, -427, -612, - 34, 90, -608, -607, -404, -603, -427, 514, 515, 95, - -593, 131, 619, -689, -688, 719, -518, -523, -498, 89, - 65, 90, -455, -505, -357, 332, 333, 34, 188, -357, - -460, -611, -610, -405, 90, 175, 174, 95, 620, 95, - 90, -540, -266, 89, 110, 44, 334, 90, 175, 131, - -607, -427, 90, -462, -610, 44, -454, 174, 65, 90, - -427, 89, -462, 90, + 318, 179, 330, 319, 320, 321, 447, -348, 6, 383, + 44, 55, 56, 517, 516, 621, 14, 305, -437, 472, + 610, 34, 39, 264, 268, 263, -658, -656, 34, -437, + 34, -506, -500, -437, -437, 175, 275, -251, -253, -518, + 175, 553, 555, 556, -688, -519, -688, -519, 275, 35, + 492, -522, 492, 35, -496, -516, 549, 551, -511, 95, + 493, -501, -521, 86, 171, -594, -519, -519, -521, -521, + 161, 175, -686, 554, 555, 258, -260, 105, -676, -674, + -437, 614, -437, -576, -576, -314, -658, -505, -496, -437, + -576, -314, -314, -314, -439, -439, 89, 174, 39, -437, + -576, -437, -437, -437, -393, 175, -392, 19, -438, -437, + 38, 95, 174, -181, -179, 127, -464, -6, 707, -464, + -6, -6, -464, -6, -464, -574, 167, -319, 105, 105, + -416, 95, -416, 105, -568, 105, 105, 624, 90, 95, + -260, 692, -262, 23, -257, -256, -464, -587, 65, -236, + 89, -234, 34, 271, 89, -576, 185, 206, 734, -303, + 131, 131, 131, 27, -437, 26, -142, -121, -645, 174, + 175, -283, -266, -312, 623, 105, -159, 24, -437, -394, + -437, 730, -394, -394, -437, 730, 732, -394, -499, -437, + -437, -437, -497, 87, -437, 759, 93, -427, -394, -394, + -451, -394, -394, 175, 25, -449, -451, -451, -303, -447, + -303, 174, -303, -426, -525, -504, -501, -527, 152, -437, + -512, 175, 14, 275, -671, -670, 484, 90, 175, -598, + 276, 572, 95, 756, 500, 252, 253, 110, 400, 111, + 112, -557, -472, -468, -462, -462, -460, -460, -466, 289, + -466, 120, -327, 170, 169, -327, -464, 757, -463, -639, + 127, -464, 38, 175, 38, 175, 87, 175, 90, -564, + -464, 174, 175, 90, 90, 19, 19, 141, 90, -464, + 90, 90, 90, 90, 19, 19, -464, 90, 174, 90, + 90, 90, 90, 87, 90, 175, 90, 90, 90, 90, + 175, 175, 175, -472, -472, -464, -472, 90, 90, 90, + -464, -464, -464, -472, 90, -464, -464, -464, -464, -464, + -464, -464, -464, -464, -464, -266, -464, -464, -535, 520, + -535, -535, -535, 90, -535, 90, 175, 90, 175, 90, + 90, 175, 175, 175, 175, 90, -262, -696, 715, 89, + 105, 175, 751, -420, -419, 95, -177, 275, -437, 724, + -437, -177, -437, -437, 131, -177, -437, 724, 95, 95, + -312, -426, -312, -426, 616, 42, 42, 185, 189, 189, + 188, -437, 95, 39, 26, 26, 339, -437, -437, -152, + 611, -296, 89, 89, -312, -312, -312, -660, 470, -437, + -672, 175, 44, -670, 565, -213, 352, -488, 87, -224, + 359, 19, 14, -312, -312, -312, -312, -326, 38, -509, + 86, -588, -473, -634, 691, -270, 90, -263, -632, -633, + -263, -269, -276, -437, -586, -586, 89, 90, 175, 19, + -245, -313, -437, -251, -250, -250, -250, -250, -250, -250, + 72, 83, 72, -264, 89, 72, 77, 72, 77, 72, + 77, 72, -402, 72, 83, -267, -440, 175, 90, -681, + -680, -679, -677, 80, 276, 81, -470, 34, 34, 56, + 55, -563, 38, -267, 175, 23, 294, -311, -434, -308, + -310, 279, -454, -309, 282, -628, 280, 278, 115, 283, + 337, 116, 273, -434, -434, 279, -357, 275, 38, -434, + -375, 273, 403, 337, 280, 23, 294, -374, 273, 116, + -437, 279, 283, 280, 278, -433, 131, -425, 161, 275, + 46, 447, -433, 622, 294, -433, -433, -433, -433, -433, + -433, -433, 311, 311, -433, -433, -433, -433, -433, -433, + -433, -433, -433, -433, -433, 180, -433, -433, -433, -433, + -433, -433, 89, 306, 307, 339, 611, 125, 624, 613, + -499, 275, 540, 540, -661, 470, 34, 427, 427, 428, + -672, 423, 45, 34, -225, 421, -378, -376, -448, 34, + 34, -519, -687, -689, 557, 554, 560, -521, -521, 105, + 275, 89, 131, -521, -521, 44, -436, -684, 561, 555, + -262, -293, 726, -437, -437, 86, -314, -287, -288, -289, + -290, -319, -413, 754, 210, 213, 215, 216, 217, 218, + 220, 221, 222, 223, 224, 227, 228, 225, 226, 288, + 205, 206, 207, 208, 192, 211, 617, 193, 194, 195, + 169, 170, 196, 199, 200, 201, 202, 198, 229, 230, + 231, 232, 233, 234, 235, 236, 238, 237, 239, 240, + 241, 242, 243, 244, 245, 246, -437, -297, 95, 19, + -293, -394, -241, -253, -437, 95, -437, 152, 128, -6, + 126, -185, -184, -183, 129, 705, 711, 128, 128, 128, + 90, 90, 90, 90, 175, 90, 90, 90, 175, 90, + 175, 105, -601, 530, -262, 95, -171, 666, 175, -254, + 40, 41, -588, -270, 90, -632, -312, -269, -437, 95, + 105, 95, 38, -223, 92, 100, 95, -304, -464, -437, + 95, -464, 206, 174, 502, -437, -614, 90, 105, -449, + -437, -449, 174, -437, -220, -222, -437, 95, -437, -496, + -436, -449, -394, -464, -464, -394, -449, -449, -451, -437, + -303, -527, 175, 275, 174, 174, -502, 450, -504, 23, + 14, -413, 42, -420, 131, 756, -437, 90, -466, -466, + 120, -462, -459, 90, 128, -464, 126, -317, -464, -317, + -318, -324, 171, 209, 288, 208, 207, 205, 164, 165, + -347, -493, 616, -254, 90, -437, -472, -464, -464, -460, + 90, -464, -464, 19, -437, -347, -460, -464, -464, -464, + -259, -259, 90, 90, -534, -535, -534, -534, 90, 90, + 90, 90, -534, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 175, 89, -535, -535, -464, + -535, -464, -535, -535, -464, 105, 107, 105, 107, -594, + -171, 89, 294, 175, 105, 95, 757, 175, 131, 421, + -437, 19, 174, 95, -437, 95, 19, 271, -437, 19, + 19, -312, -312, -312, 189, 95, -673, 346, 421, 565, + 271, 421, 346, 565, 271, -546, 105, -338, 14, -342, + 14, -153, 125, 95, 458, -298, -299, -300, -301, -302, + 141, 176, 177, -287, -267, 89, -267, -663, 532, 472, + 482, -433, 375, -456, -455, 423, 45, -581, 493, 478, + 479, -503, 302, -426, 152, -669, 102, 131, 86, 387, + 391, 393, 395, 394, 392, 388, 389, 390, -482, -483, + -481, -485, -426, 95, -656, 89, 89, -234, 38, 139, + -224, 359, 19, 89, -337, 314, 89, 38, -558, 372, + -319, 43, 175, 89, 90, 175, 65, 175, 131, 90, + 175, 90, 175, 131, -1, -437, -312, -245, -437, 19, + 175, -655, 174, 86, -278, -277, 86, 87, -279, 86, + -277, -277, 72, -265, 95, 72, 72, 72, -252, -679, + -678, 26, -628, -628, -628, 90, -339, 89, -340, -221, + -437, 95, -343, 89, -344, -345, -437, 95, -558, -319, + 38, -373, 268, 263, -531, 339, 340, -532, -548, 342, + -550, 89, -316, -413, -309, -627, -628, -484, -437, 116, + -627, 116, 89, -316, -413, -413, -376, -413, -437, -437, + -437, -437, -383, -382, -413, -386, 35, -387, -437, -437, + -437, -437, 116, -437, 116, -352, 44, 52, 53, 54, + -433, -433, 212, -355, 44, 492, 494, 495, -386, 105, + 105, 105, 105, 95, 95, 95, -433, -433, 105, 95, + -440, 95, -629, 188, 48, 49, 105, 105, 105, 105, + 44, 95, -360, 44, 322, 326, 323, 324, 325, 95, + 105, 44, 105, 44, 105, 44, -437, 89, -630, -631, + 95, -546, 95, 89, 105, 95, 264, -499, 95, 86, + -663, -433, 427, -518, 131, 131, -456, -665, 99, 473, + -665, -668, 352, -227, 565, 35, -271, 268, 263, -656, + -508, -507, -413, -508, -521, 554, 558, 559, -504, -452, + 95, -511, -171, -312, -579, 332, 333, 90, 175, -319, + -437, -396, 21, 174, 124, -6, -181, -183, -464, -6, + -464, 707, 440, 708, 95, 105, 105, -609, 514, 509, + 511, -171, -610, 500, 14, -256, -255, 47, 90, 65, + -259, 90, 27, 757, 757, 757, 757, 95, -437, 105, + -394, -449, -394, -220, -449, -449, 141, -394, -303, -394, + -394, -449, 19, -501, -496, 152, 152, -437, 451, -512, + 95, 471, 95, 271, 757, 95, -420, -459, -464, 90, + 38, 90, 90, -565, -565, -564, -567, -564, -327, -327, + 90, 89, -254, 90, 90, 26, 90, 90, 90, 90, + -464, 90, 90, 175, 175, 90, -584, 574, -585, 651, + -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, + -534, -534, -534, -534, -534, -534, -534, -534, -464, -475, + -474, 294, 90, 175, 90, 175, 90, 515, 721, 721, + 515, 721, 721, -697, 67, 713, 66, 492, 110, 342, + 90, -636, 175, -428, 347, -428, -419, 95, -437, 95, + 724, -437, 757, 757, 724, -437, 95, -312, -426, -274, + 531, -231, 125, -232, 123, 46, 95, -437, 19, -437, + -437, 339, -437, 339, -437, -437, 95, 89, 89, -158, + 624, 89, -155, 612, 95, 90, 175, -413, 90, 38, + -305, -306, -307, -316, -308, -310, 38, -664, 99, -659, + 95, -437, 96, -437, -665, 173, 425, 44, 474, 475, + 490, 420, 105, 105, 480, -657, -437, -226, 271, 421, + -226, -667, 56, 131, 95, -312, -481, -425, 161, 313, + -303, -437, 375, -391, -390, -437, 95, -305, -234, -312, + -312, 95, -305, -433, -305, -234, -559, 374, 23, 105, + 151, 116, -473, -596, -595, 65, -234, -263, -588, -633, + -594, -437, -437, -464, 90, -268, 87, 174, -253, -313, + -437, 152, -464, -464, 89, -464, 90, 89, 72, 11, + 21, 175, -339, 131, 175, -343, 131, -559, -234, -543, + 343, 89, -541, 89, -541, 116, 388, -551, -549, 294, + -381, 48, 50, -319, -625, -437, -623, -625, -437, -623, + -623, -484, -464, -381, -316, 275, 34, 263, -384, 391, + 385, 386, 391, 393, 395, 394, -513, 338, 121, -513, + 175, -254, 175, -437, -347, -347, 34, 95, 95, -314, + 90, 175, 131, 95, -155, -154, -464, -235, -238, 275, + 86, 271, -664, -659, 131, -519, 95, 95, -665, 95, + 95, -669, 131, -315, 271, -426, 175, -271, -271, -394, + 19, 175, 131, -394, 90, -280, 26, -289, 44, 375, + -395, 22, 23, 152, 128, 126, 128, 128, -437, 90, + 90, -571, 693, -605, -607, 509, 23, 23, -280, -611, + 698, 95, 451, 48, 49, -236, 65, -234, -588, -260, + 206, 95, 757, -394, -449, -394, -394, 730, -394, -496, + -512, 493, -312, 175, 757, -317, -366, 95, -464, 90, + -464, -464, 90, 95, 90, 95, 90, -259, 23, -535, + -464, -535, -464, -535, 90, 175, 90, 90, 90, 175, + 90, 90, 90, 175, 90, -636, -429, 206, 95, -429, + -437, -437, 19, -438, -229, 275, -303, -233, 370, 89, + 366, -231, 185, 89, 95, -437, 19, -437, -546, 339, + -546, 339, 271, -437, -293, -339, -343, -156, 613, 105, + -154, 95, -489, 618, -300, -319, 269, -234, 90, 175, + -234, 95, -662, 484, -547, 380, 105, 44, 105, 173, + 476, -582, -214, 99, -314, 35, -271, -214, -666, 99, + 131, 756, 89, -433, -433, -433, -229, 375, -437, 90, + 175, -433, -433, 90, -230, 54, -437, 90, 729, 90, + -335, 14, -560, 293, 105, 151, 105, 151, 105, 17, + 276, 90, -588, 131, -435, -253, -437, -394, -655, 174, + -109, -110, 125, -266, -624, -437, 278, 23, 23, -340, + 90, -222, -344, 90, -346, -437, 95, -560, -533, 344, + 105, -460, 89, -460, 89, -542, 341, 89, 90, 175, + -437, -413, -332, -331, -329, 110, 121, 44, 465, -330, + 99, 737, 738, 161, 327, 330, 329, 305, 328, -371, + -453, 86, 686, 468, 385, 386, -485, 693, 604, 701, + 38, 278, 115, 116, 452, -454, 89, 89, 87, 347, + 89, 89, -625, 90, -381, -413, 44, -384, 44, -385, + 409, -494, -494, -494, -494, 338, -382, -437, 161, -347, + 90, -631, 95, 90, -499, 271, -437, -662, 95, -521, + -667, 95, -214, -314, -656, -259, -253, -507, -594, 17, + -457, -437, -464, -472, 740, 742, 743, 277, -6, 708, + 440, -362, 694, 95, 23, 95, -603, 95, -601, 95, + -472, -588, 95, -394, -437, -174, -359, -425, 310, 90, + -365, 141, 14, 90, 90, 90, -534, -534, -534, -537, + -536, -540, 515, 339, 523, -472, 90, 90, 95, 95, + -464, 90, 95, 95, 95, 724, 421, -229, 38, 458, + 24, 630, 371, -266, 367, 368, 369, -437, 95, -472, + -235, 756, 375, -437, 19, 95, -546, 95, -546, -437, + 339, 90, 90, 38, 95, 90, 95, 95, -291, -319, + -218, 14, -335, -307, -218, 23, 14, 173, 424, 44, + 105, 44, 477, 95, -226, 131, 111, 112, -421, -422, + 95, -491, -347, -349, 95, -437, -390, -457, -457, -333, + -234, 38, -334, -388, -485, -229, 30, 375, -173, -337, + -341, -172, 314, -338, -333, 89, -561, 179, 105, 151, + 105, 105, -508, -464, -394, -394, -110, -112, 121, -437, + 90, 90, 175, -561, -550, 23, 90, -528, 90, -528, + 89, 131, -460, -549, -552, 65, -329, 110, -460, 95, + 95, 95, -349, -350, 44, 326, 322, 131, 131, -351, + 44, 306, 307, -361, 89, 337, 17, 105, 212, 89, + 702, 89, 116, 116, -312, -491, -491, -626, 387, 388, + 389, 396, 391, 392, 390, 393, 394, 395, -626, -491, + -491, 89, -514, -513, -460, -494, 131, -495, 284, 401, + 402, 99, 14, 385, 386, 406, 405, 404, 410, 411, + 415, 416, 412, 414, 413, 417, 418, 419, 407, 408, + 409, 424, 435, -433, 161, -437, 174, -666, -260, -394, + -580, 14, 741, 89, 89, -437, -437, -417, 695, 105, + 95, 511, -609, -449, -572, 696, -599, -541, -347, 131, + 90, 79, 617, 619, 90, -539, 123, 476, 480, -458, + -461, 105, 107, 203, 173, -535, -535, 90, 90, 90, + -437, -437, -312, 95, 105, 90, 120, 120, 90, 90, + -424, -423, 95, -437, 375, -437, -293, 95, -293, 95, + 339, -546, -2, 618, -219, 64, 561, 95, 96, 471, + 95, 96, 105, 424, -214, 95, 757, 175, 131, 90, + -547, -529, 294, -234, 175, -388, -425, -437, -174, -433, + -529, -336, -389, -437, 95, -578, 188, 373, 14, 105, + 151, 105, -259, -111, 120, -112, -437, 278, -562, 188, + 373, -532, 90, 90, 90, -528, 105, 90, -556, -553, + 89, -388, 296, 141, 95, 95, 105, 89, -589, 34, + 95, 38, -464, -492, 89, 90, 90, 90, 90, -491, + 111, 112, -433, -433, 95, 95, 384, -433, -433, -433, + -433, -433, -433, 89, 95, 95, -433, -433, -433, -433, + 131, -433, -433, -347, -433, 174, -437, 743, 89, -472, + -472, 89, 23, -571, -394, -573, 697, 95, -608, 514, + -602, -600, 509, 510, 511, 512, 95, 618, 69, 620, + -538, -539, 480, -458, -461, 691, 521, 521, 521, 95, + -437, 95, 757, 175, 131, -437, 375, -293, -293, -546, + 95, -294, -437, 337, 493, -422, 95, -494, -530, 346, + 23, -388, -433, -547, 736, -530, 90, 175, -433, -433, + 373, 105, 151, 105, -260, 126, -464, -111, 373, -544, + 345, 90, -556, -388, -555, -554, 344, 297, 89, 90, + -464, -476, -433, 90, 89, 90, -364, -363, 615, -491, + -494, 87, -494, 87, -494, 87, -494, 87, 90, 105, + 105, -437, 105, 105, 105, 105, 105, 105, -528, 105, + 105, 105, 105, 111, 112, 105, 105, -347, -437, -169, + 89, 90, 90, -418, -437, -603, -362, 95, -612, 276, + -606, -607, 513, -600, 23, 511, 23, 23, -175, 175, + 69, 120, 522, 522, 522, -231, -232, -231, -232, -293, + -423, 95, -437, 95, -293, -292, 38, 516, 451, 23, + -531, -347, -342, -389, -457, -457, 105, 17, 18, 126, + 105, 90, 175, -437, 293, 89, -471, -465, -464, 293, + 90, -437, -464, -515, 704, 703, -370, -368, -369, 86, + 528, 335, 336, 90, -626, -626, -626, -626, -371, 90, + 90, 175, -470, 90, 175, -417, -619, 89, 105, -605, + -604, -606, 23, -603, 23, -603, -603, 518, 14, -538, + -231, -231, -293, 95, -413, 89, -543, 34, 16, -554, + -553, -471, 90, 175, -513, 90, -369, 86, -368, 86, + 18, 17, -494, -494, -494, -494, 89, 90, -437, -622, + 34, 90, -618, -617, -414, -613, -437, 514, 515, 95, + -603, 131, 619, -700, -699, 720, -528, -533, -508, 89, + 65, 90, -465, -515, -367, 332, 333, 34, 188, -367, + -470, -621, -620, -415, 90, 175, 174, 95, 620, 95, + 90, -550, -270, 89, 110, 44, 334, 90, 175, 131, + -617, -437, 90, -472, -620, 44, -464, 174, 65, 90, + -437, 89, -472, 90, } var yyDef = [...]int{ @@ -12097,492 +12399,498 @@ var yyDef = [...]int{ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 0, 339, 340, 341, 342, 343, 344, 1110, - 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 0, - 0, 0, 848, 0, 835, 813, 814, 853, 772, 0, - 0, 0, 0, 0, 0, 0, 617, 618, 619, 620, - 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, - 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, - 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, - 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 0, 0, -2, 373, 369, 281, 282, - 283, 284, 285, 286, 287, 381, 382, 594, 0, 0, - 0, 0, 926, -2, 125, 0, 0, 0, 0, 0, - 362, 0, 353, 353, 0, 0, 1120, 1121, 1122, 1123, - 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, - -2, 0, 0, 826, 0, 773, 774, 775, 776, 777, - 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, - 788, 789, 790, 791, 792, 442, 443, 444, 438, 439, - 441, 440, 0, 0, 826, 0, 0, 0, 934, 0, - 0, 0, 979, 997, 23, 0, 6, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 18, - 0, 18, 0, 0, 0, 1647, 1648, 1649, 1650, 2550, - 2520, -2, 2262, 2222, 2444, 2445, 2333, 2349, 2215, 2597, - 2598, 2599, 2600, 2601, 2602, 2603, 2604, 2605, 2606, 2607, - 2608, 2609, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2617, - 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626, 2627, - 2628, 2629, 2630, 2631, 2632, 2633, 2634, 2635, 2636, 2637, - 2638, 2639, 2640, 2641, 2642, 2643, 2644, 2645, 2646, 2647, - 2648, 2649, 2650, 2166, 2167, 2168, 2169, 2170, 2171, 2172, - 2173, 2174, 2175, 2176, 2177, 2178, 2179, 2180, 2181, 2182, - 2183, 2184, 2185, 2186, 2187, 2188, 2189, 2190, 2191, 2192, - 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200, 2201, 2202, - 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, - 2213, 2214, 2216, 2217, 2218, 2219, 2220, 2221, 2223, 2224, + 64, 65, 0, 339, 340, 341, 342, 343, 344, 1121, + 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 0, + 0, 0, 857, 0, 844, 822, 823, 862, 779, 0, + 0, 0, 0, 0, 0, 0, 622, 623, 624, 625, + 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, + 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, + 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, + 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, + 666, 470, 471, 472, 473, 474, 475, 476, 477, 478, + 479, 480, 481, 482, 483, 0, 0, -2, 373, 369, + 281, 282, 283, 284, 285, 286, 287, 381, 382, 599, + 0, 0, 0, 0, 935, -2, 125, 0, 0, 0, + 0, 0, 362, 0, 353, 353, 0, 0, 1131, 1132, + 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, + 1143, 1144, 1145, -2, 0, 0, 835, 0, 780, 781, + 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, + 792, 793, 794, 795, 796, 797, 798, 799, 800, 442, + 443, 444, 438, 439, 441, 440, 0, 0, 835, 0, + 0, 0, 943, 0, 0, 0, 990, 1008, 23, 0, + 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 0, 0, 18, 0, 18, 0, 0, 0, 1671, + 1672, 1673, 1674, 2580, 2550, -2, 2288, 2248, 2474, 2475, + 2363, 2379, 2241, 2628, 2629, 2630, 2631, 2632, 2633, 2634, + 2635, 2636, 2637, 2638, 2639, 2640, 2641, 2642, 2643, 2644, + 2645, 2646, 2647, 2648, 2649, 2650, 2651, 2652, 2653, 2654, + 2655, 2656, 2657, 2658, 2659, 2660, 2661, 2662, 2663, 2664, + 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, + 2675, 2676, 2677, 2678, 2679, 2680, 2681, 2192, 2193, 2194, + 2195, 2196, 2197, 2198, 2199, 2200, 2201, 2202, 2203, 2204, + 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, + 2215, 2216, 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, - 2235, 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2243, 2244, - 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, - 2255, 2256, 2257, 2258, 2259, 2260, 2261, 2263, 2264, 2265, - 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2274, 2275, - 2276, 2277, 2278, 2279, 2280, 2281, 2282, 2283, 2284, 2285, - 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, 2295, - 2296, 2297, 2298, 2299, 2300, 2301, 2302, 2303, 2304, 2305, - 2306, 2307, 2308, 2309, 2310, 2311, 2312, 2313, 2314, 2315, - 2316, 2317, 2318, 2319, 2320, 2321, 2322, 2323, 2324, 2325, - 2326, 2327, 2328, 2329, 2330, 2331, 2332, 2334, 2335, 2336, - 2337, 2338, 2339, 2340, 2341, 2342, 2343, 2344, 2345, 2346, - 2347, 2348, 2351, 2352, 2353, 2354, 2355, 2356, 2357, 2358, - 2359, 2360, 2361, 2362, 2363, 2364, 2365, 2366, 2367, 2368, + 2235, 2236, 2237, 2238, 2239, 2240, 2242, 2243, 2244, 2245, + 2246, 2247, 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, + 2257, 2258, 2259, 2260, 2261, 2262, 2263, 2264, 2265, 2266, + 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, + 2277, 2278, 2279, 2280, 2281, 2282, 2283, 2284, 2285, 2286, + 2287, 2289, 2290, 2291, 2292, 2293, 2294, 2295, 2296, 2297, + 2298, 2299, 2300, 2301, 2302, 2303, 2304, 2305, 2306, 2307, + 2308, 2309, 2310, 2311, 2312, 2313, 2314, 2315, 2316, 2317, + 2318, 2319, 2320, 2321, 2322, 2323, 2324, 2325, 2326, 2327, + 2328, 2329, 2330, 2331, 2332, 2333, 2334, 2335, 2336, 2337, + 2338, 2339, 2340, 2341, 2342, 2343, 2344, 2345, 2346, 2347, + 2348, 2349, 2350, 2351, 2352, 2353, 2354, 2355, 2356, 2357, + 2358, 2359, 2360, 2361, 2362, 2364, 2365, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, - 2379, 2380, 2381, 2382, 2383, 2384, 2385, 2386, 2387, 2388, - 2389, 2390, 2391, 2392, 2393, 2394, 2395, 2396, 2397, 2398, - 2399, 2400, 2401, 2402, 2403, 2404, 2405, 2406, 2407, 2408, - 2409, 2410, 2411, 2412, 2413, 2414, 2415, 2416, 2417, 2418, - 2419, 2420, 2421, 2422, 2423, 2424, 2425, 2426, 2427, 2428, - 2429, 2430, 2431, 2432, 2433, 2434, 2435, 2436, 2437, 2438, - 2439, 2440, 2441, 2442, 2443, 2446, 2447, 2448, 2449, 2450, + 2381, 2382, 2383, 2384, 2385, 2386, 2387, 2388, 2389, 2390, + 2391, 2392, 2393, 2394, 2395, 2396, 2397, 2398, 2399, 2400, + 2401, 2402, 2403, 2404, 2405, 2406, 2407, 2408, 2409, 2410, + 2411, 2412, 2413, 2414, 2415, 2416, 2417, 2418, 2419, 2420, + 2421, 2422, 2423, 2424, 2425, 2426, 2427, 2428, 2429, 2430, + 2431, 2432, 2433, 2434, 2435, 2436, 2437, 2438, 2439, 2440, + 2441, 2442, 2443, 2444, 2445, 2446, 2447, 2448, 2449, 2450, 2451, 2452, 2453, 2454, 2455, 2456, 2457, 2458, 2459, 2460, 2461, 2462, 2463, 2464, 2465, 2466, 2467, 2468, 2469, 2470, - 2471, 2472, 2473, 2474, 2475, 2476, -2, 2478, 2479, 2480, - 2481, 2482, 2483, 2484, 2485, 2486, 2487, 2488, 2489, 2490, - 2491, 2492, 2493, 2494, 2495, 2496, 2497, 2498, 2499, 2500, - 2501, 2502, 2503, 2504, 2505, 2506, 2507, 2508, 2509, 2510, - 2511, 2512, 2513, 2514, 2515, 2516, 2517, 2518, 2519, 2521, - 2522, 2523, 2524, 2525, 2526, 2527, 2528, 2529, 2530, 2531, - 2532, 2533, 2534, 2535, -2, -2, -2, 2539, 2540, 2541, - 2542, 2543, 2544, 2545, 2546, 2547, 2548, 2549, 2551, 2552, - 2553, 2554, 2555, 2556, 2557, 2558, 2559, 2560, 2561, 2562, - 2563, 2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571, 2572, - 2573, 2574, 2575, 2576, 2577, 2578, 2579, 2580, 2581, 2582, - 2583, 2584, 2585, 2586, 2587, 0, 337, 335, 2187, 2215, - 2222, 2262, 2333, 2349, 2350, 2390, 2444, 2445, 2470, 2477, - 2520, 2536, 2537, 2538, 2550, 0, 0, 1152, 0, 374, - 815, 816, 849, 854, 934, 962, 0, 836, 837, 0, - 770, 0, 1592, 415, 0, 2239, 419, 2527, 0, 0, - 0, 0, 767, 409, 410, 411, 412, 413, 414, 0, - 0, 0, 1109, 0, 0, 2557, 405, 0, 0, 80, - 463, 661, 0, 0, 0, 0, 747, 747, 1022, 1022, - 0, 690, 0, 0, 0, 747, 0, 704, 696, 0, - 0, 0, 747, 0, 0, 955, 955, 0, 750, 757, - 747, 747, -2, 747, 747, 0, 742, 747, 0, 0, - 0, 1366, 710, 711, 712, 696, 696, 715, 716, 717, - 727, 728, 758, 2161, 0, 0, 368, 2336, 2549, 1651, - 0, 0, 0, 0, 0, 224, 1287, 226, 1289, 230, + 2471, 2472, 2473, 2476, 2477, 2478, 2479, 2480, 2481, 2482, + 2483, 2484, 2485, 2486, 2487, 2488, 2489, 2490, 2491, 2492, + 2493, 2494, 2495, 2496, 2497, 2498, 2499, 2500, 2501, 2502, + 2503, 2504, 2505, 2506, -2, 2508, 2509, 2510, 2511, 2512, + 2513, 2514, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, + 2523, 2524, 2525, 2526, 2527, 2528, 2529, 2530, 2531, 2532, + 2533, 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, + 2543, 2544, 2545, 2546, 2547, 2548, 2549, 2551, 2552, 2553, + 2554, 2555, 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563, + 2564, 2565, -2, -2, -2, 2569, 2570, 2571, 2572, 2573, + 2574, 2575, 2576, 2577, 2578, 2579, 2581, 2582, 2583, 2584, + 2585, 2586, 2587, 2588, 2589, 2590, 2591, 2592, 2593, 2594, + 2595, 2596, 2597, 2598, 2599, 2600, 2601, 2602, 2603, 2604, + 2605, 2606, 2607, 2608, 2609, 2610, 2611, 2612, 2613, 2614, + 2615, 2616, 2617, 2618, 0, 337, 335, 2213, 2241, 2248, + 2288, 2363, 2379, 2380, 2420, 2474, 2475, 2500, 2507, 2550, + 2566, 2567, 2568, 2580, 0, 0, 1165, 0, 374, 824, + 825, 858, 863, 943, 973, 0, 845, 846, 0, 777, + 0, 1616, 415, 0, 2265, 419, 2557, 0, 0, 0, + 0, 774, 409, 410, 411, 412, 413, 414, 0, 0, + 0, 1120, 0, 0, 2588, 405, 0, 0, 80, 463, + 667, 0, 0, 0, 0, 0, 754, 754, 1033, 1033, + 0, 697, 0, 0, 0, 754, 0, 711, 703, 0, + 0, 0, 754, 0, 0, 966, 966, 0, 757, 764, + 754, 754, -2, 754, 754, 0, 749, 754, 0, 0, + 0, 1379, 717, 718, 719, 703, 703, 722, 723, 724, + 734, 735, 765, 2187, 0, 0, 368, 2366, 2579, 1675, + 0, 0, 0, 0, 0, 224, 1300, 226, 1302, 230, 238, 0, 0, 0, 243, 244, 247, 248, 249, 250, 251, 0, 255, 0, 257, 260, 0, 262, 263, 0, - 266, 267, 268, 0, 278, 279, 280, 1290, 1291, 1292, - 1293, 1294, 1295, 1296, 1297, -2, 153, 1150, 2119, 2004, - 0, 2010, 2023, 2034, 1742, 1743, 1744, 1745, 0, 0, - 0, 0, 0, 0, 1753, 1754, 0, 1797, 2601, 2646, - 2647, 0, 1763, 1764, 1765, 1766, 1767, 1768, 0, 164, - 176, 177, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 0, - 2064, 2065, 2066, 0, 1726, 1647, 0, 2610, 2620, 0, - 2634, 2641, 2642, 2643, 2644, 2633, 0, 0, 1960, 0, - 1950, 0, 0, -2, -2, 0, 0, 2417, -2, 2648, - 2649, 2650, 2607, 2630, 2638, 2639, 2640, 2611, 2614, 2637, - 2603, 2604, 2605, 2598, 2599, 2600, 2602, 2616, 2618, 2629, - 0, 2625, 2635, 2636, 2525, 0, 0, 2574, 2612, 2613, - 0, 0, 0, 0, 0, 0, 2583, 2584, 2585, 2586, - 2587, 2569, 178, 179, -2, -2, -2, -2, -2, -2, + 266, 267, 268, 0, 278, 279, 280, 1303, 1304, 1305, + 1306, 1307, 1308, 1309, 1310, -2, 153, 1163, 2145, 2030, + 0, 2036, 2049, 2060, 1768, 1769, 1770, 1771, 0, 0, + 0, 0, 0, 0, 1779, 1780, 0, 1823, 2632, 2677, + 2678, 0, 1789, 1790, 1791, 1792, 1793, 1794, 0, 164, + 176, 177, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 0, + 2090, 2091, 2092, 0, 1752, 1671, 0, 2641, 2651, 0, + 2665, 2672, 2673, 2674, 2675, 2664, 0, 0, 1986, 0, + 1976, 0, 0, -2, -2, 0, 0, 2447, -2, 2679, + 2680, 2681, 2638, 2661, 2669, 2670, 2671, 2642, 2645, 2668, + 2634, 2635, 2636, 2629, 2630, 2631, 2633, 2647, 2649, 2660, + 0, 2656, 2666, 2667, 2555, 0, 0, 2605, 2643, 2644, + 0, 0, 0, 0, 0, 0, 2614, 2615, 2616, 2617, + 2618, 2600, 178, 179, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, - 1971, -2, 1973, -2, 1975, -2, 1977, -2, -2, -2, - -2, 1982, 1983, -2, 1985, -2, -2, -2, -2, -2, - -2, -2, 1962, 1963, 1964, 1965, 1954, 1955, 1956, 1957, - 1958, 1959, -2, -2, -2, 962, 1057, 0, 962, 0, - 935, 984, 987, 990, 993, 938, 0, 0, 126, 127, + 1997, -2, 1999, -2, 2001, -2, 2003, -2, -2, -2, + -2, 2008, 2009, -2, 2011, -2, -2, -2, -2, -2, + -2, -2, 1988, 1989, 1990, 1991, 1980, 1981, 1982, 1983, + 1984, 1985, -2, -2, -2, 973, 1068, 0, 973, 0, + 944, 995, 998, 1001, 1004, 947, 0, 0, 126, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 363, 364, 352, 354, 0, 358, 0, - 0, 354, 351, 345, 0, 1352, 1352, 1352, 0, 1352, - 0, 0, 0, 1352, 1352, 1352, 1352, 1352, 0, 1352, - 0, 0, 0, 0, 0, 1352, 0, 1188, 1299, 1300, - 1301, 1350, 1351, 1459, 0, 0, 0, 897, 2320, 0, - 0, 905, 948, 0, 950, 953, 831, 827, 828, 829, - 830, 0, 0, 594, 594, 0, 594, 0, 0, 594, - 0, 594, 594, 594, 0, 833, 2285, 2385, 2256, 2355, - 2197, 2336, 2549, 0, 310, 2417, 315, 0, 2261, 2288, - 0, 0, 2307, 0, -2, 0, 391, 962, 0, 0, - 934, 0, 0, 0, 594, 594, 0, 594, 594, 594, - 594, 594, 1458, 594, 594, 594, 594, 594, 0, 0, - 0, 594, 0, 594, 594, 594, 0, 998, 999, 1001, - 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 4, - 5, 18, 0, 0, 0, 0, 0, 0, 132, 131, - 0, 2120, 2156, 2069, 2070, 2071, 0, 2143, 2074, 2147, - 2147, 2147, 2147, 2104, 2105, 2106, 2107, 2108, 2109, 2110, - 2111, 2112, 2113, 2147, 2147, 0, 0, 2118, 2095, 2145, - 2145, 2145, 2143, 2122, 2075, 2076, 2077, 2078, 2079, 2080, - 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2150, 2150, - 2153, 2153, 2150, 2123, 2124, 2125, 2126, 2127, 2128, 2129, - 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2139, - 2140, 0, 468, 466, 467, 2000, 0, 0, 962, -2, - 0, 0, 895, 0, 771, 1583, 0, 0, 416, 1652, - 0, 0, 420, 0, 421, 0, 0, 423, 0, 0, - 0, 445, 0, 448, 431, 432, 433, 434, 435, 427, - 0, 204, 0, 407, 408, 404, 0, 453, 454, 456, - 459, 1579, 77, 81, 84, 0, 955, 0, 663, 747, - 747, 747, 678, 679, 680, 0, 1022, 0, 0, 683, - 684, 0, 685, 0, 0, 696, 747, 747, 702, 703, - 698, 697, 753, 754, 750, 0, 750, 750, 1022, 0, - 721, 722, 723, 747, 747, 729, 956, 0, 730, 731, - 750, 0, 755, 756, 1022, 0, 0, 1022, 1022, 0, - 739, 740, 0, 743, 747, 0, 746, 0, 0, 1352, - 0, 763, 698, 698, 2162, 2163, 370, 0, 0, 0, - 595, 0, 0, 0, 0, 0, 0, 235, 231, 239, - 242, 252, 259, 0, 271, 273, 276, 232, 240, 245, - 246, 253, 274, 233, 236, 237, 241, 275, 277, 234, - 254, 258, 272, 256, 261, 264, 265, 270, 0, 205, - 0, 0, 0, 0, 2009, 0, 0, 2042, 2043, 2044, - 2045, 2046, 2047, 2048, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -2, 2004, 0, - 0, 1748, 1749, 1750, 1751, 0, 1755, 0, 1798, 0, - 0, 0, 0, 0, 0, 2063, 2067, 0, 0, 2000, - 2000, 0, 0, 2000, 1996, 0, 0, 0, 0, 0, - 0, 2000, 1933, 0, 0, 1935, 1951, 0, 0, 1937, - 1938, 0, 1941, 1942, 2000, 0, 2000, 1946, 2000, 2000, - 2000, 1927, 1928, 0, 0, 0, 1996, 1996, 1996, 1996, - 0, 0, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, - 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 955, 0, 963, 0, -2, 0, 981, 983, 985, - 986, 988, 989, 991, 992, 994, 995, 940, 0, 0, - 128, 0, 0, 0, 109, 0, 0, 107, 0, 0, - 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 356, 0, 361, 347, 2378, - 0, 346, 0, 0, 0, 0, 1352, 0, 0, 1149, - 0, 0, 1352, 1352, 1352, 1189, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1352, 1352, 1352, 1352, 0, - 1372, 0, 0, 0, 0, 0, 897, 897, 904, 0, - 949, 0, 0, 833, 832, 0, 1036, 1037, 1038, 1075, - 1099, 1099, 0, 1099, 1079, 1592, 0, 0, 0, 1363, - 0, 0, 0, 0, 0, 0, 0, 766, 0, 0, - 0, 489, 490, 0, 0, 834, 0, 289, 293, 0, - 296, 0, 2385, 0, 2385, 0, 0, 303, 0, 0, - 0, 0, 0, 0, 333, 334, 0, 0, 0, 0, - 324, 327, 1575, 1576, 1284, 1285, 328, 329, 383, 384, - 0, 955, 980, 982, 976, 977, 978, 0, 0, 0, - 594, 0, 0, 0, 0, 0, 594, 0, 0, 0, - 0, 0, 809, 0, 1167, 811, 0, 0, 594, 0, - 0, 0, 1030, 1024, 1026, 1104, 164, 1000, 7, 149, - 146, 0, 18, 0, 0, 18, 18, 0, 18, 338, - 0, 2159, 2157, 2158, 0, 2073, 2144, 0, 2100, 0, - 2101, 2102, 2103, 2114, 2115, 0, 0, 2096, 0, 2097, - 2098, 2099, 2089, 2150, 0, 2091, 2092, 0, 2093, 2094, - 336, 465, 0, 0, 2001, 1153, 0, 955, 932, 0, - 960, 0, 0, 0, 594, 1581, 0, 1592, 0, 0, - 0, 0, 0, 417, 0, 428, 422, 0, 429, 424, - 425, 0, 0, 447, 449, 450, 451, 452, 436, 437, - 768, 401, 402, 403, 392, 393, 394, 395, 396, 397, - 398, 399, 400, -2, 0, 0, 406, 174, 0, 0, - 458, 0, 460, 0, 85, 462, 0, 665, 0, 1022, - 0, 0, 1022, 1022, 0, 0, 0, 682, 748, 749, - 1023, 686, 0, 0, 693, 2336, 1276, 698, 1022, 1022, - 705, 699, 706, 752, 707, 708, 709, 750, 1022, 1022, - 957, 747, 750, 732, 751, 750, 1592, 736, 0, 741, - 744, 745, 1592, 764, 1592, 0, 762, 713, 714, 371, - 372, 0, 0, 0, 218, 219, 220, 221, 222, 223, - 225, 209, 798, 800, 1288, 0, 1279, 0, 228, 269, - 201, 0, 0, 0, 2005, 2006, 2007, 2008, 2013, 0, - 2015, 2017, 2019, 2021, 0, 2039, -2, -2, 1727, 1728, - 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, - 1739, 1740, 1741, 2024, 2037, 2038, 0, 0, 0, 0, - 0, 0, 2035, 2035, 2030, 0, 1760, 1802, 1814, 1814, - 1769, 1577, 1578, 1746, 0, 0, 1795, 1799, 0, 0, - 0, 0, 0, 0, 1331, 2143, 0, 165, 2034, 1995, - 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, - 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, - 1914, 1915, 1916, 1917, 1918, 1919, 1920, 1921, 1922, 0, - 0, 2004, 0, 0, 0, 0, 1997, 1998, 0, 0, - 0, 1882, 0, 0, 1888, 1889, 1890, 0, 882, 0, - 1961, 1934, 1952, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1923, 1924, 1925, 1926, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1056, 1058, 0, - 891, 893, 894, 929, 960, 936, 0, 0, 0, 124, - 129, 0, 1426, 115, 0, 0, 0, 115, 0, 0, - 0, 115, 0, 0, 0, 1260, 1367, 86, 1259, 1369, - 0, 0, 0, 0, 0, 0, 0, 365, 366, 0, - 0, 360, 348, 2378, 350, 0, 0, 0, 0, 0, - 1136, 0, 0, 0, 0, 0, 0, 0, 1204, 1205, - 0, 592, 1270, 0, 0, 0, 1286, 1335, 1348, 0, - 0, 0, 0, 0, 1432, 1190, 1195, 1196, 1197, 1191, - 1192, 1198, 1199, 873, 887, 868, 0, 876, 0, 0, - 0, 951, 0, 0, 1073, 0, 0, 0, 0, 0, - 0, 0, 0, 1065, 0, 0, 0, 1064, 0, 0, - 0, 0, 0, 0, 953, 1100, 0, 1102, 1103, 1077, - -2, 0, 1033, 1035, 1082, 2000, 0, 1434, 953, 487, - 488, 493, 495, 0, 554, 554, 554, 537, 554, 0, - 0, 525, 2164, 0, 0, 0, 0, 534, 2164, 0, - 0, 2164, 2164, 2164, 2164, 2164, 2164, 2164, 0, 0, - 2164, 2164, 2164, 2164, 2164, 2164, 2164, 2164, 2164, 2164, - 2164, 0, 2164, 2164, 2164, 2164, 2164, 1561, 2164, 0, - 1364, 544, 545, 546, 547, 552, 553, 0, 0, 498, - 499, 0, 0, 0, 0, 0, 587, 0, 0, 1203, - 0, 592, 0, 0, 1248, 0, 0, 1035, 0, 0, + 0, 354, 351, 345, 0, 1365, 1365, 1365, 0, 0, + 1365, 0, 0, 0, 1365, 1365, 1365, 1365, 1365, 0, + 1365, 0, 0, 0, 0, 0, 1365, 0, 1201, 1312, + 1313, 1314, 1363, 1364, 1473, 0, 0, 0, 906, 2350, + 0, 0, 914, 959, 0, 961, 964, 840, 836, 837, + 838, 839, 0, 0, 0, 599, 599, 0, 599, 0, + 0, 599, 0, 599, 599, 599, 0, 842, 2315, 2415, + 2282, 2385, 2223, 2366, 2579, 0, 310, 2447, 315, 0, + 2287, 2318, 0, 0, 2337, 0, -2, 0, 391, 973, + 0, 0, 943, 0, 0, 0, 599, 599, 0, 0, + 599, 599, 599, 599, 599, 1472, 599, 599, 599, 599, + 599, 0, 0, 0, 599, 0, 599, 599, 599, 0, + 1009, 1010, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, + 1020, 1021, 4, 5, 18, 0, 0, 0, 0, 0, + 0, 132, 131, 0, 2146, 2182, 2095, 2096, 2097, 0, + 2169, 2100, 2173, 2173, 2173, 2173, 2130, 2131, 2132, 2133, + 2134, 2135, 2136, 2137, 2138, 2139, 2173, 2173, 0, 0, + 2144, 2121, 2171, 2171, 2171, 2169, 2148, 2101, 2102, 2103, + 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, 2112, 2113, + 2114, 2176, 2176, 2179, 2179, 2176, 2149, 2150, 2151, 2152, + 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161, 2162, + 2163, 2164, 2165, 2166, 0, 468, 466, 467, 2026, 0, + 0, 973, -2, 0, 0, 904, 0, 778, 1607, 0, + 0, 416, 1676, 0, 0, 420, 0, 421, 0, 0, + 423, 0, 0, 0, 445, 0, 448, 431, 432, 433, + 434, 435, 427, 0, 204, 0, 407, 408, 404, 0, + 453, 454, 456, 459, 1603, 77, 81, 84, 0, 966, + 0, 669, 754, 754, 754, 754, 685, 686, 687, 0, + 1033, 0, 0, 690, 691, 0, 692, 0, 0, 703, + 754, 754, 709, 710, 705, 704, 760, 761, 757, 0, + 757, 757, 1033, 0, 728, 729, 730, 754, 754, 736, + 967, 0, 737, 738, 757, 0, 762, 763, 1033, 0, + 0, 1033, 1033, 0, 746, 747, 0, 750, 754, 0, + 753, 0, 0, 1365, 0, 770, 705, 705, 2188, 2189, + 370, 0, 0, 0, 600, 0, 0, 0, 0, 0, + 0, 235, 231, 239, 242, 252, 259, 0, 271, 273, + 276, 232, 240, 245, 246, 253, 274, 233, 236, 237, + 241, 275, 277, 234, 254, 258, 272, 256, 261, 264, + 265, 270, 0, 205, 0, 0, 0, 0, 2035, 0, + 0, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -2, 2030, 0, 0, 1774, 1775, 1776, 1777, 0, + 1781, 0, 1824, 0, 0, 0, 0, 0, 0, 2089, + 2093, 0, 0, 2026, 2026, 0, 0, 2026, 2022, 0, + 0, 0, 0, 0, 0, 2026, 1959, 0, 0, 1961, + 1977, 0, 0, 1963, 1964, 0, 1967, 1968, 2026, 0, + 2026, 1972, 2026, 2026, 2026, 1953, 1954, 0, 0, 0, + 2022, 2022, 2022, 2022, 0, 0, 2022, 2022, 2022, 2022, + 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, + 2022, 2022, 2022, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 966, 0, 974, 0, -2, + 0, 992, 994, 996, 997, 999, 1000, 1002, 1003, 1005, + 1006, 949, 0, 0, 128, 0, 0, 0, 109, 0, + 0, 107, 0, 0, 0, 0, 78, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 356, + 0, 361, 347, 2408, 0, 346, 0, 0, 0, 0, + 1365, 1365, 0, 0, 1162, 0, 0, 1365, 1365, 1365, + 1202, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1365, 1365, 1365, 1365, 0, 1385, 0, 0, 0, 0, + 0, 906, 906, 913, 0, 960, 0, 0, 842, 841, + 0, 1047, 1048, 1049, 1086, 1110, 1110, 0, 1110, 1090, + 1616, 0, 0, 0, 0, 1376, 0, 0, 0, 0, + 0, 0, 0, 773, 0, 0, 0, 494, 495, 0, + 0, 843, 0, 289, 293, 0, 296, 0, 2415, 0, + 2415, 0, 0, 303, 0, 0, 0, 0, 0, 0, + 333, 334, 0, 0, 0, 0, 324, 327, 1599, 1600, + 1297, 1298, 328, 329, 383, 384, 0, 966, 991, 993, + 987, 988, 989, 0, 0, 0, 599, 599, 0, 0, + 0, 0, 0, 599, 0, 0, 0, 0, 0, 818, + 0, 1180, 820, 0, 0, 599, 0, 0, 0, 1041, + 1035, 1037, 1115, 164, 1011, 7, 149, 146, 0, 18, + 0, 0, 18, 18, 0, 18, 338, 0, 2185, 2183, + 2184, 0, 2099, 2170, 0, 2126, 0, 2127, 2128, 2129, + 2140, 2141, 0, 0, 2122, 0, 2123, 2124, 2125, 2115, + 2176, 0, 2117, 2118, 0, 2119, 2120, 336, 465, 0, + 0, 2027, 1166, 0, 966, 941, 0, 971, 0, 0, + 0, 599, 1605, 0, 1616, 0, 0, 0, 0, 0, + 417, 0, 428, 422, 0, 429, 424, 425, 0, 0, + 447, 449, 450, 451, 452, 436, 437, 775, 401, 402, + 403, 392, 393, 394, 395, 396, 397, 398, 399, 400, + -2, 0, 0, 406, 174, 0, 0, 458, 0, 460, + 0, 85, 462, 0, 671, 0, 1033, 0, 0, 1033, + 1033, 0, 0, 1033, 0, 689, 755, 756, 1034, 693, + 0, 0, 700, 2366, 1289, 705, 1033, 1033, 712, 706, + 713, 759, 714, 715, 716, 757, 1033, 1033, 968, 754, + 757, 739, 758, 757, 1616, 743, 0, 748, 751, 752, + 1616, 771, 1616, 0, 769, 720, 721, 371, 372, 0, + 0, 0, 218, 219, 220, 221, 222, 223, 225, 209, + 807, 809, 1301, 0, 1292, 0, 228, 269, 201, 0, + 0, 0, 2031, 2032, 2033, 2034, 2039, 0, 2041, 2043, + 2045, 2047, 0, 2065, -2, -2, 1753, 1754, 1755, 1756, + 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766, + 1767, 2050, 2063, 2064, 0, 0, 0, 0, 0, 0, + 2061, 2061, 2056, 0, 1786, 1828, 1840, 1840, 1795, 1601, + 1602, 1772, 0, 0, 1821, 1825, 0, 0, 0, 0, + 0, 0, 1344, 2169, 0, 165, 2060, 2021, 1920, 1921, + 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, + 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, 1940, 1941, + 1942, 1943, 1944, 1945, 1946, 1947, 1948, 0, 0, 2030, + 0, 0, 0, 0, 2023, 2024, 0, 0, 0, 1908, + 0, 0, 1914, 1915, 1916, 0, 891, 0, 1987, 1960, + 1978, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1949, 1950, 1951, 1952, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1067, 1069, 0, 900, 902, + 903, 938, 971, 951, 0, 0, 0, 124, 129, 0, + 1440, 115, 0, 0, 0, 115, 0, 0, 0, 115, + 0, 0, 0, 1273, 1380, 86, 1272, 1382, 0, 0, + 0, 0, 0, 0, 0, 365, 366, 0, 0, 360, + 348, 2408, 350, 0, 0, 0, 0, 0, 0, 1149, + 0, 0, 0, 0, 0, 0, 0, 1217, 1218, 0, + 597, 1283, 0, 0, 0, 1299, 1348, 1361, 0, 0, + 0, 0, 0, 1446, 1203, 1208, 1209, 1210, 1204, 1205, + 1211, 1212, 882, 896, 877, 0, 885, 0, 0, 0, + 962, 0, 0, 1084, 0, 0, 0, 0, 0, 0, + 0, 0, 1076, 0, 0, 0, 1075, 0, 0, 0, + 0, 0, 0, 964, 1111, 0, 1113, 1114, 1088, -2, + 0, 1044, 1046, 1093, 2026, 0, 0, 1448, 964, 492, + 493, 498, 500, 0, 559, 559, 559, 542, 559, 0, + 0, 530, 2190, 0, 0, 0, 0, 539, 2190, 0, + 0, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 0, 0, + 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, + 2190, 0, 2190, 2190, 2190, 2190, 2190, 1585, 2190, 0, + 1377, 549, 550, 551, 552, 557, 558, 0, 0, 503, + 504, 0, 0, 0, 0, 0, 592, 0, 0, 1216, + 0, 597, 0, 0, 1261, 0, 0, 1046, 0, 0, 0, 0, 301, 302, 290, 0, 291, 0, 0, 304, - 305, 0, 307, 308, 309, 316, 2256, 2355, 311, 313, + 305, 0, 307, 308, 309, 316, 2282, 2385, 311, 313, 0, 0, 317, 330, 331, 332, 0, 0, 322, 323, - 0, 0, 386, 387, 389, 0, 960, 1368, 1354, 82, - 83, 2557, 793, 0, 795, 796, 797, 801, 0, 0, - 804, 805, 806, 807, 808, 1169, 0, 0, 1257, 0, - 1261, 1263, 1354, 1022, 0, 1031, 0, 1027, 1105, 0, - 1107, 0, 0, 147, 18, 0, 140, 137, 0, 0, - 0, 0, 0, 2121, 2068, 2160, 0, 0, 0, 0, - 2141, 0, 0, 2090, 0, 0, 0, 130, 912, 960, - 0, 906, 0, 964, 965, 968, 838, 887, 840, 0, - 842, 876, 0, 0, 0, 0, 0, 0, 1583, 0, - 0, 0, 0, 1653, 0, 430, 426, 446, 0, 0, - 455, 0, 1580, 461, 464, 662, 0, 664, 667, 747, - 0, 670, 671, 747, 0, 0, 681, 689, 687, 0, - 691, 0, 692, 0, 1278, 747, 700, 701, 1022, 724, - 725, 0, 0, 1022, 747, 747, 735, 750, 759, 0, - 760, 1592, 0, 212, 1273, 0, 213, 217, 207, 0, - 0, 0, 1275, 1280, 0, 227, 0, 0, 202, 203, - 1417, 1426, 0, 0, 0, 2014, 2016, 2018, 2020, 2022, - 0, 2025, 2035, 2035, 2031, 0, 2026, 0, 2028, 0, - 1803, 1815, 1816, 1804, 2005, 1752, 0, 1800, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 968, 0, 0, - 0, 1870, 1872, 0, 0, 0, 1877, 0, 1879, 1880, - 1881, 1883, 0, 0, 0, 1887, 0, 1932, 1953, 1936, - 1939, 0, 1943, 0, 1945, 1947, 1948, 1949, 0, 0, - 0, 962, 962, 0, 0, 1839, 1839, 1839, 0, 0, - 0, 0, 1839, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1772, 0, 1773, 1774, - 1775, 0, 1777, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1059, 906, 0, 0, 0, 0, 0, - 1424, 0, 105, 0, 110, 0, 0, 106, 111, 0, - 0, 108, 0, 0, 117, 87, 0, 0, 1375, 1376, - 0, 0, 0, 367, 355, 357, 0, 349, 0, 1353, - 0, 0, 0, 1515, 1140, 0, 0, -2, 1169, 953, - 0, 953, 1215, 2164, 0, 596, 0, 0, 1272, 0, - 1237, 0, 0, 0, -2, 0, 0, 0, 1348, 0, - 0, 0, 1436, 0, 850, 0, 867, 884, 0, 888, - 0, 0, 880, 872, 877, 0, 0, 0, 902, 851, - 852, 23, 954, 0, 0, 0, 820, 824, 0, 1069, - 1060, 0, 1042, 0, 1044, 1066, 1045, 1067, 0, 0, - 1049, 0, 1051, 0, 1053, 0, 1047, 1048, 1055, 1046, - 1076, 1101, 0, 1078, 1081, 1083, 1084, 1090, 0, 0, - 0, 0, 0, 1436, 0, 0, 1363, 1502, 1470, 515, - 0, 1605, 1606, 555, 0, 1612, 1621, 1352, 1691, 0, - 1621, 0, 0, 1623, 1624, 0, 0, 0, 0, 538, - 539, 0, 524, 0, 0, 0, 0, 0, 0, 523, - 0, 0, 565, 0, 0, 0, 0, 0, 2165, 2164, - 2164, 0, 532, 533, 0, 536, 0, 0, 0, 0, - 0, 0, 0, 0, 2164, 2164, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1552, 0, 0, - 0, 0, 0, 0, 0, 1567, 1568, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1215, 2164, 0, 0, - 0, 0, 596, 1267, 1267, 1235, 1253, 0, 491, 492, - 562, 0, 0, 0, 294, 295, 0, 0, 300, 318, - 320, 292, 0, 0, 0, 319, 321, 325, 326, 385, - 388, 390, 906, 79, 1355, 794, 0, 1460, 0, 1170, - 1171, 1173, 1174, 0, 2170, -2, -2, -2, -2, -2, - -2, -2, -2, -2, -2, -2, -2, -2, 2230, -2, + 0, 0, 386, 387, 389, 0, 971, 1381, 1367, 82, + 83, 2588, 801, 0, 0, 804, 805, 806, 810, 0, + 0, 813, 814, 815, 816, 817, 1182, 0, 0, 1270, + 0, 1274, 1276, 1367, 1033, 0, 1042, 0, 1038, 1116, + 0, 1118, 0, 0, 147, 18, 0, 140, 137, 0, + 0, 0, 0, 0, 2147, 2094, 2186, 0, 0, 0, + 0, 2167, 0, 0, 2116, 0, 0, 0, 130, 921, + 971, 0, 915, 0, 975, 976, 979, 847, 896, 849, + 0, 851, 885, 0, 0, 0, 0, 0, 0, 1607, + 0, 0, 0, 0, 1677, 0, 430, 426, 446, 0, + 0, 455, 0, 1604, 461, 464, 668, 0, 670, 673, + 754, 0, 676, 677, 754, 0, 0, 683, 688, 696, + 694, 0, 698, 0, 699, 0, 1291, 754, 707, 708, + 1033, 731, 732, 0, 0, 1033, 754, 754, 742, 757, + 766, 0, 767, 1616, 0, 212, 1286, 0, 213, 217, + 207, 0, 0, 0, 1288, 1293, 0, 227, 0, 0, + 202, 203, 1431, 1440, 0, 0, 0, 2040, 2042, 2044, + 2046, 2048, 0, 2051, 2061, 2061, 2057, 0, 2052, 0, + 2054, 0, 1829, 1841, 1842, 1830, 2031, 1778, 0, 1826, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 979, + 0, 0, 0, 1896, 1898, 0, 0, 0, 1903, 0, + 1905, 1906, 1907, 1909, 0, 0, 0, 1913, 0, 1958, + 1979, 1962, 1965, 0, 1969, 0, 1971, 1973, 1974, 1975, + 0, 0, 0, 973, 973, 0, 0, 1865, 1865, 1865, + 0, 0, 0, 0, 1865, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1798, 0, + 1799, 1800, 1801, 0, 1803, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1070, 915, 945, 0, 0, + 0, 0, 0, 0, 1438, 0, 105, 0, 110, 0, + 0, 106, 111, 0, 0, 108, 0, 0, 117, 87, + 0, 0, 1388, 1389, 0, 0, 0, 367, 355, 357, + 0, 349, 0, 1366, 0, 0, 0, 1529, 1539, 1153, + 0, 0, -2, 1182, 964, 0, 964, 1228, 2190, 0, + 601, 0, 0, 1285, 0, 1250, 0, 0, 0, -2, + 0, 0, 0, 1361, 0, 0, 0, 1450, 0, 859, + 0, 876, 893, 0, 897, 0, 0, 889, 881, 886, + 0, 0, 0, 911, 860, 861, 23, 965, 0, 0, + 0, 829, 833, 0, 1080, 1071, 0, 1053, 0, 1055, + 1077, 1056, 1078, 0, 0, 1060, 0, 1062, 0, 1064, + 0, 1058, 1059, 1066, 1057, 1087, 1112, 0, 1089, 1092, + 1094, 1095, 1101, 0, 0, 0, 0, 0, 0, 488, + 489, 1450, 0, 0, 1376, 1516, 1484, 520, 0, 1629, + 1630, 560, 0, 1636, 1645, 1365, 1717, 0, 1645, 0, + 0, 1647, 1648, 0, 0, 0, 0, 543, 544, 0, + 529, 0, 0, 0, 0, 0, 0, 528, 0, 0, + 570, 0, 0, 0, 0, 0, 2191, 2190, 2190, 0, + 537, 538, 0, 541, 0, 0, 0, 0, 0, 0, + 0, 0, 2190, 2190, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1576, 0, 0, 0, 0, + 0, 0, 0, 1591, 1592, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1228, 2190, 0, 0, 0, 0, + 601, 1280, 1280, 1248, 1266, 0, 496, 497, 567, 0, + 0, 0, 294, 295, 0, 0, 300, 318, 320, 292, + 0, 0, 0, 319, 321, 325, 326, 385, 388, 390, + 915, 79, 1368, 802, 803, 0, 1474, 0, 1183, 1184, + 1186, 1187, 0, 2196, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, 2256, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, - -2, -2, -2, -2, -2, -2, -2, 1168, 812, 1258, - 0, 1265, 1013, 1025, 1032, 1106, 1108, 165, 1028, 0, - 150, 18, 149, 141, 142, 0, 18, 0, 0, 0, - 0, 2072, 2149, 2148, 2116, 0, 2117, 2146, 2151, 0, - 2154, 0, 469, 916, 0, 906, 908, 933, 0, 0, - 971, 969, 970, 839, 0, 0, 846, 962, 0, 902, - 1262, 1584, 1585, 0, 1588, 1589, 1590, 1591, 1582, 0, - 0, 0, 0, 0, 0, 0, 769, 175, 457, 666, - 1022, 747, 1022, 0, 747, 747, 677, 1522, 1523, 688, - 694, 1277, 1022, 718, 958, 959, 1592, 1022, 1022, 747, - 765, 761, 0, 0, 0, 0, 0, 799, 0, 209, - 0, 0, 229, 0, 0, 0, 1426, 1421, 1999, 2027, - 2029, 0, 2036, 2032, 1747, 1756, 1796, 0, 0, 0, - 0, 0, 1805, 2147, 2147, 1808, 2143, 2145, 2143, 1814, - 1814, 0, 1332, 0, 1333, 968, 166, 0, 0, 0, - 0, 1878, 0, 0, 0, 883, 0, 0, 0, 0, - 0, 1835, 1837, 1839, 1839, 1846, 1840, 1847, 1848, 1839, - 1839, 1839, 1839, 1853, 1839, 1839, 1839, 1839, 1839, 1839, - 1839, 1839, 1839, 1839, 1839, 1839, 0, 1833, 1776, 1778, - 0, 1781, 0, 1784, 1785, 0, 0, 0, 2057, 2058, - 892, 930, 0, 0, 943, 944, 945, 946, 947, 0, - 0, 68, 68, 1426, 0, 0, 0, 0, 0, 123, - 0, 0, 0, 0, 0, 0, 0, 1384, 1392, 0, - 359, 0, 88, 89, 91, 0, 0, 0, 0, 0, - 0, 0, 104, 1134, 0, 1144, 0, 1138, 0, 0, - 1155, 1156, 1158, 0, 1161, 1162, 1163, 0, 0, 1598, - 0, 1219, 1216, 1217, 1218, 0, 0, 1267, 597, 598, - 599, 600, 0, 0, 0, 1271, 0, 0, 0, 1228, - 0, 0, 0, 1336, 1337, 1338, 1339, 1340, 1341, 1342, - 1343, 1344, 1345, -2, 1358, 0, 1592, 0, 0, 0, - 1598, 1408, 0, 0, 1413, 0, 0, 1598, 1405, 2164, - 1598, 0, 1444, 0, 1433, 0, 887, 889, 0, 0, - 887, 0, 0, 898, 0, 899, 0, 0, 0, 1074, - 895, 0, -2, 0, 0, 822, 0, 0, 1039, 1070, - 0, 0, 1040, 0, 1041, 1043, 1068, 0, 1062, 1050, - 1052, 1054, 1034, 1085, 0, 0, 1087, 1088, 1089, 1080, - 483, 0, 1517, 0, 1520, 1521, 1444, 1435, 0, 494, - 554, 0, 1490, 0, 0, 1496, 0, 1503, 508, 0, - 556, 0, 1611, 1641, 1622, 1641, 1692, 1641, 1641, 1352, - 0, 556, 0, 0, 526, 0, 0, 0, 0, 0, - 522, 559, 968, 509, 511, 512, 513, 563, 564, 566, - 0, 568, 569, 528, 540, 541, 542, 543, 0, 0, - 0, 535, 548, 549, 550, 551, 510, 1529, 1530, 1531, - 1534, 1535, 1536, 1537, 0, 0, 1540, 1541, 1542, 1543, - 1544, 1638, 1639, 1640, 1545, 1546, 1547, 1548, 1549, 1550, - 1551, 1569, 1570, 1571, 1572, 1573, 1574, 1553, 1554, 1555, - 1556, 1557, 1558, 1559, 1560, 0, 0, 1564, 0, 0, - 1138, 0, 502, 503, 0, 505, 0, 0, 1219, 0, - 0, 0, 0, 0, 1267, 590, 0, 0, 591, 1237, - 0, 1255, 0, 1249, 1250, 0, 0, 865, 1022, 378, - 0, 1022, 288, 297, 298, 299, 306, 0, 616, 312, - 974, 802, 803, 1461, 1462, 810, 0, 1175, 0, 1011, - 0, 0, 145, 148, 0, 143, 0, 0, 0, 0, - 135, 133, 2142, 0, 0, 918, 189, 0, 0, 974, - 910, 0, 0, 966, 967, 0, 0, 887, 955, 896, - 0, 1593, 1594, 1595, 1596, 0, 1654, 418, 668, 1022, - 672, 747, 1022, 1022, 0, 695, 733, 737, 734, 1022, - 0, 1274, 209, 214, 215, 216, 210, 208, 1281, 0, - 1283, 0, 1419, 0, 0, 2033, 1801, 1757, 0, 1759, - 1761, 1806, 1807, 1809, 1810, 1811, 1812, 1813, 1762, 0, - 1334, 1871, 1873, 0, 1875, 1876, 1884, 1885, 0, 1940, - 1944, 0, 0, 1931, 0, 0, 0, 0, 1844, 1845, - 1849, 1850, 1851, 1852, 1854, 1855, 1856, 1857, 1858, 1859, - 1860, 1861, 1862, 1863, 1864, 1865, 0, 962, 1834, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 941, 0, 0, 0, 70, 0, 70, 1425, 1427, - 116, 118, 0, 112, 113, 114, 0, 0, 1104, 1398, - 1592, 1386, 0, 1378, 0, 1392, 0, 0, 0, 90, - 0, 92, 0, 2339, 0, 0, 0, 0, 1354, 0, - 1146, 0, 0, 1137, 0, 1148, 1164, 1160, 0, 0, - 0, 0, 1599, 1600, 1602, 1603, 1604, 0, 1186, 0, - 0, 1207, 1208, 1209, 1233, 1221, 0, 602, 603, 0, - 0, 0, 615, 611, 612, 613, 593, 1266, 1244, 0, - 0, 1244, 1231, 0, 0, 1243, 0, 1359, 2164, 2164, - 2164, 1398, 0, 0, 0, 1504, 2164, 2164, 0, 1410, - 1412, 1400, 0, 0, 0, 0, 1508, 1447, 0, 0, - 1438, 0, 0, 885, 0, 890, 887, 871, 881, 870, - 878, 879, 903, 0, 900, 952, 1099, 0, 0, 1022, - 821, 824, 825, 0, 1071, 0, 1061, 1063, 1094, 1091, - 0, 0, 0, 0, 0, 1447, 486, 1468, 0, 0, - 0, 0, 0, 1500, 0, 0, 1472, 0, 527, 557, - 0, -2, 0, 1642, 0, 1625, 1642, 0, 0, 1641, - 0, 516, 556, 0, 0, 0, 570, 0, 578, 579, - 1303, 1303, 1303, 1303, 576, 1687, 0, 577, 0, 561, - 0, 567, 1532, 1533, 0, 1538, 1539, 0, 1563, 0, - 0, 497, 500, 0, 1142, 1143, -2, 0, 0, 0, - 582, 0, 0, 0, 583, 584, 589, 1268, 1269, 1228, - 0, 1244, 0, 1254, 0, 1251, 1252, 962, 0, 0, - 0, 376, 314, 928, 0, 1172, 0, 0, 996, 0, - 0, 1029, 0, 18, 0, 0, 138, 2152, 2155, 920, - 0, 917, 190, 0, 0, 0, 931, 912, 0, 909, - 0, 972, 973, 841, 887, 845, 844, 847, 0, 1587, - 1597, 669, 1022, 674, 675, 0, 738, 211, 206, 1282, - 1429, 0, 1420, 0, 1711, 1771, 0, 1886, 0, 0, - 1839, 1836, 1839, 1838, 1839, 1830, 0, 1779, 0, 1782, - 0, 1786, 1787, 0, 1789, 1790, 1791, 0, 1793, 1794, - 0, 939, 0, 66, 0, 69, 67, 0, 0, 0, - 122, 1373, 0, 1398, 1377, 0, 0, 0, 1379, 0, - 0, 0, 0, 0, 93, 0, 0, 0, 0, 0, - 0, 102, 0, 0, 0, 1145, 0, 1139, 0, 0, - 1157, 1159, 0, 1193, 1508, 0, 1193, 1220, 1206, 0, - 1187, 0, 0, 604, 605, 0, 608, 614, 1222, 0, - 0, 1225, 1226, 1224, 1227, 0, 0, 1241, 0, 0, - 0, 0, 1346, 0, 1349, 1365, 0, 0, 0, -2, - 1398, 0, 0, 0, 1515, -2, 1407, 0, 1453, 0, - 1445, 0, 1437, 0, 1440, 0, 875, 886, 869, 0, - 1022, 1022, -2, 818, 823, 0, 855, 856, 0, 0, - 0, 1095, 1097, 1092, 1093, 1518, 484, 1519, 1453, 1470, - 0, 1491, 0, 0, 0, 0, 0, 0, 0, 1471, - 0, 1484, 558, 1643, -2, 1657, 1659, 0, 1364, 1662, - 1663, 0, 0, 0, 0, 0, 0, 1718, 1671, 0, - 0, 0, 1676, 1677, 1678, 0, 0, 1681, 0, 0, - 0, 2051, 2052, 0, 1690, 0, 0, 0, 0, 0, - 0, 0, 1619, 517, 518, 0, 520, 521, 1303, 0, - 572, 573, 574, 575, 1688, 560, 514, 2164, 530, 1562, - 1565, 1566, 501, 504, 0, 0, 588, 585, 586, 1231, - 1236, 1247, 1256, 866, 955, 1022, 379, 380, 975, 1176, - 1264, 1012, 1020, 2574, 2576, 2573, 139, 144, 0, 0, - 922, 0, 919, 0, 913, 915, 200, 916, 911, 961, - 843, 1586, 673, 747, 160, 192, 0, 0, 1758, 0, - 0, 0, 1874, 1929, 1930, 1842, 1843, 1866, 0, 1831, - 0, 1825, 1826, 1827, 1832, 0, 0, 0, 0, 942, - 937, 71, 120, 119, 0, 0, 1374, 0, 0, 0, - 1390, 1391, 0, 1393, 1394, 1395, 0, 0, 0, 0, - 75, 0, 0, 0, 1354, 0, 1354, 0, 0, 0, - 1516, 0, 1147, 1141, 1151, 1165, 0, 1178, 1185, 1200, - 1370, 1601, 1184, 0, 0, 0, 601, 606, 0, 609, - 610, 1245, 1244, 0, 1229, 1230, 0, 1239, 0, 0, - 1360, 1361, 1362, 1233, 1505, 1506, 1507, 1463, 1409, 0, - -2, 1526, 0, 1414, 1401, 0, 1403, 1404, 1429, 1514, - 1463, 0, 1441, 0, 1448, 0, 1446, 1439, 874, 901, - 962, 819, 857, 863, 0, 862, 1072, 1086, 0, 1450, - 496, 1502, 1492, 0, 1494, 0, 0, 0, 0, 1473, - -2, 0, 1658, 1660, 1661, 1664, 1665, 1666, 1723, 1724, - 1725, 0, 0, 1669, 1720, 1721, 1722, 1670, 0, 0, - 0, 1675, 0, 0, 0, 0, 2049, 2050, 1716, 0, - 0, 1626, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, - 1636, 1637, 1627, 0, 0, 0, 1618, 1620, 519, 571, - 0, 1304, 2164, 2164, 0, 0, 0, 1310, 1311, 2164, - 2164, 2164, 2164, 2164, 2164, 0, 0, 0, 2164, 2164, - 2164, 2164, 1325, 1326, 0, 2164, 2164, 0, 2164, 0, - 0, 1246, 375, 377, 1014, 0, 0, 0, 0, 134, - 136, 151, 0, 921, 191, 0, 918, 1022, 162, 0, - 183, 0, 1430, 0, 1770, 0, 0, 0, 1841, 1828, - 0, 0, 0, 0, 0, 2053, 2054, 2055, 0, 1780, - 1783, 1788, 1792, 0, 1399, 1387, 1388, 1389, 1385, 0, - 0, 1396, 1397, 0, 73, 0, 96, 0, 0, 97, - 1354, 98, 1354, 0, 0, 1135, 0, 0, 1201, 1202, - 1210, 1211, 0, 1213, 1214, 1234, 607, 1223, 1232, 1238, - 1241, 0, 1303, 1347, 1465, 0, 1411, 1363, 1528, 2164, - 1233, 1416, 1465, 0, 1510, 2164, 2164, 1431, 0, 1443, - 0, 1455, 0, 1449, 955, 0, 0, 863, 1096, 1098, - 485, 0, 1452, 1488, 1493, 1495, 1497, 0, 1501, 1499, - 1474, -2, 0, 1482, 0, 0, 1667, 1668, 0, 0, - 1950, 2164, 0, 0, 0, 1706, 0, 1303, 1303, 1303, - 1303, 0, 580, 581, 0, 0, 1307, 1308, 0, 0, - 0, 0, 0, 0, 0, 0, 1319, 1320, 0, 0, - 0, 0, 0, 0, 0, 529, 0, 0, 507, 1021, - 0, 0, 0, 0, 0, 920, 676, 152, 0, 161, - 180, 0, 193, 194, 0, 0, 0, 0, 1422, 0, - 1714, 1715, 0, 1817, 0, 0, 0, 1821, 1822, 1823, - 1824, 121, 1392, 1392, 1354, 75, 0, 95, 0, 99, - 100, 0, 1354, 0, 1177, 0, 1212, 1240, 1242, 1302, - 1402, 0, 1502, 1527, 0, 1415, 1406, 1509, 0, 0, - 0, 1442, 1454, 0, 1457, 817, 0, 864, 0, 1451, - 1469, 0, 1498, 1475, 1483, 0, 1478, 0, 0, 0, - 1719, 0, 1674, 0, 1680, 0, 1684, 1694, 1707, 0, - 0, 1607, 0, 1609, 0, 1613, 0, 1615, 0, 0, - 1305, 1306, 1309, 1312, 1313, 1314, 1315, 1316, 1317, 0, - 1321, 1322, 1323, 1324, 1327, 1328, 1329, 1330, 531, 506, - 0, 2000, 1016, 1017, 0, 924, 914, 922, 163, 167, - 0, 189, 186, 0, 195, 0, 0, 0, 0, 1418, - 0, 1712, 0, 1818, 1819, 1820, 1380, 1392, 1381, 1392, - 72, 74, 76, 94, 1354, 101, 0, 1179, 1180, 1194, - 0, 1490, 1532, 1511, 1512, 1513, 1456, 0, 859, 0, - 1489, 1477, 0, -2, 1485, 0, 0, 2002, 2011, 2012, - 1672, 1679, 0, 1683, 1685, 1686, 1693, 1695, 1696, 0, - 1708, 1709, 1710, 1717, 1303, 1303, 1303, 1303, 1617, 1318, - 1015, 0, 0, 923, 0, 907, 154, 0, 0, 184, - 185, 187, 0, 196, 0, 198, 199, 0, 0, 1829, - 1382, 1383, 103, 1181, 1466, 0, 1468, 0, 0, 1479, - -2, 0, 1487, 0, 1673, 1684, 1697, 0, 1698, 0, - 0, 0, 1608, 1610, 1614, 1616, 2000, 1018, 925, 1428, - 0, 168, 0, 170, 172, 173, 1644, 181, 182, 188, - 197, 0, 0, 1166, 1182, 0, 0, 1470, 858, 0, - 0, 1486, 2003, 1682, 1699, 1701, 1702, 0, 0, 1700, - 0, 155, 156, 0, 169, 0, 0, 1423, 1713, 1183, - 1467, 1464, 0, 0, 1703, 1705, 1704, 1019, 0, 0, - 171, 1645, 0, 0, 157, 158, 159, 0, 0, 861, - 1646, 0, 0, 860, + -2, -2, -2, -2, -2, -2, 1181, 821, 1271, 0, + 1278, 1024, 1036, 1043, 1117, 1119, 165, 1039, 0, 150, + 18, 149, 141, 142, 0, 18, 0, 0, 0, 0, + 2098, 2175, 2174, 2142, 0, 2143, 2172, 2177, 0, 2180, + 0, 469, 925, 0, 915, 917, 942, 0, 0, 982, + 980, 981, 848, 0, 0, 855, 973, 0, 911, 1275, + 1608, 1609, 0, 1612, 1613, 1614, 1615, 1606, 0, 0, + 0, 0, 0, 0, 0, 776, 175, 457, 672, 1033, + 754, 1033, 0, 754, 754, 684, 1536, 1537, 695, 701, + 1290, 1033, 725, 969, 970, 1616, 1033, 1033, 754, 772, + 768, 0, 0, 0, 0, 0, 808, 0, 209, 0, + 0, 229, 0, 0, 0, 1440, 1435, 2025, 2053, 2055, + 0, 2062, 2058, 1773, 1782, 1822, 0, 0, 0, 0, + 0, 1831, 2173, 2173, 1834, 2169, 2171, 2169, 1840, 1840, + 0, 1345, 0, 1346, 979, 166, 0, 0, 0, 0, + 1904, 0, 0, 0, 892, 0, 0, 0, 0, 0, + 1861, 1863, 1865, 1865, 1872, 1866, 1873, 1874, 1865, 1865, + 1865, 1865, 1879, 1865, 1865, 1865, 1865, 1865, 1865, 1865, + 1865, 1865, 1865, 1865, 1865, 0, 1859, 1802, 1804, 0, + 1807, 0, 1810, 1811, 0, 0, 0, 2083, 2084, 901, + 939, 0, 0, 0, 0, 68, 68, 1440, 0, 0, + 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, + 0, 1397, 1405, 0, 359, 0, 88, 89, 91, 0, + 0, 0, 0, 0, 0, 0, 104, 1146, 0, 1147, + 0, 1157, 0, 1151, 0, 0, 1168, 1169, 1171, 0, + 1174, 1175, 1176, 0, 0, 1622, 0, 1232, 1229, 1230, + 1231, 0, 0, 1280, 602, 603, 604, 605, 0, 0, + 0, 1284, 0, 0, 0, 1241, 0, 0, 0, 1349, + 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, -2, + 1371, 0, 1616, 0, 0, 0, 1622, 1422, 0, 0, + 1427, 0, 0, 1622, 1419, 2190, 1622, 0, 1458, 0, + 1447, 0, 896, 898, 0, 0, 896, 0, 0, 907, + 0, 908, 0, 0, 0, 1085, 904, 0, -2, 0, + 0, 831, 0, 0, 1050, 1081, 0, 0, 1051, 0, + 1052, 1054, 1079, 0, 1073, 1061, 1063, 1065, 1045, 1096, + 0, 0, 1098, 1099, 1100, 1091, 484, 0, 1531, 0, + 1534, 1535, 486, 0, 1541, 0, 1544, 1545, 1458, 1449, + 0, 499, 559, 0, 1504, 0, 0, 1510, 0, 1517, + 513, 0, 561, 0, 1635, 1665, 1646, 1665, 1718, 1665, + 1665, 1365, 0, 561, 0, 0, 531, 0, 0, 0, + 0, 0, 527, 564, 979, 514, 516, 517, 518, 568, + 569, 571, 0, 573, 574, 533, 545, 546, 547, 548, + 0, 0, 0, 540, 553, 554, 555, 556, 515, 1553, + 1554, 1555, 1558, 1559, 1560, 1561, 0, 0, 1564, 1565, + 1566, 1567, 1568, 1662, 1663, 1664, 1569, 1570, 1571, 1572, + 1573, 1574, 1575, 1593, 1594, 1595, 1596, 1597, 1598, 1577, + 1578, 1579, 1580, 1581, 1582, 1583, 1584, 0, 0, 1588, + 0, 0, 1151, 0, 507, 508, 0, 510, 0, 0, + 1232, 0, 0, 0, 0, 0, 1280, 595, 0, 0, + 596, 1250, 0, 1268, 0, 1262, 1263, 0, 0, 874, + 1033, 378, 0, 1033, 288, 297, 298, 299, 306, 0, + 621, 312, 985, 811, 812, 1475, 1476, 819, 0, 1188, + 0, 1022, 0, 0, 145, 148, 0, 143, 0, 0, + 0, 0, 135, 133, 2168, 0, 0, 927, 189, 0, + 0, 985, 919, 0, 0, 977, 978, 0, 0, 896, + 966, 905, 0, 1617, 1618, 1619, 1620, 0, 1678, 418, + 674, 1033, 678, 754, 1033, 1033, 0, 702, 740, 744, + 741, 1033, 0, 1287, 209, 214, 215, 216, 210, 208, + 1294, 0, 1296, 0, 1433, 0, 0, 2059, 1827, 1783, + 0, 1785, 1787, 1832, 1833, 1835, 1836, 1837, 1838, 1839, + 1788, 0, 1347, 1897, 1899, 0, 1901, 1902, 1910, 1911, + 0, 1966, 1970, 0, 0, 1957, 0, 0, 0, 0, + 1870, 1871, 1875, 1876, 1877, 1878, 1880, 1881, 1882, 1883, + 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1891, 0, 973, + 1860, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 954, 955, 956, 957, 958, + 950, 0, 0, 70, 0, 70, 1439, 1441, 116, 118, + 0, 112, 113, 114, 0, 0, 1115, 1411, 1616, 1399, + 0, 1391, 0, 1405, 0, 0, 0, 90, 0, 92, + 0, 2369, 0, 0, 0, 0, 1367, 0, 0, 1159, + 0, 0, 1150, 0, 1161, 1177, 1173, 0, 0, 0, + 0, 1623, 1624, 1626, 1627, 1628, 0, 1199, 0, 0, + 1220, 1221, 1222, 1246, 1234, 0, 607, 608, 0, 0, + 0, 620, 616, 617, 618, 598, 1279, 1257, 0, 0, + 1257, 1244, 0, 0, 1256, 0, 1372, 2190, 2190, 2190, + 1411, 0, 0, 0, 1518, 2190, 2190, 0, 1424, 1426, + 1413, 0, 0, 0, 0, 1522, 1461, 0, 0, 1452, + 0, 0, 894, 0, 899, 896, 880, 890, 879, 887, + 888, 912, 0, 909, 963, 1110, 0, 0, 1033, 830, + 833, 834, 0, 1082, 0, 1072, 1074, 1105, 1102, 0, + 0, 0, 0, 0, 0, 0, 0, 1461, 491, 1482, + 0, 0, 0, 0, 0, 1514, 0, 0, 1486, 0, + 532, 562, 0, -2, 0, 1666, 0, 1649, 1666, 0, + 0, 1665, 0, 521, 561, 0, 0, 0, 575, 0, + 583, 584, 1316, 1316, 1316, 1316, 581, 1713, 0, 582, + 0, 566, 0, 572, 1556, 1557, 0, 1562, 1563, 0, + 1587, 0, 0, 502, 505, 0, 1155, 1156, -2, 0, + 0, 0, 587, 0, 0, 0, 588, 589, 594, 1281, + 1282, 1241, 0, 1257, 0, 1267, 0, 1264, 1265, 973, + 0, 0, 0, 376, 314, 937, 0, 1185, 0, 0, + 1007, 0, 0, 1040, 0, 18, 0, 0, 138, 2178, + 2181, 929, 0, 926, 190, 0, 0, 0, 940, 921, + 0, 918, 0, 983, 984, 850, 896, 854, 853, 856, + 0, 1611, 1621, 675, 1033, 680, 681, 0, 745, 211, + 206, 1295, 1443, 0, 1434, 0, 1737, 1797, 0, 1912, + 0, 0, 1865, 1862, 1865, 1864, 1865, 1856, 0, 1805, + 0, 1808, 0, 1812, 1813, 0, 1815, 1816, 1817, 0, + 1819, 1820, 952, 0, 948, 0, 66, 0, 69, 67, + 0, 0, 0, 122, 1386, 0, 1411, 1390, 0, 0, + 0, 1392, 0, 0, 0, 0, 0, 93, 0, 0, + 0, 0, 0, 0, 102, 0, 0, 0, 0, 1158, + 0, 1152, 0, 0, 1170, 1172, 0, 1206, 1522, 0, + 1206, 1233, 1219, 0, 1200, 0, 0, 609, 610, 0, + 613, 619, 1235, 0, 0, 1238, 1239, 1237, 1240, 0, + 0, 1254, 0, 0, 0, 0, 1359, 0, 1362, 1378, + 0, 0, 0, -2, 1411, 0, 0, 0, 1529, -2, + 1421, 0, 1467, 0, 1459, 0, 1451, 0, 1454, 0, + 884, 895, 878, 0, 1033, 1033, -2, 827, 832, 0, + 864, 865, 0, 0, 0, 1106, 1108, 1103, 1104, 1532, + 485, 1533, 1542, 487, 1543, 1546, 1547, 1467, 1484, 0, + 1505, 0, 0, 0, 0, 0, 0, 0, 1485, 0, + 1498, 563, 1667, -2, 1681, 1683, 0, 1377, 1686, 1687, + 0, 0, 0, 0, 0, 0, 0, 0, 1744, 1697, + 0, 0, 0, 1702, 1703, 1704, 0, 0, 1707, 0, + 0, 0, 2077, 2078, 0, 1716, 0, 0, 0, 0, + 0, 0, 0, 1643, 522, 523, 0, 525, 526, 1316, + 0, 577, 578, 579, 580, 1714, 565, 519, 2190, 535, + 1586, 1589, 1590, 506, 509, 0, 0, 593, 590, 591, + 1244, 1249, 1260, 1269, 875, 966, 1033, 379, 380, 986, + 1189, 1277, 1023, 1031, 2605, 2607, 2604, 139, 144, 0, + 0, 931, 0, 928, 0, 922, 924, 200, 925, 920, + 972, 852, 1610, 679, 754, 160, 192, 0, 0, 1784, + 0, 0, 0, 1900, 1955, 1956, 1868, 1869, 1892, 0, + 1857, 0, 1851, 1852, 1853, 1858, 0, 0, 0, 0, + 0, 946, 71, 120, 119, 0, 0, 1387, 0, 0, + 0, 1403, 1404, 0, 1406, 1407, 1408, 0, 0, 0, + 0, 75, 0, 0, 0, 1367, 0, 1367, 0, 0, + 0, 1530, 1540, 0, 1160, 1154, 1164, 1178, 0, 1191, + 1198, 1213, 1383, 1625, 1197, 0, 0, 0, 606, 611, + 0, 614, 615, 1258, 1257, 0, 1242, 1243, 0, 1252, + 0, 0, 1373, 1374, 1375, 1246, 1519, 1520, 1521, 1477, + 1423, 0, -2, 1550, 0, 1428, 1414, 0, 1416, 1417, + 1418, 1443, 2190, 1528, 1477, 0, 1455, 0, 1462, 0, + 1460, 1453, 883, 910, 973, 828, 866, 872, 0, 871, + 1083, 1097, 0, 1464, 501, 1516, 1506, 0, 1508, 0, + 0, 0, 0, 1487, -2, 0, 1682, 1684, 1685, 1688, + 1689, 1690, 1691, 1692, 1749, 1750, 1751, 0, 0, 1695, + 1746, 1747, 1748, 1696, 0, 0, 0, 1701, 0, 0, + 0, 0, 2075, 2076, 1742, 0, 0, 1650, 1652, 1653, + 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1651, 0, + 0, 0, 1642, 1644, 524, 576, 0, 1317, 2190, 2190, + 0, 0, 0, 1323, 1324, 2190, 2190, 2190, 2190, 2190, + 2190, 0, 0, 0, 2190, 2190, 2190, 2190, 1338, 1339, + 0, 2190, 2190, 0, 2190, 0, 0, 1259, 375, 377, + 1025, 0, 0, 0, 0, 134, 136, 151, 0, 930, + 191, 0, 927, 1033, 162, 0, 183, 0, 1444, 0, + 1796, 0, 0, 0, 1867, 1854, 0, 0, 0, 0, + 0, 2079, 2080, 2081, 0, 1806, 1809, 1814, 1818, 953, + 0, 1412, 1400, 1401, 1402, 1398, 0, 0, 1409, 1410, + 0, 73, 0, 96, 0, 0, 97, 1367, 98, 1367, + 0, 0, 1148, 0, 0, 1214, 1215, 1223, 1224, 0, + 1226, 1227, 1247, 612, 1236, 1245, 1251, 1254, 0, 1316, + 1360, 1479, 0, 1425, 1376, 1552, 2190, 1246, 1430, 0, + 1479, 0, 1524, 2190, 2190, 1445, 0, 1457, 0, 1469, + 0, 1463, 966, 0, 0, 872, 1107, 1109, 490, 0, + 1466, 1502, 1507, 1509, 1511, 0, 1515, 1513, 1488, -2, + 0, 1496, 0, 0, 1693, 1694, 0, 0, 1976, 2190, + 0, 0, 0, 1732, 0, 1316, 1316, 1316, 1316, 0, + 585, 586, 0, 0, 1320, 1321, 0, 0, 0, 0, + 0, 0, 0, 0, 1332, 1333, 0, 0, 0, 0, + 0, 0, 0, 534, 0, 0, 512, 1032, 0, 0, + 0, 0, 0, 929, 682, 152, 0, 161, 180, 0, + 193, 194, 0, 0, 0, 0, 1436, 0, 1740, 1741, + 0, 1843, 0, 0, 0, 1847, 1848, 1849, 1850, 121, + 1405, 1405, 1367, 75, 0, 95, 0, 99, 100, 0, + 1367, 0, 1190, 0, 1225, 1253, 1255, 1315, 1415, 0, + 1516, 1551, 0, 1429, 1539, 1420, 1523, 0, 0, 0, + 1456, 1468, 0, 1471, 826, 0, 873, 0, 1465, 1483, + 0, 1512, 1489, 1497, 0, 1492, 0, 0, 0, 1745, + 0, 1700, 0, 1706, 0, 1710, 1720, 1733, 0, 0, + 1631, 0, 1633, 0, 1637, 0, 1639, 0, 0, 1318, + 1319, 1322, 1325, 1326, 1327, 1328, 1329, 1330, 0, 1334, + 1335, 1336, 1337, 1340, 1341, 1342, 1343, 536, 511, 0, + 2026, 1027, 1028, 0, 933, 923, 931, 163, 167, 0, + 189, 186, 0, 195, 0, 0, 0, 0, 1432, 0, + 1738, 0, 1844, 1845, 1846, 1393, 1405, 1394, 1405, 72, + 74, 76, 94, 1367, 101, 0, 1192, 1193, 1207, 0, + 1504, 1556, 1538, 1525, 1526, 1527, 1470, 0, 868, 0, + 1503, 1491, 0, -2, 1499, 0, 0, 2028, 2037, 2038, + 1698, 1705, 0, 1709, 1711, 1712, 1719, 1721, 1722, 0, + 1734, 1735, 1736, 1743, 1316, 1316, 1316, 1316, 1641, 1331, + 1026, 0, 0, 932, 0, 916, 154, 0, 0, 184, + 185, 187, 0, 196, 0, 198, 199, 0, 0, 1855, + 1395, 1396, 103, 1194, 1480, 0, 1482, 0, 0, 1493, + -2, 0, 1501, 0, 1699, 1710, 1723, 0, 1724, 0, + 0, 0, 1632, 1634, 1638, 1640, 2026, 1029, 934, 1442, + 0, 168, 0, 170, 172, 173, 1668, 181, 182, 188, + 197, 0, 0, 1179, 1195, 0, 0, 1484, 867, 0, + 0, 1500, 2029, 1708, 1725, 1727, 1728, 0, 0, 1726, + 0, 155, 156, 0, 169, 0, 0, 1437, 1739, 1196, + 1481, 1478, 0, 0, 1729, 1731, 1730, 1030, 0, 0, + 171, 1669, 0, 0, 157, 158, 159, 0, 0, 870, + 1670, 0, 0, 869, } var yyTok1 = [...]int{ @@ -12591,14 +12899,14 @@ var yyTok1 = [...]int{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 122, 3, 3, 3, 155, 145, 3, 89, 90, 152, 150, 175, 151, 174, 153, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 753, 750, - 132, 131, 133, 3, 754, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 758, 755, + 132, 131, 133, 3, 759, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 157, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 751, 144, 752, 158, + 3, 3, 3, 756, 144, 757, 158, } var yyTok2 = [...]int{ @@ -12726,6 +13034,7 @@ var yyTok3 = [...]int{ 58060, 735, 58061, 736, 58062, 737, 58063, 738, 58064, 739, 58065, 740, 58066, 741, 58067, 742, 58068, 743, 58069, 744, 58070, 745, 58071, 746, 58072, 747, 58073, 748, 58074, 749, + 58075, 750, 58076, 751, 58077, 752, 58078, 753, 58079, 754, 0, } @@ -13076,7 +13385,7 @@ yydefault: case 3: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:971 +//line mysql_sql.y:980 { if yyDollar[1].statementUnion() != nil { yylex.(*Lexer).AppendStmt(yyDollar[1].statementUnion()) @@ -13084,7 +13393,7 @@ yydefault: } case 4: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:977 +//line mysql_sql.y:986 { yylex.(*Lexer).AppendTopLevelSemicolon(yyDollar[2].pos) if yyDollar[3].statementUnion() != nil { @@ -13094,7 +13403,7 @@ yydefault: case 5: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:986 +//line mysql_sql.y:995 { yyLOCAL = tree.NewCompoundStmt(yyDollar[2].statementsUnion()) } @@ -13102,7 +13411,7 @@ yydefault: case 6: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []tree.Statement -//line mysql_sql.y:992 +//line mysql_sql.y:1001 { yyLOCAL = []tree.Statement{yyDollar[1].statementUnion()} } @@ -13110,7 +13419,7 @@ yydefault: case 7: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []tree.Statement -//line mysql_sql.y:996 +//line mysql_sql.y:1005 { yyLOCAL = append(yyDollar[1].statementsUnion(), yyDollar[3].statementUnion()) } @@ -13118,7 +13427,7 @@ yydefault: case 17: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1011 +//line mysql_sql.y:1020 { yyLOCAL = yyDollar[1].statementUnion() } @@ -13126,7 +13435,7 @@ yydefault: case 18: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1015 +//line mysql_sql.y:1024 { yyLOCAL = tree.Statement(nil) } @@ -13134,7 +13443,7 @@ yydefault: case 19: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1021 +//line mysql_sql.y:1030 { yyLOCAL = yyDollar[1].statementUnion() } @@ -13142,7 +13451,7 @@ yydefault: case 20: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1025 +//line mysql_sql.y:1034 { yyLOCAL = yyDollar[1].statementUnion() } @@ -13150,7 +13459,7 @@ yydefault: case 22: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1030 +//line mysql_sql.y:1039 { yyLOCAL = yyDollar[1].statementUnion() } @@ -13158,7 +13467,7 @@ yydefault: case 23: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1034 +//line mysql_sql.y:1043 { yyLOCAL = tree.Statement(nil) } @@ -13166,7 +13475,7 @@ yydefault: case 55: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1071 +//line mysql_sql.y:1080 { yyLOCAL = yyDollar[1].selectUnion() } @@ -13174,7 +13483,7 @@ yydefault: case 66: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1087 +//line mysql_sql.y:1096 { var timestamp = yyDollar[2].str var isS3 = false @@ -13189,7 +13498,7 @@ yydefault: case 67: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1098 +//line mysql_sql.y:1107 { var timestamp = yyDollar[2].str var isS3 = true @@ -13203,32 +13512,32 @@ yydefault: yyVAL.union = yyLOCAL case 68: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:1110 +//line mysql_sql.y:1119 { yyVAL.str = "" } case 69: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:1114 +//line mysql_sql.y:1123 { yyVAL.str = yyDollar[2].str } case 70: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:1119 +//line mysql_sql.y:1128 { yyVAL.str = "" } case 71: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:1123 +//line mysql_sql.y:1132 { yyVAL.str = yyDollar[2].str } case 72: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1129 +//line mysql_sql.y:1138 { yyLOCAL = &tree.CreateCDC{ IfNotExists: yyDollar[3].ifNotExistsUnion(), @@ -13245,7 +13554,7 @@ yydefault: case 73: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:1144 +//line mysql_sql.y:1153 { yyLOCAL = yyDollar[1].strsUnion() } @@ -13253,7 +13562,7 @@ yydefault: case 74: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:1148 +//line mysql_sql.y:1157 { yyLOCAL = append(yyDollar[1].strsUnion(), yyDollar[3].strsUnion()...) } @@ -13261,7 +13570,7 @@ yydefault: case 75: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:1152 +//line mysql_sql.y:1161 { yyLOCAL = []string{} } @@ -13269,7 +13578,7 @@ yydefault: case 76: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:1156 +//line mysql_sql.y:1165 { yyLOCAL = append(yyLOCAL, yyDollar[1].str) yyLOCAL = append(yyLOCAL, yyDollar[3].str) @@ -13278,7 +13587,7 @@ yydefault: case 77: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1163 +//line mysql_sql.y:1172 { yyLOCAL = &tree.ShowCDC{ Option: yyDollar[3].allCDCOptionUnion(), @@ -13288,7 +13597,7 @@ yydefault: case 78: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1171 +//line mysql_sql.y:1180 { yyLOCAL = &tree.PauseCDC{ Option: yyDollar[3].allCDCOptionUnion(), @@ -13298,7 +13607,7 @@ yydefault: case 79: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1179 +//line mysql_sql.y:1188 { yyLOCAL = tree.NewDropCDC(yyDollar[4].allCDCOptionUnion(), yyDollar[3].boolValUnion(), yyDollar[5].boolValUnion()) } @@ -13306,7 +13615,7 @@ yydefault: case 80: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.AllOrNotCDC -//line mysql_sql.y:1184 +//line mysql_sql.y:1193 { yyLOCAL = &tree.AllOrNotCDC{ All: true, @@ -13317,7 +13626,7 @@ yydefault: case 81: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.AllOrNotCDC -//line mysql_sql.y:1191 +//line mysql_sql.y:1200 { yyLOCAL = yyDollar[1].allCDCOptionUnion() } @@ -13325,7 +13634,7 @@ yydefault: case 82: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.AllOrNotCDC -//line mysql_sql.y:1197 +//line mysql_sql.y:1206 { yyLOCAL = yyDollar[1].allCDCOptionUnion() } @@ -13333,7 +13642,7 @@ yydefault: case 83: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.AllOrNotCDC -//line mysql_sql.y:1202 +//line mysql_sql.y:1211 { yyLOCAL = &tree.AllOrNotCDC{ All: false, @@ -13344,7 +13653,7 @@ yydefault: case 84: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.AllOrNotCDC -//line mysql_sql.y:1211 +//line mysql_sql.y:1220 { yyLOCAL = &tree.AllOrNotCDC{ All: true, @@ -13355,7 +13664,7 @@ yydefault: case 85: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.AllOrNotCDC -//line mysql_sql.y:1218 +//line mysql_sql.y:1227 { yyLOCAL = &tree.AllOrNotCDC{ All: false, @@ -13366,7 +13675,7 @@ yydefault: case 86: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1227 +//line mysql_sql.y:1236 { yyLOCAL = &tree.ResumeCDC{ TaskName: tree.Identifier(yyDollar[4].cstrUnion().Compare()), @@ -13376,7 +13685,7 @@ yydefault: case 87: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1235 +//line mysql_sql.y:1244 { yyLOCAL = &tree.RestartCDC{ TaskName: tree.Identifier(yyDollar[4].cstrUnion().Compare()), @@ -13386,7 +13695,7 @@ yydefault: case 88: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1243 +//line mysql_sql.y:1252 { yyLOCAL = &tree.CreateSnapShot{ IfNotExists: yyDollar[3].ifNotExistsUnion(), @@ -13398,7 +13707,7 @@ yydefault: case 89: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ObjectInfo -//line mysql_sql.y:1253 +//line mysql_sql.y:1262 { spLevel := tree.SnapshotLevelType{ Level: tree.SNAPSHOTLEVELCLUSTER, @@ -13412,7 +13721,7 @@ yydefault: case 90: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.ObjectInfo -//line mysql_sql.y:1263 +//line mysql_sql.y:1272 { spLevel := tree.SnapshotLevelType{ Level: tree.SNAPSHOTLEVELACCOUNT, @@ -13426,7 +13735,7 @@ yydefault: case 91: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ObjectInfo -//line mysql_sql.y:1273 +//line mysql_sql.y:1282 { spLevel := tree.SnapshotLevelType{ Level: tree.SNAPSHOTLEVELACCOUNT, @@ -13440,7 +13749,7 @@ yydefault: case 92: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.ObjectInfo -//line mysql_sql.y:1283 +//line mysql_sql.y:1292 { spLevel := tree.SnapshotLevelType{ Level: tree.SNAPSHOTLEVELDATABASE, @@ -13454,7 +13763,7 @@ yydefault: case 93: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.ObjectInfo -//line mysql_sql.y:1293 +//line mysql_sql.y:1302 { spLevel := tree.SnapshotLevelType{ Level: tree.SNAPSHOTLEVELTABLE, @@ -13468,7 +13777,7 @@ yydefault: case 94: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.ObjectInfo -//line mysql_sql.y:1303 +//line mysql_sql.y:1312 { spLevel := tree.SnapshotLevelType{ Level: tree.SNAPSHOTLEVELTABLE, @@ -13484,7 +13793,7 @@ yydefault: case 95: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.ObjectInfo -//line mysql_sql.y:1315 +//line mysql_sql.y:1324 { spLevel := tree.SnapshotLevelType{ Level: tree.SNAPSHOTLEVELDATABASE, @@ -13500,7 +13809,7 @@ yydefault: case 96: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.ObjectInfo -//line mysql_sql.y:1327 +//line mysql_sql.y:1336 { spLevel := tree.SnapshotLevelType{ Level: tree.SNAPSHOTLEVELACCOUNT, @@ -13515,7 +13824,7 @@ yydefault: case 97: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1340 +//line mysql_sql.y:1349 { yyLOCAL = &tree.CreatePitr{ IfNotExists: yyDollar[3].ifNotExistsUnion(), @@ -13530,7 +13839,7 @@ yydefault: case 98: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1351 +//line mysql_sql.y:1360 { yyLOCAL = &tree.CreatePitr{ IfNotExists: yyDollar[3].ifNotExistsUnion(), @@ -13545,7 +13854,7 @@ yydefault: case 99: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1362 +//line mysql_sql.y:1371 { yyLOCAL = &tree.CreatePitr{ IfNotExists: yyDollar[3].ifNotExistsUnion(), @@ -13561,7 +13870,7 @@ yydefault: case 100: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1374 +//line mysql_sql.y:1383 { yyLOCAL = &tree.CreatePitr{ IfNotExists: yyDollar[3].ifNotExistsUnion(), @@ -13577,7 +13886,7 @@ yydefault: case 101: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1386 +//line mysql_sql.y:1395 { yyLOCAL = &tree.CreatePitr{ IfNotExists: yyDollar[3].ifNotExistsUnion(), @@ -13594,7 +13903,7 @@ yydefault: case 102: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1399 +//line mysql_sql.y:1408 { yyLOCAL = &tree.CreatePitr{ IfNotExists: yyDollar[3].ifNotExistsUnion(), @@ -13609,7 +13918,7 @@ yydefault: case 103: yyDollar = yyS[yypt-13 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1410 +//line mysql_sql.y:1419 { yyLOCAL = &tree.CreatePitr{ IfNotExists: yyDollar[3].ifNotExistsUnion(), @@ -13626,7 +13935,7 @@ yydefault: case 104: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:1425 +//line mysql_sql.y:1434 { yyLOCAL = yyDollar[1].item.(int64) } @@ -13634,7 +13943,7 @@ yydefault: case 105: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1432 +//line mysql_sql.y:1441 { var account tree.Identifier var database tree.Identifier @@ -13670,7 +13979,7 @@ yydefault: case 106: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1464 +//line mysql_sql.y:1473 { var account tree.Identifier var database tree.Identifier @@ -13711,7 +14020,7 @@ yydefault: case 107: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1501 +//line mysql_sql.y:1510 { yyLOCAL = &tree.RestoreSnapShot{ Level: tree.RESTORELEVELCLUSTER, @@ -13722,7 +14031,7 @@ yydefault: case 108: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1508 +//line mysql_sql.y:1517 { result := &tree.RestoreSnapShot{ Level: tree.RESTORELEVELACCOUNT, @@ -13740,7 +14049,7 @@ yydefault: case 109: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:1524 +//line mysql_sql.y:1533 { yyLOCAL = tree.IdentifierList{tree.Identifier(yyDollar[1].cstrUnion().Compare())} } @@ -13748,7 +14057,7 @@ yydefault: case 110: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:1528 +//line mysql_sql.y:1537 { yyLOCAL = tree.IdentifierList{ tree.Identifier(yyDollar[1].cstrUnion().Compare()), @@ -13759,7 +14068,7 @@ yydefault: case 111: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:1537 +//line mysql_sql.y:1546 { yyLOCAL = tree.IdentifierList{ tree.Identifier(yyDollar[1].cstrUnion().Compare()), @@ -13770,7 +14079,7 @@ yydefault: case 112: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:1544 +//line mysql_sql.y:1553 { yyLOCAL = tree.IdentifierList{ tree.Identifier(yyDollar[1].cstrUnion().Compare()), @@ -13781,32 +14090,32 @@ yydefault: yyVAL.union = yyLOCAL case 113: yyDollar = yyS[yypt-5 : yypt+1] -//line mysql_sql.y:1554 +//line mysql_sql.y:1563 { yyVAL.str = yyDollar[4].cstrUnion().Compare() } case 114: yyDollar = yyS[yypt-5 : yypt+1] -//line mysql_sql.y:1558 +//line mysql_sql.y:1567 { yyVAL.str = strings.ToLower(yyDollar[4].str) } case 115: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:1563 +//line mysql_sql.y:1572 { yyVAL.str = "" } case 116: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:1567 +//line mysql_sql.y:1576 { yyVAL.str = yyDollar[3].cstrUnion().Compare() } case 117: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1573 +//line mysql_sql.y:1582 { yyLOCAL = &tree.RestorePitr{ Level: tree.RESTORELEVELACCOUNT, @@ -13818,7 +14127,7 @@ yydefault: case 118: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1581 +//line mysql_sql.y:1590 { yyLOCAL = &tree.RestorePitr{ Level: tree.RESTORELEVELDATABASE, @@ -13831,7 +14140,7 @@ yydefault: case 119: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1590 +//line mysql_sql.y:1599 { yyLOCAL = &tree.RestorePitr{ Level: tree.RESTORELEVELDATABASE, @@ -13845,7 +14154,7 @@ yydefault: case 120: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1600 +//line mysql_sql.y:1609 { yyLOCAL = &tree.RestorePitr{ Level: tree.RESTORELEVELTABLE, @@ -13859,7 +14168,7 @@ yydefault: case 121: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1610 +//line mysql_sql.y:1619 { yyLOCAL = &tree.RestorePitr{ Level: tree.RESTORELEVELTABLE, @@ -13874,7 +14183,7 @@ yydefault: case 122: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1621 +//line mysql_sql.y:1630 { yyLOCAL = &tree.RestorePitr{ Level: tree.RESTORELEVELACCOUNT, @@ -13888,7 +14197,7 @@ yydefault: case 123: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1631 +//line mysql_sql.y:1640 { yyLOCAL = &tree.RestorePitr{ Level: tree.RESTORELEVELCLUSTER, @@ -13900,7 +14209,7 @@ yydefault: case 124: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1641 +//line mysql_sql.y:1650 { var connectionId uint64 switch v := yyDollar[3].item.(type) { @@ -13923,7 +14232,7 @@ yydefault: case 125: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.KillOption -//line mysql_sql.y:1661 +//line mysql_sql.y:1670 { yyLOCAL = tree.KillOption{ Exist: false, @@ -13933,7 +14242,7 @@ yydefault: case 126: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.KillOption -//line mysql_sql.y:1667 +//line mysql_sql.y:1676 { yyLOCAL = tree.KillOption{ Exist: true, @@ -13944,7 +14253,7 @@ yydefault: case 127: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.KillOption -//line mysql_sql.y:1674 +//line mysql_sql.y:1683 { yyLOCAL = tree.KillOption{ Exist: true, @@ -13955,7 +14264,7 @@ yydefault: case 128: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.StatementOption -//line mysql_sql.y:1682 +//line mysql_sql.y:1691 { yyLOCAL = tree.StatementOption{ Exist: false, @@ -13965,7 +14274,7 @@ yydefault: case 129: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.StatementOption -//line mysql_sql.y:1688 +//line mysql_sql.y:1697 { yyLOCAL = tree.StatementOption{ Exist: true, @@ -13976,7 +14285,7 @@ yydefault: case 130: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1697 +//line mysql_sql.y:1706 { yyLOCAL = &tree.CallStmt{ Name: yyDollar[2].procNameUnion(), @@ -13987,7 +14296,7 @@ yydefault: case 131: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1706 +//line mysql_sql.y:1715 { yyLOCAL = &tree.LeaveStmt{ Name: tree.Identifier(yyDollar[2].cstrUnion().Compare()), @@ -13997,7 +14306,7 @@ yydefault: case 132: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1714 +//line mysql_sql.y:1723 { yyLOCAL = &tree.IterateStmt{ Name: tree.Identifier(yyDollar[2].cstrUnion().Compare()), @@ -14007,7 +14316,7 @@ yydefault: case 133: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1722 +//line mysql_sql.y:1731 { yyLOCAL = &tree.WhileStmt{ Name: "", @@ -14019,7 +14328,7 @@ yydefault: case 134: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1730 +//line mysql_sql.y:1739 { yyLOCAL = &tree.WhileStmt{ Name: tree.Identifier(yyDollar[1].cstrUnion().Compare()), @@ -14031,7 +14340,7 @@ yydefault: case 135: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1740 +//line mysql_sql.y:1749 { yyLOCAL = &tree.RepeatStmt{ Name: "", @@ -14043,7 +14352,7 @@ yydefault: case 136: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1748 +//line mysql_sql.y:1757 { yyLOCAL = &tree.RepeatStmt{ Name: tree.Identifier(yyDollar[1].cstrUnion().Compare()), @@ -14055,7 +14364,7 @@ yydefault: case 137: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1758 +//line mysql_sql.y:1767 { yyLOCAL = &tree.LoopStmt{ Name: "", @@ -14066,7 +14375,7 @@ yydefault: case 138: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1765 +//line mysql_sql.y:1774 { yyLOCAL = &tree.LoopStmt{ Name: tree.Identifier(yyDollar[1].cstrUnion().Compare()), @@ -14077,7 +14386,7 @@ yydefault: case 139: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1774 +//line mysql_sql.y:1783 { yyLOCAL = &tree.IfStmt{ Cond: yyDollar[2].exprUnion(), @@ -14090,7 +14399,7 @@ yydefault: case 140: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*tree.ElseIfStmt -//line mysql_sql.y:1784 +//line mysql_sql.y:1793 { yyLOCAL = nil } @@ -14098,7 +14407,7 @@ yydefault: case 141: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.ElseIfStmt -//line mysql_sql.y:1788 +//line mysql_sql.y:1797 { yyLOCAL = yyDollar[1].elseIfClauseListUnion() } @@ -14106,7 +14415,7 @@ yydefault: case 142: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.ElseIfStmt -//line mysql_sql.y:1794 +//line mysql_sql.y:1803 { yyLOCAL = []*tree.ElseIfStmt{yyDollar[1].elseIfClauseUnion()} } @@ -14114,7 +14423,7 @@ yydefault: case 143: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []*tree.ElseIfStmt -//line mysql_sql.y:1798 +//line mysql_sql.y:1807 { yyLOCAL = append(yyDollar[1].elseIfClauseListUnion(), yyDollar[2].elseIfClauseUnion()) } @@ -14122,7 +14431,7 @@ yydefault: case 144: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.ElseIfStmt -//line mysql_sql.y:1804 +//line mysql_sql.y:1813 { yyLOCAL = &tree.ElseIfStmt{ Cond: yyDollar[2].exprUnion(), @@ -14133,7 +14442,7 @@ yydefault: case 145: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1813 +//line mysql_sql.y:1822 { yyLOCAL = &tree.CaseStmt{ Expr: yyDollar[2].exprUnion(), @@ -14145,7 +14454,7 @@ yydefault: case 146: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.WhenStmt -//line mysql_sql.y:1823 +//line mysql_sql.y:1832 { yyLOCAL = []*tree.WhenStmt{yyDollar[1].whenClause2Union()} } @@ -14153,7 +14462,7 @@ yydefault: case 147: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []*tree.WhenStmt -//line mysql_sql.y:1827 +//line mysql_sql.y:1836 { yyLOCAL = append(yyDollar[1].whenClauseList2Union(), yyDollar[2].whenClause2Union()) } @@ -14161,7 +14470,7 @@ yydefault: case 148: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.WhenStmt -//line mysql_sql.y:1833 +//line mysql_sql.y:1842 { yyLOCAL = &tree.WhenStmt{ Cond: yyDollar[2].exprUnion(), @@ -14172,7 +14481,7 @@ yydefault: case 149: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []tree.Statement -//line mysql_sql.y:1842 +//line mysql_sql.y:1851 { yyLOCAL = nil } @@ -14180,7 +14489,7 @@ yydefault: case 150: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []tree.Statement -//line mysql_sql.y:1846 +//line mysql_sql.y:1855 { yyLOCAL = yyDollar[2].statementsUnion() } @@ -14188,7 +14497,7 @@ yydefault: case 151: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1852 +//line mysql_sql.y:1861 { ep := &tree.ExportParam{ Outfile: true, @@ -14208,7 +14517,7 @@ yydefault: case 152: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1870 +//line mysql_sql.y:1879 { yyLOCAL = &tree.Load{ Local: yyDollar[3].boolValUnion(), @@ -14224,7 +14533,7 @@ yydefault: case 153: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:1884 +//line mysql_sql.y:1893 { yyLOCAL = &tree.LoadExtension{ Name: tree.Identifier(yyDollar[2].str), @@ -14234,7 +14543,7 @@ yydefault: case 154: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.UpdateExprs -//line mysql_sql.y:1891 +//line mysql_sql.y:1900 { yyLOCAL = nil } @@ -14242,7 +14551,7 @@ yydefault: case 155: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.UpdateExprs -//line mysql_sql.y:1895 +//line mysql_sql.y:1904 { yyLOCAL = yyDollar[2].updateExprsUnion() } @@ -14250,7 +14559,7 @@ yydefault: case 156: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.UpdateExprs -//line mysql_sql.y:1901 +//line mysql_sql.y:1910 { yyLOCAL = tree.UpdateExprs{yyDollar[1].updateExprUnion()} } @@ -14258,7 +14567,7 @@ yydefault: case 157: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.UpdateExprs -//line mysql_sql.y:1905 +//line mysql_sql.y:1914 { yyLOCAL = append(yyDollar[1].updateExprsUnion(), yyDollar[3].updateExprUnion()) } @@ -14266,7 +14575,7 @@ yydefault: case 158: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.UpdateExpr -//line mysql_sql.y:1911 +//line mysql_sql.y:1920 { yyLOCAL = &tree.UpdateExpr{ Names: []*tree.UnresolvedName{yyDollar[1].unresolvedNameUnion()}, @@ -14277,7 +14586,7 @@ yydefault: case 159: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.UpdateExpr -//line mysql_sql.y:1918 +//line mysql_sql.y:1927 { yyLOCAL = &tree.UpdateExpr{ Names: []*tree.UnresolvedName{yyDollar[1].unresolvedNameUnion()}, @@ -14288,7 +14597,7 @@ yydefault: case 160: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:1926 +//line mysql_sql.y:1935 { yyLOCAL = false } @@ -14296,7 +14605,7 @@ yydefault: case 161: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:1930 +//line mysql_sql.y:1939 { str := strings.ToLower(yyDollar[2].str) if str == "true" { @@ -14312,7 +14621,7 @@ yydefault: case 162: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:1942 +//line mysql_sql.y:1951 { yyLOCAL = true } @@ -14320,7 +14629,7 @@ yydefault: case 163: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:1946 +//line mysql_sql.y:1955 { str := strings.ToLower(yyDollar[2].str) if str == "true" { @@ -14336,7 +14645,7 @@ yydefault: case 164: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.UnresolvedName -//line mysql_sql.y:1960 +//line mysql_sql.y:1969 { yyLOCAL = tree.NewUnresolvedName(yyDollar[1].cstrUnion()) } @@ -14344,7 +14653,7 @@ yydefault: case 165: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.UnresolvedName -//line mysql_sql.y:1964 +//line mysql_sql.y:1973 { tblNameCStr := yylex.(*Lexer).GetDbOrTblNameCStr(yyDollar[1].cstrUnion().Origin()) yyLOCAL = tree.NewUnresolvedName(tblNameCStr, yyDollar[3].cstrUnion()) @@ -14353,7 +14662,7 @@ yydefault: case 166: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.UnresolvedName -//line mysql_sql.y:1969 +//line mysql_sql.y:1978 { dbNameCStr := yylex.(*Lexer).GetDbOrTblNameCStr(yyDollar[1].cstrUnion().Origin()) tblNameCStr := yylex.(*Lexer).GetDbOrTblNameCStr(yyDollar[3].cstrUnion().Origin()) @@ -14363,7 +14672,7 @@ yydefault: case 167: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []tree.LoadColumn -//line mysql_sql.y:1976 +//line mysql_sql.y:1985 { yyLOCAL = nil } @@ -14371,7 +14680,7 @@ yydefault: case 168: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []tree.LoadColumn -//line mysql_sql.y:1980 +//line mysql_sql.y:1989 { yyLOCAL = nil } @@ -14379,7 +14688,7 @@ yydefault: case 169: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []tree.LoadColumn -//line mysql_sql.y:1984 +//line mysql_sql.y:1993 { yyLOCAL = yyDollar[2].loadColumnsUnion() } @@ -14387,7 +14696,7 @@ yydefault: case 170: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []tree.LoadColumn -//line mysql_sql.y:1990 +//line mysql_sql.y:1999 { switch yyDollar[1].loadColumnUnion().(type) { case *tree.UnresolvedName: @@ -14400,7 +14709,7 @@ yydefault: case 171: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []tree.LoadColumn -//line mysql_sql.y:1999 +//line mysql_sql.y:2008 { switch yyDollar[3].loadColumnUnion().(type) { case *tree.UnresolvedName: @@ -14413,7 +14722,7 @@ yydefault: case 172: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.LoadColumn -//line mysql_sql.y:2010 +//line mysql_sql.y:2019 { yyLOCAL = yyDollar[1].unresolvedNameUnion() } @@ -14421,7 +14730,7 @@ yydefault: case 173: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.LoadColumn -//line mysql_sql.y:2014 +//line mysql_sql.y:2023 { yyLOCAL = yyDollar[1].varExprUnion() } @@ -14429,7 +14738,7 @@ yydefault: case 174: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.VarExpr -//line mysql_sql.y:2020 +//line mysql_sql.y:2029 { yyLOCAL = []*tree.VarExpr{yyDollar[1].varExprUnion()} } @@ -14437,7 +14746,7 @@ yydefault: case 175: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.VarExpr -//line mysql_sql.y:2024 +//line mysql_sql.y:2033 { yyLOCAL = append(yyDollar[1].varExprsUnion(), yyDollar[3].varExprUnion()) } @@ -14445,7 +14754,7 @@ yydefault: case 176: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.VarExpr -//line mysql_sql.y:2030 +//line mysql_sql.y:2039 { yyLOCAL = yyDollar[1].varExprUnion() } @@ -14453,7 +14762,7 @@ yydefault: case 177: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.VarExpr -//line mysql_sql.y:2034 +//line mysql_sql.y:2043 { yyLOCAL = yyDollar[1].varExprUnion() } @@ -14461,7 +14770,7 @@ yydefault: case 178: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.VarExpr -//line mysql_sql.y:2040 +//line mysql_sql.y:2049 { v := strings.ToLower(yyDollar[1].str) var isGlobal bool @@ -14483,7 +14792,7 @@ yydefault: case 179: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.VarExpr -//line mysql_sql.y:2060 +//line mysql_sql.y:2069 { // vs := strings.Split($1, ".") // var r string @@ -14505,7 +14814,7 @@ yydefault: case 180: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:2079 +//line mysql_sql.y:2088 { yyLOCAL = 0 } @@ -14513,7 +14822,7 @@ yydefault: case 181: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:2083 +//line mysql_sql.y:2092 { yyLOCAL = yyDollar[2].item.(int64) } @@ -14521,7 +14830,7 @@ yydefault: case 182: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:2087 +//line mysql_sql.y:2096 { yyLOCAL = yyDollar[2].item.(int64) } @@ -14529,7 +14838,7 @@ yydefault: case 183: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.Lines -//line mysql_sql.y:2092 +//line mysql_sql.y:2101 { yyLOCAL = nil } @@ -14537,7 +14846,7 @@ yydefault: case 184: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.Lines -//line mysql_sql.y:2096 +//line mysql_sql.y:2105 { yyLOCAL = &tree.Lines{ StartingBy: yyDollar[2].str, @@ -14550,7 +14859,7 @@ yydefault: case 185: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.Lines -//line mysql_sql.y:2105 +//line mysql_sql.y:2114 { yyLOCAL = &tree.Lines{ StartingBy: yyDollar[3].str, @@ -14562,32 +14871,32 @@ yydefault: yyVAL.union = yyLOCAL case 186: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:2115 +//line mysql_sql.y:2124 { yyVAL.str = "" } case 188: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:2122 +//line mysql_sql.y:2131 { yyVAL.str = yyDollar[3].str } case 189: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:2127 +//line mysql_sql.y:2136 { yyVAL.str = "\n" } case 191: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:2134 +//line mysql_sql.y:2143 { yyVAL.str = yyDollar[3].str } case 192: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.Fields -//line mysql_sql.y:2139 +//line mysql_sql.y:2148 { yyLOCAL = nil } @@ -14595,7 +14904,7 @@ yydefault: case 193: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.Fields -//line mysql_sql.y:2143 +//line mysql_sql.y:2152 { res := &tree.Fields{ Terminated: &tree.Terminated{ @@ -14625,7 +14934,7 @@ yydefault: case 194: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.Fields -//line mysql_sql.y:2171 +//line mysql_sql.y:2180 { yyLOCAL = []*tree.Fields{yyDollar[1].fieldsUnion()} } @@ -14633,7 +14942,7 @@ yydefault: case 195: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []*tree.Fields -//line mysql_sql.y:2175 +//line mysql_sql.y:2184 { yyLOCAL = append(yyDollar[1].fieldsListUnion(), yyDollar[2].fieldsUnion()) } @@ -14641,7 +14950,7 @@ yydefault: case 196: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.Fields -//line mysql_sql.y:2181 +//line mysql_sql.y:2190 { yyLOCAL = &tree.Fields{ Terminated: &tree.Terminated{ @@ -14653,7 +14962,7 @@ yydefault: case 197: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Fields -//line mysql_sql.y:2189 +//line mysql_sql.y:2198 { str := yyDollar[4].str if str != "\\" && len(str) > 1 { @@ -14677,7 +14986,7 @@ yydefault: case 198: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.Fields -//line mysql_sql.y:2209 +//line mysql_sql.y:2218 { str := yyDollar[3].str if str != "\\" && len(str) > 1 { @@ -14700,7 +15009,7 @@ yydefault: case 199: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.Fields -//line mysql_sql.y:2228 +//line mysql_sql.y:2237 { str := yyDollar[3].str if str != "\\" && len(str) > 1 { @@ -14723,7 +15032,7 @@ yydefault: case 201: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.DuplicateKey -//line mysql_sql.y:2253 +//line mysql_sql.y:2262 { yyLOCAL = &tree.DuplicateKeyError{} } @@ -14731,7 +15040,7 @@ yydefault: case 202: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.DuplicateKey -//line mysql_sql.y:2257 +//line mysql_sql.y:2266 { yyLOCAL = &tree.DuplicateKeyIgnore{} } @@ -14739,7 +15048,7 @@ yydefault: case 203: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.DuplicateKey -//line mysql_sql.y:2261 +//line mysql_sql.y:2270 { yyLOCAL = &tree.DuplicateKeyReplace{} } @@ -14747,7 +15056,7 @@ yydefault: case 204: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:2266 +//line mysql_sql.y:2275 { yyLOCAL = false } @@ -14755,7 +15064,7 @@ yydefault: case 205: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:2270 +//line mysql_sql.y:2279 { yyLOCAL = true } @@ -14763,7 +15072,7 @@ yydefault: case 206: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2276 +//line mysql_sql.y:2285 { yyLOCAL = &tree.Grant{ Typ: tree.GrantTypePrivilege, @@ -14780,7 +15089,7 @@ yydefault: case 207: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2289 +//line mysql_sql.y:2298 { yyLOCAL = &tree.Grant{ Typ: tree.GrantTypeRole, @@ -14795,7 +15104,7 @@ yydefault: case 208: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2300 +//line mysql_sql.y:2309 { yyLOCAL = &tree.Grant{ Typ: tree.GrantTypeProxy, @@ -14811,7 +15120,7 @@ yydefault: case 209: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:2313 +//line mysql_sql.y:2322 { yyLOCAL = false } @@ -14819,7 +15128,7 @@ yydefault: case 210: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:2317 +//line mysql_sql.y:2326 { yyLOCAL = true } @@ -14827,7 +15136,7 @@ yydefault: case 211: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2327 +//line mysql_sql.y:2336 { yyLOCAL = &tree.Revoke{ Typ: tree.RevokeTypePrivilege, @@ -14844,7 +15153,7 @@ yydefault: case 212: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2340 +//line mysql_sql.y:2349 { yyLOCAL = &tree.Revoke{ Typ: tree.RevokeTypeRole, @@ -14859,7 +15168,7 @@ yydefault: case 213: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.PrivilegeLevel -//line mysql_sql.y:2353 +//line mysql_sql.y:2362 { yyLOCAL = &tree.PrivilegeLevel{ Level: tree.PRIVILEGE_LEVEL_TYPE_STAR, @@ -14869,7 +15178,7 @@ yydefault: case 214: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.PrivilegeLevel -//line mysql_sql.y:2359 +//line mysql_sql.y:2368 { yyLOCAL = &tree.PrivilegeLevel{ Level: tree.PRIVILEGE_LEVEL_TYPE_STAR_STAR, @@ -14879,7 +15188,7 @@ yydefault: case 215: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.PrivilegeLevel -//line mysql_sql.y:2365 +//line mysql_sql.y:2374 { tblName := yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) yyLOCAL = &tree.PrivilegeLevel{ @@ -14891,7 +15200,7 @@ yydefault: case 216: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.PrivilegeLevel -//line mysql_sql.y:2373 +//line mysql_sql.y:2382 { dbName := yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) tblName := yylex.(*Lexer).GetDbOrTblName(yyDollar[3].cstrUnion().Origin()) @@ -14905,7 +15214,7 @@ yydefault: case 217: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.PrivilegeLevel -//line mysql_sql.y:2383 +//line mysql_sql.y:2392 { tblName := yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) yyLOCAL = &tree.PrivilegeLevel{ @@ -14917,7 +15226,7 @@ yydefault: case 218: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ObjectType -//line mysql_sql.y:2393 +//line mysql_sql.y:2402 { yyLOCAL = tree.OBJECT_TYPE_TABLE } @@ -14925,7 +15234,7 @@ yydefault: case 219: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ObjectType -//line mysql_sql.y:2397 +//line mysql_sql.y:2406 { yyLOCAL = tree.OBJECT_TYPE_DATABASE } @@ -14933,7 +15242,7 @@ yydefault: case 220: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ObjectType -//line mysql_sql.y:2401 +//line mysql_sql.y:2410 { yyLOCAL = tree.OBJECT_TYPE_FUNCTION } @@ -14941,7 +15250,7 @@ yydefault: case 221: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ObjectType -//line mysql_sql.y:2405 +//line mysql_sql.y:2414 { yyLOCAL = tree.OBJECT_TYPE_PROCEDURE } @@ -14949,7 +15258,7 @@ yydefault: case 222: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ObjectType -//line mysql_sql.y:2409 +//line mysql_sql.y:2418 { yyLOCAL = tree.OBJECT_TYPE_VIEW } @@ -14957,7 +15266,7 @@ yydefault: case 223: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ObjectType -//line mysql_sql.y:2413 +//line mysql_sql.y:2422 { yyLOCAL = tree.OBJECT_TYPE_ACCOUNT } @@ -14965,7 +15274,7 @@ yydefault: case 224: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.Privilege -//line mysql_sql.y:2419 +//line mysql_sql.y:2428 { yyLOCAL = []*tree.Privilege{yyDollar[1].privilegeUnion()} } @@ -14973,7 +15282,7 @@ yydefault: case 225: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.Privilege -//line mysql_sql.y:2423 +//line mysql_sql.y:2432 { yyLOCAL = append(yyDollar[1].privilegesUnion(), yyDollar[3].privilegeUnion()) } @@ -14981,7 +15290,7 @@ yydefault: case 226: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.Privilege -//line mysql_sql.y:2429 +//line mysql_sql.y:2438 { yyLOCAL = &tree.Privilege{ Type: yyDollar[1].privilegeTypeUnion(), @@ -14992,7 +15301,7 @@ yydefault: case 227: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Privilege -//line mysql_sql.y:2436 +//line mysql_sql.y:2445 { yyLOCAL = &tree.Privilege{ Type: yyDollar[1].privilegeTypeUnion(), @@ -15003,7 +15312,7 @@ yydefault: case 228: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.UnresolvedName -//line mysql_sql.y:2445 +//line mysql_sql.y:2454 { yyLOCAL = []*tree.UnresolvedName{yyDollar[1].unresolvedNameUnion()} } @@ -15011,7 +15320,7 @@ yydefault: case 229: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.UnresolvedName -//line mysql_sql.y:2449 +//line mysql_sql.y:2458 { yyLOCAL = append(yyDollar[1].unresolveNamesUnion(), yyDollar[3].unresolvedNameUnion()) } @@ -15019,7 +15328,7 @@ yydefault: case 230: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2455 +//line mysql_sql.y:2464 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_ALL } @@ -15027,7 +15336,7 @@ yydefault: case 231: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2459 +//line mysql_sql.y:2468 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_CREATE_ACCOUNT } @@ -15035,7 +15344,7 @@ yydefault: case 232: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2463 +//line mysql_sql.y:2472 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_DROP_ACCOUNT } @@ -15043,7 +15352,7 @@ yydefault: case 233: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2467 +//line mysql_sql.y:2476 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_ALTER_ACCOUNT } @@ -15051,7 +15360,7 @@ yydefault: case 234: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2471 +//line mysql_sql.y:2480 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_UPGRADE_ACCOUNT } @@ -15059,7 +15368,7 @@ yydefault: case 235: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2475 +//line mysql_sql.y:2484 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_ALL } @@ -15067,7 +15376,7 @@ yydefault: case 236: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2479 +//line mysql_sql.y:2488 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_ALTER_TABLE } @@ -15075,7 +15384,7 @@ yydefault: case 237: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2483 +//line mysql_sql.y:2492 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_ALTER_VIEW } @@ -15083,7 +15392,7 @@ yydefault: case 238: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2487 +//line mysql_sql.y:2496 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_CREATE } @@ -15091,7 +15400,7 @@ yydefault: case 239: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2491 +//line mysql_sql.y:2500 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_CREATE_USER } @@ -15099,7 +15408,7 @@ yydefault: case 240: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2495 +//line mysql_sql.y:2504 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_DROP_USER } @@ -15107,7 +15416,7 @@ yydefault: case 241: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2499 +//line mysql_sql.y:2508 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_ALTER_USER } @@ -15115,7 +15424,7 @@ yydefault: case 242: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2503 +//line mysql_sql.y:2512 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_CREATE_TABLESPACE } @@ -15123,7 +15432,7 @@ yydefault: case 243: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2507 +//line mysql_sql.y:2516 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_TRIGGER } @@ -15131,7 +15440,7 @@ yydefault: case 244: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2511 +//line mysql_sql.y:2520 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_DELETE } @@ -15139,7 +15448,7 @@ yydefault: case 245: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2515 +//line mysql_sql.y:2524 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_DROP_TABLE } @@ -15147,7 +15456,7 @@ yydefault: case 246: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2519 +//line mysql_sql.y:2528 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_DROP_VIEW } @@ -15155,7 +15464,7 @@ yydefault: case 247: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2523 +//line mysql_sql.y:2532 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_EXECUTE } @@ -15163,7 +15472,7 @@ yydefault: case 248: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2527 +//line mysql_sql.y:2536 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_INDEX } @@ -15171,7 +15480,7 @@ yydefault: case 249: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2531 +//line mysql_sql.y:2540 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_INSERT } @@ -15179,7 +15488,7 @@ yydefault: case 250: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2535 +//line mysql_sql.y:2544 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_SELECT } @@ -15187,7 +15496,7 @@ yydefault: case 251: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2539 +//line mysql_sql.y:2548 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_SUPER } @@ -15195,7 +15504,7 @@ yydefault: case 252: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2543 +//line mysql_sql.y:2552 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_CREATE_DATABASE } @@ -15203,7 +15512,7 @@ yydefault: case 253: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2547 +//line mysql_sql.y:2556 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_DROP_DATABASE } @@ -15211,7 +15520,7 @@ yydefault: case 254: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2551 +//line mysql_sql.y:2560 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_SHOW_DATABASES } @@ -15219,7 +15528,7 @@ yydefault: case 255: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2555 +//line mysql_sql.y:2564 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_CONNECT } @@ -15227,7 +15536,7 @@ yydefault: case 256: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2559 +//line mysql_sql.y:2568 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_MANAGE_GRANTS } @@ -15235,7 +15544,7 @@ yydefault: case 257: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2563 +//line mysql_sql.y:2572 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_OWNERSHIP } @@ -15243,7 +15552,7 @@ yydefault: case 258: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2567 +//line mysql_sql.y:2576 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_SHOW_TABLES } @@ -15251,7 +15560,7 @@ yydefault: case 259: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2571 +//line mysql_sql.y:2580 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_CREATE_TABLE } @@ -15259,7 +15568,7 @@ yydefault: case 260: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2575 +//line mysql_sql.y:2584 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_UPDATE } @@ -15267,7 +15576,7 @@ yydefault: case 261: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2579 +//line mysql_sql.y:2588 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_GRANT_OPTION } @@ -15275,7 +15584,7 @@ yydefault: case 262: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2583 +//line mysql_sql.y:2592 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_REFERENCES } @@ -15283,7 +15592,7 @@ yydefault: case 263: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2587 +//line mysql_sql.y:2596 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_REFERENCE } @@ -15291,7 +15600,7 @@ yydefault: case 264: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2591 +//line mysql_sql.y:2600 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_REPLICATION_SLAVE } @@ -15299,7 +15608,7 @@ yydefault: case 265: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2595 +//line mysql_sql.y:2604 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_REPLICATION_CLIENT } @@ -15307,7 +15616,7 @@ yydefault: case 266: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2599 +//line mysql_sql.y:2608 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_USAGE } @@ -15315,7 +15624,7 @@ yydefault: case 267: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2603 +//line mysql_sql.y:2612 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_RELOAD } @@ -15323,7 +15632,7 @@ yydefault: case 268: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2607 +//line mysql_sql.y:2616 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_FILE } @@ -15331,7 +15640,7 @@ yydefault: case 269: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2611 +//line mysql_sql.y:2620 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_CREATE_TEMPORARY_TABLES } @@ -15339,7 +15648,7 @@ yydefault: case 270: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2615 +//line mysql_sql.y:2624 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_LOCK_TABLES } @@ -15347,7 +15656,7 @@ yydefault: case 271: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2619 +//line mysql_sql.y:2628 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_CREATE_VIEW } @@ -15355,7 +15664,7 @@ yydefault: case 272: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2623 +//line mysql_sql.y:2632 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_SHOW_VIEW } @@ -15363,7 +15672,7 @@ yydefault: case 273: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2627 +//line mysql_sql.y:2636 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_CREATE_ROLE } @@ -15371,7 +15680,7 @@ yydefault: case 274: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2631 +//line mysql_sql.y:2640 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_DROP_ROLE } @@ -15379,7 +15688,7 @@ yydefault: case 275: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2635 +//line mysql_sql.y:2644 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_ALTER_ROLE } @@ -15387,7 +15696,7 @@ yydefault: case 276: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2639 +//line mysql_sql.y:2648 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_CREATE_ROUTINE } @@ -15395,7 +15704,7 @@ yydefault: case 277: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2643 +//line mysql_sql.y:2652 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_ALTER_ROUTINE } @@ -15403,7 +15712,7 @@ yydefault: case 278: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2647 +//line mysql_sql.y:2656 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_EVENT } @@ -15411,7 +15720,7 @@ yydefault: case 279: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2651 +//line mysql_sql.y:2660 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_SHUTDOWN } @@ -15419,7 +15728,7 @@ yydefault: case 280: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.PrivilegeType -//line mysql_sql.y:2655 +//line mysql_sql.y:2664 { yyLOCAL = tree.PRIVILEGE_TYPE_STATIC_TRUNCATE } @@ -15427,7 +15736,7 @@ yydefault: case 288: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2670 +//line mysql_sql.y:2679 { yyLOCAL = &tree.SetLogserviceSettings{ Name: yyDollar[4].str, @@ -15438,7 +15747,7 @@ yydefault: case 289: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2679 +//line mysql_sql.y:2688 { yyLOCAL = &tree.SetTransaction{ Global: false, @@ -15449,7 +15758,7 @@ yydefault: case 290: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2686 +//line mysql_sql.y:2695 { yyLOCAL = &tree.SetTransaction{ Global: true, @@ -15460,7 +15769,7 @@ yydefault: case 291: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2693 +//line mysql_sql.y:2702 { yyLOCAL = &tree.SetTransaction{ Global: false, @@ -15471,7 +15780,7 @@ yydefault: case 292: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2702 +//line mysql_sql.y:2711 { var connID uint32 switch v := yyDollar[5].item.(type) { @@ -15491,7 +15800,7 @@ yydefault: case 293: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.TransactionCharacteristic -//line mysql_sql.y:2720 +//line mysql_sql.y:2729 { yyLOCAL = []*tree.TransactionCharacteristic{yyDollar[1].transactionCharacteristicUnion()} } @@ -15499,7 +15808,7 @@ yydefault: case 294: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.TransactionCharacteristic -//line mysql_sql.y:2724 +//line mysql_sql.y:2733 { yyLOCAL = append(yyDollar[1].transactionCharacteristicListUnion(), yyDollar[3].transactionCharacteristicUnion()) } @@ -15507,7 +15816,7 @@ yydefault: case 295: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.TransactionCharacteristic -//line mysql_sql.y:2730 +//line mysql_sql.y:2739 { yyLOCAL = &tree.TransactionCharacteristic{ IsLevel: true, @@ -15518,7 +15827,7 @@ yydefault: case 296: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.TransactionCharacteristic -//line mysql_sql.y:2737 +//line mysql_sql.y:2746 { yyLOCAL = &tree.TransactionCharacteristic{ Access: yyDollar[1].accessModeUnion(), @@ -15528,7 +15837,7 @@ yydefault: case 297: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IsolationLevelType -//line mysql_sql.y:2745 +//line mysql_sql.y:2754 { yyLOCAL = tree.ISOLATION_LEVEL_REPEATABLE_READ } @@ -15536,7 +15845,7 @@ yydefault: case 298: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IsolationLevelType -//line mysql_sql.y:2749 +//line mysql_sql.y:2758 { yyLOCAL = tree.ISOLATION_LEVEL_READ_COMMITTED } @@ -15544,7 +15853,7 @@ yydefault: case 299: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IsolationLevelType -//line mysql_sql.y:2753 +//line mysql_sql.y:2762 { yyLOCAL = tree.ISOLATION_LEVEL_READ_UNCOMMITTED } @@ -15552,7 +15861,7 @@ yydefault: case 300: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.IsolationLevelType -//line mysql_sql.y:2757 +//line mysql_sql.y:2766 { yyLOCAL = tree.ISOLATION_LEVEL_SERIALIZABLE } @@ -15560,7 +15869,7 @@ yydefault: case 301: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AccessModeType -//line mysql_sql.y:2763 +//line mysql_sql.y:2772 { yyLOCAL = tree.ACCESS_MODE_READ_WRITE } @@ -15568,7 +15877,7 @@ yydefault: case 302: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AccessModeType -//line mysql_sql.y:2767 +//line mysql_sql.y:2776 { yyLOCAL = tree.ACCESS_MODE_READ_ONLY } @@ -15576,7 +15885,7 @@ yydefault: case 303: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2773 +//line mysql_sql.y:2782 { yyLOCAL = &tree.SetRole{ SecondaryRole: false, @@ -15587,7 +15896,7 @@ yydefault: case 304: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2780 +//line mysql_sql.y:2789 { yyLOCAL = &tree.SetRole{ SecondaryRole: true, @@ -15598,7 +15907,7 @@ yydefault: case 305: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2787 +//line mysql_sql.y:2796 { yyLOCAL = &tree.SetRole{ SecondaryRole: true, @@ -15609,7 +15918,7 @@ yydefault: case 306: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2796 +//line mysql_sql.y:2805 { dr := yyDollar[4].setDefaultRoleUnion() dr.Users = yyDollar[6].usersUnion() @@ -15619,7 +15928,7 @@ yydefault: case 307: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.SetDefaultRole -//line mysql_sql.y:2826 +//line mysql_sql.y:2835 { yyLOCAL = &tree.SetDefaultRole{Type: tree.SET_DEFAULT_ROLE_TYPE_NONE, Roles: nil} } @@ -15627,7 +15936,7 @@ yydefault: case 308: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.SetDefaultRole -//line mysql_sql.y:2830 +//line mysql_sql.y:2839 { yyLOCAL = &tree.SetDefaultRole{Type: tree.SET_DEFAULT_ROLE_TYPE_ALL, Roles: nil} } @@ -15635,7 +15944,7 @@ yydefault: case 309: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.SetDefaultRole -//line mysql_sql.y:2834 +//line mysql_sql.y:2843 { yyLOCAL = &tree.SetDefaultRole{Type: tree.SET_DEFAULT_ROLE_TYPE_NORMAL, Roles: yyDollar[1].rolesUnion()} } @@ -15643,7 +15952,7 @@ yydefault: case 310: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2840 +//line mysql_sql.y:2849 { yyLOCAL = &tree.SetVar{Assignments: yyDollar[2].varAssignmentExprsUnion()} } @@ -15651,7 +15960,7 @@ yydefault: case 311: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2846 +//line mysql_sql.y:2855 { yyLOCAL = &tree.SetPassword{Password: yyDollar[4].str} } @@ -15659,21 +15968,21 @@ yydefault: case 312: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:2850 +//line mysql_sql.y:2859 { yyLOCAL = &tree.SetPassword{User: yyDollar[4].userUnion(), Password: yyDollar[6].str} } yyVAL.union = yyLOCAL case 314: yyDollar = yyS[yypt-4 : yypt+1] -//line mysql_sql.y:2857 +//line mysql_sql.y:2866 { yyVAL.str = yyDollar[3].str } case 315: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.VarAssignmentExpr -//line mysql_sql.y:2863 +//line mysql_sql.y:2872 { yyLOCAL = []*tree.VarAssignmentExpr{yyDollar[1].varAssignmentExprUnion()} } @@ -15681,7 +15990,7 @@ yydefault: case 316: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.VarAssignmentExpr -//line mysql_sql.y:2867 +//line mysql_sql.y:2876 { yyLOCAL = append(yyDollar[1].varAssignmentExprsUnion(), yyDollar[3].varAssignmentExprUnion()) } @@ -15689,7 +15998,7 @@ yydefault: case 317: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.VarAssignmentExpr -//line mysql_sql.y:2873 +//line mysql_sql.y:2882 { yyLOCAL = &tree.VarAssignmentExpr{ System: true, @@ -15701,7 +16010,7 @@ yydefault: case 318: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.VarAssignmentExpr -//line mysql_sql.y:2881 +//line mysql_sql.y:2890 { yyLOCAL = &tree.VarAssignmentExpr{ System: true, @@ -15714,7 +16023,7 @@ yydefault: case 319: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.VarAssignmentExpr -//line mysql_sql.y:2890 +//line mysql_sql.y:2899 { yyLOCAL = &tree.VarAssignmentExpr{ System: true, @@ -15727,7 +16036,7 @@ yydefault: case 320: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.VarAssignmentExpr -//line mysql_sql.y:2899 +//line mysql_sql.y:2908 { yyLOCAL = &tree.VarAssignmentExpr{ System: true, @@ -15739,7 +16048,7 @@ yydefault: case 321: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.VarAssignmentExpr -//line mysql_sql.y:2907 +//line mysql_sql.y:2916 { yyLOCAL = &tree.VarAssignmentExpr{ System: true, @@ -15751,7 +16060,7 @@ yydefault: case 322: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.VarAssignmentExpr -//line mysql_sql.y:2915 +//line mysql_sql.y:2924 { vs := strings.Split(yyDollar[1].str, ".") var isGlobal bool @@ -15778,7 +16087,7 @@ yydefault: case 323: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.VarAssignmentExpr -//line mysql_sql.y:2938 +//line mysql_sql.y:2947 { v := strings.ToLower(yyDollar[1].str) var isGlobal bool @@ -15801,7 +16110,7 @@ yydefault: case 324: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.VarAssignmentExpr -//line mysql_sql.y:2957 +//line mysql_sql.y:2966 { yyLOCAL = &tree.VarAssignmentExpr{ Name: strings.ToLower(yyDollar[1].str), @@ -15812,7 +16121,7 @@ yydefault: case 325: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.VarAssignmentExpr -//line mysql_sql.y:2964 +//line mysql_sql.y:2973 { yyLOCAL = &tree.VarAssignmentExpr{ Name: strings.ToLower(yyDollar[1].str), @@ -15823,7 +16132,7 @@ yydefault: case 326: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.VarAssignmentExpr -//line mysql_sql.y:2971 +//line mysql_sql.y:2980 { yyLOCAL = &tree.VarAssignmentExpr{ Name: strings.ToLower(yyDollar[1].str), @@ -15835,7 +16144,7 @@ yydefault: case 327: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.VarAssignmentExpr -//line mysql_sql.y:2979 +//line mysql_sql.y:2988 { yyLOCAL = &tree.VarAssignmentExpr{ Name: strings.ToLower(yyDollar[1].str), @@ -15846,7 +16155,7 @@ yydefault: case 328: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.VarAssignmentExpr -//line mysql_sql.y:2986 +//line mysql_sql.y:2995 { yyLOCAL = &tree.VarAssignmentExpr{ Name: strings.ToLower(yyDollar[1].str), @@ -15857,7 +16166,7 @@ yydefault: case 329: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.VarAssignmentExpr -//line mysql_sql.y:2993 +//line mysql_sql.y:3002 { yyLOCAL = &tree.VarAssignmentExpr{ Name: strings.ToLower(yyDollar[1].str), @@ -15868,7 +16177,7 @@ yydefault: case 330: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:3002 +//line mysql_sql.y:3011 { yyLOCAL = tree.NewNumVal(yyDollar[1].str, yyDollar[1].str, false, tree.P_char) } @@ -15876,7 +16185,7 @@ yydefault: case 331: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:3006 +//line mysql_sql.y:3015 { yyLOCAL = tree.NewNumVal(yyDollar[1].str, yyDollar[1].str, false, tree.P_char) } @@ -15884,39 +16193,39 @@ yydefault: case 332: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:3010 +//line mysql_sql.y:3019 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL case 333: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:3016 +//line mysql_sql.y:3025 { yyVAL.str = string(yyDollar[1].str) } case 334: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:3020 +//line mysql_sql.y:3029 { yyVAL.str = yyDollar[1].str } case 335: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:3026 +//line mysql_sql.y:3035 { yyVAL.str = yyDollar[1].cstrUnion().Compare() } case 336: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:3030 +//line mysql_sql.y:3039 { yyVAL.str = yyDollar[1].cstrUnion().Compare() + "." + yyDollar[3].cstrUnion().Compare() } case 337: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:3036 +//line mysql_sql.y:3045 { yyLOCAL = []string{yyDollar[1].str} } @@ -15924,7 +16233,7 @@ yydefault: case 338: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:3040 +//line mysql_sql.y:3049 { yyLOCAL = append(yyDollar[1].strsUnion(), yyDollar[3].str) } @@ -15932,7 +16241,7 @@ yydefault: case 345: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3054 +//line mysql_sql.y:3063 { yyLOCAL = &tree.SavePoint{Name: tree.Identifier(yyDollar[2].cstrUnion().Compare())} } @@ -15940,7 +16249,7 @@ yydefault: case 346: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3060 +//line mysql_sql.y:3069 { yyLOCAL = &tree.ReleaseSavePoint{Name: tree.Identifier(yyDollar[3].cstrUnion().Compare())} } @@ -15948,7 +16257,7 @@ yydefault: case 347: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3066 +//line mysql_sql.y:3075 { yyLOCAL = &tree.RollbackToSavePoint{Name: tree.Identifier(yyDollar[3].cstrUnion().Compare())} } @@ -15956,7 +16265,7 @@ yydefault: case 348: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3071 +//line mysql_sql.y:3080 { yyLOCAL = &tree.RollbackToSavePoint{Name: tree.Identifier(yyDollar[4].cstrUnion().Compare())} } @@ -15964,7 +16273,7 @@ yydefault: case 349: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3076 +//line mysql_sql.y:3085 { yyLOCAL = &tree.RollbackToSavePoint{Name: tree.Identifier(yyDollar[5].cstrUnion().Compare())} } @@ -15972,7 +16281,7 @@ yydefault: case 350: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3081 +//line mysql_sql.y:3090 { yyLOCAL = &tree.RollbackToSavePoint{Name: tree.Identifier(yyDollar[4].cstrUnion().Compare())} } @@ -15980,7 +16289,7 @@ yydefault: case 351: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3087 +//line mysql_sql.y:3096 { yyLOCAL = &tree.RollbackTransaction{Type: yyDollar[2].completionTypeUnion()} } @@ -15988,7 +16297,7 @@ yydefault: case 352: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3093 +//line mysql_sql.y:3102 { yyLOCAL = &tree.CommitTransaction{Type: yyDollar[2].completionTypeUnion()} } @@ -15996,7 +16305,7 @@ yydefault: case 353: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.CompletionType -//line mysql_sql.y:3098 +//line mysql_sql.y:3107 { yyLOCAL = tree.COMPLETION_TYPE_NO_CHAIN } @@ -16004,7 +16313,7 @@ yydefault: case 354: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.CompletionType -//line mysql_sql.y:3102 +//line mysql_sql.y:3111 { yyLOCAL = tree.COMPLETION_TYPE_NO_CHAIN } @@ -16012,7 +16321,7 @@ yydefault: case 355: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.CompletionType -//line mysql_sql.y:3106 +//line mysql_sql.y:3115 { yyLOCAL = tree.COMPLETION_TYPE_CHAIN } @@ -16020,7 +16329,7 @@ yydefault: case 356: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.CompletionType -//line mysql_sql.y:3110 +//line mysql_sql.y:3119 { yyLOCAL = tree.COMPLETION_TYPE_CHAIN } @@ -16028,7 +16337,7 @@ yydefault: case 357: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.CompletionType -//line mysql_sql.y:3114 +//line mysql_sql.y:3123 { yyLOCAL = tree.COMPLETION_TYPE_RELEASE } @@ -16036,7 +16345,7 @@ yydefault: case 358: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.CompletionType -//line mysql_sql.y:3118 +//line mysql_sql.y:3127 { yyLOCAL = tree.COMPLETION_TYPE_RELEASE } @@ -16044,7 +16353,7 @@ yydefault: case 359: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.CompletionType -//line mysql_sql.y:3122 +//line mysql_sql.y:3131 { yyLOCAL = tree.COMPLETION_TYPE_NO_CHAIN } @@ -16052,7 +16361,7 @@ yydefault: case 360: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.CompletionType -//line mysql_sql.y:3126 +//line mysql_sql.y:3135 { yyLOCAL = tree.COMPLETION_TYPE_NO_CHAIN } @@ -16060,7 +16369,7 @@ yydefault: case 361: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.CompletionType -//line mysql_sql.y:3130 +//line mysql_sql.y:3139 { yyLOCAL = tree.COMPLETION_TYPE_NO_CHAIN } @@ -16068,7 +16377,7 @@ yydefault: case 362: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3136 +//line mysql_sql.y:3145 { yyLOCAL = &tree.BeginTransaction{} } @@ -16076,7 +16385,7 @@ yydefault: case 363: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3140 +//line mysql_sql.y:3149 { yyLOCAL = &tree.BeginTransaction{} } @@ -16084,7 +16393,7 @@ yydefault: case 364: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3144 +//line mysql_sql.y:3153 { yyLOCAL = &tree.BeginTransaction{} } @@ -16092,7 +16401,7 @@ yydefault: case 365: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3148 +//line mysql_sql.y:3157 { m := tree.MakeTransactionModes(tree.READ_WRITE_MODE_READ_WRITE) yyLOCAL = &tree.BeginTransaction{Modes: m} @@ -16101,7 +16410,7 @@ yydefault: case 366: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3153 +//line mysql_sql.y:3162 { m := tree.MakeTransactionModes(tree.READ_WRITE_MODE_READ_ONLY) yyLOCAL = &tree.BeginTransaction{Modes: m} @@ -16110,7 +16419,7 @@ yydefault: case 367: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3158 +//line mysql_sql.y:3167 { yyLOCAL = &tree.BeginTransaction{} } @@ -16118,7 +16427,7 @@ yydefault: case 368: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3164 +//line mysql_sql.y:3173 { name := yyDollar[2].cstrUnion() secondaryRole := false @@ -16135,7 +16444,7 @@ yydefault: case 369: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3177 +//line mysql_sql.y:3186 { name := yylex.(*Lexer).GetDbOrTblNameCStr("") secondaryRole := false @@ -16152,7 +16461,7 @@ yydefault: case 370: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3190 +//line mysql_sql.y:3199 { name := yylex.(*Lexer).GetDbOrTblNameCStr("") secondaryRole := false @@ -16169,7 +16478,7 @@ yydefault: case 371: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3203 +//line mysql_sql.y:3212 { name := yylex.(*Lexer).GetDbOrTblNameCStr("") secondaryRole := true @@ -16186,7 +16495,7 @@ yydefault: case 372: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3216 +//line mysql_sql.y:3225 { name := yylex.(*Lexer).GetDbOrTblNameCStr("") secondaryRole := true @@ -16203,7 +16512,7 @@ yydefault: case 374: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3232 +//line mysql_sql.y:3241 { yyDollar[2].statementUnion().(*tree.Update).With = yyDollar[1].withClauseUnion() yyLOCAL = yyDollar[2].statementUnion() @@ -16212,7 +16521,7 @@ yydefault: case 375: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3239 +//line mysql_sql.y:3248 { // Single-table syntax yyLOCAL = &tree.Update{ @@ -16228,7 +16537,7 @@ yydefault: case 376: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3251 +//line mysql_sql.y:3260 { // Multiple-table syntax yyLOCAL = &tree.Update{ @@ -16242,7 +16551,7 @@ yydefault: case 377: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3261 +//line mysql_sql.y:3270 { // PostgreSQL-style UPDATE target SET ... FROM source_tables WHERE ... // The target table is kept in Tables; FROM-clause sources are stored @@ -16260,7 +16569,7 @@ yydefault: case 378: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.UpdateExprs -//line mysql_sql.y:3277 +//line mysql_sql.y:3286 { yyLOCAL = tree.UpdateExprs{yyDollar[1].updateExprUnion()} } @@ -16268,7 +16577,7 @@ yydefault: case 379: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.UpdateExprs -//line mysql_sql.y:3281 +//line mysql_sql.y:3290 { yyLOCAL = append(yyDollar[1].updateExprsUnion(), yyDollar[3].updateExprUnion()) } @@ -16276,7 +16585,7 @@ yydefault: case 380: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.UpdateExpr -//line mysql_sql.y:3287 +//line mysql_sql.y:3296 { yyLOCAL = &tree.UpdateExpr{Names: []*tree.UnresolvedName{yyDollar[1].unresolvedNameUnion()}, Expr: yyDollar[3].exprUnion()} } @@ -16284,7 +16593,7 @@ yydefault: case 383: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3297 +//line mysql_sql.y:3306 { yyLOCAL = &tree.LockTableStmt{TableLocks: yyDollar[3].tableLocksUnion()} } @@ -16292,7 +16601,7 @@ yydefault: case 384: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []tree.TableLock -//line mysql_sql.y:3303 +//line mysql_sql.y:3312 { yyLOCAL = []tree.TableLock{yyDollar[1].tableLockUnion()} } @@ -16300,7 +16609,7 @@ yydefault: case 385: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []tree.TableLock -//line mysql_sql.y:3307 +//line mysql_sql.y:3316 { yyLOCAL = append(yyDollar[1].tableLocksUnion(), yyDollar[3].tableLockUnion()) } @@ -16308,7 +16617,7 @@ yydefault: case 386: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.TableLock -//line mysql_sql.y:3313 +//line mysql_sql.y:3322 { yyLOCAL = tree.TableLock{Table: *yyDollar[1].tableNameUnion(), LockType: yyDollar[2].tableLockTypeUnion()} } @@ -16316,7 +16625,7 @@ yydefault: case 387: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableLockType -//line mysql_sql.y:3319 +//line mysql_sql.y:3328 { yyLOCAL = tree.TableLockRead } @@ -16324,7 +16633,7 @@ yydefault: case 388: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.TableLockType -//line mysql_sql.y:3323 +//line mysql_sql.y:3332 { yyLOCAL = tree.TableLockReadLocal } @@ -16332,7 +16641,7 @@ yydefault: case 389: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableLockType -//line mysql_sql.y:3327 +//line mysql_sql.y:3336 { yyLOCAL = tree.TableLockWrite } @@ -16340,7 +16649,7 @@ yydefault: case 390: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.TableLockType -//line mysql_sql.y:3331 +//line mysql_sql.y:3340 { yyLOCAL = tree.TableLockLowPriorityWrite } @@ -16348,7 +16657,7 @@ yydefault: case 391: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3337 +//line mysql_sql.y:3346 { yyLOCAL = &tree.UnLockTableStmt{} } @@ -16356,7 +16665,7 @@ yydefault: case 400: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3351 +//line mysql_sql.y:3360 { yyLOCAL = yyDollar[1].selectUnion() } @@ -16364,7 +16673,7 @@ yydefault: case 401: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3357 +//line mysql_sql.y:3366 { yyLOCAL = tree.NewPrepareStmt(tree.Identifier(yyDollar[2].str), yyDollar[4].statementUnion()) } @@ -16372,7 +16681,7 @@ yydefault: case 402: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3361 +//line mysql_sql.y:3370 { yyLOCAL = tree.NewPrepareString(tree.Identifier(yyDollar[2].str), yyDollar[4].str) } @@ -16380,7 +16689,7 @@ yydefault: case 403: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3365 +//line mysql_sql.y:3374 { yyLOCAL = tree.NewPrepareVar(tree.Identifier(yyDollar[2].str), yyDollar[4].varExprUnion()) } @@ -16388,7 +16697,7 @@ yydefault: case 404: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3371 +//line mysql_sql.y:3380 { yyLOCAL = &tree.ExecuteSQLTask{ Name: tree.Identifier(yyDollar[3].cstrUnion().Compare()), @@ -16398,7 +16707,7 @@ yydefault: case 405: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3377 +//line mysql_sql.y:3386 { yyLOCAL = tree.NewExecute(tree.Identifier(yyDollar[2].str)) } @@ -16406,7 +16715,7 @@ yydefault: case 406: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3381 +//line mysql_sql.y:3390 { yyLOCAL = tree.NewExecuteWithVariables(tree.Identifier(yyDollar[2].str), yyDollar[4].varExprsUnion()) } @@ -16414,7 +16723,7 @@ yydefault: case 407: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3387 +//line mysql_sql.y:3396 { yyLOCAL = tree.NewDeallocate(tree.Identifier(yyDollar[3].str), false) } @@ -16422,7 +16731,7 @@ yydefault: case 408: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3393 +//line mysql_sql.y:3402 { yyLOCAL = tree.NewReset(tree.Identifier(yyDollar[3].str)) } @@ -16430,7 +16739,7 @@ yydefault: case 414: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3404 +//line mysql_sql.y:3413 { yyLOCAL = yyDollar[1].selectUnion() } @@ -16438,7 +16747,7 @@ yydefault: case 415: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3410 +//line mysql_sql.y:3419 { yyLOCAL = &tree.ShowColumns{Table: yyDollar[2].unresolvedObjectNameUnion()} } @@ -16446,7 +16755,7 @@ yydefault: case 416: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3414 +//line mysql_sql.y:3423 { yyLOCAL = &tree.ShowColumns{Table: yyDollar[2].unresolvedObjectNameUnion(), ColName: yyDollar[3].unresolvedNameUnion()} } @@ -16454,7 +16763,7 @@ yydefault: case 417: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3418 +//line mysql_sql.y:3427 { yyLOCAL = tree.NewExplainFor("", uint64(yyDollar[4].item.(int64))) } @@ -16462,7 +16771,7 @@ yydefault: case 418: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3422 +//line mysql_sql.y:3431 { yyLOCAL = tree.NewExplainFor(yyDollar[4].str, uint64(yyDollar[7].item.(int64))) } @@ -16470,7 +16779,7 @@ yydefault: case 419: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3426 +//line mysql_sql.y:3435 { yyLOCAL = tree.NewExplainStmt(yyDollar[2].statementUnion(), "text") } @@ -16478,7 +16787,7 @@ yydefault: case 420: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3430 +//line mysql_sql.y:3439 { options := []tree.OptionElem{ tree.MakeOptionElem(tree.VerboseOption, "NULL"), @@ -16489,7 +16798,7 @@ yydefault: case 421: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3437 +//line mysql_sql.y:3446 { options := []tree.OptionElem{ tree.MakeOptionElem(tree.AnalyzeOption, "NULL"), @@ -16500,7 +16809,7 @@ yydefault: case 422: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3444 +//line mysql_sql.y:3453 { options := []tree.OptionElem{ tree.MakeOptionElem(tree.AnalyzeOption, "NULL"), @@ -16512,7 +16821,7 @@ yydefault: case 423: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3452 +//line mysql_sql.y:3461 { options := []tree.OptionElem{ tree.MakeOptionElem(tree.PhyPlanOption, "NULL"), @@ -16523,7 +16832,7 @@ yydefault: case 424: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3459 +//line mysql_sql.y:3468 { options := []tree.OptionElem{ tree.MakeOptionElem(tree.PhyPlanOption, "NULL"), @@ -16535,7 +16844,7 @@ yydefault: case 425: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3467 +//line mysql_sql.y:3476 { options := []tree.OptionElem{ tree.MakeOptionElem(tree.PhyPlanOption, "NULL"), @@ -16547,7 +16856,7 @@ yydefault: case 426: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3475 +//line mysql_sql.y:3484 { yyLOCAL = tree.MakeExplainStmt(yyDollar[5].statementUnion(), yyDollar[3].explainOptionsUnion()) } @@ -16555,7 +16864,7 @@ yydefault: case 427: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3479 +//line mysql_sql.y:3488 { yyLOCAL = tree.MakeExplainStmt(yyDollar[3].statementUnion(), nil) } @@ -16563,7 +16872,7 @@ yydefault: case 428: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3483 +//line mysql_sql.y:3492 { options := []tree.OptionElem{ tree.MakeOptionElem(tree.VerboseOption, "NULL"), @@ -16574,7 +16883,7 @@ yydefault: case 429: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3490 +//line mysql_sql.y:3499 { options := []tree.OptionElem{ tree.MakeOptionElem(tree.AnalyzeOption, "NULL"), @@ -16585,7 +16894,7 @@ yydefault: case 430: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3497 +//line mysql_sql.y:3506 { options := []tree.OptionElem{ tree.MakeOptionElem(tree.AnalyzeOption, "NULL"), @@ -16597,7 +16906,7 @@ yydefault: case 445: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []tree.OptionElem -//line mysql_sql.y:3535 +//line mysql_sql.y:3544 { yyLOCAL = []tree.OptionElem{yyDollar[1].explainOptionUnion()} } @@ -16605,7 +16914,7 @@ yydefault: case 446: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []tree.OptionElem -//line mysql_sql.y:3539 +//line mysql_sql.y:3548 { yyLOCAL = append(yyDollar[1].explainOptionsUnion(), yyDollar[3].explainOptionUnion()) } @@ -16613,45 +16922,45 @@ yydefault: case 447: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.OptionElem -//line mysql_sql.y:3545 +//line mysql_sql.y:3554 { yyLOCAL = tree.MakeOptionElem(yyDollar[1].str, yyDollar[2].str) } yyVAL.union = yyLOCAL case 448: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:3551 +//line mysql_sql.y:3560 { yyVAL.str = yyDollar[1].str } case 449: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:3556 +//line mysql_sql.y:3565 { yyVAL.str = "true" } case 450: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:3557 +//line mysql_sql.y:3566 { yyVAL.str = "false" } case 451: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:3558 +//line mysql_sql.y:3567 { yyVAL.str = yyDollar[1].str } case 452: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:3559 +//line mysql_sql.y:3568 { yyVAL.str = yyDollar[1].str } case 453: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3563 +//line mysql_sql.y:3572 { yyLOCAL = tree.NewAnalyzeStmt(yyDollar[3].analyzeTableEntriesUnion()) } @@ -16659,7 +16968,7 @@ yydefault: case 454: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.AnalyzeTableEntry -//line mysql_sql.y:3569 +//line mysql_sql.y:3578 { yyLOCAL = []*tree.AnalyzeTableEntry{yyDollar[1].analyzeTableEntryUnion()} } @@ -16667,7 +16976,7 @@ yydefault: case 455: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.AnalyzeTableEntry -//line mysql_sql.y:3573 +//line mysql_sql.y:3582 { yyLOCAL = append(yyDollar[1].analyzeTableEntriesUnion(), yyDollar[3].analyzeTableEntryUnion()) } @@ -16675,7 +16984,7 @@ yydefault: case 456: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.AnalyzeTableEntry -//line mysql_sql.y:3579 +//line mysql_sql.y:3588 { yyLOCAL = &tree.AnalyzeTableEntry{Table: yyDollar[1].tableNameUnion()} } @@ -16683,7 +16992,7 @@ yydefault: case 457: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.AnalyzeTableEntry -//line mysql_sql.y:3583 +//line mysql_sql.y:3592 { yyLOCAL = &tree.AnalyzeTableEntry{Table: yyDollar[1].tableNameUnion(), Cols: yyDollar[3].identifierListUnion()} } @@ -16691,7 +17000,7 @@ yydefault: case 458: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3589 +//line mysql_sql.y:3598 { yyLOCAL = tree.NewCheckTableStmt(yyDollar[3].tableNamesUnion(), yyDollar[4].checkTableOptionUnion()) } @@ -16699,7 +17008,7 @@ yydefault: case 459: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.CheckTableOption -//line mysql_sql.y:3595 +//line mysql_sql.y:3604 { yyLOCAL = tree.CheckTableOptionNone } @@ -16707,7 +17016,7 @@ yydefault: case 460: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.CheckTableOption -//line mysql_sql.y:3599 +//line mysql_sql.y:3608 { yyLOCAL = tree.CheckTableOptionExtended } @@ -16715,7 +17024,7 @@ yydefault: case 461: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.CheckTableOption -//line mysql_sql.y:3603 +//line mysql_sql.y:3612 { yyLOCAL = tree.CheckTableOptionForUpgrade } @@ -16723,7 +17032,7 @@ yydefault: case 462: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3609 +//line mysql_sql.y:3618 { yyLOCAL = tree.NewShowProfileStmt(yyDollar[3].int64ValUnion(), yyDollar[4].limitUnion()) } @@ -16731,7 +17040,7 @@ yydefault: case 463: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:3615 +//line mysql_sql.y:3624 { yyLOCAL = 0 } @@ -16739,7 +17048,7 @@ yydefault: case 464: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:3619 +//line mysql_sql.y:3628 { yyLOCAL = yyDollar[3].item.(int64) } @@ -16747,7 +17056,7 @@ yydefault: case 465: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3625 +//line mysql_sql.y:3634 { yyLOCAL = &tree.UpgradeStatement{ Target: yyDollar[3].upgrade_targetUnion(), @@ -16758,7 +17067,7 @@ yydefault: case 466: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.Target -//line mysql_sql.y:3634 +//line mysql_sql.y:3643 { yyLOCAL = &tree.Target{ AccountName: yyDollar[1].str, @@ -16769,7 +17078,7 @@ yydefault: case 467: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.Target -//line mysql_sql.y:3641 +//line mysql_sql.y:3650 { yyLOCAL = &tree.Target{ AccountName: "", @@ -16780,7 +17089,7 @@ yydefault: case 468: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:3649 +//line mysql_sql.y:3658 { yyLOCAL = -1 } @@ -16788,7 +17097,7 @@ yydefault: case 469: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:3653 +//line mysql_sql.y:3662 { res := yyDollar[3].item.(int64) if res <= 0 { @@ -16798,10 +17107,10 @@ yydefault: yyLOCAL = res } yyVAL.union = yyLOCAL - case 483: + case 484: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3680 +//line mysql_sql.y:3690 { yyLOCAL = &tree.AlterIcebergCatalog{ Name: tree.Identifier(yyDollar[4].cstrUnion().Compare()), @@ -16809,10 +17118,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 484: + case 485: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3687 +//line mysql_sql.y:3697 { yyLOCAL = &tree.AlterIcebergCatalog{ Name: tree.Identifier(yyDollar[4].cstrUnion().Compare()), @@ -16820,10 +17129,56 @@ yydefault: } } yyVAL.union = yyLOCAL - case 485: + case 486: + yyDollar = yyS[yypt-6 : yypt+1] + var yyLOCAL tree.Statement +//line mysql_sql.y:3706 + { + yyLOCAL = &tree.AlterMongoDBConnection{ + Name: tree.Identifier(yyDollar[4].cstrUnion().Compare()), + Action: tree.AlterMongoDBConnectionSet, + Options: yyDollar[6].mongodbOptionsUnion(), + } + } + yyVAL.union = yyLOCAL + case 487: + yyDollar = yyS[yypt-8 : yypt+1] + var yyLOCAL tree.Statement +//line mysql_sql.y:3714 + { + yyLOCAL = &tree.AlterMongoDBConnection{ + Name: tree.Identifier(yyDollar[4].cstrUnion().Compare()), + Action: tree.AlterMongoDBConnectionSet, + Options: yyDollar[7].mongodbOptionsUnion(), + } + } + yyVAL.union = yyLOCAL + case 488: + yyDollar = yyS[yypt-5 : yypt+1] + var yyLOCAL tree.Statement +//line mysql_sql.y:3722 + { + yyLOCAL = &tree.AlterMongoDBConnection{ + Name: tree.Identifier(yyDollar[4].cstrUnion().Compare()), + Action: tree.AlterMongoDBConnectionEnable, + } + } + yyVAL.union = yyLOCAL + case 489: + yyDollar = yyS[yypt-5 : yypt+1] + var yyLOCAL tree.Statement +//line mysql_sql.y:3729 + { + yyLOCAL = &tree.AlterMongoDBConnection{ + Name: tree.Identifier(yyDollar[4].cstrUnion().Compare()), + Action: tree.AlterMongoDBConnectionDisable, + } + } + yyVAL.union = yyLOCAL + case 490: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3696 +//line mysql_sql.y:3738 { var ifExists = yyDollar[3].boolValUnion() var name = yyDollar[4].tableNameUnion() @@ -16845,10 +17200,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 486: + case 491: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3719 +//line mysql_sql.y:3761 { var ifExists = yyDollar[3].boolValUnion() var name = yyDollar[4].tableNameUnion() @@ -16857,10 +17212,10 @@ yydefault: yyLOCAL = tree.NewAlterView(ifExists, name, colNames, asSource) } yyVAL.union = yyLOCAL - case 487: + case 492: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3729 +//line mysql_sql.y:3771 { var table = yyDollar[3].tableNameUnion() alterTable := tree.NewAlterTable(table) @@ -16868,10 +17223,10 @@ yydefault: yyLOCAL = alterTable } yyVAL.union = yyLOCAL - case 488: + case 493: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3736 +//line mysql_sql.y:3778 { var table = yyDollar[3].tableNameUnion() alterTable := tree.NewAlterTable(table) @@ -16879,36 +17234,36 @@ yydefault: yyLOCAL = alterTable } yyVAL.union = yyLOCAL - case 489: + case 494: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3745 +//line mysql_sql.y:3787 { alterTables := yyDollar[3].renameTableOptionsUnion() renameTables := tree.NewRenameTable(alterTables) yyLOCAL = renameTables } yyVAL.union = yyLOCAL - case 490: + case 495: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.AlterTable -//line mysql_sql.y:3753 +//line mysql_sql.y:3795 { yyLOCAL = []*tree.AlterTable{yyDollar[1].renameTableOptionUnion()} } yyVAL.union = yyLOCAL - case 491: + case 496: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.AlterTable -//line mysql_sql.y:3757 +//line mysql_sql.y:3799 { yyLOCAL = append(yyDollar[1].renameTableOptionsUnion(), yyDollar[3].renameTableOptionUnion()) } yyVAL.union = yyLOCAL - case 492: + case 497: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.AlterTable -//line mysql_sql.y:3763 +//line mysql_sql.y:3805 { var table = yyDollar[1].tableNameUnion() alterTable := tree.NewAlterTable(table) @@ -16917,34 +17272,34 @@ yydefault: yyLOCAL = alterTable } yyVAL.union = yyLOCAL - case 493: + case 498: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.AlterTableOptions -//line mysql_sql.y:3773 +//line mysql_sql.y:3815 { yyLOCAL = []tree.AlterTableOption{yyDollar[1].alterTableOptionUnion()} } yyVAL.union = yyLOCAL - case 494: + case 499: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AlterTableOptions -//line mysql_sql.y:3777 +//line mysql_sql.y:3819 { yyLOCAL = append(yyDollar[1].alterTableOptionsUnion(), yyDollar[3].alterTableOptionUnion()) } yyVAL.union = yyLOCAL - case 495: + case 500: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.AlterPartitionOption -//line mysql_sql.y:3783 +//line mysql_sql.y:3825 { yyLOCAL = yyDollar[1].alterPartitionOptionUnion() } yyVAL.union = yyLOCAL - case 496: + case 501: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.AlterPartitionOption -//line mysql_sql.y:3787 +//line mysql_sql.y:3829 { yyDollar[3].partitionByUnion().Num = uint64(yyDollar[4].int64ValUnion()) var PartBy = yyDollar[3].partitionByUnion() @@ -16967,10 +17322,10 @@ yydefault: yyLOCAL = tree.AlterPartitionOption(opt) } yyVAL.union = yyLOCAL - case 497: + case 502: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3811 +//line mysql_sql.y:3853 { var ifExists = yyDollar[3].boolValUnion() var name = tree.Identifier(yyDollar[4].cstrUnion().Compare()) @@ -16979,10 +17334,10 @@ yydefault: yyLOCAL = tree.NewAlterPitr(ifExists, name, pitrValue, pitrUnit) } yyVAL.union = yyLOCAL - case 498: + case 503: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3821 +//line mysql_sql.y:3863 { yyLOCAL = &tree.AlterSQLTask{ Name: tree.Identifier(yyDollar[3].cstrUnion().Compare()), @@ -16990,10 +17345,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 499: + case 504: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3828 +//line mysql_sql.y:3870 { yyLOCAL = &tree.AlterSQLTask{ Name: tree.Identifier(yyDollar[3].cstrUnion().Compare()), @@ -17001,10 +17356,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 500: + case 505: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3835 +//line mysql_sql.y:3877 { yyLOCAL = &tree.AlterSQLTask{ Name: tree.Identifier(yyDollar[3].cstrUnion().Compare()), @@ -17014,10 +17369,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 501: + case 506: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3844 +//line mysql_sql.y:3886 { yyLOCAL = &tree.AlterSQLTask{ Name: tree.Identifier(yyDollar[3].cstrUnion().Compare()), @@ -17026,10 +17381,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 502: + case 507: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3852 +//line mysql_sql.y:3894 { yyLOCAL = &tree.AlterSQLTask{ Name: tree.Identifier(yyDollar[3].cstrUnion().Compare()), @@ -17038,10 +17393,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 503: + case 508: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3860 +//line mysql_sql.y:3902 { yyLOCAL = &tree.AlterSQLTask{ Name: tree.Identifier(yyDollar[3].cstrUnion().Compare()), @@ -17050,30 +17405,30 @@ yydefault: } } yyVAL.union = yyLOCAL - case 504: + case 509: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3870 +//line mysql_sql.y:3912 { var oldName = yyDollar[5].cstrUnion().Compare() var newName = yyDollar[8].cstrUnion().Compare() yyLOCAL = tree.NewAlterRole(true, oldName, newName) } yyVAL.union = yyLOCAL - case 505: + case 510: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3876 +//line mysql_sql.y:3918 { var oldName = yyDollar[3].cstrUnion().Compare() var newName = yyDollar[6].cstrUnion().Compare() yyLOCAL = tree.NewAlterRole(false, oldName, newName) } yyVAL.union = yyLOCAL - case 506: + case 511: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3882 +//line mysql_sql.y:3924 { var roleName = yyDollar[3].cstrUnion().Compare() var ruleSQL = yyDollar[6].str @@ -17083,10 +17438,10 @@ yydefault: yyLOCAL = tree.NewAlterRoleAddRule(roleName, ruleName, ruleSQL, dbName, tblName) } yyVAL.union = yyLOCAL - case 507: + case 512: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:3891 +//line mysql_sql.y:3933 { var roleName = yyDollar[3].cstrUnion().Compare() var dbName = yyDollar[8].cstrUnion().Compare() @@ -17094,10 +17449,10 @@ yydefault: yyLOCAL = tree.NewAlterRoleDropRule(roleName, dbName, tblName) } yyVAL.union = yyLOCAL - case 508: + case 513: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AlterPartitionOption -//line mysql_sql.y:3900 +//line mysql_sql.y:3942 { var typ = tree.AlterPartitionAddPartition var partitions = yyDollar[3].partitionsUnion() @@ -17108,10 +17463,10 @@ yydefault: yyLOCAL = tree.AlterPartitionOption(opt) } yyVAL.union = yyLOCAL - case 509: + case 514: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AlterPartitionOption -//line mysql_sql.y:3910 +//line mysql_sql.y:3952 { var typ = tree.AlterPartitionDropPartition var partitionNames = yyDollar[3].PartitionNamesUnion() @@ -17128,10 +17483,10 @@ yydefault: yyLOCAL = tree.AlterPartitionOption(opt) } yyVAL.union = yyLOCAL - case 510: + case 515: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AlterPartitionOption -//line mysql_sql.y:3926 +//line mysql_sql.y:3968 { var typ = tree.AlterPartitionTruncatePartition var partitionNames = yyDollar[3].PartitionNamesUnion() @@ -17148,52 +17503,52 @@ yydefault: yyLOCAL = tree.AlterPartitionOption(opt) } yyVAL.union = yyLOCAL - case 511: + case 516: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:3944 +//line mysql_sql.y:3986 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 512: + case 517: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:3948 +//line mysql_sql.y:3990 { yyLOCAL = yyDollar[1].PartitionNamesUnion() } yyVAL.union = yyLOCAL - case 513: + case 518: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:3954 +//line mysql_sql.y:3996 { yyLOCAL = tree.IdentifierList{tree.Identifier(yyDollar[1].cstrUnion().Compare())} } yyVAL.union = yyLOCAL - case 514: + case 519: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:3958 +//line mysql_sql.y:4000 { yyLOCAL = append(yyDollar[1].PartitionNamesUnion(), tree.Identifier(yyDollar[3].cstrUnion().Compare())) } yyVAL.union = yyLOCAL - case 515: + case 520: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:3964 +//line mysql_sql.y:4006 { var def = yyDollar[2].tableDefUnion() opt := tree.NewAlterOptionAdd(def) yyLOCAL = tree.AlterTableOption(opt) } yyVAL.union = yyLOCAL - case 516: + case 521: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:3970 +//line mysql_sql.y:4012 { var typ = tree.AlterTableModifyColumn var newColumn = yyDollar[3].columnTableDefUnion() @@ -17202,10 +17557,10 @@ yydefault: yyLOCAL = tree.AlterTableOption(opt) } yyVAL.union = yyLOCAL - case 517: + case 522: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:3978 +//line mysql_sql.y:4020 { // Type OldColumnName NewColumn Position var typ = tree.AlterTableChangeColumn @@ -17216,10 +17571,10 @@ yydefault: yyLOCAL = tree.AlterTableOption(opt) } yyVAL.union = yyLOCAL - case 518: + case 523: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:3988 +//line mysql_sql.y:4030 { var typ = tree.AlterTableRenameColumn var oldColumnName = yyDollar[3].unresolvedNameUnion() @@ -17228,10 +17583,10 @@ yydefault: yyLOCAL = tree.AlterTableOption(opt) } yyVAL.union = yyLOCAL - case 519: + case 524: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:3996 +//line mysql_sql.y:4038 { var typ = tree.AlterTableAlterColumn var columnName = yyDollar[3].unresolvedNameUnion() @@ -17242,10 +17597,10 @@ yydefault: yyLOCAL = tree.AlterTableOption(opt) } yyVAL.union = yyLOCAL - case 520: + case 525: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4006 +//line mysql_sql.y:4048 { var typ = tree.AlterTableAlterColumn var columnName = yyDollar[3].unresolvedNameUnion() @@ -17256,10 +17611,10 @@ yydefault: yyLOCAL = tree.AlterTableOption(opt) } yyVAL.union = yyLOCAL - case 521: + case 526: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4016 +//line mysql_sql.y:4058 { var typ = tree.AlterTableAlterColumn var columnName = yyDollar[3].unresolvedNameUnion() @@ -17270,10 +17625,10 @@ yydefault: yyLOCAL = tree.AlterTableOption(opt) } yyVAL.union = yyLOCAL - case 522: + case 527: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4026 +//line mysql_sql.y:4068 { var orderByClauseType = tree.AlterTableOrderByColumn var orderByColumnList = yyDollar[3].alterColumnOrderByUnion() @@ -17281,42 +17636,42 @@ yydefault: yyLOCAL = tree.AlterTableOption(opt) } yyVAL.union = yyLOCAL - case 523: + case 528: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4033 +//line mysql_sql.y:4075 { yyLOCAL = tree.AlterTableOption(yyDollar[2].alterTableOptionUnion()) } yyVAL.union = yyLOCAL - case 524: + case 529: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4037 +//line mysql_sql.y:4079 { yyLOCAL = tree.AlterTableOption(yyDollar[2].alterTableOptionUnion()) } yyVAL.union = yyLOCAL - case 525: + case 530: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4041 +//line mysql_sql.y:4083 { yyLOCAL = tree.AlterTableOption(yyDollar[1].tableOptionUnion()) } yyVAL.union = yyLOCAL - case 526: + case 531: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4045 +//line mysql_sql.y:4087 { yyLOCAL = tree.AlterTableOption(yyDollar[3].alterTableOptionUnion()) } yyVAL.union = yyLOCAL - case 527: + case 532: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4049 +//line mysql_sql.y:4091 { var column = yyDollar[3].columnTableDefUnion() var position = yyDollar[4].alterColPositionUnion() @@ -17324,205 +17679,205 @@ yydefault: yyLOCAL = tree.AlterTableOption(opt) } yyVAL.union = yyLOCAL - case 528: + case 533: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4056 +//line mysql_sql.y:4098 { yyLOCAL = tree.NewAlterOptionAlgorithm(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 529: + case 534: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4060 +//line mysql_sql.y:4102 { yyLOCAL = tree.NewTableOptionCharset(yyDollar[4].str) } yyVAL.union = yyLOCAL - case 530: + case 535: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4064 +//line mysql_sql.y:4106 { yyLOCAL = tree.NewTableOptionCharset(yyDollar[5].str) } yyVAL.union = yyLOCAL - case 531: + case 536: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4068 +//line mysql_sql.y:4110 { yyLOCAL = tree.NewTableOptionCharset(yyDollar[5].str) } yyVAL.union = yyLOCAL - case 532: + case 537: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4072 +//line mysql_sql.y:4114 { yyLOCAL = tree.NewTableOptionCharset(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 533: + case 538: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4076 +//line mysql_sql.y:4118 { yyLOCAL = tree.NewTableOptionCharset(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 534: + case 539: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4080 +//line mysql_sql.y:4122 { yyLOCAL = tree.NewTableOptionCharset(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 535: + case 540: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4084 +//line mysql_sql.y:4126 { yyLOCAL = tree.NewAlterOptionLock(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 536: + case 541: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4088 +//line mysql_sql.y:4130 { yyLOCAL = tree.NewTableOptionCharset(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 537: + case 542: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:4093 +//line mysql_sql.y:4135 { yyVAL.str = "" } - case 554: + case 559: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:4124 +//line mysql_sql.y:4166 { yyVAL.str = "" } - case 555: + case 560: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:4128 +//line mysql_sql.y:4170 { yyVAL.str = string("COLUMN") } - case 556: + case 561: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.ColumnPosition -//line mysql_sql.y:4133 +//line mysql_sql.y:4175 { var typ = tree.ColumnPositionNone var relativeColumn *tree.UnresolvedName yyLOCAL = tree.NewColumnPosition(typ, relativeColumn) } yyVAL.union = yyLOCAL - case 557: + case 562: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.ColumnPosition -//line mysql_sql.y:4139 +//line mysql_sql.y:4181 { var typ = tree.ColumnPositionFirst var relativeColumn *tree.UnresolvedName yyLOCAL = tree.NewColumnPosition(typ, relativeColumn) } yyVAL.union = yyLOCAL - case 558: + case 563: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.ColumnPosition -//line mysql_sql.y:4145 +//line mysql_sql.y:4187 { var typ = tree.ColumnPositionAfter var relativeColumn = yyDollar[2].unresolvedNameUnion() yyLOCAL = tree.NewColumnPosition(typ, relativeColumn) } yyVAL.union = yyLOCAL - case 559: + case 564: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.AlterColumnOrder -//line mysql_sql.y:4153 +//line mysql_sql.y:4195 { yyLOCAL = []*tree.AlterColumnOrder{yyDollar[1].alterColumnOrderUnion()} } yyVAL.union = yyLOCAL - case 560: + case 565: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.AlterColumnOrder -//line mysql_sql.y:4157 +//line mysql_sql.y:4199 { yyLOCAL = append(yyDollar[1].alterColumnOrderByUnion(), yyDollar[3].alterColumnOrderUnion()) } yyVAL.union = yyLOCAL - case 561: + case 566: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.AlterColumnOrder -//line mysql_sql.y:4163 +//line mysql_sql.y:4205 { var column = yyDollar[1].unresolvedNameUnion() var direction = yyDollar[2].directionUnion() yyLOCAL = tree.NewAlterColumnOrder(column, direction) } yyVAL.union = yyLOCAL - case 562: + case 567: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4171 +//line mysql_sql.y:4213 { var name = yyDollar[1].unresolvedObjectNameUnion() yyLOCAL = tree.NewAlterOptionTableName(name) } yyVAL.union = yyLOCAL - case 563: + case 568: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4178 +//line mysql_sql.y:4220 { var dropType = tree.AlterTableDropIndex var name = tree.Identifier(yyDollar[2].cstrUnion().Compare()) yyLOCAL = tree.NewAlterOptionDrop(dropType, name) } yyVAL.union = yyLOCAL - case 564: + case 569: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4184 +//line mysql_sql.y:4226 { var dropType = tree.AlterTableDropKey var name = tree.Identifier(yyDollar[2].cstrUnion().Compare()) yyLOCAL = tree.NewAlterOptionDrop(dropType, name) } yyVAL.union = yyLOCAL - case 565: + case 570: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4190 +//line mysql_sql.y:4232 { var dropType = tree.AlterTableDropColumn var name = tree.Identifier(yyDollar[1].cstrUnion().Compare()) yyLOCAL = tree.NewAlterOptionDrop(dropType, name) } yyVAL.union = yyLOCAL - case 566: + case 571: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4196 +//line mysql_sql.y:4238 { var dropType = tree.AlterTableDropColumn var name = tree.Identifier(yyDollar[2].cstrUnion().Compare()) yyLOCAL = tree.NewAlterOptionDrop(dropType, name) } yyVAL.union = yyLOCAL - case 567: + case 572: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4202 +//line mysql_sql.y:4244 { var dropType = tree.AlterTableDropForeignKey var name = tree.Identifier(yyDollar[3].cstrUnion().Compare()) @@ -17530,10 +17885,10 @@ yydefault: } yyVAL.union = yyLOCAL - case 568: + case 573: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4209 +//line mysql_sql.y:4251 { yyLOCAL = &tree.AlterOptionDrop{ Typ: tree.AlterTableDropForeignKey, @@ -17541,30 +17896,30 @@ yydefault: } } yyVAL.union = yyLOCAL - case 569: + case 574: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4216 +//line mysql_sql.y:4258 { var dropType = tree.AlterTableDropPrimaryKey var name = tree.Identifier("") yyLOCAL = tree.NewAlterOptionDrop(dropType, name) } yyVAL.union = yyLOCAL - case 570: + case 575: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4224 +//line mysql_sql.y:4266 { var indexName = tree.Identifier(yyDollar[2].cstrUnion().Compare()) var visibility = yyDollar[3].indexVisibilityUnion() yyLOCAL = tree.NewAlterOptionAlterIndex(indexName, visibility) } yyVAL.union = yyLOCAL - case 571: + case 576: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4230 +//line mysql_sql.y:4272 { var io *tree.IndexOption = nil if yyDollar[5].indexOptionUnion() == nil { @@ -17580,10 +17935,10 @@ yydefault: yyLOCAL = tree.NewAlterOptionAlterAutoUpdate(name, io) } yyVAL.union = yyLOCAL - case 572: + case 577: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4245 +//line mysql_sql.y:4287 { var io *tree.IndexOption = nil if yyDollar[4].indexOptionUnion() == nil { @@ -17597,10 +17952,10 @@ yydefault: yyLOCAL = tree.NewAlterOptionAlterReIndex(name, io) } yyVAL.union = yyLOCAL - case 573: + case 578: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4258 +//line mysql_sql.y:4300 { var io *tree.IndexOption = nil if yyDollar[4].indexOptionUnion() == nil { @@ -17614,10 +17969,10 @@ yydefault: yyLOCAL = tree.NewAlterOptionAlterReIndex(name, io) } yyVAL.union = yyLOCAL - case 574: + case 579: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4271 +//line mysql_sql.y:4313 { var io *tree.IndexOption = nil if yyDollar[4].indexOptionUnion() == nil { @@ -17631,10 +17986,10 @@ yydefault: yyLOCAL = tree.NewAlterOptionAlterReIndex(name, io) } yyVAL.union = yyLOCAL - case 575: + case 580: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4284 +//line mysql_sql.y:4326 { var io *tree.IndexOption = nil if yyDollar[4].indexOptionUnion() == nil { @@ -17648,62 +18003,62 @@ yydefault: yyLOCAL = tree.NewAlterOptionAlterReIndex(name, io) } yyVAL.union = yyLOCAL - case 576: + case 581: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4297 +//line mysql_sql.y:4339 { var checkType = yyDollar[1].str var enforce = yyDollar[3].boolValUnion() yyLOCAL = tree.NewAlterOptionAlterCheck(checkType, enforce) } yyVAL.union = yyLOCAL - case 577: + case 582: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AlterTableOption -//line mysql_sql.y:4303 +//line mysql_sql.y:4345 { var checkType = yyDollar[1].str var enforce = yyDollar[3].boolValUnion() yyLOCAL = tree.NewAlterOptionAlterCheck(checkType, enforce) } yyVAL.union = yyLOCAL - case 578: + case 583: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.VisibleType -//line mysql_sql.y:4311 +//line mysql_sql.y:4353 { yyLOCAL = tree.VISIBLE_TYPE_VISIBLE } yyVAL.union = yyLOCAL - case 579: + case 584: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.VisibleType -//line mysql_sql.y:4315 +//line mysql_sql.y:4357 { yyLOCAL = tree.VISIBLE_TYPE_INVISIBLE } yyVAL.union = yyLOCAL - case 580: + case 585: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:4321 +//line mysql_sql.y:4363 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 581: + case 586: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:4325 +//line mysql_sql.y:4367 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 582: + case 587: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4331 +//line mysql_sql.y:4373 { var ifExists = yyDollar[3].boolValUnion() var name = yyDollar[4].exprUnion() @@ -17720,10 +18075,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 583: + case 588: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4349 +//line mysql_sql.y:4391 { var accountName = "" var dbName = yyDollar[3].str @@ -17739,10 +18094,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 584: + case 589: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4364 +//line mysql_sql.y:4406 { var accountName = "" var dbName = yyDollar[3].str @@ -17758,10 +18113,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 585: + case 590: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4379 +//line mysql_sql.y:4421 { var accountName = yyDollar[4].str var dbName = "" @@ -17777,10 +18132,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 586: + case 591: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4394 +//line mysql_sql.y:4436 { assignments := []*tree.VarAssignmentExpr{ { @@ -17793,20 +18148,20 @@ yydefault: yyLOCAL = &tree.SetVar{Assignments: assignments} } yyVAL.union = yyLOCAL - case 587: + case 592: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.AlterAccountAuthOption -//line mysql_sql.y:4407 +//line mysql_sql.y:4449 { yyLOCAL = tree.AlterAccountAuthOption{ Exist: false, } } yyVAL.union = yyLOCAL - case 588: + case 593: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.AlterAccountAuthOption -//line mysql_sql.y:4413 +//line mysql_sql.y:4455 { yyLOCAL = tree.AlterAccountAuthOption{ Exist: true, @@ -17816,10 +18171,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 589: + case 594: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4424 +//line mysql_sql.y:4466 { // Create temporary variables with meaningful names ifExists := yyDollar[3].boolValUnion() @@ -17832,10 +18187,10 @@ yydefault: yyLOCAL = tree.NewAlterUser(ifExists, users, role, miscOpt, commentOrAttribute) } yyVAL.union = yyLOCAL - case 590: + case 595: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4436 +//line mysql_sql.y:4478 { ifExists := yyDollar[3].boolValUnion() var Username = yyDollar[4].usernameRecordUnion().Username @@ -17847,10 +18202,10 @@ yydefault: yyLOCAL = tree.NewAlterUser(ifExists, users, nil, miscOpt, commentOrAttribute) } yyVAL.union = yyLOCAL - case 591: + case 596: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4447 +//line mysql_sql.y:4489 { ifExists := yyDollar[3].boolValUnion() var Username = yyDollar[4].usernameRecordUnion().Username @@ -17862,18 +18217,18 @@ yydefault: yyLOCAL = tree.NewAlterUser(ifExists, users, nil, miscOpt, commentOrAttribute) } yyVAL.union = yyLOCAL - case 592: + case 597: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.Role -//line mysql_sql.y:4459 +//line mysql_sql.y:4501 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 593: + case 598: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.Role -//line mysql_sql.y:4463 +//line mysql_sql.y:4505 { var UserName = yyDollar[3].str yyLOCAL = tree.NewRole( @@ -17881,66 +18236,66 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 594: + case 599: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:4471 +//line mysql_sql.y:4513 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 595: + case 600: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:4475 +//line mysql_sql.y:4517 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 596: + case 601: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4480 +//line mysql_sql.y:4522 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 597: + case 602: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4484 +//line mysql_sql.y:4526 { yyLOCAL = yyDollar[1].userMiscOptionUnion() } yyVAL.union = yyLOCAL - case 598: + case 603: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4500 +//line mysql_sql.y:4542 { yyLOCAL = tree.NewUserMiscOptionAccountUnlock() } yyVAL.union = yyLOCAL - case 599: + case 604: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4504 +//line mysql_sql.y:4546 { yyLOCAL = tree.NewUserMiscOptionAccountLock() } yyVAL.union = yyLOCAL - case 600: + case 605: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4508 +//line mysql_sql.y:4550 { yyLOCAL = tree.NewUserMiscOptionPasswordExpireNone() } yyVAL.union = yyLOCAL - case 601: + case 606: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4512 +//line mysql_sql.y:4554 { var Value = yyDollar[3].item.(int64) yyLOCAL = tree.NewUserMiscOptionPasswordExpireInterval( @@ -17948,34 +18303,34 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 602: + case 607: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4519 +//line mysql_sql.y:4561 { yyLOCAL = tree.NewUserMiscOptionPasswordExpireNever() } yyVAL.union = yyLOCAL - case 603: + case 608: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4523 +//line mysql_sql.y:4565 { yyLOCAL = tree.NewUserMiscOptionPasswordExpireDefault() } yyVAL.union = yyLOCAL - case 604: + case 609: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4527 +//line mysql_sql.y:4569 { yyLOCAL = tree.NewUserMiscOptionPasswordHistoryDefault() } yyVAL.union = yyLOCAL - case 605: + case 610: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4531 +//line mysql_sql.y:4573 { var Value = yyDollar[3].item.(int64) yyLOCAL = tree.NewUserMiscOptionPasswordHistoryCount( @@ -17983,18 +18338,18 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 606: + case 611: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4538 +//line mysql_sql.y:4580 { yyLOCAL = tree.NewUserMiscOptionPasswordReuseIntervalDefault() } yyVAL.union = yyLOCAL - case 607: + case 612: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4542 +//line mysql_sql.y:4584 { var Value = yyDollar[4].item.(int64) yyLOCAL = tree.NewUserMiscOptionPasswordReuseIntervalCount( @@ -18002,34 +18357,34 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 608: + case 613: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4549 +//line mysql_sql.y:4591 { yyLOCAL = tree.NewUserMiscOptionPasswordRequireCurrentNone() } yyVAL.union = yyLOCAL - case 609: + case 614: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4553 +//line mysql_sql.y:4595 { yyLOCAL = tree.NewUserMiscOptionPasswordRequireCurrentDefault() } yyVAL.union = yyLOCAL - case 610: + case 615: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4557 +//line mysql_sql.y:4599 { yyLOCAL = tree.NewUserMiscOptionPasswordRequireCurrentOptional() } yyVAL.union = yyLOCAL - case 611: + case 616: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4561 +//line mysql_sql.y:4603 { var Value = yyDollar[2].item.(int64) yyLOCAL = tree.NewUserMiscOptionFailedLoginAttempts( @@ -18037,10 +18392,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 612: + case 617: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4568 +//line mysql_sql.y:4610 { var Value = yyDollar[2].item.(int64) yyLOCAL = tree.NewUserMiscOptionPasswordLockTimeCount( @@ -18048,38 +18403,38 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 613: + case 618: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.UserMiscOption -//line mysql_sql.y:4575 +//line mysql_sql.y:4617 { yyLOCAL = tree.NewUserMiscOptionPasswordLockTimeUnbounded() } yyVAL.union = yyLOCAL - case 614: + case 619: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:4581 +//line mysql_sql.y:4623 { yyVAL.item = nil } - case 615: + case 620: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:4586 +//line mysql_sql.y:4628 { yyVAL.item = nil } - case 661: + case 667: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4641 +//line mysql_sql.y:4684 { yyLOCAL = &tree.ShowSQLTasks{} } yyVAL.union = yyLOCAL - case 662: + case 668: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4647 +//line mysql_sql.y:4690 { stmt := &tree.ShowSQLTaskRuns{} if yyDollar[4].str != "" { @@ -18093,38 +18448,38 @@ yydefault: yyLOCAL = stmt } yyVAL.union = yyLOCAL - case 663: + case 669: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:4661 +//line mysql_sql.y:4704 { yyVAL.str = "" } - case 664: + case 670: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:4665 +//line mysql_sql.y:4708 { yyVAL.str = yyDollar[2].cstrUnion().Compare() } - case 665: + case 671: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:4670 +//line mysql_sql.y:4713 { yyLOCAL = -1 } yyVAL.union = yyLOCAL - case 666: + case 672: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:4674 +//line mysql_sql.y:4717 { yyLOCAL = sqlTaskInt64(yyDollar[2].item) } yyVAL.union = yyLOCAL - case 667: + case 673: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4680 +//line mysql_sql.y:4723 { yyLOCAL = &tree.ShowIcebergCatalogs{ Like: yyDollar[4].comparisionExprUnion(), @@ -18132,10 +18487,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 668: + case 674: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4687 +//line mysql_sql.y:4731 { yyLOCAL = &tree.ShowIcebergNamespaces{ Catalog: tree.Identifier(yyDollar[5].cstrUnion().Compare()), @@ -18144,10 +18499,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 669: + case 675: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4695 +//line mysql_sql.y:4739 { yyLOCAL = &tree.ShowIcebergNamespaces{ Catalog: tree.Identifier(yyDollar[6].cstrUnion().Compare()), @@ -18156,10 +18511,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 670: + case 676: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4703 +//line mysql_sql.y:4747 { yyLOCAL = &tree.ShowIcebergNamespaces{ Like: yyDollar[4].comparisionExprUnion(), @@ -18167,10 +18522,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 671: + case 677: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4710 +//line mysql_sql.y:4754 { yyLOCAL = &tree.ShowIcebergTables{ Like: yyDollar[4].comparisionExprUnion(), @@ -18178,10 +18533,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 672: + case 678: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4717 +//line mysql_sql.y:4761 { yyLOCAL = &tree.ShowIcebergTables{ Catalog: tree.Identifier(yyDollar[5].cstrUnion().Compare()), @@ -18190,10 +18545,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 673: + case 679: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4725 +//line mysql_sql.y:4769 { yyLOCAL = &tree.ShowIcebergTables{ Catalog: tree.Identifier(yyDollar[5].cstrUnion().Compare()), @@ -18203,10 +18558,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 674: + case 680: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4734 +//line mysql_sql.y:4778 { yyLOCAL = &tree.ShowIcebergTables{ Catalog: tree.Identifier(yyDollar[6].cstrUnion().Compare()), @@ -18215,10 +18570,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 675: + case 681: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4742 +//line mysql_sql.y:4786 { yyLOCAL = &tree.ShowIcebergTables{ Namespace: yyDollar[6].str, @@ -18227,10 +18582,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 676: + case 682: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4750 +//line mysql_sql.y:4794 { yyLOCAL = &tree.ShowIcebergTables{ Namespace: yyDollar[6].str, @@ -18240,50 +18595,61 @@ yydefault: } } yyVAL.union = yyLOCAL - case 677: + case 683: + yyDollar = yyS[yypt-5 : yypt+1] + var yyLOCAL tree.Statement +//line mysql_sql.y:4805 + { + yyLOCAL = &tree.ShowMongoDBConnections{ + Like: yyDollar[4].comparisionExprUnion(), + Where: yyDollar[5].whereUnion(), + } + } + yyVAL.union = yyLOCAL + case 684: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:4761 +//line mysql_sql.y:4814 { yyVAL.str = yyDollar[1].str } - case 678: + case 685: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4767 +//line mysql_sql.y:4820 { yyLOCAL = &tree.ShowLogserviceReplicas{} } yyVAL.union = yyLOCAL - case 679: + case 686: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4773 +//line mysql_sql.y:4826 { yyLOCAL = &tree.ShowLogserviceStores{} } yyVAL.union = yyLOCAL - case 680: + case 687: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4779 +//line mysql_sql.y:4832 { yyLOCAL = &tree.ShowLogserviceSettings{} } yyVAL.union = yyLOCAL - case 681: + case 688: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4785 +//line mysql_sql.y:4838 { yyLOCAL = &tree.ShowRules{ RoleName: yyDollar[5].cstrUnion().Compare(), } } yyVAL.union = yyLOCAL - case 682: + case 689: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4793 +//line mysql_sql.y:4846 { yyLOCAL = &tree.ShowCollation{ Like: yyDollar[3].comparisionExprUnion(), @@ -18291,50 +18657,50 @@ yydefault: } } yyVAL.union = yyLOCAL - case 683: + case 690: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4802 +//line mysql_sql.y:4855 { yyLOCAL = &tree.ShowStages{ Like: yyDollar[3].comparisionExprUnion(), } } yyVAL.union = yyLOCAL - case 684: + case 691: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4810 +//line mysql_sql.y:4863 { yyLOCAL = &tree.ShowSnapShots{ Where: yyDollar[3].whereUnion(), } } yyVAL.union = yyLOCAL - case 685: + case 692: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4818 +//line mysql_sql.y:4871 { yyLOCAL = &tree.ShowPitr{ Where: yyDollar[3].whereUnion(), } } yyVAL.union = yyLOCAL - case 686: + case 693: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4826 +//line mysql_sql.y:4879 { yyLOCAL = &tree.ShowRecoveryWindow{ Level: tree.RECOVERYWINDOWLEVELACCOUNT, } } yyVAL.union = yyLOCAL - case 687: + case 694: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4832 +//line mysql_sql.y:4885 { yyLOCAL = &tree.ShowRecoveryWindow{ Level: tree.RECOVERYWINDOWLEVELDATABASE, @@ -18342,10 +18708,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 688: + case 695: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4839 +//line mysql_sql.y:4892 { yyLOCAL = &tree.ShowRecoveryWindow{ Level: tree.RECOVERYWINDOWLEVELTABLE, @@ -18354,10 +18720,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 689: + case 696: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4847 +//line mysql_sql.y:4900 { yyLOCAL = &tree.ShowRecoveryWindow{ Level: tree.RECOVERYWINDOWLEVELACCOUNT, @@ -18365,26 +18731,26 @@ yydefault: } } yyVAL.union = yyLOCAL - case 690: + case 697: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4856 +//line mysql_sql.y:4909 { yyLOCAL = &tree.ShowGrants{ShowGrantType: tree.GrantForUser} } yyVAL.union = yyLOCAL - case 691: + case 698: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4860 +//line mysql_sql.y:4913 { yyLOCAL = &tree.ShowGrants{Username: yyDollar[4].usernameRecordUnion().Username, Hostname: yyDollar[4].usernameRecordUnion().Hostname, Roles: yyDollar[5].rolesUnion(), ShowGrantType: tree.GrantForUser} } yyVAL.union = yyLOCAL - case 692: + case 699: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4864 +//line mysql_sql.y:4917 { s := &tree.ShowGrants{} roles := []*tree.Role{ @@ -18395,44 +18761,44 @@ yydefault: yyLOCAL = s } yyVAL.union = yyLOCAL - case 693: + case 700: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*tree.Role -//line mysql_sql.y:4875 +//line mysql_sql.y:4928 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 694: + case 701: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []*tree.Role -//line mysql_sql.y:4879 +//line mysql_sql.y:4932 { yyLOCAL = yyDollar[2].rolesUnion() } yyVAL.union = yyLOCAL - case 695: + case 702: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4885 +//line mysql_sql.y:4938 { yyLOCAL = &tree.ShowTableStatus{DbName: yyDollar[5].str, Like: yyDollar[6].comparisionExprUnion(), Where: yyDollar[7].whereUnion()} } yyVAL.union = yyLOCAL - case 696: + case 703: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:4890 +//line mysql_sql.y:4943 { } - case 698: + case 705: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:4894 +//line mysql_sql.y:4947 { } - case 700: + case 707: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4899 +//line mysql_sql.y:4952 { yyLOCAL = &tree.ShowFunctionOrProcedureStatus{ Like: yyDollar[4].comparisionExprUnion(), @@ -18441,10 +18807,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 701: + case 708: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4909 +//line mysql_sql.y:4962 { yyLOCAL = &tree.ShowFunctionOrProcedureStatus{ Like: yyDollar[4].comparisionExprUnion(), @@ -18453,68 +18819,68 @@ yydefault: } } yyVAL.union = yyLOCAL - case 702: + case 709: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4919 +//line mysql_sql.y:4972 { yyLOCAL = &tree.ShowRolesStmt{ Like: yyDollar[3].comparisionExprUnion(), } } yyVAL.union = yyLOCAL - case 703: + case 710: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4927 +//line mysql_sql.y:4980 { yyLOCAL = &tree.ShowNodeList{} } yyVAL.union = yyLOCAL - case 704: + case 711: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4933 +//line mysql_sql.y:4986 { yyLOCAL = &tree.ShowLocks{} } yyVAL.union = yyLOCAL - case 705: + case 712: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4939 +//line mysql_sql.y:4992 { yyLOCAL = &tree.ShowTableNumber{DbName: yyDollar[4].str} } yyVAL.union = yyLOCAL - case 706: + case 713: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4945 +//line mysql_sql.y:4998 { yyLOCAL = &tree.ShowColumnNumber{Table: yyDollar[3].unresolvedObjectNameUnion(), DbName: yyDollar[4].str} } yyVAL.union = yyLOCAL - case 707: + case 714: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4951 +//line mysql_sql.y:5004 { yyLOCAL = &tree.ShowTableValues{Table: yyDollar[3].unresolvedObjectNameUnion(), DbName: yyDollar[4].str} } yyVAL.union = yyLOCAL - case 708: + case 715: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4957 +//line mysql_sql.y:5010 { yyLOCAL = &tree.ShowTableSize{Table: yyDollar[3].unresolvedObjectNameUnion(), DbName: yyDollar[4].str} } yyVAL.union = yyLOCAL - case 709: + case 716: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4963 +//line mysql_sql.y:5016 { s := yyDollar[2].statementUnion().(*tree.ShowTarget) s.Like = yyDollar[3].comparisionExprUnion() @@ -18522,74 +18888,74 @@ yydefault: yyLOCAL = s } yyVAL.union = yyLOCAL - case 710: + case 717: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4972 +//line mysql_sql.y:5025 { yyLOCAL = &tree.ShowTarget{Type: tree.ShowConfig} } yyVAL.union = yyLOCAL - case 711: + case 718: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4976 +//line mysql_sql.y:5029 { yyLOCAL = &tree.ShowTarget{Type: tree.ShowCharset} } yyVAL.union = yyLOCAL - case 712: + case 719: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4980 +//line mysql_sql.y:5033 { yyLOCAL = &tree.ShowTarget{Type: tree.ShowEngines} } yyVAL.union = yyLOCAL - case 713: + case 720: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4984 +//line mysql_sql.y:5037 { yyLOCAL = &tree.ShowTarget{DbName: yyDollar[3].str, Type: tree.ShowTriggers} } yyVAL.union = yyLOCAL - case 714: + case 721: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4988 +//line mysql_sql.y:5041 { yyLOCAL = &tree.ShowTarget{DbName: yyDollar[3].str, Type: tree.ShowEvents} } yyVAL.union = yyLOCAL - case 715: + case 722: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4992 +//line mysql_sql.y:5045 { yyLOCAL = &tree.ShowTarget{Type: tree.ShowPlugins} } yyVAL.union = yyLOCAL - case 716: + case 723: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:4996 +//line mysql_sql.y:5049 { yyLOCAL = &tree.ShowTarget{Type: tree.ShowPrivileges} } yyVAL.union = yyLOCAL - case 717: + case 724: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5000 +//line mysql_sql.y:5053 { yyLOCAL = &tree.ShowTarget{Type: tree.ShowProfiles} } yyVAL.union = yyLOCAL - case 718: + case 725: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5006 +//line mysql_sql.y:5059 { yyLOCAL = &tree.ShowIndex{ TableName: yyDollar[4].unresolvedObjectNameUnion(), @@ -18598,20 +18964,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 719: + case 726: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:5015 +//line mysql_sql.y:5068 { } - case 720: + case 727: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:5017 +//line mysql_sql.y:5070 { } - case 724: + case 731: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5026 +//line mysql_sql.y:5079 { yyLOCAL = &tree.ShowVariables{ Global: yyDollar[2].boolValUnion(), @@ -18620,10 +18986,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 725: + case 732: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5036 +//line mysql_sql.y:5089 { yyLOCAL = &tree.ShowStatus{ Global: yyDollar[2].boolValUnion(), @@ -18632,58 +18998,58 @@ yydefault: } } yyVAL.union = yyLOCAL - case 726: + case 733: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:5045 +//line mysql_sql.y:5098 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 727: + case 734: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:5049 +//line mysql_sql.y:5102 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 728: + case 735: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:5053 +//line mysql_sql.y:5106 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 729: + case 736: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5059 +//line mysql_sql.y:5112 { yyLOCAL = &tree.ShowWarnings{} } yyVAL.union = yyLOCAL - case 730: + case 737: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5065 +//line mysql_sql.y:5118 { yyLOCAL = &tree.ShowErrors{} } yyVAL.union = yyLOCAL - case 731: + case 738: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5071 +//line mysql_sql.y:5124 { yyLOCAL = &tree.ShowProcessList{Full: yyDollar[2].fullOptUnion()} } yyVAL.union = yyLOCAL - case 732: + case 739: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5077 +//line mysql_sql.y:5130 { yyLOCAL = &tree.ShowSequences{ DBName: yyDollar[3].str, @@ -18691,10 +19057,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 733: + case 740: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5086 +//line mysql_sql.y:5139 { yyLOCAL = &tree.ShowTables{ Open: false, @@ -18706,10 +19072,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 734: + case 741: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5097 +//line mysql_sql.y:5150 { yyLOCAL = &tree.ShowTables{ Open: true, @@ -18720,10 +19086,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 735: + case 742: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5109 +//line mysql_sql.y:5162 { yyLOCAL = &tree.ShowDatabases{ Like: yyDollar[3].comparisionExprUnion(), @@ -18732,18 +19098,18 @@ yydefault: } } yyVAL.union = yyLOCAL - case 736: + case 743: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5117 +//line mysql_sql.y:5170 { yyLOCAL = &tree.ShowDatabases{Like: yyDollar[3].comparisionExprUnion(), Where: yyDollar[4].whereUnion()} } yyVAL.union = yyLOCAL - case 737: + case 744: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5123 +//line mysql_sql.y:5176 { yyLOCAL = &tree.ShowColumns{ Ext: false, @@ -18756,10 +19122,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 738: + case 745: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5135 +//line mysql_sql.y:5188 { yyLOCAL = &tree.ShowColumns{ Ext: true, @@ -18772,134 +19138,134 @@ yydefault: } } yyVAL.union = yyLOCAL - case 739: + case 746: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5149 +//line mysql_sql.y:5202 { yyLOCAL = &tree.ShowAccounts{Like: yyDollar[3].comparisionExprUnion()} } yyVAL.union = yyLOCAL - case 740: + case 747: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5155 +//line mysql_sql.y:5208 { yyLOCAL = &tree.ShowPublications{Like: yyDollar[3].comparisionExprUnion()} } yyVAL.union = yyLOCAL - case 741: + case 748: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5161 +//line mysql_sql.y:5214 { yyLOCAL = &tree.ShowPublicationCoverage{Name: yyDollar[4].str} } yyVAL.union = yyLOCAL - case 742: + case 749: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5167 +//line mysql_sql.y:5220 { yyLOCAL = &tree.ShowAccountUpgrade{} } yyVAL.union = yyLOCAL - case 743: + case 750: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5173 +//line mysql_sql.y:5226 { yyLOCAL = &tree.ShowSubscriptions{Like: yyDollar[3].comparisionExprUnion()} } yyVAL.union = yyLOCAL - case 744: + case 751: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5177 +//line mysql_sql.y:5230 { yyLOCAL = &tree.ShowSubscriptions{All: true, Like: yyDollar[4].comparisionExprUnion()} } yyVAL.union = yyLOCAL - case 745: + case 752: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5183 +//line mysql_sql.y:5236 { yyLOCAL = &tree.ShowCcprSubscriptions{TaskId: yyDollar[4].str} } yyVAL.union = yyLOCAL - case 746: + case 753: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5187 +//line mysql_sql.y:5240 { yyLOCAL = &tree.ShowCcprSubscriptions{} } yyVAL.union = yyLOCAL - case 747: + case 754: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.ComparisonExpr -//line mysql_sql.y:5192 +//line mysql_sql.y:5245 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 748: + case 755: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.ComparisonExpr -//line mysql_sql.y:5196 +//line mysql_sql.y:5249 { yyLOCAL = tree.NewComparisonExpr(tree.LIKE, nil, yyDollar[2].exprUnion()) } yyVAL.union = yyLOCAL - case 749: + case 756: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.ComparisonExpr -//line mysql_sql.y:5200 +//line mysql_sql.y:5253 { yyLOCAL = tree.NewComparisonExpr(tree.ILIKE, nil, yyDollar[2].exprUnion()) } yyVAL.union = yyLOCAL - case 750: + case 757: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:5205 +//line mysql_sql.y:5258 { yyVAL.str = "" } - case 751: + case 758: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:5209 +//line mysql_sql.y:5262 { yyVAL.str = yyDollar[2].cstrUnion().Compare() } - case 752: + case 759: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.UnresolvedObjectName -//line mysql_sql.y:5215 +//line mysql_sql.y:5268 { yyLOCAL = yyDollar[2].unresolvedObjectNameUnion() } yyVAL.union = yyLOCAL - case 757: + case 764: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:5228 +//line mysql_sql.y:5281 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 758: + case 765: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:5232 +//line mysql_sql.y:5285 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 759: + case 766: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5238 +//line mysql_sql.y:5291 { yyLOCAL = &tree.ShowCreateTable{ Name: yyDollar[4].unresolvedObjectNameUnion(), @@ -18907,10 +19273,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 760: + case 767: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5246 +//line mysql_sql.y:5299 { yyLOCAL = &tree.ShowCreateView{ Name: yyDollar[4].unresolvedObjectNameUnion(), @@ -18918,10 +19284,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 761: + case 768: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5253 +//line mysql_sql.y:5306 { yyLOCAL = &tree.ShowCreateDatabase{ IfNotExists: yyDollar[4].ifNotExistsUnion(), @@ -18930,94 +19296,94 @@ yydefault: } } yyVAL.union = yyLOCAL - case 762: + case 769: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5261 +//line mysql_sql.y:5314 { yyLOCAL = &tree.ShowCreatePublications{Name: yyDollar[4].str} } yyVAL.union = yyLOCAL - case 763: + case 770: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5267 +//line mysql_sql.y:5320 { yyLOCAL = &tree.ShowBackendServers{} } yyVAL.union = yyLOCAL - case 764: + case 771: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.UnresolvedObjectName -//line mysql_sql.y:5273 +//line mysql_sql.y:5326 { tblName := yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) yyLOCAL = tree.NewUnresolvedObjectName(tblName) } yyVAL.union = yyLOCAL - case 765: + case 772: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.UnresolvedObjectName -//line mysql_sql.y:5278 +//line mysql_sql.y:5331 { dbName := yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) tblName := yylex.(*Lexer).GetDbOrTblName(yyDollar[3].cstrUnion().Origin()) yyLOCAL = tree.NewUnresolvedObjectName(dbName, tblName) } yyVAL.union = yyLOCAL - case 766: + case 773: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:5286 +//line mysql_sql.y:5339 { yyVAL.str = yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) } - case 767: + case 774: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.UnresolvedObjectName -//line mysql_sql.y:5292 +//line mysql_sql.y:5345 { tblName := yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) yyLOCAL = tree.NewUnresolvedObjectName(tblName) } yyVAL.union = yyLOCAL - case 768: + case 775: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.UnresolvedObjectName -//line mysql_sql.y:5297 +//line mysql_sql.y:5350 { dbName := yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) tblName := yylex.(*Lexer).GetDbOrTblName(yyDollar[3].cstrUnion().Origin()) yyLOCAL = tree.NewUnresolvedObjectName(dbName, tblName) } yyVAL.union = yyLOCAL - case 769: + case 776: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.UnresolvedObjectName -//line mysql_sql.y:5303 +//line mysql_sql.y:5356 { yyLOCAL = tree.NewUnresolvedObjectName(yyDollar[1].cstrUnion().Compare(), yyDollar[3].cstrUnion().Compare(), yyDollar[5].cstrUnion().Compare()) } yyVAL.union = yyLOCAL - case 770: + case 777: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5309 +//line mysql_sql.y:5362 { yyLOCAL = tree.NewTruncateTable(yyDollar[2].tableNameUnion()) } yyVAL.union = yyLOCAL - case 771: + case 778: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5313 +//line mysql_sql.y:5366 { yyLOCAL = tree.NewTruncateTable(yyDollar[3].tableNameUnion()) } yyVAL.union = yyLOCAL - case 793: + case 801: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5344 +//line mysql_sql.y:5398 { yyLOCAL = &tree.DropSQLTask{ IfExists: yyDollar[3].boolValUnion(), @@ -19025,10 +19391,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 794: + case 802: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5353 +//line mysql_sql.y:5407 { yyLOCAL = &tree.DropIcebergCatalog{ IfExists: yyDollar[4].boolValUnion(), @@ -19036,56 +19402,67 @@ yydefault: } } yyVAL.union = yyLOCAL - case 795: + case 803: + yyDollar = yyS[yypt-5 : yypt+1] + var yyLOCAL tree.Statement +//line mysql_sql.y:5416 + { + yyLOCAL = &tree.DropMongoDBConnection{ + IfExists: yyDollar[4].boolValUnion(), + Name: tree.Identifier(yyDollar[5].cstrUnion().Compare()), + } + } + yyVAL.union = yyLOCAL + case 804: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5362 +//line mysql_sql.y:5425 { var ifExists = yyDollar[3].boolValUnion() var name = yyDollar[4].tableNamesUnion() yyLOCAL = tree.NewDropSequence(ifExists, name) } yyVAL.union = yyLOCAL - case 796: + case 805: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5370 +//line mysql_sql.y:5433 { var ifExists = yyDollar[3].boolValUnion() var name = yyDollar[4].exprUnion() yyLOCAL = tree.NewDropAccount(ifExists, name) } yyVAL.union = yyLOCAL - case 797: + case 806: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5378 +//line mysql_sql.y:5441 { var ifExists = yyDollar[3].boolValUnion() var users = yyDollar[4].usersUnion() yyLOCAL = tree.NewDropUser(ifExists, users) } yyVAL.union = yyLOCAL - case 798: + case 807: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.User -//line mysql_sql.y:5386 +//line mysql_sql.y:5449 { yyLOCAL = []*tree.User{yyDollar[1].userUnion()} } yyVAL.union = yyLOCAL - case 799: + case 808: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.User -//line mysql_sql.y:5390 +//line mysql_sql.y:5453 { yyLOCAL = append(yyDollar[1].usersUnion(), yyDollar[3].userUnion()) } yyVAL.union = yyLOCAL - case 800: + case 809: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.User -//line mysql_sql.y:5396 +//line mysql_sql.y:5459 { var Username = yyDollar[1].usernameRecordUnion().Username var Hostname = yyDollar[1].usernameRecordUnion().Hostname @@ -19097,20 +19474,20 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 801: + case 810: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5409 +//line mysql_sql.y:5472 { var ifExists = yyDollar[3].boolValUnion() var roles = yyDollar[4].rolesUnion() yyLOCAL = tree.NewDropRole(ifExists, roles) } yyVAL.union = yyLOCAL - case 802: + case 811: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5417 +//line mysql_sql.y:5480 { var name = tree.Identifier(yyDollar[4].cstrUnion().Compare()) var tableName = yyDollar[6].tableNameUnion() @@ -19118,126 +19495,126 @@ yydefault: yyLOCAL = tree.NewDropIndex(name, tableName, ifExists) } yyVAL.union = yyLOCAL - case 803: + case 812: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5426 +//line mysql_sql.y:5489 { var ifExists = yyDollar[4].boolValUnion() var names = yyDollar[5].tableNamesUnion() yyLOCAL = tree.NewDropTable(ifExists, names) } yyVAL.union = yyLOCAL - case 804: + case 813: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5432 +//line mysql_sql.y:5495 { var ifExists = yyDollar[3].boolValUnion() var names = yyDollar[4].tableNamesUnion() yyLOCAL = tree.NewDropTable(ifExists, names) } yyVAL.union = yyLOCAL - case 805: + case 814: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5440 +//line mysql_sql.y:5503 { var ifExists = yyDollar[3].boolValUnion() var names = yyDollar[4].tableNamesUnion() yyLOCAL = tree.NewDropConnector(ifExists, names) } yyVAL.union = yyLOCAL - case 806: + case 815: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5448 +//line mysql_sql.y:5511 { var ifExists = yyDollar[3].boolValUnion() var names = yyDollar[4].tableNamesUnion() yyLOCAL = tree.NewDropView(ifExists, names) } yyVAL.union = yyLOCAL - case 807: + case 816: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5456 +//line mysql_sql.y:5519 { var name = tree.Identifier(yyDollar[4].cstrUnion().Compare()) var ifExists = yyDollar[3].boolValUnion() yyLOCAL = tree.NewDropDatabase(name, ifExists) } yyVAL.union = yyLOCAL - case 808: + case 817: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5462 +//line mysql_sql.y:5525 { var name = tree.Identifier(yyDollar[4].cstrUnion().Compare()) var ifExists = yyDollar[3].boolValUnion() yyLOCAL = tree.NewDropDatabase(name, ifExists) } yyVAL.union = yyLOCAL - case 809: + case 818: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5470 +//line mysql_sql.y:5533 { yyLOCAL = tree.NewDeallocate(tree.Identifier(yyDollar[3].str), true) } yyVAL.union = yyLOCAL - case 810: + case 819: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5476 +//line mysql_sql.y:5539 { var name = yyDollar[3].functionNameUnion() var args = yyDollar[5].funcArgsUnion() yyLOCAL = tree.NewDropFunction(name, args) } yyVAL.union = yyLOCAL - case 811: + case 820: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5484 +//line mysql_sql.y:5547 { var name = yyDollar[3].procNameUnion() var ifExists = false yyLOCAL = tree.NewDropProcedure(name, ifExists) } yyVAL.union = yyLOCAL - case 812: + case 821: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5490 +//line mysql_sql.y:5553 { var name = yyDollar[5].procNameUnion() var ifExists = true yyLOCAL = tree.NewDropProcedure(name, ifExists) } yyVAL.union = yyLOCAL - case 815: + case 824: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5500 +//line mysql_sql.y:5563 { yyDollar[2].statementUnion().(*tree.Delete).With = yyDollar[1].withClauseUnion() yyLOCAL = yyDollar[2].statementUnion() } yyVAL.union = yyLOCAL - case 816: + case 825: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5505 +//line mysql_sql.y:5568 { yyDollar[2].statementUnion().(*tree.Delete).With = yyDollar[1].withClauseUnion() yyLOCAL = yyDollar[2].statementUnion() } yyVAL.union = yyLOCAL - case 817: + case 826: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5512 +//line mysql_sql.y:5575 { // Single-Table Syntax t := &tree.AliasedTableExpr{ @@ -19254,10 +19631,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 818: + case 827: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5528 +//line mysql_sql.y:5591 { // Multiple-Table Syntax yyLOCAL = &tree.Delete{ @@ -19267,10 +19644,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 819: + case 828: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5539 +//line mysql_sql.y:5602 { // Multiple-Table Syntax yyLOCAL = &tree.Delete{ @@ -19280,36 +19657,36 @@ yydefault: } } yyVAL.union = yyLOCAL - case 820: + case 829: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableExprs -//line mysql_sql.y:5550 +//line mysql_sql.y:5613 { yyLOCAL = tree.TableExprs{yyDollar[1].tableNameUnion()} } yyVAL.union = yyLOCAL - case 821: + case 830: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableExprs -//line mysql_sql.y:5554 +//line mysql_sql.y:5617 { yyLOCAL = append(yyDollar[1].tableExprsUnion(), yyDollar[3].tableNameUnion()) } yyVAL.union = yyLOCAL - case 822: + case 831: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.TableName -//line mysql_sql.y:5560 +//line mysql_sql.y:5623 { tblName := yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) prefix := tree.ObjectNamePrefix{ExplicitSchema: false} yyLOCAL = tree.NewTableName(tree.Identifier(tblName), prefix, nil) } yyVAL.union = yyLOCAL - case 823: + case 832: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.TableName -//line mysql_sql.y:5566 +//line mysql_sql.y:5629 { dbName := yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) tblName := yylex.(*Lexer).GetDbOrTblName(yyDollar[3].cstrUnion().Origin()) @@ -19317,47 +19694,47 @@ yydefault: yyLOCAL = tree.NewTableName(tree.Identifier(tblName), prefix, nil) } yyVAL.union = yyLOCAL - case 824: + case 833: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:5575 +//line mysql_sql.y:5638 { } - case 825: + case 834: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:5577 +//line mysql_sql.y:5640 { } - case 826: + case 835: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:5580 +//line mysql_sql.y:5643 { } - case 831: + case 840: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:5589 +//line mysql_sql.y:5652 { } - case 833: + case 842: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:5593 +//line mysql_sql.y:5656 { yyVAL.str = "" } - case 834: + case 843: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:5597 +//line mysql_sql.y:5660 { yyVAL.str = "ignore" } - case 835: + case 844: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:5605 +//line mysql_sql.y:5668 { } - case 838: + case 847: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5611 +//line mysql_sql.y:5674 { rep := yyDollar[5].replaceUnion() rep.Table = yyDollar[3].tableExprUnion() @@ -19365,10 +19742,10 @@ yydefault: yyLOCAL = rep } yyVAL.union = yyLOCAL - case 839: + case 848: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.Replace -//line mysql_sql.y:5620 +//line mysql_sql.y:5683 { vc := tree.NewValuesClause(yyDollar[2].rowsExprsUnion()) yyLOCAL = &tree.Replace{ @@ -19376,20 +19753,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 840: + case 849: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.Replace -//line mysql_sql.y:5627 +//line mysql_sql.y:5690 { yyLOCAL = &tree.Replace{ Rows: yyDollar[1].selectUnion(), } } yyVAL.union = yyLOCAL - case 841: + case 850: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Replace -//line mysql_sql.y:5633 +//line mysql_sql.y:5696 { yyLOCAL = &tree.Replace{ Columns: yyDollar[2].identifierListUnion(), @@ -19397,20 +19774,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 842: + case 851: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.Replace -//line mysql_sql.y:5640 +//line mysql_sql.y:5703 { yyLOCAL = &tree.Replace{ Rows: yyDollar[1].selectUnion(), } } yyVAL.union = yyLOCAL - case 843: + case 852: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.Replace -//line mysql_sql.y:5646 +//line mysql_sql.y:5709 { vc := tree.NewValuesClause(yyDollar[5].rowsExprsUnion()) yyLOCAL = &tree.Replace{ @@ -19419,10 +19796,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 844: + case 853: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Replace -//line mysql_sql.y:5654 +//line mysql_sql.y:5717 { vc := tree.NewValuesClause(yyDollar[4].rowsExprsUnion()) yyLOCAL = &tree.Replace{ @@ -19430,10 +19807,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 845: + case 854: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Replace -//line mysql_sql.y:5661 +//line mysql_sql.y:5724 { yyLOCAL = &tree.Replace{ Columns: yyDollar[2].identifierListUnion(), @@ -19441,10 +19818,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 846: + case 855: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.Replace -//line mysql_sql.y:5668 +//line mysql_sql.y:5731 { if yyDollar[2].assignmentsUnion() == nil { yylex.Error("the set list of replace can not be empty") @@ -19464,29 +19841,29 @@ yydefault: } } yyVAL.union = yyLOCAL - case 847: + case 856: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Select -//line mysql_sql.y:5689 +//line mysql_sql.y:5752 { // MySQL treats TABLE as a query source, so ORDER BY and LIMIT belong to // the SELECT wrapper produced by the TABLE-to-SELECT rewrite. yyLOCAL = tree.NewSelect(makeSelectStarFromTable(yyDollar[2].tableNameUnion()), yyDollar[3].orderByUnion(), yyDollar[4].limitUnion()) } yyVAL.union = yyLOCAL - case 849: + case 858: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5698 +//line mysql_sql.y:5761 { yyDollar[2].statementUnion().(*tree.Insert).With = yyDollar[1].withClauseUnion() yyLOCAL = yyDollar[2].statementUnion() } yyVAL.union = yyLOCAL - case 850: + case 859: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5705 +//line mysql_sql.y:5768 { ins := yyDollar[4].insertUnion() ins.Table = yyDollar[2].tableExprUnion() @@ -19498,10 +19875,10 @@ yydefault: yyLOCAL = ins } yyVAL.union = yyLOCAL - case 851: + case 860: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5716 +//line mysql_sql.y:5779 { ins := yyDollar[5].insertUnion() ins.Table = yyDollar[3].tableExprUnion() @@ -19513,10 +19890,10 @@ yydefault: yyLOCAL = ins } yyVAL.union = yyLOCAL - case 852: + case 861: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5727 +//line mysql_sql.y:5790 { ins := yyDollar[5].insertUnion() ins.Table = yyDollar[3].tableExprUnion() @@ -19528,27 +19905,27 @@ yydefault: yyLOCAL = ins } yyVAL.union = yyLOCAL - case 853: + case 862: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5740 +//line mysql_sql.y:5803 { yyLOCAL = yyDollar[1].mergeUnion() } yyVAL.union = yyLOCAL - case 854: + case 863: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:5744 +//line mysql_sql.y:5807 { yyDollar[2].mergeUnion().With = yyDollar[1].withClauseUnion() yyLOCAL = yyDollar[2].mergeUnion() } yyVAL.union = yyLOCAL - case 855: + case 864: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *tree.Merge -//line mysql_sql.y:5751 +//line mysql_sql.y:5814 { yyLOCAL = &tree.Merge{ Target: yyDollar[3].tableExprUnion(), @@ -19558,26 +19935,26 @@ yydefault: } } yyVAL.union = yyLOCAL - case 856: + case 865: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.MergeClauses -//line mysql_sql.y:5762 +//line mysql_sql.y:5825 { yyLOCAL = tree.MergeClauses{yyDollar[1].mergeClauseUnion()} } yyVAL.union = yyLOCAL - case 857: + case 866: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.MergeClauses -//line mysql_sql.y:5766 +//line mysql_sql.y:5829 { yyLOCAL = append(yyDollar[1].mergeClausesUnion(), yyDollar[2].mergeClauseUnion()) } yyVAL.union = yyLOCAL - case 858: + case 867: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *tree.MergeClause -//line mysql_sql.y:5772 +//line mysql_sql.y:5835 { yyLOCAL = &tree.MergeClause{ Matched: true, @@ -19587,10 +19964,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 859: + case 868: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.MergeClause -//line mysql_sql.y:5781 +//line mysql_sql.y:5844 { yyLOCAL = &tree.MergeClause{ Matched: true, @@ -19599,10 +19976,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 860: + case 869: yyDollar = yyS[yypt-13 : yypt+1] var yyLOCAL *tree.MergeClause -//line mysql_sql.y:5789 +//line mysql_sql.y:5852 { yyLOCAL = &tree.MergeClause{ Matched: false, @@ -19613,10 +19990,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 861: + case 870: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL *tree.MergeClause -//line mysql_sql.y:5799 +//line mysql_sql.y:5862 { yyLOCAL = &tree.MergeClause{ Matched: false, @@ -19626,9 +20003,9 @@ yydefault: } } yyVAL.union = yyLOCAL - case 862: + case 871: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:5810 +//line mysql_sql.y:5873 { if !strings.EqualFold(yyDollar[1].cstrUnion().Origin(), "matched") { yylex.Error("expected MATCHED") @@ -19636,42 +20013,42 @@ yydefault: } yyVAL.str = yyDollar[1].cstrUnion().Origin() } - case 863: + case 872: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:5819 +//line mysql_sql.y:5882 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 864: + case 873: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:5823 +//line mysql_sql.y:5886 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 865: + case 874: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:5829 +//line mysql_sql.y:5892 { yyLOCAL = tree.IdentifierList{tree.Identifier(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 866: + case 875: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:5833 +//line mysql_sql.y:5896 { yyLOCAL = append(yyDollar[1].identifierListUnion(), tree.Identifier(yyDollar[3].str)) } yyVAL.union = yyLOCAL - case 867: + case 876: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.Insert -//line mysql_sql.y:5839 +//line mysql_sql.y:5902 { vc := tree.NewValuesClause(yyDollar[2].rowsExprsUnion()) yyLOCAL = &tree.Insert{ @@ -19679,20 +20056,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 868: + case 877: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.Insert -//line mysql_sql.y:5846 +//line mysql_sql.y:5909 { yyLOCAL = &tree.Insert{ Rows: yyDollar[1].selectUnion(), } } yyVAL.union = yyLOCAL - case 869: + case 878: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.Insert -//line mysql_sql.y:5852 +//line mysql_sql.y:5915 { vc := tree.NewValuesClause(yyDollar[5].rowsExprsUnion()) yyLOCAL = &tree.Insert{ @@ -19701,10 +20078,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 870: + case 879: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Insert -//line mysql_sql.y:5860 +//line mysql_sql.y:5923 { vc := tree.NewValuesClause(yyDollar[4].rowsExprsUnion()) yyLOCAL = &tree.Insert{ @@ -19712,10 +20089,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 871: + case 880: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Insert -//line mysql_sql.y:5867 +//line mysql_sql.y:5930 { yyLOCAL = &tree.Insert{ Columns: yyDollar[2].identifierListUnion(), @@ -19723,10 +20100,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 872: + case 881: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.Insert -//line mysql_sql.y:5874 +//line mysql_sql.y:5937 { if yyDollar[2].assignmentsUnion() == nil { yylex.Error("the set list of insert can not be empty") @@ -19745,58 +20122,58 @@ yydefault: } } yyVAL.union = yyLOCAL - case 873: + case 882: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.UpdateExprs -//line mysql_sql.y:5893 +//line mysql_sql.y:5956 { yyLOCAL = []*tree.UpdateExpr{} } yyVAL.union = yyLOCAL - case 874: + case 883: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.UpdateExprs -//line mysql_sql.y:5897 +//line mysql_sql.y:5960 { yyLOCAL = yyDollar[5].updateExprsUnion() } yyVAL.union = yyLOCAL - case 875: + case 884: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.UpdateExprs -//line mysql_sql.y:5901 +//line mysql_sql.y:5964 { yyLOCAL = []*tree.UpdateExpr{nil} } yyVAL.union = yyLOCAL - case 876: + case 885: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*tree.Assignment -//line mysql_sql.y:5906 +//line mysql_sql.y:5969 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 877: + case 886: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.Assignment -//line mysql_sql.y:5910 +//line mysql_sql.y:5973 { yyLOCAL = []*tree.Assignment{yyDollar[1].assignmentUnion()} } yyVAL.union = yyLOCAL - case 878: + case 887: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.Assignment -//line mysql_sql.y:5914 +//line mysql_sql.y:5977 { yyLOCAL = append(yyDollar[1].assignmentsUnion(), yyDollar[3].assignmentUnion()) } yyVAL.union = yyLOCAL - case 879: + case 888: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.Assignment -//line mysql_sql.y:5920 +//line mysql_sql.y:5983 { yyLOCAL = &tree.Assignment{ Column: tree.Identifier(yyDollar[1].str), @@ -19804,195 +20181,195 @@ yydefault: } } yyVAL.union = yyLOCAL - case 880: + case 889: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:5929 +//line mysql_sql.y:5992 { yyLOCAL = tree.IdentifierList{tree.Identifier(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 881: + case 890: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:5933 +//line mysql_sql.y:5996 { yyLOCAL = append(yyDollar[1].identifierListUnion(), tree.Identifier(yyDollar[3].str)) } yyVAL.union = yyLOCAL - case 882: + case 891: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:5939 +//line mysql_sql.y:6002 { yyVAL.str = yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) } - case 883: + case 892: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:5943 +//line mysql_sql.y:6006 { yyVAL.str = yylex.(*Lexer).GetDbOrTblName(yyDollar[3].cstrUnion().Origin()) } - case 884: + case 893: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []tree.Exprs -//line mysql_sql.y:5949 +//line mysql_sql.y:6012 { yyLOCAL = []tree.Exprs{yyDollar[1].exprsUnion()} } yyVAL.union = yyLOCAL - case 885: + case 894: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []tree.Exprs -//line mysql_sql.y:5953 +//line mysql_sql.y:6016 { yyLOCAL = append(yyDollar[1].rowsExprsUnion(), yyDollar[3].exprsUnion()) } yyVAL.union = yyLOCAL - case 886: + case 895: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Exprs -//line mysql_sql.y:5959 +//line mysql_sql.y:6022 { yyLOCAL = yyDollar[3].exprsUnion() } yyVAL.union = yyLOCAL - case 887: + case 896: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:5964 +//line mysql_sql.y:6027 { } - case 889: + case 898: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.Exprs -//line mysql_sql.y:5968 +//line mysql_sql.y:6031 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 891: + case 900: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Exprs -//line mysql_sql.y:5975 +//line mysql_sql.y:6038 { yyLOCAL = tree.Exprs{yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 892: + case 901: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Exprs -//line mysql_sql.y:5979 +//line mysql_sql.y:6042 { yyLOCAL = append(yyDollar[1].exprsUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 894: + case 903: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:5986 +//line mysql_sql.y:6049 { yyLOCAL = &tree.DefaultVal{} } yyVAL.union = yyLOCAL - case 895: + case 904: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:5991 +//line mysql_sql.y:6054 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 896: + case 905: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:5995 +//line mysql_sql.y:6058 { yyLOCAL = yyDollar[3].identifierListUnion() } yyVAL.union = yyLOCAL - case 897: + case 906: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.InsertPartitionClause -//line mysql_sql.y:6000 +//line mysql_sql.y:6063 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 898: + case 907: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.InsertPartitionClause -//line mysql_sql.y:6004 +//line mysql_sql.y:6067 { yyLOCAL = &tree.InsertPartitionClause{Names: yyDollar[3].identifierListUnion()} } yyVAL.union = yyLOCAL - case 899: + case 908: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.InsertPartitionClause -//line mysql_sql.y:6008 +//line mysql_sql.y:6071 { yyLOCAL = &tree.InsertPartitionClause{Values: yyDollar[3].partitionValuesUnion()} } yyVAL.union = yyLOCAL - case 900: + case 909: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.PartitionValues -//line mysql_sql.y:6014 +//line mysql_sql.y:6077 { yyLOCAL = tree.PartitionValues{{Name: tree.Identifier(yyDollar[1].cstrUnion().Compare()), Expr: yyDollar[3].exprUnion()}} } yyVAL.union = yyLOCAL - case 901: + case 910: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.PartitionValues -//line mysql_sql.y:6018 +//line mysql_sql.y:6081 { yyLOCAL = append(yyDollar[1].partitionValuesUnion(), tree.PartitionValue{Name: tree.Identifier(yyDollar[3].cstrUnion().Compare()), Expr: yyDollar[5].exprUnion()}) } yyVAL.union = yyLOCAL - case 902: + case 911: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:6024 +//line mysql_sql.y:6087 { yyLOCAL = tree.IdentifierList{tree.Identifier(yyDollar[1].cstrUnion().Compare())} } yyVAL.union = yyLOCAL - case 903: + case 912: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:6028 +//line mysql_sql.y:6091 { yyLOCAL = append(yyDollar[1].identifierListUnion(), tree.Identifier(yyDollar[3].cstrUnion().Compare())) } yyVAL.union = yyLOCAL - case 904: + case 913: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.TableExpr -//line mysql_sql.y:6034 +//line mysql_sql.y:6097 { yyLOCAL = yyDollar[2].tableNameUnion() } yyVAL.union = yyLOCAL - case 905: + case 914: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableExpr -//line mysql_sql.y:6038 +//line mysql_sql.y:6101 { yyLOCAL = yyDollar[1].tableNameUnion() } yyVAL.union = yyLOCAL - case 906: + case 915: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.ExportParam -//line mysql_sql.y:6043 +//line mysql_sql.y:6106 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 907: + case 916: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL *tree.ExportParam -//line mysql_sql.y:6047 +//line mysql_sql.y:6110 { yyLOCAL = &tree.ExportParam{ Outfile: true, @@ -20007,15 +20384,15 @@ yydefault: } } yyVAL.union = yyLOCAL - case 908: + case 917: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:6062 +//line mysql_sql.y:6125 { yyVAL.str = "" } - case 909: + case 918: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:6066 +//line mysql_sql.y:6129 { str := strings.ToLower(yyDollar[2].str) if str != "csv" && str != "jsonline" && str != "parquet" { @@ -20024,18 +20401,18 @@ yydefault: } yyVAL.str = str } - case 910: + case 919: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6076 +//line mysql_sql.y:6139 { yyLOCAL = uint64(0) } yyVAL.union = yyLOCAL - case 911: + case 920: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6080 +//line mysql_sql.y:6143 { size, err := util.ParseDataSize(yyDollar[2].str) if err != nil { @@ -20045,10 +20422,10 @@ yydefault: yyLOCAL = size } yyVAL.union = yyLOCAL - case 912: + case 921: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.Fields -//line mysql_sql.y:6090 +//line mysql_sql.y:6153 { yyLOCAL = &tree.Fields{ Terminated: &tree.Terminated{ @@ -20060,10 +20437,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 913: + case 922: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Fields -//line mysql_sql.y:6101 +//line mysql_sql.y:6164 { yyLOCAL = &tree.Fields{ Terminated: &tree.Terminated{ @@ -20075,10 +20452,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 914: + case 923: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *tree.Fields -//line mysql_sql.y:6112 +//line mysql_sql.y:6175 { str := yyDollar[7].str if str != "\\" && len(str) > 1 { @@ -20101,10 +20478,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 915: + case 924: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Fields -//line mysql_sql.y:6134 +//line mysql_sql.y:6197 { str := yyDollar[4].str if str != "\\" && len(str) > 1 { @@ -20127,10 +20504,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 916: + case 925: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.Lines -//line mysql_sql.y:6157 +//line mysql_sql.y:6220 { yyLOCAL = &tree.Lines{ TerminatedBy: &tree.Terminated{ @@ -20139,10 +20516,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 917: + case 926: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.Lines -//line mysql_sql.y:6165 +//line mysql_sql.y:6228 { yyLOCAL = &tree.Lines{ TerminatedBy: &tree.Terminated{ @@ -20151,18 +20528,18 @@ yydefault: } } yyVAL.union = yyLOCAL - case 918: + case 927: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:6174 +//line mysql_sql.y:6237 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 919: + case 928: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:6178 +//line mysql_sql.y:6241 { str := strings.ToLower(yyDollar[2].str) if str == "true" { @@ -20175,143 +20552,144 @@ yydefault: } } yyVAL.union = yyLOCAL - case 920: + case 929: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:6191 +//line mysql_sql.y:6254 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 921: + case 930: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:6195 +//line mysql_sql.y:6258 { yyLOCAL = yyDollar[2].item.(int64) } yyVAL.union = yyLOCAL - case 922: + case 931: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:6200 +//line mysql_sql.y:6263 { yyLOCAL = []string{} } yyVAL.union = yyLOCAL - case 923: + case 932: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:6204 +//line mysql_sql.y:6267 { yyLOCAL = yyDollar[3].strsUnion() } yyVAL.union = yyLOCAL - case 924: + case 933: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:6210 +//line mysql_sql.y:6273 { yyLOCAL = make([]string, 0, 4) yyLOCAL = append(yyLOCAL, yyDollar[1].cstrUnion().Compare()) } yyVAL.union = yyLOCAL - case 925: + case 934: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:6215 +//line mysql_sql.y:6278 { yyLOCAL = append(yyDollar[1].strsUnion(), yyDollar[3].cstrUnion().Compare()) } yyVAL.union = yyLOCAL - case 927: + case 936: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.Select -//line mysql_sql.y:6222 +//line mysql_sql.y:6285 { yyLOCAL = &tree.Select{Select: yyDollar[1].selectStatementUnion()} } yyVAL.union = yyLOCAL - case 928: + case 937: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *tree.Select -//line mysql_sql.y:6228 +//line mysql_sql.y:6291 { yyLOCAL = &tree.Select{Select: yyDollar[1].selectStatementUnion(), TimeWindow: yyDollar[2].timeWindowUnion(), OrderBy: yyDollar[3].orderByUnion(), Limit: yyDollar[4].limitUnion(), RankOption: yyDollar[5].rankOptionUnion(), Ep: yyDollar[6].exportParmUnion(), SelectLockInfo: yyDollar[7].selectLockInfoUnion()} } yyVAL.union = yyLOCAL - case 929: + case 938: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Select -//line mysql_sql.y:6232 +//line mysql_sql.y:6295 { yyLOCAL = &tree.Select{Select: yyDollar[1].selectStatementUnion(), TimeWindow: yyDollar[2].timeWindowUnion(), OrderBy: yyDollar[3].orderByUnion(), Ep: yyDollar[4].exportParmUnion()} } yyVAL.union = yyLOCAL - case 930: + case 939: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.Select -//line mysql_sql.y:6236 +//line mysql_sql.y:6299 { yyLOCAL = &tree.Select{Select: yyDollar[1].selectStatementUnion(), TimeWindow: yyDollar[2].timeWindowUnion(), OrderBy: yyDollar[3].orderByUnion(), Limit: yyDollar[4].limitUnion(), RankOption: yyDollar[5].rankOptionUnion(), Ep: yyDollar[6].exportParmUnion()} } yyVAL.union = yyLOCAL - case 931: + case 940: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *tree.Select -//line mysql_sql.y:6240 +//line mysql_sql.y:6303 { yyLOCAL = &tree.Select{Select: yyDollar[2].selectStatementUnion(), TimeWindow: yyDollar[3].timeWindowUnion(), OrderBy: yyDollar[4].orderByUnion(), Limit: yyDollar[5].limitUnion(), RankOption: yyDollar[6].rankOptionUnion(), Ep: yyDollar[7].exportParmUnion(), SelectLockInfo: yyDollar[8].selectLockInfoUnion(), With: yyDollar[1].withClauseUnion()} } yyVAL.union = yyLOCAL - case 932: + case 941: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Select -//line mysql_sql.y:6244 +//line mysql_sql.y:6307 { yyLOCAL = &tree.Select{Select: yyDollar[2].selectStatementUnion(), OrderBy: yyDollar[3].orderByUnion(), Ep: yyDollar[4].exportParmUnion(), With: yyDollar[1].withClauseUnion()} } yyVAL.union = yyLOCAL - case 933: + case 942: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.Select -//line mysql_sql.y:6248 +//line mysql_sql.y:6311 { yyLOCAL = &tree.Select{Select: yyDollar[2].selectStatementUnion(), OrderBy: yyDollar[3].orderByUnion(), Limit: yyDollar[4].limitUnion(), RankOption: yyDollar[5].rankOptionUnion(), Ep: yyDollar[6].exportParmUnion(), With: yyDollar[1].withClauseUnion()} } yyVAL.union = yyLOCAL - case 934: + case 943: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.TimeWindow -//line mysql_sql.y:6253 +//line mysql_sql.y:6316 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 935: + case 944: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.TimeWindow -//line mysql_sql.y:6257 +//line mysql_sql.y:6320 { yyLOCAL = yyDollar[1].timeWindowUnion() } yyVAL.union = yyLOCAL - case 936: - yyDollar = yyS[yypt-3 : yypt+1] + case 945: + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.TimeWindow -//line mysql_sql.y:6263 +//line mysql_sql.y:6326 { yyLOCAL = &tree.TimeWindow{ Interval: yyDollar[1].timeIntervalUnion(), Sliding: yyDollar[2].timeSlidingUnion(), - Fill: yyDollar[3].timeFillUnion(), + GapFill: yyDollar[3].boolValUnion(), + Fill: yyDollar[4].timeFillUnion(), } } yyVAL.union = yyLOCAL - case 937: + case 946: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *tree.Interval -//line mysql_sql.y:6273 +//line mysql_sql.y:6337 { str := fmt.Sprintf("%v", yyDollar[5].item) v, errStr := util.GetInt64(yyDollar[5].item) @@ -20326,18 +20704,18 @@ yydefault: } } yyVAL.union = yyLOCAL - case 938: + case 947: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.Sliding -//line mysql_sql.y:6288 +//line mysql_sql.y:6352 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 939: + case 948: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.Sliding -//line mysql_sql.y:6292 +//line mysql_sql.y:6356 { str := fmt.Sprintf("%v", yyDollar[3].item) v, errStr := util.GetInt64(yyDollar[3].item) @@ -20351,28 +20729,44 @@ yydefault: } } yyVAL.union = yyLOCAL - case 940: + case 949: + yyDollar = yyS[yypt-0 : yypt+1] + var yyLOCAL bool +//line mysql_sql.y:6370 + { + yyLOCAL = false + } + yyVAL.union = yyLOCAL + case 950: + yyDollar = yyS[yypt-4 : yypt+1] + var yyLOCAL bool +//line mysql_sql.y:6374 + { + yyLOCAL = true + } + yyVAL.union = yyLOCAL + case 951: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.Fill -//line mysql_sql.y:6306 +//line mysql_sql.y:6379 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 941: + case 952: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Fill -//line mysql_sql.y:6310 +//line mysql_sql.y:6383 { yyLOCAL = &tree.Fill{ Mode: yyDollar[3].fillModeUnion(), } } yyVAL.union = yyLOCAL - case 942: + case 953: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.Fill -//line mysql_sql.y:6316 +//line mysql_sql.y:6389 { yyLOCAL = &tree.Fill{ Mode: tree.FillValue, @@ -20380,50 +20774,50 @@ yydefault: } } yyVAL.union = yyLOCAL - case 943: + case 954: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.FillMode -//line mysql_sql.y:6325 +//line mysql_sql.y:6398 { yyLOCAL = tree.FillPrev } yyVAL.union = yyLOCAL - case 944: + case 955: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.FillMode -//line mysql_sql.y:6329 +//line mysql_sql.y:6402 { yyLOCAL = tree.FillNext } yyVAL.union = yyLOCAL - case 945: + case 956: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.FillMode -//line mysql_sql.y:6333 +//line mysql_sql.y:6406 { yyLOCAL = tree.FillNone } yyVAL.union = yyLOCAL - case 946: + case 957: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.FillMode -//line mysql_sql.y:6337 +//line mysql_sql.y:6410 { yyLOCAL = tree.FillNull } yyVAL.union = yyLOCAL - case 947: + case 958: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.FillMode -//line mysql_sql.y:6341 +//line mysql_sql.y:6414 { yyLOCAL = tree.FillLinear } yyVAL.union = yyLOCAL - case 948: + case 959: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.With -//line mysql_sql.y:6347 +//line mysql_sql.y:6420 { yyLOCAL = &tree.With{ IsRecursive: false, @@ -20431,10 +20825,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 949: + case 960: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.With -//line mysql_sql.y:6354 +//line mysql_sql.y:6427 { yyLOCAL = &tree.With{ IsRecursive: true, @@ -20442,26 +20836,26 @@ yydefault: } } yyVAL.union = yyLOCAL - case 950: + case 961: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.CTE -//line mysql_sql.y:6363 +//line mysql_sql.y:6436 { yyLOCAL = []*tree.CTE{yyDollar[1].cteUnion()} } yyVAL.union = yyLOCAL - case 951: + case 962: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.CTE -//line mysql_sql.y:6367 +//line mysql_sql.y:6440 { yyLOCAL = append(yyDollar[1].cteListUnion(), yyDollar[3].cteUnion()) } yyVAL.union = yyLOCAL - case 952: + case 963: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.CTE -//line mysql_sql.y:6373 +//line mysql_sql.y:6446 { yyLOCAL = &tree.CTE{ Name: &tree.AliasClause{Alias: tree.Identifier(yyDollar[1].cstrUnion().Compare()), Cols: yyDollar[2].identifierListUnion()}, @@ -20469,74 +20863,74 @@ yydefault: } } yyVAL.union = yyLOCAL - case 953: + case 964: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:6381 +//line mysql_sql.y:6454 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 954: + case 965: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:6385 +//line mysql_sql.y:6458 { yyLOCAL = yyDollar[2].identifierListUnion() } yyVAL.union = yyLOCAL - case 955: + case 966: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.Limit -//line mysql_sql.y:6390 +//line mysql_sql.y:6463 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 956: + case 967: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.Limit -//line mysql_sql.y:6394 +//line mysql_sql.y:6467 { yyLOCAL = yyDollar[1].limitUnion() } yyVAL.union = yyLOCAL - case 957: + case 968: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.Limit -//line mysql_sql.y:6400 +//line mysql_sql.y:6473 { yyLOCAL = &tree.Limit{Count: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 958: + case 969: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Limit -//line mysql_sql.y:6404 +//line mysql_sql.y:6477 { yyLOCAL = &tree.Limit{Offset: yyDollar[2].exprUnion(), Count: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 959: + case 970: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Limit -//line mysql_sql.y:6408 +//line mysql_sql.y:6481 { yyLOCAL = &tree.Limit{Offset: yyDollar[4].exprUnion(), Count: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 960: + case 971: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.RankOption -//line mysql_sql.y:6413 +//line mysql_sql.y:6486 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 961: + case 972: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.RankOption -//line mysql_sql.y:6417 +//line mysql_sql.y:6490 { // Parse option strings to extract key=value pairs into a map optionMap := make(map[string]string) @@ -20571,140 +20965,140 @@ yydefault: } } yyVAL.union = yyLOCAL - case 962: + case 973: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.OrderBy -//line mysql_sql.y:6452 +//line mysql_sql.y:6525 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 963: + case 974: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.OrderBy -//line mysql_sql.y:6456 +//line mysql_sql.y:6529 { yyLOCAL = yyDollar[1].orderByUnion() } yyVAL.union = yyLOCAL - case 964: + case 975: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.OrderBy -//line mysql_sql.y:6462 +//line mysql_sql.y:6535 { yyLOCAL = yyDollar[3].orderByUnion() } yyVAL.union = yyLOCAL - case 965: + case 976: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.OrderBy -//line mysql_sql.y:6468 +//line mysql_sql.y:6541 { yyLOCAL = tree.OrderBy{yyDollar[1].orderUnion()} } yyVAL.union = yyLOCAL - case 966: + case 977: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.OrderBy -//line mysql_sql.y:6472 +//line mysql_sql.y:6545 { yyLOCAL = append(yyDollar[1].orderByUnion(), yyDollar[3].orderUnion()) } yyVAL.union = yyLOCAL - case 967: + case 978: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.Order -//line mysql_sql.y:6478 +//line mysql_sql.y:6551 { yyLOCAL = &tree.Order{Expr: yyDollar[1].exprUnion(), Direction: yyDollar[2].directionUnion(), NullsPosition: yyDollar[3].nullsPositionUnion()} } yyVAL.union = yyLOCAL - case 968: + case 979: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.Direction -//line mysql_sql.y:6483 +//line mysql_sql.y:6556 { yyLOCAL = tree.DefaultDirection } yyVAL.union = yyLOCAL - case 969: + case 980: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Direction -//line mysql_sql.y:6487 +//line mysql_sql.y:6560 { yyLOCAL = tree.Ascending } yyVAL.union = yyLOCAL - case 970: + case 981: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Direction -//line mysql_sql.y:6491 +//line mysql_sql.y:6564 { yyLOCAL = tree.Descending } yyVAL.union = yyLOCAL - case 971: + case 982: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.NullsPosition -//line mysql_sql.y:6496 +//line mysql_sql.y:6569 { yyLOCAL = tree.DefaultNullsPosition } yyVAL.union = yyLOCAL - case 972: + case 983: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.NullsPosition -//line mysql_sql.y:6500 +//line mysql_sql.y:6573 { yyLOCAL = tree.NullsFirst } yyVAL.union = yyLOCAL - case 973: + case 984: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.NullsPosition -//line mysql_sql.y:6504 +//line mysql_sql.y:6577 { yyLOCAL = tree.NullsLast } yyVAL.union = yyLOCAL - case 974: + case 985: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.SelectLockInfo -//line mysql_sql.y:6509 +//line mysql_sql.y:6582 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 975: + case 986: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.SelectLockInfo -//line mysql_sql.y:6513 +//line mysql_sql.y:6586 { yyLOCAL = &tree.SelectLockInfo{ LockType: tree.SelectLockForUpdate, } } yyVAL.union = yyLOCAL - case 976: + case 987: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.SelectStatement -//line mysql_sql.y:6521 +//line mysql_sql.y:6594 { yyLOCAL = &tree.ParenSelect{Select: yyDollar[2].selectUnion()} } yyVAL.union = yyLOCAL - case 977: + case 988: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.SelectStatement -//line mysql_sql.y:6525 +//line mysql_sql.y:6598 { yyLOCAL = &tree.ParenSelect{Select: &tree.Select{Select: yyDollar[2].selectStatementUnion()}} } yyVAL.union = yyLOCAL - case 978: + case 989: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.SelectStatement -//line mysql_sql.y:6529 +//line mysql_sql.y:6602 { valuesStmt := yyDollar[2].statementUnion().(*tree.ValuesStatement) yyLOCAL = &tree.ParenSelect{Select: &tree.Select{ @@ -20717,18 +21111,18 @@ yydefault: }} } yyVAL.union = yyLOCAL - case 979: + case 990: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.SelectStatement -//line mysql_sql.y:6543 +//line mysql_sql.y:6616 { yyLOCAL = yyDollar[1].selectStatementUnion() } yyVAL.union = yyLOCAL - case 980: + case 991: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.SelectStatement -//line mysql_sql.y:6547 +//line mysql_sql.y:6620 { yyLOCAL = &tree.UnionClause{ Type: yyDollar[2].unionTypeRecordUnion().Type, @@ -20739,10 +21133,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 981: + case 992: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.SelectStatement -//line mysql_sql.y:6557 +//line mysql_sql.y:6630 { yyLOCAL = &tree.UnionClause{ Type: yyDollar[2].unionTypeRecordUnion().Type, @@ -20753,10 +21147,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 982: + case 993: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.SelectStatement -//line mysql_sql.y:6567 +//line mysql_sql.y:6640 { yyLOCAL = &tree.UnionClause{ Type: yyDollar[2].unionTypeRecordUnion().Type, @@ -20767,10 +21161,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 983: + case 994: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.SelectStatement -//line mysql_sql.y:6577 +//line mysql_sql.y:6650 { yyLOCAL = &tree.UnionClause{ Type: yyDollar[2].unionTypeRecordUnion().Type, @@ -20781,10 +21175,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 984: + case 995: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.UnionTypeRecord -//line mysql_sql.y:6589 +//line mysql_sql.y:6662 { yyLOCAL = &tree.UnionTypeRecord{ Type: tree.UNION, @@ -20793,10 +21187,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 985: + case 996: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.UnionTypeRecord -//line mysql_sql.y:6597 +//line mysql_sql.y:6670 { yyLOCAL = &tree.UnionTypeRecord{ Type: tree.UNION, @@ -20805,10 +21199,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 986: + case 997: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.UnionTypeRecord -//line mysql_sql.y:6605 +//line mysql_sql.y:6678 { yyLOCAL = &tree.UnionTypeRecord{ Type: tree.UNION, @@ -20817,10 +21211,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 987: + case 998: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.UnionTypeRecord -//line mysql_sql.y:6614 +//line mysql_sql.y:6687 { yyLOCAL = &tree.UnionTypeRecord{ Type: tree.EXCEPT, @@ -20829,10 +21223,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 988: + case 999: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.UnionTypeRecord -//line mysql_sql.y:6622 +//line mysql_sql.y:6695 { yyLOCAL = &tree.UnionTypeRecord{ Type: tree.EXCEPT, @@ -20841,10 +21235,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 989: + case 1000: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.UnionTypeRecord -//line mysql_sql.y:6630 +//line mysql_sql.y:6703 { yyLOCAL = &tree.UnionTypeRecord{ Type: tree.EXCEPT, @@ -20853,10 +21247,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 990: + case 1001: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.UnionTypeRecord -//line mysql_sql.y:6638 +//line mysql_sql.y:6711 { yyLOCAL = &tree.UnionTypeRecord{ Type: tree.INTERSECT, @@ -20865,10 +21259,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 991: + case 1002: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.UnionTypeRecord -//line mysql_sql.y:6646 +//line mysql_sql.y:6719 { yyLOCAL = &tree.UnionTypeRecord{ Type: tree.INTERSECT, @@ -20877,10 +21271,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 992: + case 1003: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.UnionTypeRecord -//line mysql_sql.y:6654 +//line mysql_sql.y:6727 { yyLOCAL = &tree.UnionTypeRecord{ Type: tree.INTERSECT, @@ -20889,10 +21283,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 993: + case 1004: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.UnionTypeRecord -//line mysql_sql.y:6662 +//line mysql_sql.y:6735 { yyLOCAL = &tree.UnionTypeRecord{ Type: tree.UT_MINUS, @@ -20901,10 +21295,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 994: + case 1005: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.UnionTypeRecord -//line mysql_sql.y:6670 +//line mysql_sql.y:6743 { yyLOCAL = &tree.UnionTypeRecord{ Type: tree.UT_MINUS, @@ -20913,10 +21307,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 995: + case 1006: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.UnionTypeRecord -//line mysql_sql.y:6678 +//line mysql_sql.y:6751 { yyLOCAL = &tree.UnionTypeRecord{ Type: tree.UT_MINUS, @@ -20925,10 +21319,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 996: + case 1007: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.SelectStatement -//line mysql_sql.y:6688 +//line mysql_sql.y:6761 { yyLOCAL = &tree.SelectClause{ Distinct: tree.QuerySpecOptionDistinct&yyDollar[2].selectOptionsUnion() != 0, @@ -20941,146 +21335,146 @@ yydefault: } } yyVAL.union = yyLOCAL - case 997: + case 1008: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6702 +//line mysql_sql.y:6775 { yyLOCAL = tree.QuerySpecOptionNone } yyVAL.union = yyLOCAL - case 998: + case 1009: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6706 +//line mysql_sql.y:6779 { yyLOCAL = yyDollar[1].selectOptionsUnion() } yyVAL.union = yyLOCAL - case 999: + case 1010: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6712 +//line mysql_sql.y:6785 { yyLOCAL = yyDollar[1].selectOptionUnion() } yyVAL.union = yyLOCAL - case 1000: + case 1011: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6716 +//line mysql_sql.y:6789 { yyLOCAL = yyDollar[1].selectOptionsUnion() | yyDollar[2].selectOptionUnion() } yyVAL.union = yyLOCAL - case 1001: + case 1012: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6722 +//line mysql_sql.y:6795 { yyLOCAL = tree.QuerySpecOptionSqlSmallResult } yyVAL.union = yyLOCAL - case 1002: + case 1013: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6726 +//line mysql_sql.y:6799 { yyLOCAL = tree.QuerySpecOptionSqlBigResult } yyVAL.union = yyLOCAL - case 1003: + case 1014: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6730 +//line mysql_sql.y:6803 { yyLOCAL = tree.QuerySpecOptionSqlBufferResult } yyVAL.union = yyLOCAL - case 1004: + case 1015: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6734 +//line mysql_sql.y:6807 { yyLOCAL = tree.QuerySpecOptionStraightJoin } yyVAL.union = yyLOCAL - case 1005: + case 1016: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6738 +//line mysql_sql.y:6811 { yyLOCAL = tree.QuerySpecOptionHighPriority } yyVAL.union = yyLOCAL - case 1006: + case 1017: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6742 +//line mysql_sql.y:6815 { yyLOCAL = tree.QuerySpecOptionSqlCalcFoundRows } yyVAL.union = yyLOCAL - case 1007: + case 1018: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6746 +//line mysql_sql.y:6819 { yyLOCAL = tree.QuerySpecOptionSqlNoCache } yyVAL.union = yyLOCAL - case 1008: + case 1019: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6750 +//line mysql_sql.y:6823 { yyLOCAL = tree.QuerySpecOptionAll } yyVAL.union = yyLOCAL - case 1009: + case 1020: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6754 +//line mysql_sql.y:6827 { yyLOCAL = tree.QuerySpecOptionDistinct } yyVAL.union = yyLOCAL - case 1010: + case 1021: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL uint64 -//line mysql_sql.y:6758 +//line mysql_sql.y:6831 { yyLOCAL = tree.QuerySpecOptionDistinctRow } yyVAL.union = yyLOCAL - case 1011: + case 1022: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.Where -//line mysql_sql.y:6780 +//line mysql_sql.y:6853 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1012: + case 1023: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.Where -//line mysql_sql.y:6784 +//line mysql_sql.y:6857 { yyLOCAL = &tree.Where{Type: tree.AstHaving, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1013: + case 1024: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.GroupByClause -//line mysql_sql.y:6789 +//line mysql_sql.y:6862 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1014: + case 1025: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.GroupByClause -//line mysql_sql.y:6793 +//line mysql_sql.y:6866 { exprsList := []tree.Exprs{yyDollar[3].exprsUnion()} yyLOCAL = &tree.GroupByClause{ @@ -21091,10 +21485,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1015: + case 1026: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *tree.GroupByClause -//line mysql_sql.y:6803 +//line mysql_sql.y:6876 { yyLOCAL = &tree.GroupByClause{ GroupByExprsList: yyDollar[6].rowsExprsUnion(), @@ -21104,10 +21498,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1016: + case 1027: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.GroupByClause -//line mysql_sql.y:6812 +//line mysql_sql.y:6885 { yyLOCAL = &tree.GroupByClause{ GroupByExprsList: []tree.Exprs{yyDollar[5].exprsUnion()}, @@ -21117,10 +21511,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1017: + case 1028: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.GroupByClause -//line mysql_sql.y:6821 +//line mysql_sql.y:6894 { yyLOCAL = &tree.GroupByClause{ GroupByExprsList: []tree.Exprs{yyDollar[5].exprsUnion()}, @@ -21130,106 +21524,106 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1018: + case 1029: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []tree.Exprs -//line mysql_sql.y:6832 +//line mysql_sql.y:6905 { yyLOCAL = []tree.Exprs{yyDollar[2].exprsUnion()} } yyVAL.union = yyLOCAL - case 1019: + case 1030: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL []tree.Exprs -//line mysql_sql.y:6836 +//line mysql_sql.y:6909 { yyLOCAL = append(yyDollar[1].rowsExprsUnion(), yyDollar[4].exprsUnion()) } yyVAL.union = yyLOCAL - case 1020: + case 1031: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:6842 +//line mysql_sql.y:6915 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1021: + case 1032: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:6846 +//line mysql_sql.y:6919 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1022: + case 1033: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.Where -//line mysql_sql.y:6851 +//line mysql_sql.y:6924 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1023: + case 1034: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.Where -//line mysql_sql.y:6855 +//line mysql_sql.y:6928 { yyLOCAL = &tree.Where{Type: tree.AstWhere, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1024: + case 1035: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.SelectExprs -//line mysql_sql.y:6861 +//line mysql_sql.y:6934 { yyLOCAL = tree.SelectExprs{yyDollar[1].selectExprUnion()} } yyVAL.union = yyLOCAL - case 1025: + case 1036: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.SelectExprs -//line mysql_sql.y:6865 +//line mysql_sql.y:6938 { yyLOCAL = append(yyDollar[1].selectExprsUnion(), yyDollar[3].selectExprUnion()) } yyVAL.union = yyLOCAL - case 1026: + case 1037: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.SelectExpr -//line mysql_sql.y:6871 +//line mysql_sql.y:6944 { yyLOCAL = tree.SelectExpr{Expr: tree.StarExpr()} } yyVAL.union = yyLOCAL - case 1027: + case 1038: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.SelectExpr -//line mysql_sql.y:6875 +//line mysql_sql.y:6948 { yyLOCAL = tree.SelectExpr{Expr: yyDollar[1].exprUnion(), As: yyDollar[2].cstrUnion()} } yyVAL.union = yyLOCAL - case 1028: + case 1039: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.SelectExpr -//line mysql_sql.y:6879 +//line mysql_sql.y:6952 { yyLOCAL = tree.SelectExpr{Expr: tree.NewUnresolvedNameWithStar(yyDollar[1].cstrUnion())} } yyVAL.union = yyLOCAL - case 1029: + case 1040: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.SelectExpr -//line mysql_sql.y:6883 +//line mysql_sql.y:6956 { yyLOCAL = tree.SelectExpr{Expr: tree.NewUnresolvedNameWithStar(yyDollar[1].cstrUnion(), yyDollar[3].cstrUnion())} } yyVAL.union = yyLOCAL - case 1030: + case 1041: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.From -//line mysql_sql.y:6888 +//line mysql_sql.y:6961 { prefix := tree.ObjectNamePrefix{ExplicitSchema: false} tn := tree.NewTableName(tree.Identifier(""), prefix, nil) @@ -21238,28 +21632,28 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1031: + case 1042: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.From -//line mysql_sql.y:6896 +//line mysql_sql.y:6969 { yyLOCAL = yyDollar[1].fromUnion() } yyVAL.union = yyLOCAL - case 1032: + case 1043: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.From -//line mysql_sql.y:6902 +//line mysql_sql.y:6975 { yyLOCAL = &tree.From{ Tables: tree.TableExprs{yyDollar[2].tableExprUnion()}, } } yyVAL.union = yyLOCAL - case 1033: + case 1044: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableExpr -//line mysql_sql.y:6910 +//line mysql_sql.y:6983 { if t, ok := yyDollar[1].tableExprUnion().(*tree.JoinTableExpr); ok { yyLOCAL = t @@ -21270,34 +21664,34 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1034: + case 1045: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableExpr -//line mysql_sql.y:6920 +//line mysql_sql.y:6993 { yyLOCAL = &tree.JoinTableExpr{Left: yyDollar[1].tableExprUnion(), Right: yyDollar[3].tableExprUnion(), JoinType: tree.JOIN_TYPE_CROSS} } yyVAL.union = yyLOCAL - case 1037: + case 1048: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableExpr -//line mysql_sql.y:6930 +//line mysql_sql.y:7003 { yyLOCAL = yyDollar[1].joinTableExprUnion() } yyVAL.union = yyLOCAL - case 1038: + case 1049: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableExpr -//line mysql_sql.y:6934 +//line mysql_sql.y:7007 { yyLOCAL = yyDollar[1].applyTableExprUnion() } yyVAL.union = yyLOCAL - case 1039: + case 1050: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.JoinTableExpr -//line mysql_sql.y:6940 +//line mysql_sql.y:7013 { if strings.Contains(yyDollar[2].str, ":") { ss := strings.SplitN(yyDollar[2].str, ":", 2) @@ -21318,10 +21712,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1040: + case 1051: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.JoinTableExpr -//line mysql_sql.y:6960 +//line mysql_sql.y:7033 { yyLOCAL = &tree.JoinTableExpr{ Left: yyDollar[1].tableExprUnion(), @@ -21331,10 +21725,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1041: + case 1052: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.JoinTableExpr -//line mysql_sql.y:6969 +//line mysql_sql.y:7042 { yyLOCAL = &tree.JoinTableExpr{ Left: yyDollar[1].tableExprUnion(), @@ -21344,10 +21738,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1042: + case 1053: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.JoinTableExpr -//line mysql_sql.y:6978 +//line mysql_sql.y:7051 { yyLOCAL = &tree.JoinTableExpr{ Left: yyDollar[1].tableExprUnion(), @@ -21356,10 +21750,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1043: + case 1054: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.JoinTableExpr -//line mysql_sql.y:6986 +//line mysql_sql.y:7059 { yyLOCAL = &tree.JoinTableExpr{ Left: yyDollar[1].tableExprUnion(), @@ -21369,10 +21763,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1044: + case 1055: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.ApplyTableExpr -//line mysql_sql.y:6997 +//line mysql_sql.y:7070 { yyLOCAL = &tree.ApplyTableExpr{ Left: yyDollar[1].tableExprUnion(), @@ -21381,27 +21775,27 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1045: + case 1056: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7007 +//line mysql_sql.y:7080 { yyVAL.str = tree.APPLY_TYPE_CROSS } - case 1046: + case 1057: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7011 +//line mysql_sql.y:7084 { yyVAL.str = tree.APPLY_TYPE_OUTER } - case 1047: + case 1058: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7017 +//line mysql_sql.y:7090 { yyVAL.str = tree.JOIN_TYPE_NATURAL } - case 1048: + case 1059: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7021 +//line mysql_sql.y:7094 { switch yyDollar[2].str { case tree.JOIN_TYPE_LEFT: @@ -21412,52 +21806,52 @@ yydefault: yyVAL.str = tree.JOIN_TYPE_NATURAL_FULL } } - case 1049: + case 1060: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7034 +//line mysql_sql.y:7107 { yyVAL.str = tree.JOIN_TYPE_LEFT } - case 1050: + case 1061: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:7038 +//line mysql_sql.y:7111 { yyVAL.str = tree.JOIN_TYPE_LEFT } - case 1051: + case 1062: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7042 +//line mysql_sql.y:7115 { yyVAL.str = tree.JOIN_TYPE_RIGHT } - case 1052: + case 1063: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:7046 +//line mysql_sql.y:7119 { yyVAL.str = tree.JOIN_TYPE_RIGHT } - case 1053: + case 1064: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7050 +//line mysql_sql.y:7123 { yyVAL.str = tree.JOIN_TYPE_FULL } - case 1054: + case 1065: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:7054 +//line mysql_sql.y:7127 { yyVAL.str = tree.JOIN_TYPE_FULL } - case 1055: + case 1066: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7060 +//line mysql_sql.y:7133 { yyVAL.str = tree.JOIN_TYPE_DEDUP } - case 1056: + case 1067: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:7066 +//line mysql_sql.y:7139 { yyLOCAL = &tree.ValuesStatement{ Rows: yyDollar[2].rowsExprsUnion(), @@ -21466,148 +21860,148 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1057: + case 1068: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []tree.Exprs -//line mysql_sql.y:7076 +//line mysql_sql.y:7149 { yyLOCAL = []tree.Exprs{yyDollar[1].exprsUnion()} } yyVAL.union = yyLOCAL - case 1058: + case 1069: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []tree.Exprs -//line mysql_sql.y:7080 +//line mysql_sql.y:7153 { yyLOCAL = append(yyDollar[1].rowsExprsUnion(), yyDollar[3].exprsUnion()) } yyVAL.union = yyLOCAL - case 1059: + case 1070: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Exprs -//line mysql_sql.y:7086 +//line mysql_sql.y:7159 { yyLOCAL = yyDollar[3].exprsUnion() } yyVAL.union = yyLOCAL - case 1060: + case 1071: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.JoinCond -//line mysql_sql.y:7092 +//line mysql_sql.y:7165 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1061: + case 1072: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.JoinCond -//line mysql_sql.y:7096 +//line mysql_sql.y:7169 { yyLOCAL = &tree.OnJoinCond{Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1062: + case 1073: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:7102 +//line mysql_sql.y:7175 { yyVAL.str = yyDollar[1].str } - case 1063: + case 1074: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:7108 +//line mysql_sql.y:7181 { yyVAL.str = yyDollar[2].str } - case 1064: + case 1075: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:7114 +//line mysql_sql.y:7187 { yyVAL.str = tree.JOIN_TYPE_STRAIGHT } - case 1065: + case 1076: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:7120 +//line mysql_sql.y:7193 { yyVAL.str = tree.JOIN_TYPE_INNER } - case 1066: + case 1077: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7124 +//line mysql_sql.y:7197 { yyVAL.str = tree.JOIN_TYPE_INNER } - case 1067: + case 1078: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7128 +//line mysql_sql.y:7201 { yyVAL.str = tree.JOIN_TYPE_CROSS } - case 1068: + case 1079: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:7132 +//line mysql_sql.y:7205 { yyVAL.str = tree.JOIN_TYPE_CENTROIDX + ":" + yyDollar[2].str } - case 1069: + case 1080: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.JoinCond -//line mysql_sql.y:7138 +//line mysql_sql.y:7211 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1070: + case 1081: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.JoinCond -//line mysql_sql.y:7142 +//line mysql_sql.y:7215 { yyLOCAL = yyDollar[1].joinCondUnion() } yyVAL.union = yyLOCAL - case 1071: + case 1082: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.JoinCond -//line mysql_sql.y:7148 +//line mysql_sql.y:7221 { yyLOCAL = &tree.OnJoinCond{Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1072: + case 1083: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.JoinCond -//line mysql_sql.y:7152 +//line mysql_sql.y:7225 { yyLOCAL = &tree.UsingJoinCond{Cols: yyDollar[3].identifierListUnion()} } yyVAL.union = yyLOCAL - case 1073: + case 1084: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:7158 +//line mysql_sql.y:7231 { yyLOCAL = tree.IdentifierList{tree.Identifier(yyDollar[1].cstrUnion().Compare())} } yyVAL.union = yyLOCAL - case 1074: + case 1085: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:7162 +//line mysql_sql.y:7235 { yyLOCAL = append(yyDollar[1].identifierListUnion(), tree.Identifier(yyDollar[3].cstrUnion().Compare())) } yyVAL.union = yyLOCAL - case 1075: + case 1086: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableExpr -//line mysql_sql.y:7168 +//line mysql_sql.y:7241 { yyLOCAL = yyDollar[1].aliasedTableExprUnion() } yyVAL.union = yyLOCAL - case 1076: + case 1087: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableExpr -//line mysql_sql.y:7172 +//line mysql_sql.y:7245 { yyLOCAL = &tree.AliasedTableExpr{ Expr: yyDollar[1].parenTableExprUnion(), @@ -21618,10 +22012,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1077: + case 1088: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.TableExpr -//line mysql_sql.y:7182 +//line mysql_sql.y:7255 { if yyDollar[2].str != "" { yyLOCAL = &tree.AliasedTableExpr{ @@ -21635,26 +22029,26 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1078: + case 1089: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableExpr -//line mysql_sql.y:7195 +//line mysql_sql.y:7268 { yyLOCAL = yyDollar[2].tableExprUnion() } yyVAL.union = yyLOCAL - case 1079: + case 1090: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.ParenTableExpr -//line mysql_sql.y:7201 +//line mysql_sql.y:7274 { yyLOCAL = &tree.ParenTableExpr{Expr: yyDollar[1].selectStatementUnion().(*tree.ParenSelect).Select} } yyVAL.union = yyLOCAL - case 1080: + case 1091: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.TableExpr -//line mysql_sql.y:7207 +//line mysql_sql.y:7280 { name := tree.NewUnresolvedName(yyDollar[1].cstrUnion()) yyLOCAL = &tree.TableFunction{ @@ -21667,10 +22061,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1081: + case 1092: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.AliasedTableExpr -//line mysql_sql.y:7221 +//line mysql_sql.y:7294 { yyLOCAL = &tree.AliasedTableExpr{ Expr: yyDollar[1].tableNameUnion(), @@ -21681,34 +22075,34 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1082: + case 1093: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*tree.IndexHint -//line mysql_sql.y:7232 +//line mysql_sql.y:7305 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1084: + case 1095: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.IndexHint -//line mysql_sql.y:7239 +//line mysql_sql.y:7312 { yyLOCAL = []*tree.IndexHint{yyDollar[1].indexHintUnion()} } yyVAL.union = yyLOCAL - case 1085: + case 1096: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []*tree.IndexHint -//line mysql_sql.y:7243 +//line mysql_sql.y:7316 { yyLOCAL = append(yyDollar[1].indexHintListUnion(), yyDollar[2].indexHintUnion()) } yyVAL.union = yyLOCAL - case 1086: + case 1097: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.IndexHint -//line mysql_sql.y:7249 +//line mysql_sql.y:7322 { yyLOCAL = &tree.IndexHint{ IndexNames: yyDollar[4].strsUnion(), @@ -21717,182 +22111,182 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1087: + case 1098: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IndexHintType -//line mysql_sql.y:7259 +//line mysql_sql.y:7332 { yyLOCAL = tree.HintUse } yyVAL.union = yyLOCAL - case 1088: + case 1099: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IndexHintType -//line mysql_sql.y:7263 +//line mysql_sql.y:7336 { yyLOCAL = tree.HintIgnore } yyVAL.union = yyLOCAL - case 1089: + case 1100: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IndexHintType -//line mysql_sql.y:7267 +//line mysql_sql.y:7340 { yyLOCAL = tree.HintForce } yyVAL.union = yyLOCAL - case 1090: + case 1101: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.IndexHintScope -//line mysql_sql.y:7272 +//line mysql_sql.y:7345 { yyLOCAL = tree.HintForScan } yyVAL.union = yyLOCAL - case 1091: + case 1102: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IndexHintScope -//line mysql_sql.y:7276 +//line mysql_sql.y:7349 { yyLOCAL = tree.HintForJoin } yyVAL.union = yyLOCAL - case 1092: + case 1103: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.IndexHintScope -//line mysql_sql.y:7280 +//line mysql_sql.y:7353 { yyLOCAL = tree.HintForOrderBy } yyVAL.union = yyLOCAL - case 1093: + case 1104: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.IndexHintScope -//line mysql_sql.y:7284 +//line mysql_sql.y:7357 { yyLOCAL = tree.HintForGroupBy } yyVAL.union = yyLOCAL - case 1094: + case 1105: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:7289 +//line mysql_sql.y:7362 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1095: + case 1106: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:7293 +//line mysql_sql.y:7366 { yyLOCAL = []string{yyDollar[1].cstrUnion().Compare()} } yyVAL.union = yyLOCAL - case 1096: + case 1107: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:7297 +//line mysql_sql.y:7370 { yyLOCAL = append(yyDollar[1].strsUnion(), yyDollar[3].cstrUnion().Compare()) } yyVAL.union = yyLOCAL - case 1097: + case 1108: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:7301 +//line mysql_sql.y:7374 { yyLOCAL = []string{yyDollar[1].str} } yyVAL.union = yyLOCAL - case 1098: + case 1109: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:7305 +//line mysql_sql.y:7378 { yyLOCAL = append(yyDollar[1].strsUnion(), yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1099: + case 1110: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:7310 +//line mysql_sql.y:7383 { yyVAL.str = "" } - case 1100: + case 1111: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:7314 +//line mysql_sql.y:7387 { yyVAL.str = yyDollar[1].str } - case 1101: + case 1112: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7318 +//line mysql_sql.y:7391 { yyVAL.str = yyDollar[2].str } - case 1102: + case 1113: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:7324 +//line mysql_sql.y:7397 { yyVAL.str = yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) } - case 1103: + case 1114: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:7328 +//line mysql_sql.y:7401 { yyVAL.str = yylex.(*Lexer).GetDbOrTblName(yyDollar[1].str) } - case 1104: + case 1115: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:7333 +//line mysql_sql.y:7406 { yyLOCAL = tree.NewCStr("", 1) } yyVAL.union = yyLOCAL - case 1105: + case 1116: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:7337 +//line mysql_sql.y:7410 { yyLOCAL = yyDollar[1].cstrUnion() } yyVAL.union = yyLOCAL - case 1106: + case 1117: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:7341 +//line mysql_sql.y:7414 { yyLOCAL = yyDollar[2].cstrUnion() } yyVAL.union = yyLOCAL - case 1107: + case 1118: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:7345 +//line mysql_sql.y:7418 { yyLOCAL = tree.NewCStr(yyDollar[1].str, 1) } yyVAL.union = yyLOCAL - case 1108: + case 1119: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:7349 +//line mysql_sql.y:7422 { yyLOCAL = tree.NewCStr(yyDollar[2].str, 1) } yyVAL.union = yyLOCAL - case 1109: + case 1120: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:7355 +//line mysql_sql.y:7428 { yyVAL.str = yyDollar[1].cstrUnion().Compare() } - case 1134: + case 1146: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:7399 +//line mysql_sql.y:7473 { yyLOCAL = &tree.CreateIcebergCatalog{ IfNotExists: yyDollar[4].ifNotExistsUnion(), @@ -21901,10 +22295,22 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1135: + case 1147: + yyDollar = yyS[yypt-6 : yypt+1] + var yyLOCAL tree.Statement +//line mysql_sql.y:7483 + { + yyLOCAL = &tree.CreateMongoDBConnection{ + IfNotExists: yyDollar[4].ifNotExistsUnion(), + Name: tree.Identifier(yyDollar[5].cstrUnion().Compare()), + Options: yyDollar[6].mongodbOptionsUnion(), + } + } + yyVAL.union = yyLOCAL + case 1148: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:7409 +//line mysql_sql.y:7493 { cronExpr := "" timezone := "" @@ -21924,18 +22330,18 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1136: + case 1149: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.SQLTaskSchedule -//line mysql_sql.y:7429 +//line mysql_sql.y:7513 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1137: + case 1150: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.SQLTaskSchedule -//line mysql_sql.y:7433 +//line mysql_sql.y:7517 { yyLOCAL = &tree.SQLTaskSchedule{ CronExpr: yyDollar[2].str, @@ -21943,82 +22349,82 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1138: + case 1151: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:7441 +//line mysql_sql.y:7525 { yyVAL.str = "" } - case 1139: + case 1152: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7445 +//line mysql_sql.y:7529 { yyVAL.str = yyDollar[2].str } - case 1140: + case 1153: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:7450 +//line mysql_sql.y:7534 { yyLOCAL = tree.Expr(nil) } yyVAL.union = yyLOCAL - case 1141: + case 1154: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:7454 +//line mysql_sql.y:7538 { yyLOCAL = yyDollar[3].exprUnion() } yyVAL.union = yyLOCAL - case 1142: + case 1155: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:7460 +//line mysql_sql.y:7544 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1143: + case 1156: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:7464 +//line mysql_sql.y:7548 { yyLOCAL = tree.NewSubquery(yyDollar[1].selectUnion(), false) } yyVAL.union = yyLOCAL - case 1144: + case 1157: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:7469 +//line mysql_sql.y:7553 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 1145: + case 1158: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:7473 +//line mysql_sql.y:7557 { yyLOCAL = sqlTaskInt64(yyDollar[2].item) } yyVAL.union = yyLOCAL - case 1146: + case 1159: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:7478 +//line mysql_sql.y:7562 { yyVAL.str = "" } - case 1147: + case 1160: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7482 +//line mysql_sql.y:7566 { yyVAL.str = yyDollar[2].str } - case 1148: + case 1161: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:7488 +//line mysql_sql.y:7572 { var Language = yyDollar[3].str var Name = tree.Identifier(yyDollar[5].str) @@ -22030,135 +22436,135 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1149: + case 1162: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:7501 +//line mysql_sql.y:7585 { yyVAL.str = yyDollar[1].cstrUnion().Compare() } - case 1150: + case 1163: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:7507 +//line mysql_sql.y:7591 { yyVAL.str = yyDollar[1].cstrUnion().Compare() } - case 1151: + case 1164: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:7513 +//line mysql_sql.y:7597 { yyLOCAL = tree.NewCreateProcedure( yyDollar[2].sourceOptionalUnion(), yyDollar[4].procNameUnion(), yyDollar[6].procArgsUnion(), yyDollar[8].str, yyDollar[9].str, ) } yyVAL.union = yyLOCAL - case 1152: + case 1165: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.ProcedureName -//line mysql_sql.y:7521 +//line mysql_sql.y:7605 { prefix := tree.ObjectNamePrefix{ExplicitSchema: false} yyLOCAL = tree.NewProcedureName(tree.Identifier(yyDollar[1].cstrUnion().Compare()), prefix) } yyVAL.union = yyLOCAL - case 1153: + case 1166: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.ProcedureName -//line mysql_sql.y:7526 +//line mysql_sql.y:7610 { dbName := yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) prefix := tree.ObjectNamePrefix{SchemaName: tree.Identifier(dbName), ExplicitSchema: true} yyLOCAL = tree.NewProcedureName(tree.Identifier(yyDollar[3].cstrUnion().Compare()), prefix) } yyVAL.union = yyLOCAL - case 1154: + case 1167: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.ProcedureArgs -//line mysql_sql.y:7533 +//line mysql_sql.y:7617 { yyLOCAL = tree.ProcedureArgs(nil) } yyVAL.union = yyLOCAL - case 1156: + case 1169: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ProcedureArgs -//line mysql_sql.y:7540 +//line mysql_sql.y:7624 { yyLOCAL = tree.ProcedureArgs{yyDollar[1].procArgUnion()} } yyVAL.union = yyLOCAL - case 1157: + case 1170: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.ProcedureArgs -//line mysql_sql.y:7544 +//line mysql_sql.y:7628 { yyLOCAL = append(yyDollar[1].procArgsUnion(), yyDollar[3].procArgUnion()) } yyVAL.union = yyLOCAL - case 1158: + case 1171: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ProcedureArg -//line mysql_sql.y:7550 +//line mysql_sql.y:7634 { yyLOCAL = tree.ProcedureArg(yyDollar[1].procArgDeclUnion()) } yyVAL.union = yyLOCAL - case 1159: + case 1172: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.ProcedureArgDecl -//line mysql_sql.y:7556 +//line mysql_sql.y:7640 { yyLOCAL = tree.NewProcedureArgDecl(yyDollar[1].procArgTypeUnion(), yyDollar[2].unresolvedNameUnion(), yyDollar[3].columnTypeUnion()) } yyVAL.union = yyLOCAL - case 1160: + case 1173: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.InOutArgType -//line mysql_sql.y:7561 +//line mysql_sql.y:7645 { yyLOCAL = tree.TYPE_IN } yyVAL.union = yyLOCAL - case 1161: + case 1174: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.InOutArgType -//line mysql_sql.y:7565 +//line mysql_sql.y:7649 { yyLOCAL = tree.TYPE_IN } yyVAL.union = yyLOCAL - case 1162: + case 1175: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.InOutArgType -//line mysql_sql.y:7569 +//line mysql_sql.y:7653 { yyLOCAL = tree.TYPE_OUT } yyVAL.union = yyLOCAL - case 1163: + case 1176: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.InOutArgType -//line mysql_sql.y:7573 +//line mysql_sql.y:7657 { yyLOCAL = tree.TYPE_INOUT } yyVAL.union = yyLOCAL - case 1164: + case 1177: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:7578 +//line mysql_sql.y:7662 { yyVAL.str = "sql" } - case 1165: + case 1178: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7582 +//line mysql_sql.y:7666 { yyVAL.str = yyDollar[2].str } - case 1166: + case 1179: yyDollar = yyS[yypt-14 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:7588 +//line mysql_sql.y:7672 { if yyDollar[13].str == "" { yylex.Error("no function body error") @@ -22190,127 +22596,127 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1167: + case 1180: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.FunctionName -//line mysql_sql.y:7621 +//line mysql_sql.y:7705 { prefix := tree.ObjectNamePrefix{ExplicitSchema: false} yyLOCAL = tree.NewFuncName(tree.Identifier(yyDollar[1].cstrUnion().Compare()), prefix) } yyVAL.union = yyLOCAL - case 1168: + case 1181: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.FunctionName -//line mysql_sql.y:7626 +//line mysql_sql.y:7710 { dbName := yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) prefix := tree.ObjectNamePrefix{SchemaName: tree.Identifier(dbName), ExplicitSchema: true} yyLOCAL = tree.NewFuncName(tree.Identifier(yyDollar[3].cstrUnion().Compare()), prefix) } yyVAL.union = yyLOCAL - case 1169: + case 1182: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.FunctionArgs -//line mysql_sql.y:7633 +//line mysql_sql.y:7717 { yyLOCAL = tree.FunctionArgs(nil) } yyVAL.union = yyLOCAL - case 1171: + case 1184: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.FunctionArgs -//line mysql_sql.y:7640 +//line mysql_sql.y:7724 { yyLOCAL = tree.FunctionArgs{yyDollar[1].funcArgUnion()} } yyVAL.union = yyLOCAL - case 1172: + case 1185: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.FunctionArgs -//line mysql_sql.y:7644 +//line mysql_sql.y:7728 { yyLOCAL = append(yyDollar[1].funcArgsUnion(), yyDollar[3].funcArgUnion()) } yyVAL.union = yyLOCAL - case 1173: + case 1186: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.FunctionArg -//line mysql_sql.y:7650 +//line mysql_sql.y:7734 { yyLOCAL = tree.FunctionArg(yyDollar[1].funcArgDeclUnion()) } yyVAL.union = yyLOCAL - case 1174: + case 1187: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.FunctionArgDecl -//line mysql_sql.y:7656 +//line mysql_sql.y:7740 { yyLOCAL = tree.NewFunctionArgDecl(nil, yyDollar[1].columnTypeUnion(), nil) } yyVAL.union = yyLOCAL - case 1175: + case 1188: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FunctionArgDecl -//line mysql_sql.y:7660 +//line mysql_sql.y:7744 { yyLOCAL = tree.NewFunctionArgDecl(yyDollar[1].unresolvedNameUnion(), yyDollar[2].columnTypeUnion(), nil) } yyVAL.union = yyLOCAL - case 1176: + case 1189: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FunctionArgDecl -//line mysql_sql.y:7664 +//line mysql_sql.y:7748 { yyLOCAL = tree.NewFunctionArgDecl(yyDollar[1].unresolvedNameUnion(), yyDollar[2].columnTypeUnion(), yyDollar[4].exprUnion()) } yyVAL.union = yyLOCAL - case 1177: + case 1190: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:7670 +//line mysql_sql.y:7754 { yyVAL.str = yyDollar[1].cstrUnion().Compare() } - case 1178: + case 1191: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.ReturnType -//line mysql_sql.y:7676 +//line mysql_sql.y:7760 { yyLOCAL = tree.NewReturnType(yyDollar[1].columnTypeUnion()) } yyVAL.union = yyLOCAL - case 1179: + case 1192: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:7682 +//line mysql_sql.y:7766 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1180: + case 1193: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:7686 +//line mysql_sql.y:7770 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1181: + case 1194: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:7691 +//line mysql_sql.y:7775 { yyVAL.str = "" } - case 1183: + case 1196: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7698 +//line mysql_sql.y:7782 { yyVAL.str = yyDollar[2].str } - case 1184: + case 1197: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:7704 +//line mysql_sql.y:7788 { var Replace bool var Name = yyDollar[5].tableNameUnion() @@ -22326,10 +22732,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1185: + case 1198: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:7719 +//line mysql_sql.y:7803 { var Replace = yyDollar[2].sourceOptionalUnion() var Name = yyDollar[5].tableNameUnion() @@ -22345,10 +22751,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1186: + case 1199: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:7736 +//line mysql_sql.y:7820 { var IfNotExists = yyDollar[3].ifNotExistsUnion() var Name = yyDollar[4].exprUnion() @@ -22364,10 +22770,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1187: + case 1200: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:7751 +//line mysql_sql.y:7835 { var FromUri = yyDollar[4].str var SubscriptionAccountName = yyDollar[5].cstrUnion().Compare() @@ -22385,81 +22791,81 @@ yydefault: yyLOCAL = cs } yyVAL.union = yyLOCAL - case 1188: + case 1201: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:7770 +//line mysql_sql.y:7854 { yyVAL.str = yyDollar[1].str } - case 1189: + case 1202: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:7774 +//line mysql_sql.y:7858 { yyVAL.str = yyVAL.str + yyDollar[2].str } - case 1190: + case 1203: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:7780 +//line mysql_sql.y:7864 { yyVAL.str = "ALGORITHM = " + yyDollar[3].str } - case 1191: + case 1204: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:7784 +//line mysql_sql.y:7868 { yyVAL.str = "DEFINER = " } - case 1192: + case 1205: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:7788 +//line mysql_sql.y:7872 { yyVAL.str = "SQL SECURITY " + yyDollar[3].str } - case 1193: + case 1206: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:7793 +//line mysql_sql.y:7877 { yyVAL.str = "" } - case 1194: + case 1207: yyDollar = yyS[yypt-4 : yypt+1] -//line mysql_sql.y:7797 +//line mysql_sql.y:7881 { yyVAL.str = "WITH " + yyDollar[2].str + " CHECK OPTION" } - case 1200: + case 1213: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:7811 +//line mysql_sql.y:7895 { yyVAL.str = "" } - case 1203: + case 1216: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:7819 +//line mysql_sql.y:7903 { yyVAL.str = yyDollar[1].cstrUnion().Compare() } - case 1204: + case 1217: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:7825 +//line mysql_sql.y:7909 { var str = yyDollar[1].cstrUnion().Compare() yyLOCAL = tree.NewNumVal(str, str, false, tree.P_char) } yyVAL.union = yyLOCAL - case 1205: + case 1218: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:7830 +//line mysql_sql.y:7914 { yyLOCAL = tree.NewParamExpr(yylex.(*Lexer).GetParamIndex()) } yyVAL.union = yyLOCAL - case 1206: + case 1219: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.AccountAuthOption -//line mysql_sql.y:7836 +//line mysql_sql.y:7920 { var Equal = yyDollar[2].str var AdminName = yyDollar[3].exprUnion() @@ -22471,36 +22877,36 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1207: + case 1220: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:7849 +//line mysql_sql.y:7933 { var str = yyDollar[1].str yyLOCAL = tree.NewNumVal(str, str, false, tree.P_char) } yyVAL.union = yyLOCAL - case 1208: + case 1221: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:7854 +//line mysql_sql.y:7938 { var str = yyDollar[1].cstrUnion().Compare() yyLOCAL = tree.NewNumVal(str, str, false, tree.P_char) } yyVAL.union = yyLOCAL - case 1209: + case 1222: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:7859 +//line mysql_sql.y:7943 { yyLOCAL = tree.NewParamExpr(yylex.(*Lexer).GetParamIndex()) } yyVAL.union = yyLOCAL - case 1210: + case 1223: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AccountIdentified -//line mysql_sql.y:7865 +//line mysql_sql.y:7949 { yyLOCAL = *tree.NewAccountIdentified( tree.AccountIdentifiedByPassword, @@ -22508,10 +22914,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1211: + case 1224: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AccountIdentified -//line mysql_sql.y:7872 +//line mysql_sql.y:7956 { yyLOCAL = *tree.NewAccountIdentified( tree.AccountIdentifiedByPassword, @@ -22519,10 +22925,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1212: + case 1225: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.AccountIdentified -//line mysql_sql.y:7879 +//line mysql_sql.y:7963 { yyLOCAL = *tree.NewAccountIdentified( tree.AccountIdentifiedByRandomPassword, @@ -22530,10 +22936,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1213: + case 1226: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AccountIdentified -//line mysql_sql.y:7886 +//line mysql_sql.y:7970 { yyLOCAL = *tree.NewAccountIdentified( tree.AccountIdentifiedWithSSL, @@ -22541,10 +22947,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1214: + case 1227: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.AccountIdentified -//line mysql_sql.y:7893 +//line mysql_sql.y:7977 { yyLOCAL = *tree.NewAccountIdentified( tree.AccountIdentifiedWithSSL, @@ -22552,20 +22958,20 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1215: + case 1228: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.AccountStatus -//line mysql_sql.y:7901 +//line mysql_sql.y:7985 { as := tree.NewAccountStatus() as.Exist = false yyLOCAL = *as } yyVAL.union = yyLOCAL - case 1216: + case 1229: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.AccountStatus -//line mysql_sql.y:7907 +//line mysql_sql.y:7991 { as := tree.NewAccountStatus() as.Exist = true @@ -22573,10 +22979,10 @@ yydefault: yyLOCAL = *as } yyVAL.union = yyLOCAL - case 1217: + case 1230: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.AccountStatus -//line mysql_sql.y:7914 +//line mysql_sql.y:7998 { as := tree.NewAccountStatus() as.Exist = true @@ -22584,10 +22990,10 @@ yydefault: yyLOCAL = *as } yyVAL.union = yyLOCAL - case 1218: + case 1231: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.AccountStatus -//line mysql_sql.y:7921 +//line mysql_sql.y:8005 { as := tree.NewAccountStatus() as.Exist = true @@ -22595,20 +23001,20 @@ yydefault: yyLOCAL = *as } yyVAL.union = yyLOCAL - case 1219: + case 1232: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.AccountComment -//line mysql_sql.y:7929 +//line mysql_sql.y:8013 { ac := tree.NewAccountComment() ac.Exist = false yyLOCAL = *ac } yyVAL.union = yyLOCAL - case 1220: + case 1233: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AccountComment -//line mysql_sql.y:7935 +//line mysql_sql.y:8019 { ac := tree.NewAccountComment() ac.Exist = true @@ -22616,10 +23022,10 @@ yydefault: yyLOCAL = *ac } yyVAL.union = yyLOCAL - case 1221: + case 1234: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:7944 +//line mysql_sql.y:8028 { var IfNotExists = yyDollar[3].ifNotExistsUnion() var Users = yyDollar[4].usersUnion() @@ -22635,10 +23041,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1222: + case 1235: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:7961 +//line mysql_sql.y:8045 { var IfNotExists = yyDollar[3].ifNotExistsUnion() var Name = tree.Identifier(yyDollar[4].cstrUnion().Compare()) @@ -22655,10 +23061,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1223: + case 1236: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:7977 +//line mysql_sql.y:8061 { var IfNotExists = yyDollar[3].ifNotExistsUnion() var Name = tree.Identifier(yyDollar[4].cstrUnion().Compare()) @@ -22676,10 +23082,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1224: + case 1237: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:7994 +//line mysql_sql.y:8078 { var IfNotExists = yyDollar[3].ifNotExistsUnion() var Name = tree.Identifier(yyDollar[4].cstrUnion().Compare()) @@ -22696,30 +23102,30 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1225: + case 1238: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.AccountsSetOption -//line mysql_sql.y:8012 +//line mysql_sql.y:8096 { yyLOCAL = &tree.AccountsSetOption{ All: true, } } yyVAL.union = yyLOCAL - case 1226: + case 1239: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.AccountsSetOption -//line mysql_sql.y:8018 +//line mysql_sql.y:8102 { yyLOCAL = &tree.AccountsSetOption{ SetAccounts: yyDollar[2].identifierListUnion(), } } yyVAL.union = yyLOCAL - case 1227: + case 1240: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:8026 +//line mysql_sql.y:8110 { var IfNotExists = yyDollar[3].ifNotExistsUnion() var Name = tree.Identifier(yyDollar[4].cstrUnion().Compare()) @@ -22737,20 +23143,20 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1228: + case 1241: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.StageStatus -//line mysql_sql.y:8044 +//line mysql_sql.y:8128 { yyLOCAL = tree.StageStatus{ Exist: false, } } yyVAL.union = yyLOCAL - case 1229: + case 1242: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.StageStatus -//line mysql_sql.y:8050 +//line mysql_sql.y:8134 { yyLOCAL = tree.StageStatus{ Exist: true, @@ -22758,10 +23164,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1230: + case 1243: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.StageStatus -//line mysql_sql.y:8057 +//line mysql_sql.y:8141 { yyLOCAL = tree.StageStatus{ Exist: true, @@ -22769,20 +23175,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1231: + case 1244: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.StageComment -//line mysql_sql.y:8065 +//line mysql_sql.y:8149 { yyLOCAL = tree.StageComment{ Exist: false, } } yyVAL.union = yyLOCAL - case 1232: + case 1245: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.StageComment -//line mysql_sql.y:8071 +//line mysql_sql.y:8155 { yyLOCAL = tree.StageComment{ Exist: true, @@ -22790,18 +23196,18 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1233: + case 1246: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:8080 +//line mysql_sql.y:8164 { yyLOCAL = int64(0) } yyVAL.union = yyLOCAL - case 1234: + case 1247: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:8084 +//line mysql_sql.y:8168 { switch v := yyDollar[3].item.(type) { case int64: @@ -22813,20 +23219,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1235: + case 1248: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.StageUrl -//line mysql_sql.y:8096 +//line mysql_sql.y:8180 { yyLOCAL = tree.StageUrl{ Exist: false, } } yyVAL.union = yyLOCAL - case 1236: + case 1249: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.StageUrl -//line mysql_sql.y:8102 +//line mysql_sql.y:8186 { yyLOCAL = tree.StageUrl{ Exist: true, @@ -22834,20 +23240,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1237: + case 1250: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.StageCredentials -//line mysql_sql.y:8110 +//line mysql_sql.y:8194 { yyLOCAL = tree.StageCredentials{ Exist: false, } } yyVAL.union = yyLOCAL - case 1238: + case 1251: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.StageCredentials -//line mysql_sql.y:8116 +//line mysql_sql.y:8200 { yyLOCAL = tree.StageCredentials{ Exist: true, @@ -22855,61 +23261,61 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1239: + case 1252: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:8125 +//line mysql_sql.y:8209 { yyLOCAL = yyDollar[1].strsUnion() } yyVAL.union = yyLOCAL - case 1240: + case 1253: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:8129 +//line mysql_sql.y:8213 { yyLOCAL = append(yyDollar[1].strsUnion(), yyDollar[3].strsUnion()...) } yyVAL.union = yyLOCAL - case 1241: + case 1254: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:8134 +//line mysql_sql.y:8218 { yyLOCAL = []string{} } yyVAL.union = yyLOCAL - case 1242: + case 1255: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:8138 +//line mysql_sql.y:8222 { yyLOCAL = append(yyLOCAL, yyDollar[1].str) yyLOCAL = append(yyLOCAL, yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1243: + case 1256: yyDollar = yyS[yypt-3 : yypt+1] -//line mysql_sql.y:8145 +//line mysql_sql.y:8229 { yyVAL.str = yyDollar[3].str } - case 1244: + case 1257: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:8150 +//line mysql_sql.y:8234 { yyVAL.str = "" } - case 1245: + case 1258: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:8154 +//line mysql_sql.y:8238 { yyVAL.str = yyDollar[2].str } - case 1246: + case 1259: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:8160 +//line mysql_sql.y:8244 { var ifNotExists = yyDollar[3].boolValUnion() var name = tree.Identifier(yyDollar[4].cstrUnion().Compare()) @@ -22920,10 +23326,10 @@ yydefault: yyLOCAL = tree.NewAlterStage(ifNotExists, name, urlOption, credentialsOption, statusOption, comment) } yyVAL.union = yyLOCAL - case 1247: + case 1260: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:8172 +//line mysql_sql.y:8256 { var ifExists = yyDollar[3].boolValUnion() var name = tree.Identifier(yyDollar[4].cstrUnion().Compare()) @@ -22934,154 +23340,154 @@ yydefault: yyLOCAL = tree.NewAlterPublication(ifExists, name, accountsSet, dbName, table, comment) } yyVAL.union = yyLOCAL - case 1248: + case 1261: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.AccountsSetOption -//line mysql_sql.y:8183 +//line mysql_sql.y:8267 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1249: + case 1262: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.AccountsSetOption -//line mysql_sql.y:8187 +//line mysql_sql.y:8271 { yyLOCAL = &tree.AccountsSetOption{ All: true, } } yyVAL.union = yyLOCAL - case 1250: + case 1263: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.AccountsSetOption -//line mysql_sql.y:8193 +//line mysql_sql.y:8277 { yyLOCAL = &tree.AccountsSetOption{ SetAccounts: yyDollar[2].identifierListUnion(), } } yyVAL.union = yyLOCAL - case 1251: + case 1264: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.AccountsSetOption -//line mysql_sql.y:8199 +//line mysql_sql.y:8283 { yyLOCAL = &tree.AccountsSetOption{ AddAccounts: yyDollar[3].identifierListUnion(), } } yyVAL.union = yyLOCAL - case 1252: + case 1265: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.AccountsSetOption -//line mysql_sql.y:8205 +//line mysql_sql.y:8289 { yyLOCAL = &tree.AccountsSetOption{ DropAccounts: yyDollar[3].identifierListUnion(), } } yyVAL.union = yyLOCAL - case 1253: + case 1266: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:8212 +//line mysql_sql.y:8296 { yyVAL.str = "" } - case 1254: + case 1267: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:8216 +//line mysql_sql.y:8300 { yyVAL.str = yyDollar[2].str } - case 1255: + case 1268: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.TableNames -//line mysql_sql.y:8221 +//line mysql_sql.y:8305 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1256: + case 1269: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.TableNames -//line mysql_sql.y:8225 +//line mysql_sql.y:8309 { yyLOCAL = yyDollar[2].tableNamesUnion() } yyVAL.union = yyLOCAL - case 1257: + case 1270: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:8231 +//line mysql_sql.y:8315 { var ifExists = yyDollar[3].boolValUnion() var name = tree.Identifier(yyDollar[4].cstrUnion().Compare()) yyLOCAL = tree.NewDropPublication(ifExists, name) } yyVAL.union = yyLOCAL - case 1258: + case 1271: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:8239 +//line mysql_sql.y:8323 { var ifExists = yyDollar[4].boolValUnion() var taskID = yyDollar[5].str yyLOCAL = tree.NewDropCcprSubscription(ifExists, taskID) } yyVAL.union = yyLOCAL - case 1259: + case 1272: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:8247 +//line mysql_sql.y:8331 { var taskID = yyDollar[4].str yyLOCAL = tree.NewResumeCcprSubscription(taskID) } yyVAL.union = yyLOCAL - case 1260: + case 1273: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:8254 +//line mysql_sql.y:8338 { var taskID = yyDollar[4].str yyLOCAL = tree.NewPauseCcprSubscription(taskID) } yyVAL.union = yyLOCAL - case 1261: + case 1274: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:8261 +//line mysql_sql.y:8345 { var ifNotExists = yyDollar[3].boolValUnion() var name = tree.Identifier(yyDollar[4].cstrUnion().Compare()) yyLOCAL = tree.NewDropStage(ifNotExists, name) } yyVAL.union = yyLOCAL - case 1262: + case 1275: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:8269 +//line mysql_sql.y:8353 { var ifExists = yyDollar[5].boolValUnion() var path = yyDollar[6].str yyLOCAL = tree.NewRemoveStageFiles(ifExists, path) } yyVAL.union = yyLOCAL - case 1263: + case 1276: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:8277 +//line mysql_sql.y:8361 { var ifExists = yyDollar[3].boolValUnion() var name = tree.Identifier(yyDollar[4].cstrUnion().Compare()) yyLOCAL = tree.NewDropSnapShot(ifExists, name, "", "") } yyVAL.union = yyLOCAL - case 1264: + case 1277: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:8283 +//line mysql_sql.y:8367 { var ifExists = yyDollar[3].boolValUnion() var name = tree.Identifier(yyDollar[4].cstrUnion().Compare()) @@ -23090,10 +23496,10 @@ yydefault: yyLOCAL = tree.NewDropSnapShot(ifExists, name, accountName, pubName) } yyVAL.union = yyLOCAL - case 1265: + case 1278: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:8293 +//line mysql_sql.y:8377 { var ifExists = yyDollar[3].boolValUnion() var name = tree.Identifier(yyDollar[4].cstrUnion().Compare()) @@ -23105,16 +23511,16 @@ yydefault: } yyVAL.union = yyLOCAL - case 1266: + case 1279: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:8306 +//line mysql_sql.y:8390 { yyVAL.str = yyDollar[1].cstrUnion().Compare() } - case 1267: + case 1280: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.AccountCommentOrAttribute -//line mysql_sql.y:8311 +//line mysql_sql.y:8395 { var Exist = false var IsComment bool @@ -23127,10 +23533,10 @@ yydefault: } yyVAL.union = yyLOCAL - case 1268: + case 1281: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AccountCommentOrAttribute -//line mysql_sql.y:8323 +//line mysql_sql.y:8407 { var Exist = true var IsComment = true @@ -23142,10 +23548,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1269: + case 1282: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.AccountCommentOrAttribute -//line mysql_sql.y:8334 +//line mysql_sql.y:8418 { var Exist = true var IsComment = false @@ -23157,26 +23563,26 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1270: + case 1283: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.User -//line mysql_sql.y:8442 +//line mysql_sql.y:8526 { yyLOCAL = []*tree.User{yyDollar[1].userUnion()} } yyVAL.union = yyLOCAL - case 1271: + case 1284: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.User -//line mysql_sql.y:8446 +//line mysql_sql.y:8530 { yyLOCAL = append(yyDollar[1].usersUnion(), yyDollar[3].userUnion()) } yyVAL.union = yyLOCAL - case 1272: + case 1285: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.User -//line mysql_sql.y:8452 +//line mysql_sql.y:8536 { var Username = yyDollar[1].usernameRecordUnion().Username var Hostname = yyDollar[1].usernameRecordUnion().Hostname @@ -23188,26 +23594,26 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1273: + case 1286: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.User -//line mysql_sql.y:8465 +//line mysql_sql.y:8549 { yyLOCAL = []*tree.User{yyDollar[1].userUnion()} } yyVAL.union = yyLOCAL - case 1274: + case 1287: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.User -//line mysql_sql.y:8469 +//line mysql_sql.y:8553 { yyLOCAL = append(yyDollar[1].usersUnion(), yyDollar[3].userUnion()) } yyVAL.union = yyLOCAL - case 1275: + case 1288: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.User -//line mysql_sql.y:8475 +//line mysql_sql.y:8559 { var Username = yyDollar[1].usernameRecordUnion().Username var Hostname = yyDollar[1].usernameRecordUnion().Hostname @@ -23219,50 +23625,50 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1276: + case 1289: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.UsernameRecord -//line mysql_sql.y:8488 +//line mysql_sql.y:8572 { yyLOCAL = &tree.UsernameRecord{Username: yyDollar[1].str, Hostname: "%"} } yyVAL.union = yyLOCAL - case 1277: + case 1290: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.UsernameRecord -//line mysql_sql.y:8492 +//line mysql_sql.y:8576 { yyLOCAL = &tree.UsernameRecord{Username: yyDollar[1].str, Hostname: yyDollar[3].str} } yyVAL.union = yyLOCAL - case 1278: + case 1291: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.UsernameRecord -//line mysql_sql.y:8496 +//line mysql_sql.y:8580 { yyLOCAL = &tree.UsernameRecord{Username: yyDollar[1].str, Hostname: yyDollar[2].str} } yyVAL.union = yyLOCAL - case 1279: + case 1292: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.AccountIdentified -//line mysql_sql.y:8501 +//line mysql_sql.y:8585 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1280: + case 1293: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.AccountIdentified -//line mysql_sql.y:8505 +//line mysql_sql.y:8589 { yyLOCAL = yyDollar[1].userIdentifiedUnion() } yyVAL.union = yyLOCAL - case 1281: + case 1294: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.AccountIdentified -//line mysql_sql.y:8511 +//line mysql_sql.y:8595 { yyLOCAL = &tree.AccountIdentified{ Typ: tree.AccountIdentifiedByPassword, @@ -23270,20 +23676,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1282: + case 1295: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.AccountIdentified -//line mysql_sql.y:8518 +//line mysql_sql.y:8602 { yyLOCAL = &tree.AccountIdentified{ Typ: tree.AccountIdentifiedByRandomPassword, } } yyVAL.union = yyLOCAL - case 1283: + case 1296: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.AccountIdentified -//line mysql_sql.y:8524 +//line mysql_sql.y:8608 { yyLOCAL = &tree.AccountIdentified{ Typ: tree.AccountIdentifiedWithSSL, @@ -23291,16 +23697,16 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1284: + case 1297: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:8533 +//line mysql_sql.y:8617 { yyVAL.str = yyDollar[1].cstrUnion().Compare() } - case 1286: + case 1299: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:8540 +//line mysql_sql.y:8624 { var IfNotExists = yyDollar[3].ifNotExistsUnion() var Roles = yyDollar[4].rolesUnion() @@ -23310,26 +23716,26 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1287: + case 1300: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.Role -//line mysql_sql.y:8551 +//line mysql_sql.y:8635 { yyLOCAL = []*tree.Role{yyDollar[1].roleUnion()} } yyVAL.union = yyLOCAL - case 1288: + case 1301: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.Role -//line mysql_sql.y:8555 +//line mysql_sql.y:8639 { yyLOCAL = append(yyDollar[1].rolesUnion(), yyDollar[3].roleUnion()) } yyVAL.union = yyLOCAL - case 1289: + case 1302: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.Role -//line mysql_sql.y:8561 +//line mysql_sql.y:8645 { var UserName = yyDollar[1].cstrUnion().Compare() yyLOCAL = tree.NewRole( @@ -23337,106 +23743,106 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1290: + case 1303: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:8570 +//line mysql_sql.y:8654 { yyLOCAL = tree.NewCStr(yyDollar[1].str, 1) } yyVAL.union = yyLOCAL - case 1291: + case 1304: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:8574 +//line mysql_sql.y:8658 { yyLOCAL = tree.NewCStr(yyDollar[1].str, 1) } yyVAL.union = yyLOCAL - case 1292: + case 1305: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:8578 +//line mysql_sql.y:8662 { yyLOCAL = tree.NewCStr(yyDollar[1].str, 1) } yyVAL.union = yyLOCAL - case 1293: + case 1306: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:8582 +//line mysql_sql.y:8666 { yyLOCAL = tree.NewCStr("lag", 1) } yyVAL.union = yyLOCAL - case 1294: + case 1307: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:8586 +//line mysql_sql.y:8670 { yyLOCAL = tree.NewCStr("lead", 1) } yyVAL.union = yyLOCAL - case 1295: + case 1308: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:8590 +//line mysql_sql.y:8674 { yyLOCAL = tree.NewCStr("first_value", 1) } yyVAL.union = yyLOCAL - case 1296: + case 1309: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:8594 +//line mysql_sql.y:8678 { yyLOCAL = tree.NewCStr("last_value", 1) } yyVAL.union = yyLOCAL - case 1297: + case 1310: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:8598 +//line mysql_sql.y:8682 { yyLOCAL = tree.NewCStr("nth_value", 1) } yyVAL.union = yyLOCAL - case 1298: + case 1311: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.IndexCategory -//line mysql_sql.y:8603 +//line mysql_sql.y:8687 { yyLOCAL = tree.INDEX_CATEGORY_NONE } yyVAL.union = yyLOCAL - case 1299: + case 1312: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.IndexCategory -//line mysql_sql.y:8607 +//line mysql_sql.y:8691 { yyLOCAL = tree.INDEX_CATEGORY_FULLTEXT } yyVAL.union = yyLOCAL - case 1300: + case 1313: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.IndexCategory -//line mysql_sql.y:8611 +//line mysql_sql.y:8695 { yyLOCAL = tree.INDEX_CATEGORY_SPATIAL } yyVAL.union = yyLOCAL - case 1301: + case 1314: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.IndexCategory -//line mysql_sql.y:8615 +//line mysql_sql.y:8699 { yyLOCAL = tree.INDEX_CATEGORY_UNIQUE } yyVAL.union = yyLOCAL - case 1302: + case 1315: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:8621 +//line mysql_sql.y:8705 { var io *tree.IndexOption = nil if yyDollar[11].indexOptionUnion() == nil && yyDollar[5].indexTypeUnion() != tree.INDEX_TYPE_INVALID { @@ -23467,18 +23873,18 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1303: + case 1316: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8652 +//line mysql_sql.y:8736 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1304: + case 1317: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8656 +//line mysql_sql.y:8740 { // Merge the options if yyDollar[1].indexOptionUnion() == nil { @@ -23541,20 +23947,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1305: + case 1318: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8720 +//line mysql_sql.y:8804 { io := tree.NewIndexOption() io.KeyBlockSize = uint64(yyDollar[3].item.(int64)) yyLOCAL = io } yyVAL.union = yyLOCAL - case 1306: + case 1319: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8726 +//line mysql_sql.y:8810 { val := int64(yyDollar[3].item.(int64)) if val <= 0 { @@ -23567,60 +23973,60 @@ yydefault: yyLOCAL = io } yyVAL.union = yyLOCAL - case 1307: + case 1320: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8738 +//line mysql_sql.y:8822 { io := tree.NewIndexOption() io.AlgoParamVectorOpType = yyDollar[2].str yyLOCAL = io } yyVAL.union = yyLOCAL - case 1308: + case 1321: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8744 +//line mysql_sql.y:8828 { io := tree.NewIndexOption() io.Comment = yyDollar[2].str yyLOCAL = io } yyVAL.union = yyLOCAL - case 1309: + case 1322: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8750 +//line mysql_sql.y:8834 { io := tree.NewIndexOption() io.ParserName = yyDollar[3].cstrUnion().Compare() yyLOCAL = io } yyVAL.union = yyLOCAL - case 1310: + case 1323: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8756 +//line mysql_sql.y:8840 { io := tree.NewIndexOption() io.Visible = tree.VISIBLE_TYPE_VISIBLE yyLOCAL = io } yyVAL.union = yyLOCAL - case 1311: + case 1324: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8762 +//line mysql_sql.y:8846 { io := tree.NewIndexOption() io.Visible = tree.VISIBLE_TYPE_INVISIBLE yyLOCAL = io } yyVAL.union = yyLOCAL - case 1312: + case 1325: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8768 +//line mysql_sql.y:8852 { val := int64(yyDollar[3].item.(int64)) if val <= 0 { @@ -23632,10 +24038,10 @@ yydefault: yyLOCAL = io } yyVAL.union = yyLOCAL - case 1313: + case 1326: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8779 +//line mysql_sql.y:8863 { val := int64(yyDollar[3].item.(int64)) if val <= 0 { @@ -23647,10 +24053,10 @@ yydefault: yyLOCAL = io } yyVAL.union = yyLOCAL - case 1314: + case 1327: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8790 +//line mysql_sql.y:8874 { val := int64(yyDollar[3].item.(int64)) if val <= 0 { @@ -23662,10 +24068,10 @@ yydefault: yyLOCAL = io } yyVAL.union = yyLOCAL - case 1315: + case 1328: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8801 +//line mysql_sql.y:8885 { val := int64(yyDollar[3].item.(int64)) if val <= 0 { @@ -23677,10 +24083,10 @@ yydefault: yyLOCAL = io } yyVAL.union = yyLOCAL - case 1316: + case 1329: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8812 +//line mysql_sql.y:8896 { val := int64(yyDollar[3].item.(int64)) if val <= 0 { @@ -23692,10 +24098,10 @@ yydefault: yyLOCAL = io } yyVAL.union = yyLOCAL - case 1317: + case 1330: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8823 +//line mysql_sql.y:8907 { val := int64(yyDollar[3].item.(int64)) if val <= 0 { @@ -23707,40 +24113,40 @@ yydefault: yyLOCAL = io } yyVAL.union = yyLOCAL - case 1318: + case 1331: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8834 +//line mysql_sql.y:8918 { io := tree.NewIndexOption() io.IncludeColumns = yyDollar[3].unresolveNamesUnion() yyLOCAL = io } yyVAL.union = yyLOCAL - case 1319: + case 1332: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8840 +//line mysql_sql.y:8924 { io := tree.NewIndexOption() io.Quantization = yyDollar[2].str yyLOCAL = io } yyVAL.union = yyLOCAL - case 1320: + case 1333: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8846 +//line mysql_sql.y:8930 { io := tree.NewIndexOption() io.DistributionMode = yyDollar[2].str yyLOCAL = io } yyVAL.union = yyLOCAL - case 1321: + case 1334: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8852 +//line mysql_sql.y:8936 { val := int64(yyDollar[3].item.(int64)) if val <= 0 { @@ -23752,10 +24158,10 @@ yydefault: yyLOCAL = io } yyVAL.union = yyLOCAL - case 1322: + case 1335: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8863 +//line mysql_sql.y:8947 { val := int64(yyDollar[3].item.(int64)) if val <= 0 { @@ -23767,10 +24173,10 @@ yydefault: yyLOCAL = io } yyVAL.union = yyLOCAL - case 1323: + case 1336: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8874 +//line mysql_sql.y:8958 { val := int64(yyDollar[3].item.(int64)) if val <= 0 { @@ -23782,10 +24188,10 @@ yydefault: yyLOCAL = io } yyVAL.union = yyLOCAL - case 1324: + case 1337: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8885 +//line mysql_sql.y:8969 { val := int64(yyDollar[3].item.(int64)) if val <= 0 { @@ -23797,50 +24203,50 @@ yydefault: yyLOCAL = io } yyVAL.union = yyLOCAL - case 1325: + case 1338: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8896 +//line mysql_sql.y:8980 { io := tree.NewIndexOption() io.Async = true yyLOCAL = io } yyVAL.union = yyLOCAL - case 1326: + case 1339: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8902 +//line mysql_sql.y:8986 { io := tree.NewIndexOption() io.ForceSync = true yyLOCAL = io } yyVAL.union = yyLOCAL - case 1327: + case 1340: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8908 +//line mysql_sql.y:8992 { io := tree.NewIndexOption() io.AutoUpdate = true yyLOCAL = io } yyVAL.union = yyLOCAL - case 1328: + case 1341: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8914 +//line mysql_sql.y:8998 { io := tree.NewIndexOption() io.AutoUpdate = false yyLOCAL = io } yyVAL.union = yyLOCAL - case 1329: + case 1342: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8920 +//line mysql_sql.y:9004 { val := int64(yyDollar[3].item.(int64)) if val < 0 { @@ -23852,10 +24258,10 @@ yydefault: yyLOCAL = io } yyVAL.union = yyLOCAL - case 1330: + case 1343: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IndexOption -//line mysql_sql.y:8931 +//line mysql_sql.y:9015 { val := int64(yyDollar[3].item.(int64)) if val < 0 || val > 23 { @@ -23867,26 +24273,26 @@ yydefault: yyLOCAL = io } yyVAL.union = yyLOCAL - case 1331: + case 1344: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.KeyPart -//line mysql_sql.y:8945 +//line mysql_sql.y:9029 { yyLOCAL = []*tree.KeyPart{yyDollar[1].keyPartUnion()} } yyVAL.union = yyLOCAL - case 1332: + case 1345: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.KeyPart -//line mysql_sql.y:8949 +//line mysql_sql.y:9033 { yyLOCAL = append(yyDollar[1].keyPartsUnion(), yyDollar[3].keyPartUnion()) } yyVAL.union = yyLOCAL - case 1333: + case 1346: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.KeyPart -//line mysql_sql.y:8955 +//line mysql_sql.y:9039 { // Order is parsed but just ignored as MySQL dtree. var ColName = yyDollar[1].unresolvedNameUnion() @@ -23901,10 +24307,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1334: + case 1347: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.KeyPart -//line mysql_sql.y:8969 +//line mysql_sql.y:9053 { var ColName *tree.UnresolvedName var Length int @@ -23918,90 +24324,90 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1335: + case 1348: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.IndexType -//line mysql_sql.y:8983 +//line mysql_sql.y:9067 { yyLOCAL = tree.INDEX_TYPE_INVALID } yyVAL.union = yyLOCAL - case 1336: + case 1349: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IndexType -//line mysql_sql.y:8987 +//line mysql_sql.y:9071 { yyLOCAL = tree.INDEX_TYPE_BTREE } yyVAL.union = yyLOCAL - case 1337: + case 1350: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IndexType -//line mysql_sql.y:8991 +//line mysql_sql.y:9075 { yyLOCAL = tree.INDEX_TYPE_IVFFLAT } yyVAL.union = yyLOCAL - case 1338: + case 1351: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IndexType -//line mysql_sql.y:8995 +//line mysql_sql.y:9079 { yyLOCAL = tree.INDEX_TYPE_HNSW } yyVAL.union = yyLOCAL - case 1339: + case 1352: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IndexType -//line mysql_sql.y:8999 +//line mysql_sql.y:9083 { yyLOCAL = tree.INDEX_TYPE_IVFPQ } yyVAL.union = yyLOCAL - case 1340: + case 1353: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IndexType -//line mysql_sql.y:9003 +//line mysql_sql.y:9087 { yyLOCAL = tree.INDEX_TYPE_CAGRA } yyVAL.union = yyLOCAL - case 1341: + case 1354: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IndexType -//line mysql_sql.y:9007 +//line mysql_sql.y:9091 { yyLOCAL = tree.INDEX_TYPE_MASTER } yyVAL.union = yyLOCAL - case 1342: + case 1355: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IndexType -//line mysql_sql.y:9011 +//line mysql_sql.y:9095 { yyLOCAL = tree.INDEX_TYPE_HASH } yyVAL.union = yyLOCAL - case 1343: + case 1356: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IndexType -//line mysql_sql.y:9015 +//line mysql_sql.y:9099 { yyLOCAL = tree.INDEX_TYPE_RTREE } yyVAL.union = yyLOCAL - case 1344: + case 1357: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.IndexType -//line mysql_sql.y:9019 +//line mysql_sql.y:9103 { yyLOCAL = tree.INDEX_TYPE_BSI } yyVAL.union = yyLOCAL - case 1345: + case 1358: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9025 +//line mysql_sql.y:9109 { var IfNotExists = yyDollar[3].ifNotExistsUnion() var Name = tree.Identifier(yyDollar[4].str) @@ -24015,10 +24421,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1346: + case 1359: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9039 +//line mysql_sql.y:9123 { var t = tree.NewCloneDatabase() t.DstDatabase = tree.Identifier(yyDollar[4].str) @@ -24028,10 +24434,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1347: + case 1360: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9048 +//line mysql_sql.y:9132 { var DbName = tree.Identifier(yyDollar[4].str) var FromUri = yyDollar[6].str @@ -24049,92 +24455,92 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1348: + case 1361: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.SubscriptionOption -//line mysql_sql.y:9066 +//line mysql_sql.y:9150 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1349: + case 1362: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.SubscriptionOption -//line mysql_sql.y:9070 +//line mysql_sql.y:9154 { var From = tree.Identifier(yyDollar[2].str) var Publication = tree.Identifier(yyDollar[4].cstrUnion().Compare()) yyLOCAL = tree.NewSubscriptionOption(From, Publication) } yyVAL.union = yyLOCAL - case 1352: + case 1365: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9081 +//line mysql_sql.y:9165 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1353: + case 1366: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9085 +//line mysql_sql.y:9169 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1354: + case 1367: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9090 +//line mysql_sql.y:9174 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1355: + case 1368: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9094 +//line mysql_sql.y:9178 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1356: + case 1369: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []tree.CreateOption -//line mysql_sql.y:9099 +//line mysql_sql.y:9183 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1357: + case 1370: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []tree.CreateOption -//line mysql_sql.y:9103 +//line mysql_sql.y:9187 { yyLOCAL = yyDollar[1].createOptionsUnion() } yyVAL.union = yyLOCAL - case 1358: + case 1371: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []tree.CreateOption -//line mysql_sql.y:9109 +//line mysql_sql.y:9193 { yyLOCAL = []tree.CreateOption{yyDollar[1].createOptionUnion()} } yyVAL.union = yyLOCAL - case 1359: + case 1372: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []tree.CreateOption -//line mysql_sql.y:9113 +//line mysql_sql.y:9197 { yyLOCAL = append(yyDollar[1].createOptionsUnion(), yyDollar[2].createOptionUnion()) } yyVAL.union = yyLOCAL - case 1360: + case 1373: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.CreateOption -//line mysql_sql.y:9119 +//line mysql_sql.y:9203 { var IsDefault = yyDollar[1].defaultOptionalUnion() var Charset = yyDollar[4].str @@ -24144,10 +24550,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1361: + case 1374: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.CreateOption -//line mysql_sql.y:9128 +//line mysql_sql.y:9212 { var IsDefault = yyDollar[1].defaultOptionalUnion() var Collate = yyDollar[4].str @@ -24157,35 +24563,35 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1362: + case 1375: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.CreateOption -//line mysql_sql.y:9137 +//line mysql_sql.y:9221 { var Encrypt = yyDollar[4].str yyLOCAL = tree.NewCreateOptionEncryption(Encrypt) } yyVAL.union = yyLOCAL - case 1363: + case 1376: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9143 +//line mysql_sql.y:9227 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1364: + case 1377: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9147 +//line mysql_sql.y:9231 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1365: + case 1378: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9153 +//line mysql_sql.y:9237 { var TableName = yyDollar[4].tableNameUnion() var Options = yyDollar[7].connectorOptionsUnion() @@ -24195,18 +24601,18 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1366: + case 1379: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9164 +//line mysql_sql.y:9248 { yyLOCAL = &tree.ShowConnectors{} } yyVAL.union = yyLOCAL - case 1367: + case 1380: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9170 +//line mysql_sql.y:9254 { var taskID uint64 switch v := yyDollar[4].item.(type) { @@ -24223,10 +24629,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1368: + case 1381: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9188 +//line mysql_sql.y:9272 { var taskID uint64 switch v := yyDollar[4].item.(type) { @@ -24243,10 +24649,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1369: + case 1382: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9206 +//line mysql_sql.y:9290 { var taskID uint64 switch v := yyDollar[4].item.(type) { @@ -24263,10 +24669,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1370: + case 1383: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9224 +//line mysql_sql.y:9308 { var Replace = yyDollar[2].sourceOptionalUnion() var IfNotExists = yyDollar[4].ifNotExistsUnion() @@ -24282,26 +24688,26 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1371: + case 1384: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9240 +//line mysql_sql.y:9324 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1372: + case 1385: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9244 +//line mysql_sql.y:9328 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1373: + case 1386: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9250 +//line mysql_sql.y:9334 { t := tree.NewDataBranchCreateTable() t.CreateTable.Table = *yyDollar[5].tableNameUnion() @@ -24312,10 +24718,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1374: + case 1387: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9260 +//line mysql_sql.y:9344 { t := tree.NewDataBranchCreateDatabase() t.DstDatabase = tree.Identifier(yyDollar[5].str) @@ -24325,30 +24731,30 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1375: + case 1388: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9269 +//line mysql_sql.y:9353 { t := tree.NewDataBranchDeleteTable() t.TableName = *yyDollar[5].tableNameUnion() yyLOCAL = t } yyVAL.union = yyLOCAL - case 1376: + case 1389: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9275 +//line mysql_sql.y:9359 { t := tree.NewDataBranchDeleteDatabase() t.DatabaseName = tree.Identifier(yyDollar[5].str) yyLOCAL = t } yyVAL.union = yyLOCAL - case 1377: + case 1390: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9281 +//line mysql_sql.y:9365 { t := tree.NewDataBranchDiff() t.TargetTable = *yyDollar[4].tableNameUnion() @@ -24358,10 +24764,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1378: + case 1391: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9290 +//line mysql_sql.y:9374 { t := tree.NewDataBranchMerge() t.SrcTable = *yyDollar[4].tableNameUnion() @@ -24370,10 +24776,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1379: + case 1392: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9298 +//line mysql_sql.y:9382 { t := tree.NewDataBranchPick() t.SrcTable = *yyDollar[4].tableNameUnion() @@ -24383,10 +24789,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1380: + case 1393: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9307 +//line mysql_sql.y:9391 { t := tree.NewDataBranchPick() t.SrcTable = *yyDollar[4].tableNameUnion() @@ -24397,10 +24803,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1381: + case 1394: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9317 +//line mysql_sql.y:9401 { t := tree.NewDataBranchPick() t.SrcTable = *yyDollar[4].tableNameUnion() @@ -24411,10 +24817,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1382: + case 1395: yyDollar = yyS[yypt-13 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9327 +//line mysql_sql.y:9411 { t := tree.NewDataBranchPick() t.SrcTable = *yyDollar[4].tableNameUnion() @@ -24426,10 +24832,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1383: + case 1396: yyDollar = yyS[yypt-13 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9338 +//line mysql_sql.y:9422 { t := tree.NewDataBranchPick() t.SrcTable = *yyDollar[4].tableNameUnion() @@ -24441,54 +24847,54 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1384: + case 1397: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:9350 +//line mysql_sql.y:9434 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1385: + case 1398: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.IdentifierList -//line mysql_sql.y:9354 +//line mysql_sql.y:9438 { yyLOCAL = yyDollar[3].identifierListUnion() } yyVAL.union = yyLOCAL - case 1386: + case 1399: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.DiffOutputOpt -//line mysql_sql.y:9359 +//line mysql_sql.y:9443 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1387: + case 1400: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.DiffOutputOpt -//line mysql_sql.y:9363 +//line mysql_sql.y:9447 { yyLOCAL = &tree.DiffOutputOpt{ As: *yyDollar[3].tableNameUnion(), } } yyVAL.union = yyLOCAL - case 1388: + case 1401: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.DiffOutputOpt -//line mysql_sql.y:9369 +//line mysql_sql.y:9453 { yyLOCAL = &tree.DiffOutputOpt{ DirPath: yyDollar[3].str, } } yyVAL.union = yyLOCAL - case 1389: + case 1402: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.DiffOutputOpt -//line mysql_sql.y:9375 +//line mysql_sql.y:9459 { x := yyDollar[3].item.(int64) yyLOCAL = &tree.DiffOutputOpt{ @@ -24496,68 +24902,68 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1390: + case 1403: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.DiffOutputOpt -//line mysql_sql.y:9382 +//line mysql_sql.y:9466 { yyLOCAL = &tree.DiffOutputOpt{ Count: true, } } yyVAL.union = yyLOCAL - case 1391: + case 1404: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.DiffOutputOpt -//line mysql_sql.y:9388 +//line mysql_sql.y:9472 { yyLOCAL = &tree.DiffOutputOpt{ Summary: true, } } yyVAL.union = yyLOCAL - case 1392: + case 1405: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.ConflictOpt -//line mysql_sql.y:9396 +//line mysql_sql.y:9480 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1393: + case 1406: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.ConflictOpt -//line mysql_sql.y:9400 +//line mysql_sql.y:9484 { yyLOCAL = &tree.ConflictOpt{ Opt: tree.CONFLICT_FAIL, } } yyVAL.union = yyLOCAL - case 1394: + case 1407: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.ConflictOpt -//line mysql_sql.y:9406 +//line mysql_sql.y:9490 { yyLOCAL = &tree.ConflictOpt{ Opt: tree.CONFLICT_SKIP, } } yyVAL.union = yyLOCAL - case 1395: + case 1408: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.ConflictOpt -//line mysql_sql.y:9412 +//line mysql_sql.y:9496 { yyLOCAL = &tree.ConflictOpt{ Opt: tree.CONFLICT_ACCEPT, } } yyVAL.union = yyLOCAL - case 1396: + case 1409: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.PickKeys -//line mysql_sql.y:9420 +//line mysql_sql.y:9504 { yyLOCAL = &tree.PickKeys{ Type: tree.PickKeysValues, @@ -24565,10 +24971,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1397: + case 1410: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.PickKeys -//line mysql_sql.y:9427 +//line mysql_sql.y:9511 { yyLOCAL = &tree.PickKeys{ Type: tree.PickKeysSubquery, @@ -24576,44 +24982,44 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1398: + case 1411: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.ToAccountOpt -//line mysql_sql.y:9436 +//line mysql_sql.y:9520 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1399: + case 1412: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.ToAccountOpt -//line mysql_sql.y:9440 +//line mysql_sql.y:9524 { yyLOCAL = &tree.ToAccountOpt{ AccountName: tree.Identifier(yyDollar[3].cstrUnion().Compare()), } } yyVAL.union = yyLOCAL - case 1400: + case 1413: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9448 +//line mysql_sql.y:9532 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1401: + case 1414: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9452 +//line mysql_sql.y:9536 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1402: + case 1415: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9458 +//line mysql_sql.y:9542 { t := tree.NewCreateTable() t.Temporary = yyDollar[2].boolValUnion() @@ -24626,10 +25032,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1403: + case 1416: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9470 +//line mysql_sql.y:9554 { t := tree.NewCreateTable() t.IfNotExists = yyDollar[4].ifNotExistsUnion() @@ -24639,10 +25045,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1404: + case 1417: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9479 +//line mysql_sql.y:9563 { t := tree.NewCreateTable() t.IfNotExists = yyDollar[4].ifNotExistsUnion() @@ -24652,10 +25058,23 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1405: + case 1418: + yyDollar = yyS[yypt-9 : yypt+1] + var yyLOCAL tree.Statement +//line mysql_sql.y:9572 + { + t := tree.NewCreateTable() + t.IfNotExists = yyDollar[4].ifNotExistsUnion() + t.Table = *yyDollar[5].tableNameUnion() + t.Defs = yyDollar[7].tableDefsUnion() + t.MongoDBParam = yyDollar[9].mongodbTableParamUnion() + yyLOCAL = t + } + yyVAL.union = yyLOCAL + case 1419: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9488 +//line mysql_sql.y:9581 { t := tree.NewCreateTable() t.IfNotExists = yyDollar[4].ifNotExistsUnion() @@ -24664,10 +25083,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1406: + case 1420: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9496 +//line mysql_sql.y:9589 { t := tree.NewCreateTable() t.IsClusterTable = true @@ -24680,10 +25099,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1407: + case 1421: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9508 +//line mysql_sql.y:9601 { t := tree.NewCreateTable() t.IsDynamicTable = true @@ -24694,10 +25113,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1408: + case 1422: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9518 +//line mysql_sql.y:9611 { t := tree.NewCreateTable() t.IsAsSelect = true @@ -24708,10 +25127,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1409: + case 1423: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9528 +//line mysql_sql.y:9621 { t := tree.NewCreateTable() t.IsAsSelect = true @@ -24723,10 +25142,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1410: + case 1424: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9539 +//line mysql_sql.y:9632 { t := tree.NewCreateTable() t.IsAsSelect = true @@ -24737,10 +25156,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1411: + case 1425: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9549 +//line mysql_sql.y:9642 { t := tree.NewCreateTable() t.IsAsSelect = true @@ -24752,10 +25171,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1412: + case 1426: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9560 +//line mysql_sql.y:9653 { t := tree.NewCreateTable() t.IsAsLike = true @@ -24766,10 +25185,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1413: + case 1427: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9570 +//line mysql_sql.y:9663 { t := tree.NewCreateTable() t.Temporary = yyDollar[2].boolValUnion() @@ -24779,10 +25198,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1414: + case 1428: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9579 +//line mysql_sql.y:9672 { t := tree.NewCloneTable() t.CreateTable.Temporary = yyDollar[2].boolValUnion() @@ -24796,10 +25215,10 @@ yydefault: yyLOCAL = t } yyVAL.union = yyLOCAL - case 1415: + case 1429: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9592 +//line mysql_sql.y:9685 { var TableName = yyDollar[5].tableNameUnion() var FromUri = yyDollar[7].str @@ -24823,19 +25242,19 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1416: + case 1430: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.ExternParam -//line mysql_sql.y:9617 +//line mysql_sql.y:9710 { yyLOCAL = yyDollar[1].loadParamUnion() yyLOCAL.Tail = yyDollar[2].tailParamUnion() } yyVAL.union = yyLOCAL - case 1417: + case 1431: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.ExternParam -//line mysql_sql.y:9624 +//line mysql_sql.y:9717 { yyLOCAL = &tree.ExternParam{ ExParamConst: tree.ExParamConst{ @@ -24846,10 +25265,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1418: + case 1432: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *tree.ExternParam -//line mysql_sql.y:9634 +//line mysql_sql.y:9727 { yyLOCAL = &tree.ExternParam{ ExParamConst: tree.ExParamConst{ @@ -24863,10 +25282,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1419: + case 1433: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.ExternParam -//line mysql_sql.y:9647 +//line mysql_sql.y:9740 { yyLOCAL = &tree.ExternParam{ ExParamConst: tree.ExParamConst{ @@ -24875,10 +25294,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1420: + case 1434: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.ExternParam -//line mysql_sql.y:9655 +//line mysql_sql.y:9748 { yyLOCAL = &tree.ExternParam{ ExParamConst: tree.ExParamConst{ @@ -24888,10 +25307,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1421: + case 1435: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.ExternParam -//line mysql_sql.y:9664 +//line mysql_sql.y:9757 { yyLOCAL = &tree.ExternParam{ ExParamConst: tree.ExParamConst{ @@ -24900,55 +25319,55 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1422: + case 1436: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:9673 +//line mysql_sql.y:9766 { yyVAL.str = "" } - case 1423: + case 1437: yyDollar = yyS[yypt-4 : yypt+1] -//line mysql_sql.y:9677 +//line mysql_sql.y:9770 { yyVAL.str = yyDollar[4].str } - case 1424: + case 1438: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:9683 +//line mysql_sql.y:9776 { yyLOCAL = yyDollar[1].strsUnion() } yyVAL.union = yyLOCAL - case 1425: + case 1439: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:9687 +//line mysql_sql.y:9780 { yyLOCAL = append(yyDollar[1].strsUnion(), yyDollar[3].strsUnion()...) } yyVAL.union = yyLOCAL - case 1426: + case 1440: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:9692 +//line mysql_sql.y:9785 { yyLOCAL = []string{} } yyVAL.union = yyLOCAL - case 1427: + case 1441: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:9696 +//line mysql_sql.y:9789 { yyLOCAL = append(yyLOCAL, yyDollar[1].str) yyLOCAL = append(yyLOCAL, yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1428: + case 1442: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.TailParameter -//line mysql_sql.y:9703 +//line mysql_sql.y:9796 { yyLOCAL = &tree.TailParameter{ Charset: yyDollar[1].str, @@ -24960,22 +25379,22 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1429: + case 1443: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:9715 +//line mysql_sql.y:9808 { yyVAL.str = "" } - case 1430: + case 1444: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:9719 +//line mysql_sql.y:9812 { yyVAL.str = yyDollar[2].str } - case 1431: + case 1445: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:9725 +//line mysql_sql.y:9818 { var Name = yyDollar[4].tableNameUnion() var Type = yyDollar[5].columnTypeUnion() @@ -24997,10 +25416,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1432: + case 1446: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:9746 +//line mysql_sql.y:9839 { locale := "" fstr := "bigint" @@ -25015,44 +25434,44 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1433: + case 1447: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:9760 +//line mysql_sql.y:9853 { yyLOCAL = yyDollar[2].columnTypeUnion() } yyVAL.union = yyLOCAL - case 1434: + case 1448: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.TypeOption -//line mysql_sql.y:9764 +//line mysql_sql.y:9857 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1435: + case 1449: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.TypeOption -//line mysql_sql.y:9768 +//line mysql_sql.y:9861 { yyLOCAL = &tree.TypeOption{ Type: yyDollar[2].columnTypeUnion(), } } yyVAL.union = yyLOCAL - case 1436: + case 1450: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.IncrementByOption -//line mysql_sql.y:9774 +//line mysql_sql.y:9867 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1437: + case 1451: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IncrementByOption -//line mysql_sql.y:9778 +//line mysql_sql.y:9871 { yyLOCAL = &tree.IncrementByOption{ Minus: false, @@ -25060,10 +25479,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1438: + case 1452: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.IncrementByOption -//line mysql_sql.y:9785 +//line mysql_sql.y:9878 { yyLOCAL = &tree.IncrementByOption{ Minus: false, @@ -25071,10 +25490,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1439: + case 1453: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.IncrementByOption -//line mysql_sql.y:9792 +//line mysql_sql.y:9885 { yyLOCAL = &tree.IncrementByOption{ Minus: true, @@ -25082,10 +25501,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1440: + case 1454: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IncrementByOption -//line mysql_sql.y:9799 +//line mysql_sql.y:9892 { yyLOCAL = &tree.IncrementByOption{ Minus: true, @@ -25093,42 +25512,42 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1441: + case 1455: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9806 +//line mysql_sql.y:9899 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1442: + case 1456: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9810 +//line mysql_sql.y:9903 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1443: + case 1457: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9814 +//line mysql_sql.y:9907 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1444: + case 1458: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.MinValueOption -//line mysql_sql.y:9818 +//line mysql_sql.y:9911 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1445: + case 1459: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.MinValueOption -//line mysql_sql.y:9822 +//line mysql_sql.y:9915 { yyLOCAL = &tree.MinValueOption{ Minus: false, @@ -25136,10 +25555,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1446: + case 1460: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.MinValueOption -//line mysql_sql.y:9829 +//line mysql_sql.y:9922 { yyLOCAL = &tree.MinValueOption{ Minus: true, @@ -25147,18 +25566,18 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1447: + case 1461: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.MaxValueOption -//line mysql_sql.y:9836 +//line mysql_sql.y:9929 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1448: + case 1462: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.MaxValueOption -//line mysql_sql.y:9840 +//line mysql_sql.y:9933 { yyLOCAL = &tree.MaxValueOption{ Minus: false, @@ -25166,10 +25585,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1449: + case 1463: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.MaxValueOption -//line mysql_sql.y:9847 +//line mysql_sql.y:9940 { yyLOCAL = &tree.MaxValueOption{ Minus: true, @@ -25177,46 +25596,46 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1450: + case 1464: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.CycleOption -//line mysql_sql.y:9854 +//line mysql_sql.y:9947 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1451: + case 1465: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.CycleOption -//line mysql_sql.y:9858 +//line mysql_sql.y:9951 { yyLOCAL = &tree.CycleOption{ Cycle: false, } } yyVAL.union = yyLOCAL - case 1452: + case 1466: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CycleOption -//line mysql_sql.y:9864 +//line mysql_sql.y:9957 { yyLOCAL = &tree.CycleOption{ Cycle: true, } } yyVAL.union = yyLOCAL - case 1453: + case 1467: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.StartWithOption -//line mysql_sql.y:9870 +//line mysql_sql.y:9963 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1454: + case 1468: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.StartWithOption -//line mysql_sql.y:9874 +//line mysql_sql.y:9967 { yyLOCAL = &tree.StartWithOption{ Minus: false, @@ -25224,10 +25643,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1455: + case 1469: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.StartWithOption -//line mysql_sql.y:9881 +//line mysql_sql.y:9974 { yyLOCAL = &tree.StartWithOption{ Minus: false, @@ -25235,10 +25654,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1456: + case 1470: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.StartWithOption -//line mysql_sql.y:9888 +//line mysql_sql.y:9981 { yyLOCAL = &tree.StartWithOption{ Minus: true, @@ -25246,10 +25665,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1457: + case 1471: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.StartWithOption -//line mysql_sql.y:9895 +//line mysql_sql.y:9988 { yyLOCAL = &tree.StartWithOption{ Minus: true, @@ -25257,58 +25676,58 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1458: + case 1472: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9902 +//line mysql_sql.y:9995 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1459: + case 1473: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9906 +//line mysql_sql.y:9999 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1460: + case 1474: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9911 +//line mysql_sql.y:10004 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1461: + case 1475: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9915 +//line mysql_sql.y:10008 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1462: + case 1476: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:9919 +//line mysql_sql.y:10012 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1463: + case 1477: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.PartitionOption -//line mysql_sql.y:9924 +//line mysql_sql.y:10017 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1464: + case 1478: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.PartitionOption -//line mysql_sql.y:9928 +//line mysql_sql.y:10021 { yyDollar[3].partitionByUnion().Num = uint64(yyDollar[4].int64ValUnion()) var PartBy = yyDollar[3].partitionByUnion() @@ -25321,18 +25740,18 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1465: + case 1479: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.ClusterByOption -//line mysql_sql.y:9941 +//line mysql_sql.y:10034 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1466: + case 1480: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.ClusterByOption -//line mysql_sql.y:9945 +//line mysql_sql.y:10038 { var ColumnList = []*tree.UnresolvedName{yyDollar[3].unresolvedNameUnion()} yyLOCAL = tree.NewClusterByOption( @@ -25341,10 +25760,10 @@ yydefault: } yyVAL.union = yyLOCAL - case 1467: + case 1481: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.ClusterByOption -//line mysql_sql.y:9953 +//line mysql_sql.y:10046 { var ColumnList = yyDollar[4].unresolveNamesUnion() yyLOCAL = tree.NewClusterByOption( @@ -25352,18 +25771,18 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1468: + case 1482: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.PartitionBy -//line mysql_sql.y:9961 +//line mysql_sql.y:10054 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1469: + case 1483: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.PartitionBy -//line mysql_sql.y:9965 +//line mysql_sql.y:10058 { var IsSubPartition = true var PType = yyDollar[3].partitionByUnion().PType @@ -25377,42 +25796,42 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1470: + case 1484: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*tree.Partition -//line mysql_sql.y:9979 +//line mysql_sql.y:10072 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1471: + case 1485: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.Partition -//line mysql_sql.y:9983 +//line mysql_sql.y:10076 { yyLOCAL = yyDollar[2].partitionsUnion() } yyVAL.union = yyLOCAL - case 1472: + case 1486: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.Partition -//line mysql_sql.y:9989 +//line mysql_sql.y:10082 { yyLOCAL = []*tree.Partition{yyDollar[1].partitionUnion()} } yyVAL.union = yyLOCAL - case 1473: + case 1487: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.Partition -//line mysql_sql.y:9993 +//line mysql_sql.y:10086 { yyLOCAL = append(yyDollar[1].partitionsUnion(), yyDollar[3].partitionUnion()) } yyVAL.union = yyLOCAL - case 1474: + case 1488: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.Partition -//line mysql_sql.y:9999 +//line mysql_sql.y:10092 { var Name = tree.Identifier(yyDollar[2].cstrUnion().Compare()) var Values = yyDollar[3].valuesUnion() @@ -25426,10 +25845,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1475: + case 1489: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.Partition -//line mysql_sql.y:10012 +//line mysql_sql.y:10105 { var Name = tree.Identifier(yyDollar[2].cstrUnion().Compare()) var Values = yyDollar[3].valuesUnion() @@ -25443,42 +25862,42 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1476: + case 1490: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*tree.SubPartition -//line mysql_sql.y:10026 +//line mysql_sql.y:10119 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1477: + case 1491: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.SubPartition -//line mysql_sql.y:10030 +//line mysql_sql.y:10123 { yyLOCAL = yyDollar[2].subPartitionsUnion() } yyVAL.union = yyLOCAL - case 1478: + case 1492: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.SubPartition -//line mysql_sql.y:10036 +//line mysql_sql.y:10129 { yyLOCAL = []*tree.SubPartition{yyDollar[1].subPartitionUnion()} } yyVAL.union = yyLOCAL - case 1479: + case 1493: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.SubPartition -//line mysql_sql.y:10040 +//line mysql_sql.y:10133 { yyLOCAL = append(yyDollar[1].subPartitionsUnion(), yyDollar[3].subPartitionUnion()) } yyVAL.union = yyLOCAL - case 1480: + case 1494: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.SubPartition -//line mysql_sql.y:10046 +//line mysql_sql.y:10139 { var Name = tree.Identifier(yyDollar[2].cstrUnion().Compare()) var Options []tree.TableOption @@ -25488,10 +25907,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1481: + case 1495: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.SubPartition -//line mysql_sql.y:10055 +//line mysql_sql.y:10148 { var Name = tree.Identifier(yyDollar[2].cstrUnion().Compare()) var Options = yyDollar[3].tableOptionsUnion() @@ -25501,53 +25920,53 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1482: + case 1496: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []tree.TableOption -//line mysql_sql.y:10066 +//line mysql_sql.y:10159 { yyLOCAL = []tree.TableOption{yyDollar[1].tableOptionUnion()} } yyVAL.union = yyLOCAL - case 1483: + case 1497: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []tree.TableOption -//line mysql_sql.y:10070 +//line mysql_sql.y:10163 { yyLOCAL = append(yyDollar[1].tableOptionsUnion(), yyDollar[2].tableOptionUnion()) } yyVAL.union = yyLOCAL - case 1484: + case 1498: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.Values -//line mysql_sql.y:10075 +//line mysql_sql.y:10168 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1485: + case 1499: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Values -//line mysql_sql.y:10079 +//line mysql_sql.y:10172 { expr := tree.NewMaxValue() var valueList = tree.Exprs{expr} yyLOCAL = tree.NewValuesLessThan(valueList) } yyVAL.union = yyLOCAL - case 1486: + case 1500: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Values -//line mysql_sql.y:10085 +//line mysql_sql.y:10178 { var valueList = yyDollar[5].exprsUnion() yyLOCAL = tree.NewValuesLessThan(valueList) } yyVAL.union = yyLOCAL - case 1487: + case 1501: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Values -//line mysql_sql.y:10090 +//line mysql_sql.y:10183 { var valueList = yyDollar[4].exprsUnion() yyLOCAL = tree.NewValuesIn( @@ -25555,18 +25974,18 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1488: + case 1502: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:10098 +//line mysql_sql.y:10191 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 1489: + case 1503: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:10102 +//line mysql_sql.y:10195 { res := yyDollar[2].item.(int64) if res == 0 { @@ -25576,18 +25995,18 @@ yydefault: yyLOCAL = res } yyVAL.union = yyLOCAL - case 1490: + case 1504: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:10112 +//line mysql_sql.y:10205 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 1491: + case 1505: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:10116 +//line mysql_sql.y:10209 { res := yyDollar[2].item.(int64) if res == 0 { @@ -25597,10 +26016,10 @@ yydefault: yyLOCAL = res } yyVAL.union = yyLOCAL - case 1492: + case 1506: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.PartitionBy -//line mysql_sql.y:10127 +//line mysql_sql.y:10220 { rangeTyp := tree.NewRangeType() rangeTyp.Expr = yyDollar[3].exprUnion() @@ -25609,10 +26028,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1493: + case 1507: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.PartitionBy -//line mysql_sql.y:10135 +//line mysql_sql.y:10228 { rangeTyp := tree.NewRangeType() rangeTyp.ColumnList = yyDollar[4].unresolveNamesUnion() @@ -25621,10 +26040,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1494: + case 1508: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.PartitionBy -//line mysql_sql.y:10143 +//line mysql_sql.y:10236 { listTyp := tree.NewListType() listTyp.Expr = yyDollar[3].exprUnion() @@ -25633,10 +26052,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1495: + case 1509: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.PartitionBy -//line mysql_sql.y:10151 +//line mysql_sql.y:10244 { listTyp := tree.NewListType() listTyp.ColumnList = yyDollar[4].unresolveNamesUnion() @@ -25645,10 +26064,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1497: + case 1511: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.PartitionBy -//line mysql_sql.y:10162 +//line mysql_sql.y:10255 { keyTyp := tree.NewKeyType() keyTyp.Linear = yyDollar[1].boolValUnion() @@ -25658,10 +26077,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1498: + case 1512: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.PartitionBy -//line mysql_sql.y:10171 +//line mysql_sql.y:10264 { keyTyp := tree.NewKeyType() keyTyp.Linear = yyDollar[1].boolValUnion() @@ -25672,10 +26091,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1499: + case 1513: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.PartitionBy -//line mysql_sql.y:10181 +//line mysql_sql.y:10274 { Linear := yyDollar[1].boolValUnion() Expr := yyDollar[4].exprUnion() @@ -25685,58 +26104,58 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1500: + case 1514: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:10191 +//line mysql_sql.y:10284 { yyLOCAL = 2 } yyVAL.union = yyLOCAL - case 1501: + case 1515: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:10195 +//line mysql_sql.y:10288 { yyLOCAL = yyDollar[3].item.(int64) } yyVAL.union = yyLOCAL - case 1502: + case 1516: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:10200 +//line mysql_sql.y:10293 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1503: + case 1517: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:10204 +//line mysql_sql.y:10297 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1504: + case 1518: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.ConnectorOption -//line mysql_sql.y:10210 +//line mysql_sql.y:10303 { yyLOCAL = []*tree.ConnectorOption{yyDollar[1].connectorOptionUnion()} } yyVAL.union = yyLOCAL - case 1505: + case 1519: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.ConnectorOption -//line mysql_sql.y:10214 +//line mysql_sql.y:10307 { yyLOCAL = append(yyDollar[1].connectorOptionsUnion(), yyDollar[3].connectorOptionUnion()) } yyVAL.union = yyLOCAL - case 1506: + case 1520: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.ConnectorOption -//line mysql_sql.y:10220 +//line mysql_sql.y:10313 { var Key = tree.Identifier(yyDollar[1].cstrUnion().Compare()) var Val = yyDollar[3].exprUnion() @@ -25746,10 +26165,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1507: + case 1521: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.ConnectorOption -//line mysql_sql.y:10229 +//line mysql_sql.y:10322 { var Key = tree.Identifier(yyDollar[1].str) var Val = yyDollar[3].exprUnion() @@ -25759,42 +26178,42 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1508: + case 1522: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []tree.TableOption -//line mysql_sql.y:10239 +//line mysql_sql.y:10332 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1509: + case 1523: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL []tree.TableOption -//line mysql_sql.y:10243 +//line mysql_sql.y:10336 { yyLOCAL = yyDollar[3].tableOptionsUnion() } yyVAL.union = yyLOCAL - case 1510: + case 1524: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []tree.TableOption -//line mysql_sql.y:10249 +//line mysql_sql.y:10342 { yyLOCAL = []tree.TableOption{yyDollar[1].tableOptionUnion()} } yyVAL.union = yyLOCAL - case 1511: + case 1525: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []tree.TableOption -//line mysql_sql.y:10253 +//line mysql_sql.y:10346 { yyLOCAL = append(yyDollar[1].tableOptionsUnion(), yyDollar[3].tableOptionUnion()) } yyVAL.union = yyLOCAL - case 1512: + case 1526: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10259 +//line mysql_sql.y:10352 { var Key = tree.Identifier(yyDollar[1].cstrUnion().Compare()) var Val = yyDollar[3].exprUnion() @@ -25804,10 +26223,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1513: + case 1527: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10268 +//line mysql_sql.y:10361 { var Key = tree.Identifier(yyDollar[1].str) var Val = yyDollar[3].exprUnion() @@ -25817,436 +26236,508 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1514: + case 1528: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.IcebergTableParam -//line mysql_sql.y:10279 +//line mysql_sql.y:10372 { yyLOCAL = tree.NewIcebergTableParam(yyDollar[4].icebergOptionsUnion()) } yyVAL.union = yyLOCAL - case 1515: + case 1529: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.IcebergOptions -//line mysql_sql.y:10284 +//line mysql_sql.y:10377 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1516: + case 1530: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.IcebergOptions -//line mysql_sql.y:10288 +//line mysql_sql.y:10381 { yyLOCAL = yyDollar[3].icebergOptionsUnion() } yyVAL.union = yyLOCAL - case 1517: + case 1531: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.IcebergOptions -//line mysql_sql.y:10294 +//line mysql_sql.y:10387 { yyLOCAL = tree.IcebergOptions{yyDollar[1].icebergOptionUnion()} } yyVAL.union = yyLOCAL - case 1518: + case 1532: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.IcebergOptions -//line mysql_sql.y:10298 +//line mysql_sql.y:10391 { yyLOCAL = append(yyDollar[1].icebergOptionsUnion(), yyDollar[3].icebergOptionUnion()) } yyVAL.union = yyLOCAL - case 1519: + case 1533: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IcebergOption -//line mysql_sql.y:10304 +//line mysql_sql.y:10397 { yyLOCAL = tree.NewIcebergOption(tree.Identifier(yyDollar[1].str), yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1520: + case 1534: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:10310 +//line mysql_sql.y:10403 { yyVAL.str = yyDollar[1].cstrUnion().Compare() } - case 1521: + case 1535: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:10314 +//line mysql_sql.y:10407 { yyVAL.str = yyDollar[1].str } - case 1522: + case 1536: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:10320 +//line mysql_sql.y:10413 { yyVAL.str = yyDollar[1].cstrUnion().Compare() } - case 1523: + case 1537: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:10324 +//line mysql_sql.y:10417 { yyVAL.str = yyDollar[1].str } - case 1524: + case 1538: + yyDollar = yyS[yypt-4 : yypt+1] + var yyLOCAL *tree.MongoDBTableParam +//line mysql_sql.y:10423 + { + yyLOCAL = tree.NewMongoDBTableParam(yyDollar[4].mongodbOptionsUnion()) + } + yyVAL.union = yyLOCAL + case 1539: + yyDollar = yyS[yypt-0 : yypt+1] + var yyLOCAL tree.MongoDBOptions +//line mysql_sql.y:10428 + { + yyLOCAL = nil + } + yyVAL.union = yyLOCAL + case 1540: + yyDollar = yyS[yypt-4 : yypt+1] + var yyLOCAL tree.MongoDBOptions +//line mysql_sql.y:10432 + { + yyLOCAL = yyDollar[3].mongodbOptionsUnion() + } + yyVAL.union = yyLOCAL + case 1541: + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL tree.MongoDBOptions +//line mysql_sql.y:10438 + { + yyLOCAL = tree.MongoDBOptions{yyDollar[1].mongodbOptionUnion()} + } + yyVAL.union = yyLOCAL + case 1542: + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL tree.MongoDBOptions +//line mysql_sql.y:10442 + { + yyLOCAL = append(yyDollar[1].mongodbOptionsUnion(), yyDollar[3].mongodbOptionUnion()) + } + yyVAL.union = yyLOCAL + case 1543: + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL *tree.MongoDBOption +//line mysql_sql.y:10448 + { + yyLOCAL = tree.NewMongoDBOption(tree.Identifier(yyDollar[1].str), yyDollar[3].str) + } + yyVAL.union = yyLOCAL + case 1544: + yyDollar = yyS[yypt-1 : yypt+1] +//line mysql_sql.y:10454 + { + yyVAL.str = yyDollar[1].cstrUnion().Compare() + } + case 1545: + yyDollar = yyS[yypt-1 : yypt+1] +//line mysql_sql.y:10458 + { + yyVAL.str = yyDollar[1].str + } + case 1546: + yyDollar = yyS[yypt-1 : yypt+1] +//line mysql_sql.y:10464 + { + yyVAL.str = yyDollar[1].cstrUnion().Compare() + } + case 1547: + yyDollar = yyS[yypt-1 : yypt+1] +//line mysql_sql.y:10468 + { + yyVAL.str = yyDollar[1].str + } + case 1548: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []tree.TableOption -//line mysql_sql.y:10329 +//line mysql_sql.y:10473 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1525: + case 1549: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []tree.TableOption -//line mysql_sql.y:10333 +//line mysql_sql.y:10477 { yyLOCAL = yyDollar[1].tableOptionsUnion() } yyVAL.union = yyLOCAL - case 1526: + case 1550: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []tree.TableOption -//line mysql_sql.y:10339 +//line mysql_sql.y:10483 { yyLOCAL = []tree.TableOption{yyDollar[1].tableOptionUnion()} } yyVAL.union = yyLOCAL - case 1527: + case 1551: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []tree.TableOption -//line mysql_sql.y:10343 +//line mysql_sql.y:10487 { yyLOCAL = append(yyDollar[1].tableOptionsUnion(), yyDollar[3].tableOptionUnion()) } yyVAL.union = yyLOCAL - case 1528: + case 1552: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []tree.TableOption -//line mysql_sql.y:10347 +//line mysql_sql.y:10491 { yyLOCAL = append(yyDollar[1].tableOptionsUnion(), yyDollar[2].tableOptionUnion()) } yyVAL.union = yyLOCAL - case 1529: + case 1553: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10353 +//line mysql_sql.y:10497 { yyLOCAL = tree.NewTableOptionAUTOEXTEND_SIZE(uint64(yyDollar[3].item.(int64))) } yyVAL.union = yyLOCAL - case 1530: + case 1554: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10357 +//line mysql_sql.y:10501 { yyLOCAL = tree.NewTableOptionAutoIncrement(uint64(yyDollar[3].item.(int64))) } yyVAL.union = yyLOCAL - case 1531: + case 1555: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10361 +//line mysql_sql.y:10505 { yyLOCAL = tree.NewTableOptionAvgRowLength(uint64(yyDollar[3].item.(int64))) } yyVAL.union = yyLOCAL - case 1532: + case 1556: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10365 +//line mysql_sql.y:10509 { yyLOCAL = tree.NewTableOptionCharset(yyDollar[4].str) } yyVAL.union = yyLOCAL - case 1533: + case 1557: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10369 +//line mysql_sql.y:10513 { yyLOCAL = tree.NewTableOptionCollate(yyDollar[4].str) } yyVAL.union = yyLOCAL - case 1534: + case 1558: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10373 +//line mysql_sql.y:10517 { yyLOCAL = tree.NewTableOptionChecksum(uint64(yyDollar[3].item.(int64))) } yyVAL.union = yyLOCAL - case 1535: + case 1559: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10377 +//line mysql_sql.y:10521 { str := util.DealCommentString(yyDollar[3].str) yyLOCAL = tree.NewTableOptionComment(str) } yyVAL.union = yyLOCAL - case 1536: + case 1560: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10382 +//line mysql_sql.y:10526 { yyLOCAL = tree.NewTableOptionCompression(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1537: + case 1561: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10386 +//line mysql_sql.y:10530 { yyLOCAL = tree.NewTableOptionConnection(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1538: + case 1562: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10390 +//line mysql_sql.y:10534 { yyLOCAL = tree.NewTableOptionDataDirectory(yyDollar[4].str) } yyVAL.union = yyLOCAL - case 1539: + case 1563: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10394 +//line mysql_sql.y:10538 { yyLOCAL = tree.NewTableOptionIndexDirectory(yyDollar[4].str) } yyVAL.union = yyLOCAL - case 1540: + case 1564: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10398 +//line mysql_sql.y:10542 { yyLOCAL = tree.NewTableOptionDelayKeyWrite(uint64(yyDollar[3].item.(int64))) } yyVAL.union = yyLOCAL - case 1541: + case 1565: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10402 +//line mysql_sql.y:10546 { yyLOCAL = tree.NewTableOptionEncryption(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1542: + case 1566: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10406 +//line mysql_sql.y:10550 { yyLOCAL = tree.NewTableOptionEngine(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1543: + case 1567: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10410 +//line mysql_sql.y:10554 { yyLOCAL = tree.NewTableOptionEngineAttr(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1544: + case 1568: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10414 +//line mysql_sql.y:10558 { yyLOCAL = tree.NewTableOptionInsertMethod(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1545: + case 1569: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10418 +//line mysql_sql.y:10562 { yyLOCAL = tree.NewTableOptionKeyBlockSize(uint64(yyDollar[3].item.(int64))) } yyVAL.union = yyLOCAL - case 1546: + case 1570: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10422 +//line mysql_sql.y:10566 { yyLOCAL = tree.NewTableOptionMaxRows(uint64(yyDollar[3].item.(int64))) } yyVAL.union = yyLOCAL - case 1547: + case 1571: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10426 +//line mysql_sql.y:10570 { yyLOCAL = tree.NewTableOptionMinRows(uint64(yyDollar[3].item.(int64))) } yyVAL.union = yyLOCAL - case 1548: + case 1572: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10430 +//line mysql_sql.y:10574 { t := tree.NewTableOptionPackKeys() t.Value = yyDollar[3].item.(int64) yyLOCAL = t } yyVAL.union = yyLOCAL - case 1549: + case 1573: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10436 +//line mysql_sql.y:10580 { t := tree.NewTableOptionPackKeys() t.Default = true yyLOCAL = t } yyVAL.union = yyLOCAL - case 1550: + case 1574: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10442 +//line mysql_sql.y:10586 { yyLOCAL = tree.NewTableOptionPassword(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1551: + case 1575: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10446 +//line mysql_sql.y:10590 { yyLOCAL = tree.NewTableOptionRowFormat(yyDollar[3].rowFormatTypeUnion()) } yyVAL.union = yyLOCAL - case 1552: + case 1576: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10450 +//line mysql_sql.y:10594 { yyLOCAL = tree.NewTTableOptionStartTrans(true) } yyVAL.union = yyLOCAL - case 1553: + case 1577: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10454 +//line mysql_sql.y:10598 { yyLOCAL = tree.NewTTableOptionSecondaryEngineAttr(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1554: + case 1578: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10458 +//line mysql_sql.y:10602 { t := tree.NewTableOptionStatsAutoRecalc() t.Value = uint64(yyDollar[3].item.(int64)) yyLOCAL = t } yyVAL.union = yyLOCAL - case 1555: + case 1579: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10464 +//line mysql_sql.y:10608 { t := tree.NewTableOptionStatsAutoRecalc() t.Default = true yyLOCAL = t } yyVAL.union = yyLOCAL - case 1556: + case 1580: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10470 +//line mysql_sql.y:10614 { t := tree.NewTableOptionStatsPersistent() t.Value = uint64(yyDollar[3].item.(int64)) yyLOCAL = t } yyVAL.union = yyLOCAL - case 1557: + case 1581: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10476 +//line mysql_sql.y:10620 { t := tree.NewTableOptionStatsPersistent() t.Default = true yyLOCAL = t } yyVAL.union = yyLOCAL - case 1558: + case 1582: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10482 +//line mysql_sql.y:10626 { t := tree.NewTableOptionStatsSamplePages() t.Value = uint64(yyDollar[3].item.(int64)) yyLOCAL = t } yyVAL.union = yyLOCAL - case 1559: + case 1583: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10488 +//line mysql_sql.y:10632 { t := tree.NewTableOptionStatsSamplePages() t.Default = true yyLOCAL = t } yyVAL.union = yyLOCAL - case 1560: + case 1584: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10494 +//line mysql_sql.y:10638 { yyLOCAL = tree.NewTableOptionTablespace(yyDollar[3].cstrUnion().Compare(), "") } yyVAL.union = yyLOCAL - case 1561: + case 1585: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10498 +//line mysql_sql.y:10642 { yyLOCAL = tree.NewTableOptionTablespace("", yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1562: + case 1586: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10502 +//line mysql_sql.y:10646 { yyLOCAL = tree.NewTableOptionUnion(yyDollar[4].tableNamesUnion()) } yyVAL.union = yyLOCAL - case 1563: + case 1587: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.TableOption -//line mysql_sql.y:10506 +//line mysql_sql.y:10650 { var Preperties = yyDollar[3].propertiesUnion() yyLOCAL = tree.NewTableOptionProperties(Preperties) } yyVAL.union = yyLOCAL - case 1564: + case 1588: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []tree.Property -//line mysql_sql.y:10513 +//line mysql_sql.y:10657 { yyLOCAL = []tree.Property{yyDollar[1].propertyUnion()} } yyVAL.union = yyLOCAL - case 1565: + case 1589: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []tree.Property -//line mysql_sql.y:10517 +//line mysql_sql.y:10661 { yyLOCAL = append(yyDollar[1].propertiesUnion(), yyDollar[3].propertyUnion()) } yyVAL.union = yyLOCAL - case 1566: + case 1590: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Property -//line mysql_sql.y:10523 +//line mysql_sql.y:10667 { var Key = yyDollar[1].str var Value = yyDollar[3].str @@ -26256,86 +26747,86 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1567: + case 1591: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:10534 +//line mysql_sql.y:10678 { yyVAL.str = " " + yyDollar[1].str + " " + yyDollar[2].str } - case 1568: + case 1592: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:10538 +//line mysql_sql.y:10682 { yyVAL.str = " " + yyDollar[1].str + " " + yyDollar[2].str } - case 1569: + case 1593: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.RowFormatType -//line mysql_sql.y:10544 +//line mysql_sql.y:10688 { yyLOCAL = tree.ROW_FORMAT_DEFAULT } yyVAL.union = yyLOCAL - case 1570: + case 1594: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.RowFormatType -//line mysql_sql.y:10548 +//line mysql_sql.y:10692 { yyLOCAL = tree.ROW_FORMAT_DYNAMIC } yyVAL.union = yyLOCAL - case 1571: + case 1595: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.RowFormatType -//line mysql_sql.y:10552 +//line mysql_sql.y:10696 { yyLOCAL = tree.ROW_FORMAT_FIXED } yyVAL.union = yyLOCAL - case 1572: + case 1596: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.RowFormatType -//line mysql_sql.y:10556 +//line mysql_sql.y:10700 { yyLOCAL = tree.ROW_FORMAT_COMPRESSED } yyVAL.union = yyLOCAL - case 1573: + case 1597: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.RowFormatType -//line mysql_sql.y:10560 +//line mysql_sql.y:10704 { yyLOCAL = tree.ROW_FORMAT_REDUNDANT } yyVAL.union = yyLOCAL - case 1574: + case 1598: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.RowFormatType -//line mysql_sql.y:10564 +//line mysql_sql.y:10708 { yyLOCAL = tree.ROW_FORMAT_COMPACT } yyVAL.union = yyLOCAL - case 1579: + case 1603: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableNames -//line mysql_sql.y:10578 +//line mysql_sql.y:10722 { yyLOCAL = tree.TableNames{yyDollar[1].tableNameUnion()} } yyVAL.union = yyLOCAL - case 1580: + case 1604: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableNames -//line mysql_sql.y:10582 +//line mysql_sql.y:10726 { yyLOCAL = append(yyDollar[1].tableNamesUnion(), yyDollar[3].tableNameUnion()) } yyVAL.union = yyLOCAL - case 1581: + case 1605: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.TableName -//line mysql_sql.y:10591 +//line mysql_sql.y:10735 { tblName := yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) prefix := tree.ObjectNamePrefix{ExplicitSchema: false} @@ -26343,10 +26834,10 @@ yydefault: yyLOCAL.IcebergRef = yyDollar[3].icebergRefSpecUnion() } yyVAL.union = yyLOCAL - case 1582: + case 1606: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.TableName -//line mysql_sql.y:10598 +//line mysql_sql.y:10742 { dbName := yylex.(*Lexer).GetDbOrTblName(yyDollar[1].cstrUnion().Origin()) tblName := yylex.(*Lexer).GetDbOrTblName(yyDollar[3].cstrUnion().Origin()) @@ -26355,85 +26846,85 @@ yydefault: yyLOCAL.IcebergRef = yyDollar[5].icebergRefSpecUnion() } yyVAL.union = yyLOCAL - case 1583: + case 1607: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.IcebergRefSpec -//line mysql_sql.y:10607 +//line mysql_sql.y:10751 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1584: + case 1608: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IcebergRefSpec -//line mysql_sql.y:10611 +//line mysql_sql.y:10755 { raw := fmt.Sprintf("%v", yyDollar[3].item) yyLOCAL = tree.NewIcebergSnapshotRef(tree.NewNumVal(raw, raw, false, tree.P_int64)) } yyVAL.union = yyLOCAL - case 1585: + case 1609: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IcebergRefSpec -//line mysql_sql.y:10616 +//line mysql_sql.y:10760 { yyLOCAL = tree.NewIcebergSnapshotRef(tree.NewNumVal(yyDollar[3].str, yyDollar[3].str, false, tree.P_char)) } yyVAL.union = yyLOCAL - case 1586: + case 1610: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.IcebergRefSpec -//line mysql_sql.y:10620 +//line mysql_sql.y:10764 { yyLOCAL = tree.NewIcebergTimestampRef(tree.NewNumVal(yyDollar[6].str, yyDollar[6].str, false, tree.P_char)) } yyVAL.union = yyLOCAL - case 1587: + case 1611: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.IcebergRefSpec -//line mysql_sql.y:10624 +//line mysql_sql.y:10768 { yyLOCAL = tree.NewIcebergTimestampRef(tree.NewNumVal(yyDollar[5].str, yyDollar[5].str, false, tree.P_char)) } yyVAL.union = yyLOCAL - case 1588: + case 1612: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.IcebergRefSpec -//line mysql_sql.y:10628 +//line mysql_sql.y:10772 { yyLOCAL = tree.NewIcebergNamedRef(tree.Identifier(yyDollar[3].str)) } yyVAL.union = yyLOCAL - case 1589: + case 1613: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:10634 +//line mysql_sql.y:10778 { yyVAL.str = yyDollar[1].str } - case 1590: + case 1614: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:10638 +//line mysql_sql.y:10782 { yyVAL.str = yyDollar[1].str } - case 1591: + case 1615: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:10642 +//line mysql_sql.y:10786 { yyVAL.str = yyDollar[1].str } - case 1592: + case 1616: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.AtTimeStamp -//line mysql_sql.y:10647 +//line mysql_sql.y:10791 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1593: + case 1617: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.AtTimeStamp -//line mysql_sql.y:10651 +//line mysql_sql.y:10795 { yyLOCAL = &tree.AtTimeStamp{ Type: tree.ATTIMESTAMPTIME, @@ -26441,10 +26932,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1594: + case 1618: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.AtTimeStamp -//line mysql_sql.y:10658 +//line mysql_sql.y:10802 { var str = yyDollar[4].cstrUnion().Compare() yyLOCAL = &tree.AtTimeStamp{ @@ -26454,10 +26945,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1595: + case 1619: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.AtTimeStamp -//line mysql_sql.y:10667 +//line mysql_sql.y:10811 { yyLOCAL = &tree.AtTimeStamp{ Type: tree.ATTIMESTAMPSNAPSHOT, @@ -26466,10 +26957,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1596: + case 1620: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.AtTimeStamp -//line mysql_sql.y:10675 +//line mysql_sql.y:10819 { yyLOCAL = &tree.AtTimeStamp{ Type: tree.ATMOTIMESTAMP, @@ -26477,10 +26968,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1597: + case 1621: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.AtTimeStamp -//line mysql_sql.y:10682 +//line mysql_sql.y:10826 { yyLOCAL = &tree.AtTimeStamp{ Type: tree.ASOFTIMESTAMP, @@ -26488,74 +26979,74 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1598: + case 1622: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.TableDefs -//line mysql_sql.y:10690 +//line mysql_sql.y:10834 { yyLOCAL = tree.TableDefs(nil) } yyVAL.union = yyLOCAL - case 1600: + case 1624: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableDefs -//line mysql_sql.y:10697 +//line mysql_sql.y:10841 { yyLOCAL = tree.TableDefs{yyDollar[1].tableDefUnion()} } yyVAL.union = yyLOCAL - case 1601: + case 1625: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.TableDefs -//line mysql_sql.y:10701 +//line mysql_sql.y:10845 { yyLOCAL = append(yyDollar[1].tableDefsUnion(), yyDollar[3].tableDefUnion()) } yyVAL.union = yyLOCAL - case 1602: + case 1626: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10707 +//line mysql_sql.y:10851 { yyLOCAL = tree.TableDef(yyDollar[1].columnTableDefUnion()) } yyVAL.union = yyLOCAL - case 1603: + case 1627: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10711 +//line mysql_sql.y:10855 { yyLOCAL = yyDollar[1].tableDefUnion() } yyVAL.union = yyLOCAL - case 1604: + case 1628: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10715 +//line mysql_sql.y:10859 { yyLOCAL = yyDollar[1].tableDefUnion() } yyVAL.union = yyLOCAL - case 1605: + case 1629: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10721 +//line mysql_sql.y:10865 { yyLOCAL = yyDollar[1].tableDefUnion() } yyVAL.union = yyLOCAL - case 1606: + case 1630: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10725 +//line mysql_sql.y:10869 { yyLOCAL = yyDollar[1].tableDefUnion() } yyVAL.union = yyLOCAL - case 1607: + case 1631: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10731 +//line mysql_sql.y:10875 { var KeyParts = yyDollar[5].keyPartsUnion() var Name = yyDollar[3].str @@ -26569,10 +27060,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1608: + case 1632: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10744 +//line mysql_sql.y:10888 { var KeyParts = yyDollar[5].keyPartsUnion() var Name = yyDollar[3].str @@ -26586,10 +27077,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1609: + case 1633: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10757 +//line mysql_sql.y:10901 { keyTyp := tree.INDEX_TYPE_INVALID if yyDollar[3].strsUnion()[1] != "" { @@ -26635,10 +27126,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1610: + case 1634: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10802 +//line mysql_sql.y:10946 { keyTyp := tree.INDEX_TYPE_INVALID if yyDollar[3].strsUnion()[1] != "" { @@ -26683,10 +27174,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1611: + case 1635: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10848 +//line mysql_sql.y:10992 { if yyDollar[1].str != "" { switch v := yyDollar[2].tableDefUnion().(type) { @@ -26701,18 +27192,18 @@ yydefault: yyLOCAL = yyDollar[2].tableDefUnion() } yyVAL.union = yyLOCAL - case 1612: + case 1636: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10862 +//line mysql_sql.y:11006 { yyLOCAL = yyDollar[1].tableDefUnion() } yyVAL.union = yyLOCAL - case 1613: + case 1637: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10868 +//line mysql_sql.y:11012 { var KeyParts = yyDollar[5].keyPartsUnion() var Name = yyDollar[3].strsUnion()[0] @@ -26726,10 +27217,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1614: + case 1638: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10881 +//line mysql_sql.y:11025 { var KeyParts = yyDollar[5].keyPartsUnion() var Name = yyDollar[3].strsUnion()[0] @@ -26743,10 +27234,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1615: + case 1639: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10894 +//line mysql_sql.y:11038 { var KeyParts = yyDollar[5].keyPartsUnion() var Name = yyDollar[3].strsUnion()[0] @@ -26760,10 +27251,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1616: + case 1640: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10907 +//line mysql_sql.y:11051 { var KeyParts = yyDollar[5].keyPartsUnion() var Name = yyDollar[3].strsUnion()[0] @@ -26777,10 +27268,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1617: + case 1641: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10920 +//line mysql_sql.y:11064 { var IfNotExists = yyDollar[3].ifNotExistsUnion() var KeyParts = yyDollar[6].keyPartsUnion() @@ -26796,10 +27287,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1618: + case 1642: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.TableDef -//line mysql_sql.y:10935 +//line mysql_sql.y:11079 { var Expr = yyDollar[3].exprUnion() var Enforced = yyDollar[5].boolValUnion() @@ -26809,327 +27300,343 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1619: + case 1643: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:10945 +//line mysql_sql.y:11089 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1621: + case 1645: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:10951 +//line mysql_sql.y:11095 { yyVAL.str = "" } - case 1622: + case 1646: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:10955 +//line mysql_sql.y:11099 { yyVAL.str = yyDollar[1].str } - case 1625: + case 1649: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:10965 +//line mysql_sql.y:11109 { yyLOCAL = make([]string, 2) yyLOCAL[0] = yyDollar[1].str yyLOCAL[1] = "" } yyVAL.union = yyLOCAL - case 1626: + case 1650: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:10971 +//line mysql_sql.y:11115 { yyLOCAL = make([]string, 2) yyLOCAL[0] = yyDollar[1].str yyLOCAL[1] = yyDollar[3].str } yyVAL.union = yyLOCAL - case 1627: + case 1651: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:10977 +//line mysql_sql.y:11121 { yyLOCAL = make([]string, 2) yyLOCAL[0] = yyDollar[1].cstrUnion().Compare() yyLOCAL[1] = yyDollar[3].str } yyVAL.union = yyLOCAL - case 1641: + case 1665: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:11001 +//line mysql_sql.y:11145 { yyVAL.str = "" } - case 1642: + case 1666: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:11005 +//line mysql_sql.y:11149 { yyVAL.str = yyDollar[1].cstrUnion().Compare() } - case 1643: + case 1667: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.ColumnTableDef -//line mysql_sql.y:11011 +//line mysql_sql.y:11155 { yyLOCAL = tree.NewColumnTableDef(yyDollar[1].unresolvedNameUnion(), yyDollar[2].columnTypeUnion(), yyDollar[3].columnAttributesUnion()) } yyVAL.union = yyLOCAL - case 1644: + case 1668: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.UnresolvedName -//line mysql_sql.y:11017 +//line mysql_sql.y:11161 { yyLOCAL = tree.NewUnresolvedName(yyDollar[1].cstrUnion()) } yyVAL.union = yyLOCAL - case 1645: + case 1669: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.UnresolvedName -//line mysql_sql.y:11021 +//line mysql_sql.y:11165 { tblNameCStr := yylex.(*Lexer).GetDbOrTblNameCStr(yyDollar[1].cstrUnion().Origin()) yyLOCAL = tree.NewUnresolvedName(tblNameCStr, yyDollar[3].cstrUnion()) } yyVAL.union = yyLOCAL - case 1646: + case 1670: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.UnresolvedName -//line mysql_sql.y:11026 +//line mysql_sql.y:11170 { dbNameCStr := yylex.(*Lexer).GetDbOrTblNameCStr(yyDollar[1].cstrUnion().Origin()) tblNameCStr := yylex.(*Lexer).GetDbOrTblNameCStr(yyDollar[3].cstrUnion().Origin()) yyLOCAL = tree.NewUnresolvedName(dbNameCStr, tblNameCStr, yyDollar[5].cstrUnion()) } yyVAL.union = yyLOCAL - case 1647: + case 1671: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:11034 +//line mysql_sql.y:11178 { yyLOCAL = tree.NewCStr(yyDollar[1].str, 1) } yyVAL.union = yyLOCAL - case 1648: + case 1672: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:11038 +//line mysql_sql.y:11182 { yyLOCAL = tree.NewCStr(yyDollar[1].str, 1) } yyVAL.union = yyLOCAL - case 1649: + case 1673: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:11042 +//line mysql_sql.y:11186 { yyLOCAL = tree.NewCStr(yyDollar[1].str, 1) } yyVAL.union = yyLOCAL - case 1650: + case 1674: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:11046 +//line mysql_sql.y:11190 { yyLOCAL = tree.NewCStr(yyDollar[1].str, 1) } yyVAL.union = yyLOCAL - case 1651: + case 1675: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.CStr -//line mysql_sql.y:11052 +//line mysql_sql.y:11196 { yyLOCAL = yylex.(*Lexer).GetDbOrTblNameCStr(yyDollar[1].cstrUnion().Origin()) } yyVAL.union = yyLOCAL - case 1652: + case 1676: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.UnresolvedName -//line mysql_sql.y:11058 +//line mysql_sql.y:11202 { yyLOCAL = tree.NewUnresolvedName(yyDollar[1].cstrUnion()) } yyVAL.union = yyLOCAL - case 1653: + case 1677: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.UnresolvedName -//line mysql_sql.y:11062 +//line mysql_sql.y:11206 { tblNameCStr := yylex.(*Lexer).GetDbOrTblNameCStr(yyDollar[1].cstrUnion().Origin()) yyLOCAL = tree.NewUnresolvedName(tblNameCStr, yyDollar[3].cstrUnion()) } yyVAL.union = yyLOCAL - case 1654: + case 1678: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.UnresolvedName -//line mysql_sql.y:11067 +//line mysql_sql.y:11211 { dbNameCStr := yylex.(*Lexer).GetDbOrTblNameCStr(yyDollar[1].cstrUnion().Origin()) tblNameCStr := yylex.(*Lexer).GetDbOrTblNameCStr(yyDollar[3].cstrUnion().Origin()) yyLOCAL = tree.NewUnresolvedName(dbNameCStr, tblNameCStr, yyDollar[5].cstrUnion()) } yyVAL.union = yyLOCAL - case 1655: + case 1679: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []tree.ColumnAttribute -//line mysql_sql.y:11074 +//line mysql_sql.y:11218 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1656: + case 1680: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []tree.ColumnAttribute -//line mysql_sql.y:11078 +//line mysql_sql.y:11222 { yyLOCAL = yyDollar[1].columnAttributesUnion() } yyVAL.union = yyLOCAL - case 1657: + case 1681: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []tree.ColumnAttribute -//line mysql_sql.y:11084 +//line mysql_sql.y:11228 { yyLOCAL = []tree.ColumnAttribute{yyDollar[1].columnAttributeUnion()} } yyVAL.union = yyLOCAL - case 1658: + case 1682: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []tree.ColumnAttribute -//line mysql_sql.y:11088 +//line mysql_sql.y:11232 { yyLOCAL = append(yyDollar[1].columnAttributesUnion(), yyDollar[2].columnAttributeUnion()) } yyVAL.union = yyLOCAL - case 1659: + case 1683: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11094 +//line mysql_sql.y:11238 { yyLOCAL = tree.NewAttributeNull(true) } yyVAL.union = yyLOCAL - case 1660: + case 1684: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11098 +//line mysql_sql.y:11242 { yyLOCAL = tree.NewAttributeNull(false) } yyVAL.union = yyLOCAL - case 1661: + case 1685: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11102 +//line mysql_sql.y:11246 { yyLOCAL = tree.NewAttributeDefault(yyDollar[2].exprUnion()) } yyVAL.union = yyLOCAL - case 1662: + case 1686: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11106 +//line mysql_sql.y:11250 { yyLOCAL = tree.NewAttributeAutoIncrement() } yyVAL.union = yyLOCAL - case 1663: + case 1687: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11110 +//line mysql_sql.y:11254 { yyLOCAL = yyDollar[1].columnAttributeUnion() } yyVAL.union = yyLOCAL - case 1664: + case 1688: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11114 +//line mysql_sql.y:11258 { str := util.DealCommentString(yyDollar[2].str) yyLOCAL = tree.NewAttributeComment(tree.NewNumVal(str, str, false, tree.P_char)) } yyVAL.union = yyLOCAL - case 1665: + case 1689: + yyDollar = yyS[yypt-2 : yypt+1] + var yyLOCAL tree.ColumnAttribute +//line mysql_sql.y:11263 + { + yyLOCAL = tree.NewAttributeMongoDBPath(yyDollar[2].str) + } + yyVAL.union = yyLOCAL + case 1690: + yyDollar = yyS[yypt-2 : yypt+1] + var yyLOCAL tree.ColumnAttribute +//line mysql_sql.y:11267 + { + yyLOCAL = tree.NewAttributeMongoDBConvert(yyDollar[2].str) + } + yyVAL.union = yyLOCAL + case 1691: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11119 +//line mysql_sql.y:11271 { yyLOCAL = tree.NewAttributeCollate(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 1666: + case 1692: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11123 +//line mysql_sql.y:11275 { yyLOCAL = tree.NewAttributeColumnFormat(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 1667: + case 1693: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11127 +//line mysql_sql.y:11279 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1668: + case 1694: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11131 +//line mysql_sql.y:11283 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1669: + case 1695: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11135 +//line mysql_sql.y:11287 { yyLOCAL = tree.NewAttributeStorage(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 1670: + case 1696: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11139 +//line mysql_sql.y:11291 { yyLOCAL = tree.NewAttributeAutoRandom(int(yyDollar[2].int64ValUnion())) } yyVAL.union = yyLOCAL - case 1671: + case 1697: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11143 +//line mysql_sql.y:11295 { yyLOCAL = yyDollar[1].attributeReferenceUnion() } yyVAL.union = yyLOCAL - case 1672: + case 1698: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11147 +//line mysql_sql.y:11299 { yyLOCAL = tree.NewAttributeCheckConstraint(yyDollar[4].exprUnion(), false, yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1673: + case 1699: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11151 +//line mysql_sql.y:11303 { yyLOCAL = tree.NewAttributeCheckConstraint(yyDollar[4].exprUnion(), yyDollar[6].boolValUnion(), yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1674: + case 1700: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11155 +//line mysql_sql.y:11307 { name := tree.NewUnresolvedColName(yyDollar[3].str) var es tree.Exprs = nil @@ -27144,10 +27651,10 @@ yydefault: yyLOCAL = tree.NewAttributeOnUpdate(expr) } yyVAL.union = yyLOCAL - case 1675: + case 1701: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11169 +//line mysql_sql.y:11321 { v, errStr := util.GetInt64(yyDollar[2].item) if errStr != "" { @@ -27161,138 +27668,138 @@ yydefault: yyLOCAL = tree.NewAttributeSRID(uint32(v)) } yyVAL.union = yyLOCAL - case 1676: + case 1702: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11182 +//line mysql_sql.y:11334 { yyLOCAL = tree.NewAttributeLowCardinality() } yyVAL.union = yyLOCAL - case 1677: + case 1703: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11186 +//line mysql_sql.y:11338 { yyLOCAL = tree.NewAttributeVisable(true) } yyVAL.union = yyLOCAL - case 1678: + case 1704: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11190 +//line mysql_sql.y:11342 { yyLOCAL = tree.NewAttributeVisable(false) } yyVAL.union = yyLOCAL - case 1679: + case 1705: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11194 +//line mysql_sql.y:11346 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1680: + case 1706: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11198 +//line mysql_sql.y:11350 { yyLOCAL = tree.NewAttributeHeader(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1681: + case 1707: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11202 +//line mysql_sql.y:11354 { yyLOCAL = tree.NewAttributeHeaders() } yyVAL.union = yyLOCAL - case 1682: + case 1708: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11206 +//line mysql_sql.y:11358 { yyLOCAL = tree.NewAttributeGeneratedAlways(yyDollar[5].exprUnion(), yyDollar[7].boolValUnion()) } yyVAL.union = yyLOCAL - case 1683: + case 1709: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:11210 +//line mysql_sql.y:11362 { yyLOCAL = tree.NewAttributeGeneratedAlways(yyDollar[3].exprUnion(), yyDollar[5].boolValUnion()) } yyVAL.union = yyLOCAL - case 1684: + case 1710: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:11215 +//line mysql_sql.y:11367 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1685: + case 1711: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:11219 +//line mysql_sql.y:11371 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1686: + case 1712: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:11223 +//line mysql_sql.y:11375 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1687: + case 1713: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:11229 +//line mysql_sql.y:11381 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1688: + case 1714: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:11233 +//line mysql_sql.y:11385 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1689: + case 1715: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:11238 +//line mysql_sql.y:11390 { yyVAL.str = "" } - case 1690: + case 1716: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:11242 +//line mysql_sql.y:11394 { yyVAL.str = yyDollar[1].str } - case 1691: + case 1717: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:11248 +//line mysql_sql.y:11400 { yyVAL.str = "" } - case 1692: + case 1718: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:11252 +//line mysql_sql.y:11404 { yyVAL.str = yyDollar[2].cstrUnion().Compare() } - case 1693: + case 1719: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.AttributeReference -//line mysql_sql.y:11258 +//line mysql_sql.y:11410 { var TableName = yyDollar[2].tableNameUnion() var KeyParts = yyDollar[3].keyPartsUnion() @@ -27308,10 +27815,10 @@ yydefault: ) } yyVAL.union = yyLOCAL - case 1694: + case 1720: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.ReferenceOnRecord -//line mysql_sql.y:11275 +//line mysql_sql.y:11427 { yyLOCAL = &tree.ReferenceOnRecord{ OnDelete: tree.REFERENCE_OPTION_INVALID, @@ -27319,10 +27826,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1695: + case 1721: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.ReferenceOnRecord -//line mysql_sql.y:11282 +//line mysql_sql.y:11434 { yyLOCAL = &tree.ReferenceOnRecord{ OnDelete: yyDollar[1].referenceOptionTypeUnion(), @@ -27330,10 +27837,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1696: + case 1722: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.ReferenceOnRecord -//line mysql_sql.y:11289 +//line mysql_sql.y:11441 { yyLOCAL = &tree.ReferenceOnRecord{ OnDelete: tree.REFERENCE_OPTION_INVALID, @@ -27341,10 +27848,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1697: + case 1723: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.ReferenceOnRecord -//line mysql_sql.y:11296 +//line mysql_sql.y:11448 { yyLOCAL = &tree.ReferenceOnRecord{ OnDelete: yyDollar[1].referenceOptionTypeUnion(), @@ -27352,10 +27859,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1698: + case 1724: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.ReferenceOnRecord -//line mysql_sql.y:11303 +//line mysql_sql.y:11455 { yyLOCAL = &tree.ReferenceOnRecord{ OnDelete: yyDollar[2].referenceOptionTypeUnion(), @@ -27363,202 +27870,202 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1699: + case 1725: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.ReferenceOptionType -//line mysql_sql.y:11312 +//line mysql_sql.y:11464 { yyLOCAL = yyDollar[3].referenceOptionTypeUnion() } yyVAL.union = yyLOCAL - case 1700: + case 1726: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.ReferenceOptionType -//line mysql_sql.y:11318 +//line mysql_sql.y:11470 { yyLOCAL = yyDollar[3].referenceOptionTypeUnion() } yyVAL.union = yyLOCAL - case 1701: + case 1727: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ReferenceOptionType -//line mysql_sql.y:11324 +//line mysql_sql.y:11476 { yyLOCAL = tree.REFERENCE_OPTION_RESTRICT } yyVAL.union = yyLOCAL - case 1702: + case 1728: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ReferenceOptionType -//line mysql_sql.y:11328 +//line mysql_sql.y:11480 { yyLOCAL = tree.REFERENCE_OPTION_CASCADE } yyVAL.union = yyLOCAL - case 1703: + case 1729: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.ReferenceOptionType -//line mysql_sql.y:11332 +//line mysql_sql.y:11484 { yyLOCAL = tree.REFERENCE_OPTION_SET_NULL } yyVAL.union = yyLOCAL - case 1704: + case 1730: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.ReferenceOptionType -//line mysql_sql.y:11336 +//line mysql_sql.y:11488 { yyLOCAL = tree.REFERENCE_OPTION_NO_ACTION } yyVAL.union = yyLOCAL - case 1705: + case 1731: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.ReferenceOptionType -//line mysql_sql.y:11340 +//line mysql_sql.y:11492 { yyLOCAL = tree.REFERENCE_OPTION_SET_DEFAULT } yyVAL.union = yyLOCAL - case 1706: + case 1732: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.MatchType -//line mysql_sql.y:11345 +//line mysql_sql.y:11497 { yyLOCAL = tree.MATCH_INVALID } yyVAL.union = yyLOCAL - case 1708: + case 1734: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.MatchType -//line mysql_sql.y:11352 +//line mysql_sql.y:11504 { yyLOCAL = tree.MATCH_FULL } yyVAL.union = yyLOCAL - case 1709: + case 1735: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.MatchType -//line mysql_sql.y:11356 +//line mysql_sql.y:11508 { yyLOCAL = tree.MATCH_PARTIAL } yyVAL.union = yyLOCAL - case 1710: + case 1736: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.MatchType -//line mysql_sql.y:11360 +//line mysql_sql.y:11512 { yyLOCAL = tree.MATCH_SIMPLE } yyVAL.union = yyLOCAL - case 1711: + case 1737: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.FullTextSearchType -//line mysql_sql.y:11365 +//line mysql_sql.y:11517 { yyLOCAL = tree.FULLTEXT_DEFAULT } yyVAL.union = yyLOCAL - case 1712: + case 1738: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.FullTextSearchType -//line mysql_sql.y:11369 +//line mysql_sql.y:11521 { yyLOCAL = tree.FULLTEXT_NL } yyVAL.union = yyLOCAL - case 1713: + case 1739: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.FullTextSearchType -//line mysql_sql.y:11373 +//line mysql_sql.y:11525 { yyLOCAL = tree.FULLTEXT_NL_QUERY_EXPANSION } yyVAL.union = yyLOCAL - case 1714: + case 1740: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.FullTextSearchType -//line mysql_sql.y:11377 +//line mysql_sql.y:11529 { yyLOCAL = tree.FULLTEXT_BOOLEAN } yyVAL.union = yyLOCAL - case 1715: + case 1741: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.FullTextSearchType -//line mysql_sql.y:11381 +//line mysql_sql.y:11533 { yyLOCAL = tree.FULLTEXT_QUERY_EXPANSION } yyVAL.union = yyLOCAL - case 1716: + case 1742: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*tree.KeyPart -//line mysql_sql.y:11386 +//line mysql_sql.y:11538 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1717: + case 1743: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*tree.KeyPart -//line mysql_sql.y:11390 +//line mysql_sql.y:11542 { yyLOCAL = yyDollar[2].keyPartsUnion() } yyVAL.union = yyLOCAL - case 1718: + case 1744: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:11395 +//line mysql_sql.y:11547 { yyLOCAL = -1 } yyVAL.union = yyLOCAL - case 1719: + case 1745: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int64 -//line mysql_sql.y:11399 +//line mysql_sql.y:11551 { yyLOCAL = yyDollar[2].item.(int64) } yyVAL.union = yyLOCAL - case 1726: + case 1752: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.Subquery -//line mysql_sql.y:11415 +//line mysql_sql.y:11567 { yyLOCAL = &tree.Subquery{Select: yyDollar[1].selectStatementUnion(), Exists: false} } yyVAL.union = yyLOCAL - case 1727: + case 1753: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11421 +//line mysql_sql.y:11573 { yyLOCAL = tree.NewBinaryExpr(tree.BIT_AND, yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 1728: + case 1754: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11425 +//line mysql_sql.y:11577 { yyLOCAL = tree.NewBinaryExpr(tree.BIT_OR, yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 1729: + case 1755: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11429 +//line mysql_sql.y:11581 { yyLOCAL = tree.NewBinaryExpr(tree.BIT_XOR, yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 1730: + case 1756: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11433 +//line mysql_sql.y:11585 { name := tree.NewUnresolvedColName("concat") yyLOCAL = &tree.FuncExpr{ @@ -27568,82 +28075,82 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1731: + case 1757: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11442 +//line mysql_sql.y:11594 { yyLOCAL = tree.NewBinaryExpr(tree.PLUS, yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 1732: + case 1758: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11446 +//line mysql_sql.y:11598 { yyLOCAL = tree.NewBinaryExpr(tree.MINUS, yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 1733: + case 1759: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11450 +//line mysql_sql.y:11602 { yyLOCAL = tree.NewBinaryExpr(tree.MULTI, yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 1734: + case 1760: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11454 +//line mysql_sql.y:11606 { yyLOCAL = tree.NewBinaryExpr(tree.DIV, yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 1735: + case 1761: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11458 +//line mysql_sql.y:11610 { yyLOCAL = tree.NewBinaryExpr(tree.INTEGER_DIV, yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 1736: + case 1762: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11462 +//line mysql_sql.y:11614 { yyLOCAL = tree.NewBinaryExpr(tree.MOD, yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 1737: + case 1763: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11466 +//line mysql_sql.y:11618 { yyLOCAL = tree.NewBinaryExpr(tree.MOD, yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 1738: + case 1764: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11470 +//line mysql_sql.y:11622 { yyLOCAL = tree.NewBinaryExpr(tree.LEFT_SHIFT, yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 1739: + case 1765: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11474 +//line mysql_sql.y:11626 { yyLOCAL = tree.NewBinaryExpr(tree.RIGHT_SHIFT, yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 1740: + case 1766: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11478 +//line mysql_sql.y:11630 { name := tree.NewUnresolvedColName("json_extract") yyLOCAL = &tree.FuncExpr{ @@ -27653,10 +28160,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1741: + case 1767: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11487 +//line mysql_sql.y:11639 { extractName := tree.NewUnresolvedColName("json_extract") inner := &tree.FuncExpr{ @@ -27672,90 +28179,90 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1742: + case 1768: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11502 +//line mysql_sql.y:11654 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1743: + case 1769: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11508 +//line mysql_sql.y:11660 { yyLOCAL = yyDollar[1].unresolvedNameUnion() } yyVAL.union = yyLOCAL - case 1744: + case 1770: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11512 +//line mysql_sql.y:11664 { yyLOCAL = yyDollar[1].varExprUnion() } yyVAL.union = yyLOCAL - case 1745: + case 1771: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11516 +//line mysql_sql.y:11668 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1746: + case 1772: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11520 +//line mysql_sql.y:11672 { yyLOCAL = tree.NewParentExpr(yyDollar[2].exprUnion()) } yyVAL.union = yyLOCAL - case 1747: + case 1773: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11524 +//line mysql_sql.y:11676 { yyLOCAL = tree.NewTuple(append(yyDollar[2].exprsUnion(), yyDollar[4].exprUnion())) } yyVAL.union = yyLOCAL - case 1748: + case 1774: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11528 +//line mysql_sql.y:11680 { yyLOCAL = tree.NewUnaryExpr(tree.UNARY_PLUS, yyDollar[2].exprUnion()) } yyVAL.union = yyLOCAL - case 1749: + case 1775: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11532 +//line mysql_sql.y:11684 { yyLOCAL = tree.NewUnaryExpr(tree.UNARY_MINUS, yyDollar[2].exprUnion()) } yyVAL.union = yyLOCAL - case 1750: + case 1776: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11536 +//line mysql_sql.y:11688 { yyLOCAL = tree.NewUnaryExpr(tree.UNARY_TILDE, yyDollar[2].exprUnion()) } yyVAL.union = yyLOCAL - case 1751: + case 1777: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11540 +//line mysql_sql.y:11692 { yyLOCAL = tree.NewUnaryExpr(tree.UNARY_MARK, yyDollar[2].exprUnion()) } yyVAL.union = yyLOCAL - case 1752: + case 1778: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11544 +//line mysql_sql.y:11696 { hint := strings.ToLower(yyDollar[2].cstrUnion().Compare()) switch hint { @@ -27798,35 +28305,35 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1753: + case 1779: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11586 +//line mysql_sql.y:11738 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1754: + case 1780: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11590 +//line mysql_sql.y:11742 { yyLOCAL = yyDollar[1].subqueryUnion() } yyVAL.union = yyLOCAL - case 1755: + case 1781: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11594 +//line mysql_sql.y:11746 { yyDollar[2].subqueryUnion().Exists = true yyLOCAL = yyDollar[2].subqueryUnion() } yyVAL.union = yyLOCAL - case 1756: + case 1782: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11599 +//line mysql_sql.y:11751 { yyLOCAL = &tree.CaseExpr{ Expr: yyDollar[2].exprUnion(), @@ -27835,50 +28342,50 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1757: + case 1783: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11607 +//line mysql_sql.y:11759 { yyLOCAL = tree.NewCastExpr(yyDollar[3].exprUnion(), yyDollar[5].columnTypeUnion()) } yyVAL.union = yyLOCAL - case 1758: + case 1784: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11611 +//line mysql_sql.y:11763 { yyLOCAL = tree.NewSerialExtractExpr(yyDollar[3].exprUnion(), yyDollar[5].exprUnion(), yyDollar[7].columnTypeUnion()) } yyVAL.union = yyLOCAL - case 1759: + case 1785: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11615 +//line mysql_sql.y:11767 { yyLOCAL = tree.NewBitCastExpr(yyDollar[3].exprUnion(), yyDollar[5].columnTypeUnion()) } yyVAL.union = yyLOCAL - case 1760: + case 1786: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11619 +//line mysql_sql.y:11771 { yyLOCAL = tree.NewCastExpr(yyDollar[1].exprUnion(), yyDollar[3].columnTypeUnion()) } yyVAL.union = yyLOCAL - case 1761: + case 1787: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11623 +//line mysql_sql.y:11775 { yyLOCAL = tree.NewCastExpr(yyDollar[3].exprUnion(), yyDollar[5].columnTypeUnion()) } yyVAL.union = yyLOCAL - case 1762: + case 1788: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11627 +//line mysql_sql.y:11779 { name := tree.NewUnresolvedColName(yyDollar[1].str) es := tree.NewNumVal(yyDollar[5].str, yyDollar[5].str, false, tree.P_char) @@ -27889,66 +28396,66 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1763: + case 1789: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11637 +//line mysql_sql.y:11789 { yyLOCAL = yyDollar[1].funcExprUnion() } yyVAL.union = yyLOCAL - case 1764: + case 1790: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11641 +//line mysql_sql.y:11793 { yyLOCAL = yyDollar[1].funcExprUnion() } yyVAL.union = yyLOCAL - case 1765: + case 1791: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11645 +//line mysql_sql.y:11797 { yyLOCAL = yyDollar[1].funcExprUnion() } yyVAL.union = yyLOCAL - case 1766: + case 1792: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11649 +//line mysql_sql.y:11801 { yyLOCAL = yyDollar[1].funcExprUnion() } yyVAL.union = yyLOCAL - case 1767: + case 1793: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11653 +//line mysql_sql.y:11805 { yyLOCAL = yyDollar[1].funcExprUnion() } yyVAL.union = yyLOCAL - case 1768: + case 1794: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11657 +//line mysql_sql.y:11809 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1769: + case 1795: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11661 +//line mysql_sql.y:11813 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1770: + case 1796: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11665 +//line mysql_sql.y:11817 { val, err := tree.NewFullTextMatchFuncExpression(yyDollar[3].keyPartsUnion(), yyDollar[7].str, yyDollar[8].fullTextSearchTypeUnion()) if err != nil { @@ -27958,16 +28465,16 @@ yydefault: yyLOCAL = val } yyVAL.union = yyLOCAL - case 1771: + case 1797: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:11676 +//line mysql_sql.y:11828 { yyVAL.str = yyDollar[1].str } - case 1772: + case 1798: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:11682 +//line mysql_sql.y:11834 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -27977,10 +28484,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1773: + case 1799: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:11691 +//line mysql_sql.y:11843 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -27990,10 +28497,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1774: + case 1800: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:11700 +//line mysql_sql.y:11852 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28003,10 +28510,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1775: + case 1801: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:11709 +//line mysql_sql.y:11861 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28016,10 +28523,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1776: + case 1802: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:11718 +//line mysql_sql.y:11870 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28030,10 +28537,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1777: + case 1803: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:11728 +//line mysql_sql.y:11880 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28043,10 +28550,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1778: + case 1804: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:11737 +//line mysql_sql.y:11889 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28057,10 +28564,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1779: + case 1805: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:11747 +//line mysql_sql.y:11899 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28071,10 +28578,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1780: + case 1806: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:11757 +//line mysql_sql.y:11909 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28085,10 +28592,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1781: + case 1807: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:11767 +//line mysql_sql.y:11919 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28099,10 +28606,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1782: + case 1808: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:11777 +//line mysql_sql.y:11929 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28113,10 +28620,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1783: + case 1809: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:11787 +//line mysql_sql.y:11939 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28127,10 +28634,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1784: + case 1810: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:11797 +//line mysql_sql.y:11949 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28141,10 +28648,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1785: + case 1811: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:11807 +//line mysql_sql.y:11959 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28155,10 +28662,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1786: + case 1812: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:11817 +//line mysql_sql.y:11969 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28169,10 +28676,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1787: + case 1813: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11829 +//line mysql_sql.y:11981 { v := int(yyDollar[5].item.(int64)) val, err := tree.NewSampleRowsFuncExpression(v, true, nil, "block") @@ -28183,10 +28690,10 @@ yydefault: yyLOCAL = val } yyVAL.union = yyLOCAL - case 1788: + case 1814: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11839 +//line mysql_sql.y:11991 { v := int(yyDollar[5].item.(int64)) val, err := tree.NewSampleRowsFuncExpression(v, true, nil, yyDollar[8].str) @@ -28197,10 +28704,10 @@ yydefault: yyLOCAL = val } yyVAL.union = yyLOCAL - case 1789: + case 1815: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11849 +//line mysql_sql.y:12001 { val, err := tree.NewSamplePercentFuncExpression1(yyDollar[5].item.(int64), true, nil) if err != nil { @@ -28210,10 +28717,10 @@ yydefault: yyLOCAL = val } yyVAL.union = yyLOCAL - case 1790: + case 1816: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11858 +//line mysql_sql.y:12010 { val, err := tree.NewSamplePercentFuncExpression2(yyDollar[5].item.(float64), true, nil) if err != nil { @@ -28223,10 +28730,10 @@ yydefault: yyLOCAL = val } yyVAL.union = yyLOCAL - case 1791: + case 1817: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11868 +//line mysql_sql.y:12020 { v := int(yyDollar[5].item.(int64)) val, err := tree.NewSampleRowsFuncExpression(v, false, yyDollar[3].exprsUnion(), "block") @@ -28237,10 +28744,10 @@ yydefault: yyLOCAL = val } yyVAL.union = yyLOCAL - case 1792: + case 1818: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11878 +//line mysql_sql.y:12030 { v := int(yyDollar[5].item.(int64)) val, err := tree.NewSampleRowsFuncExpression(v, false, yyDollar[3].exprsUnion(), yyDollar[8].str) @@ -28251,10 +28758,10 @@ yydefault: yyLOCAL = val } yyVAL.union = yyLOCAL - case 1793: + case 1819: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11888 +//line mysql_sql.y:12040 { val, err := tree.NewSamplePercentFuncExpression1(yyDollar[5].item.(int64), false, yyDollar[3].exprsUnion()) if err != nil { @@ -28264,10 +28771,10 @@ yydefault: yyLOCAL = val } yyVAL.union = yyLOCAL - case 1794: + case 1820: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11897 +//line mysql_sql.y:12049 { val, err := tree.NewSamplePercentFuncExpression2(yyDollar[5].item.(float64), false, yyDollar[3].exprsUnion()) if err != nil { @@ -28277,58 +28784,58 @@ yydefault: yyLOCAL = val } yyVAL.union = yyLOCAL - case 1795: + case 1821: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11907 +//line mysql_sql.y:12059 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1796: + case 1822: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11911 +//line mysql_sql.y:12063 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1797: + case 1823: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11916 +//line mysql_sql.y:12068 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1798: + case 1824: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:11920 +//line mysql_sql.y:12072 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1799: + case 1825: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*tree.When -//line mysql_sql.y:11926 +//line mysql_sql.y:12078 { yyLOCAL = []*tree.When{yyDollar[1].whenClauseUnion()} } yyVAL.union = yyLOCAL - case 1800: + case 1826: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []*tree.When -//line mysql_sql.y:11930 +//line mysql_sql.y:12082 { yyLOCAL = append(yyDollar[1].whenClauseListUnion(), yyDollar[2].whenClauseUnion()) } yyVAL.union = yyLOCAL - case 1801: + case 1827: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.When -//line mysql_sql.y:11936 +//line mysql_sql.y:12088 { yyLOCAL = &tree.When{ Cond: yyDollar[2].exprUnion(), @@ -28336,9 +28843,9 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1802: + case 1828: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:11945 +//line mysql_sql.y:12097 { t := yyVAL.columnTypeUnion() str := strings.ToLower(t.InternalType.FamilyString) @@ -28351,10 +28858,10 @@ yydefault: } } } - case 1803: + case 1829: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:11957 +//line mysql_sql.y:12109 { name := yyDollar[1].str if yyDollar[2].str != "" { @@ -28372,10 +28879,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1804: + case 1830: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:11974 +//line mysql_sql.y:12126 { locale := "" yyLOCAL = &tree.T{ @@ -28390,10 +28897,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1806: + case 1832: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:11991 +//line mysql_sql.y:12143 { locale := "" yyLOCAL = &tree.T{ @@ -28408,10 +28915,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1807: + case 1833: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:12005 +//line mysql_sql.y:12157 { locale := "" oid := uint32(defines.MYSQL_TYPE_STRING) @@ -28431,10 +28938,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1808: + case 1834: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:12024 +//line mysql_sql.y:12176 { locale := "" yyLOCAL = &tree.T{ @@ -28447,10 +28954,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1809: + case 1835: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:12036 +//line mysql_sql.y:12188 { locale := "" yyLOCAL = &tree.T{ @@ -28465,10 +28972,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1810: + case 1836: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:12050 +//line mysql_sql.y:12202 { locale := "" yyLOCAL = &tree.T{ @@ -28484,10 +28991,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1811: + case 1837: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:12065 +//line mysql_sql.y:12217 { locale := "" yyLOCAL = &tree.T{ @@ -28503,10 +29010,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1812: + case 1838: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:12080 +//line mysql_sql.y:12232 { name := yyDollar[1].str if yyDollar[2].str != "" { @@ -28524,10 +29031,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1813: + case 1839: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:12097 +//line mysql_sql.y:12249 { locale := "" yyLOCAL = &tree.T{ @@ -28542,96 +29049,96 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1814: + case 1840: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:12113 +//line mysql_sql.y:12265 { yyVAL.str = "" } - case 1818: + case 1844: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FrameBound -//line mysql_sql.y:12122 +//line mysql_sql.y:12274 { yyLOCAL = &tree.FrameBound{Type: tree.Following, UnBounded: true} } yyVAL.union = yyLOCAL - case 1819: + case 1845: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FrameBound -//line mysql_sql.y:12126 +//line mysql_sql.y:12278 { yyLOCAL = &tree.FrameBound{Type: tree.Following, Expr: yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1820: + case 1846: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FrameBound -//line mysql_sql.y:12130 +//line mysql_sql.y:12282 { yyLOCAL = &tree.FrameBound{Type: tree.Following, Expr: yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1821: + case 1847: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FrameBound -//line mysql_sql.y:12136 +//line mysql_sql.y:12288 { yyLOCAL = &tree.FrameBound{Type: tree.CurrentRow} } yyVAL.union = yyLOCAL - case 1822: + case 1848: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FrameBound -//line mysql_sql.y:12140 +//line mysql_sql.y:12292 { yyLOCAL = &tree.FrameBound{Type: tree.Preceding, UnBounded: true} } yyVAL.union = yyLOCAL - case 1823: + case 1849: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FrameBound -//line mysql_sql.y:12144 +//line mysql_sql.y:12296 { yyLOCAL = &tree.FrameBound{Type: tree.Preceding, Expr: yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1824: + case 1850: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FrameBound -//line mysql_sql.y:12148 +//line mysql_sql.y:12300 { yyLOCAL = &tree.FrameBound{Type: tree.Preceding, Expr: yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1825: + case 1851: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.FrameType -//line mysql_sql.y:12154 +//line mysql_sql.y:12306 { yyLOCAL = tree.Rows } yyVAL.union = yyLOCAL - case 1826: + case 1852: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.FrameType -//line mysql_sql.y:12158 +//line mysql_sql.y:12310 { yyLOCAL = tree.Range } yyVAL.union = yyLOCAL - case 1827: + case 1853: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.FrameType -//line mysql_sql.y:12162 +//line mysql_sql.y:12314 { yyLOCAL = tree.Groups } yyVAL.union = yyLOCAL - case 1828: + case 1854: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FrameClause -//line mysql_sql.y:12168 +//line mysql_sql.y:12320 { yyLOCAL = &tree.FrameClause{ Type: yyDollar[1].frameTypeUnion(), @@ -28640,10 +29147,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1829: + case 1855: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.FrameClause -//line mysql_sql.y:12176 +//line mysql_sql.y:12328 { yyLOCAL = &tree.FrameClause{ Type: yyDollar[1].frameTypeUnion(), @@ -28653,82 +29160,82 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1830: + case 1856: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.FrameClause -//line mysql_sql.y:12186 +//line mysql_sql.y:12338 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1831: + case 1857: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.FrameClause -//line mysql_sql.y:12190 +//line mysql_sql.y:12342 { yyLOCAL = yyDollar[1].frameClauseUnion() } yyVAL.union = yyLOCAL - case 1832: + case 1858: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Exprs -//line mysql_sql.y:12196 +//line mysql_sql.y:12348 { yyLOCAL = yyDollar[3].exprsUnion() } yyVAL.union = yyLOCAL - case 1833: + case 1859: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.Exprs -//line mysql_sql.y:12201 +//line mysql_sql.y:12353 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1834: + case 1860: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Exprs -//line mysql_sql.y:12205 +//line mysql_sql.y:12357 { yyLOCAL = yyDollar[1].exprsUnion() } yyVAL.union = yyLOCAL - case 1835: + case 1861: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:12210 +//line mysql_sql.y:12362 { yyVAL.str = "," } - case 1836: + case 1862: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:12214 +//line mysql_sql.y:12366 { yyVAL.str = yyDollar[2].str } - case 1837: + case 1863: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:12219 +//line mysql_sql.y:12371 { yyVAL.str = "1,vector_l2_ops,random,false" } - case 1838: + case 1864: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:12223 +//line mysql_sql.y:12375 { yyVAL.str = yyDollar[2].str } - case 1839: + case 1865: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *tree.WindowSpec -//line mysql_sql.y:12228 +//line mysql_sql.y:12380 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1841: + case 1867: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.WindowSpec -//line mysql_sql.y:12235 +//line mysql_sql.y:12387 { hasFrame := true var f *tree.FrameClause @@ -28753,10 +29260,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1842: + case 1868: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12261 +//line mysql_sql.y:12413 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28769,10 +29276,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1843: + case 1869: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12273 +//line mysql_sql.y:12425 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28785,10 +29292,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1844: + case 1870: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12285 +//line mysql_sql.y:12437 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28800,10 +29307,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1845: + case 1871: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12296 +//line mysql_sql.y:12448 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28815,10 +29322,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1846: + case 1872: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12307 +//line mysql_sql.y:12459 { name := tree.NewUnresolvedColName(yyDollar[1].str) es := tree.NewNumVal("*", "*", false, tree.P_star) @@ -28830,10 +29337,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1847: + case 1873: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12318 +//line mysql_sql.y:12470 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28844,10 +29351,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1848: + case 1874: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12328 +//line mysql_sql.y:12480 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28858,10 +29365,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1849: + case 1875: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12338 +//line mysql_sql.y:12490 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28873,10 +29380,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1850: + case 1876: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12349 +//line mysql_sql.y:12501 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28888,10 +29395,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1851: + case 1877: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12360 +//line mysql_sql.y:12512 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28903,10 +29410,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1852: + case 1878: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12371 +//line mysql_sql.y:12523 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28918,10 +29425,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1853: + case 1879: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12382 +//line mysql_sql.y:12534 { name := tree.NewUnresolvedColName(yyDollar[1].str) es := tree.NewNumVal("*", "*", false, tree.P_star) @@ -28933,10 +29440,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1854: + case 1880: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12393 +//line mysql_sql.y:12545 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28948,10 +29455,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1855: + case 1881: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12404 +//line mysql_sql.y:12556 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28963,10 +29470,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1856: + case 1882: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12415 +//line mysql_sql.y:12567 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28978,10 +29485,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1857: + case 1883: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12426 +//line mysql_sql.y:12578 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -28993,10 +29500,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1858: + case 1884: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12437 +//line mysql_sql.y:12589 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29008,10 +29515,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1859: + case 1885: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12448 +//line mysql_sql.y:12600 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29023,10 +29530,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1860: + case 1886: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12459 +//line mysql_sql.y:12611 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29038,10 +29545,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1861: + case 1887: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12470 +//line mysql_sql.y:12622 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29053,10 +29560,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1862: + case 1888: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12481 +//line mysql_sql.y:12633 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29068,10 +29575,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1863: + case 1889: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12492 +//line mysql_sql.y:12644 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29083,10 +29590,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1864: + case 1890: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12503 +//line mysql_sql.y:12655 { name := tree.NewUnresolvedColName(yyDollar[1].str) var columnList tree.Exprs @@ -29104,10 +29611,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1865: + case 1891: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12520 +//line mysql_sql.y:12672 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29119,10 +29626,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1866: + case 1892: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12531 +//line mysql_sql.y:12683 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29134,10 +29641,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1870: + case 1896: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12549 +//line mysql_sql.y:12701 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29147,10 +29654,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1871: + case 1897: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12558 +//line mysql_sql.y:12710 { name := tree.NewUnresolvedColName(yyDollar[1].str) exprs := tree.Exprs{yyDollar[3].exprUnion()} @@ -29162,10 +29669,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1872: + case 1898: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12569 +//line mysql_sql.y:12721 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29175,10 +29682,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1873: + case 1899: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12578 +//line mysql_sql.y:12730 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29188,10 +29695,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1874: + case 1900: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12587 +//line mysql_sql.y:12739 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29201,10 +29708,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1875: + case 1901: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12596 +//line mysql_sql.y:12748 { name := tree.NewUnresolvedColName(yyDollar[1].str) str := strings.ToLower(yyDollar[3].str) @@ -29216,10 +29723,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1876: + case 1902: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12607 +//line mysql_sql.y:12759 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29229,10 +29736,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1877: + case 1903: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12616 +//line mysql_sql.y:12768 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29242,10 +29749,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1878: + case 1904: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12625 +//line mysql_sql.y:12777 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29256,10 +29763,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1879: + case 1905: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12635 +//line mysql_sql.y:12787 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29269,10 +29776,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1880: + case 1906: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12644 +//line mysql_sql.y:12796 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29282,10 +29789,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1881: + case 1907: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12653 +//line mysql_sql.y:12805 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29295,10 +29802,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1882: + case 1908: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12662 +//line mysql_sql.y:12814 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29308,10 +29815,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1883: + case 1909: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12671 +//line mysql_sql.y:12823 { name := tree.NewUnresolvedColName(yyDollar[1].str) arg0 := tree.NewNumVal(int64(0), "0", false, tree.P_int64) @@ -29324,10 +29831,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1884: + case 1910: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12683 +//line mysql_sql.y:12835 { name := tree.NewUnresolvedColName(yyDollar[1].str) arg0 := tree.NewNumVal(int64(1), "1", false, tree.P_int64) @@ -29339,10 +29846,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1885: + case 1911: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12694 +//line mysql_sql.y:12846 { name := tree.NewUnresolvedColName(yyDollar[1].str) arg0 := tree.NewNumVal(int64(2), "2", false, tree.P_int64) @@ -29356,10 +29863,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1886: + case 1912: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12707 +//line mysql_sql.y:12859 { name := tree.NewUnresolvedColName(yyDollar[1].str) arg0 := tree.NewNumVal(int64(3), "3", false, tree.P_int64) @@ -29372,10 +29879,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1887: + case 1913: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12719 +//line mysql_sql.y:12871 { column := tree.NewUnresolvedColName(yyDollar[3].str) name := tree.NewUnresolvedColName(yyDollar[1].str) @@ -29386,16 +29893,16 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1894: + case 1920: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:12741 +//line mysql_sql.y:12893 { yyVAL.str = yyDollar[1].str } - case 1927: + case 1953: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12783 +//line mysql_sql.y:12935 { name := tree.NewUnresolvedColName(yyDollar[1].str) var es tree.Exprs = nil @@ -29409,10 +29916,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1928: + case 1954: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12796 +//line mysql_sql.y:12948 { name := tree.NewUnresolvedColName(yyDollar[1].str) var es tree.Exprs = nil @@ -29426,10 +29933,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1929: + case 1955: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12809 +//line mysql_sql.y:12961 { name := tree.NewUnresolvedColName(yyDollar[1].str) str := strings.ToLower(yyDollar[3].str) @@ -29441,10 +29948,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1930: + case 1956: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12820 +//line mysql_sql.y:12972 { name := tree.NewUnresolvedColName(yyDollar[1].str) str := strings.ToLower(yyDollar[3].str) @@ -29456,10 +29963,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1931: + case 1957: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12831 +//line mysql_sql.y:12983 { name := tree.NewUnresolvedColName(yyDollar[1].str) str := strings.ToUpper(yyDollar[3].str) @@ -29471,10 +29978,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1932: + case 1958: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12843 +//line mysql_sql.y:12995 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29484,10 +29991,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1933: + case 1959: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12852 +//line mysql_sql.y:13004 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29496,10 +30003,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1934: + case 1960: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12860 +//line mysql_sql.y:13012 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29508,10 +30015,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1935: + case 1961: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12868 +//line mysql_sql.y:13020 { name := tree.NewUnresolvedColName(yyDollar[1].str) var es tree.Exprs = nil @@ -29525,10 +30032,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1936: + case 1962: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12881 +//line mysql_sql.y:13033 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29538,10 +30045,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1937: + case 1963: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12890 +//line mysql_sql.y:13042 { name := tree.NewUnresolvedColName(yyDollar[1].str) exprs := make([]tree.Expr, 1) @@ -29553,10 +30060,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1938: + case 1964: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12901 +//line mysql_sql.y:13053 { name := tree.NewUnresolvedColName(yyDollar[1].str) exprs := make([]tree.Expr, 1) @@ -29568,10 +30075,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1939: + case 1965: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12912 +//line mysql_sql.y:13064 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29581,10 +30088,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1940: + case 1966: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12921 +//line mysql_sql.y:13073 { cn := tree.NewNumVal(yyDollar[5].str, yyDollar[5].str, false, tree.P_char) es := yyDollar[3].exprsUnion() @@ -29597,10 +30104,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1941: + case 1967: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12933 +//line mysql_sql.y:13085 { val := tree.NewNumVal(yyDollar[2].str, yyDollar[2].str, false, tree.P_char) name := tree.NewUnresolvedColName(yyDollar[1].str) @@ -29611,10 +30118,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1942: + case 1968: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12943 +//line mysql_sql.y:13095 { val := tree.NewNumVal(yyDollar[2].str, yyDollar[2].str, false, tree.P_char) name := tree.NewUnresolvedColName(yyDollar[1].str) @@ -29625,10 +30132,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1943: + case 1969: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12953 +//line mysql_sql.y:13105 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29638,10 +30145,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1944: + case 1970: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12962 +//line mysql_sql.y:13114 { es := tree.Exprs{yyDollar[3].exprUnion()} es = append(es, yyDollar[5].exprUnion()) @@ -29653,10 +30160,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1945: + case 1971: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12973 +//line mysql_sql.y:13125 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29666,10 +30173,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1946: + case 1972: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12982 +//line mysql_sql.y:13134 { val := tree.NewNumVal(yyDollar[2].str, yyDollar[2].str, false, tree.P_char) name := tree.NewUnresolvedColName(yyDollar[1].str) @@ -29680,10 +30187,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1947: + case 1973: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:12992 +//line mysql_sql.y:13144 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29693,10 +30200,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1948: + case 1974: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:13001 +//line mysql_sql.y:13153 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29706,10 +30213,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1949: + case 1975: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.FuncExpr -//line mysql_sql.y:13010 +//line mysql_sql.y:13162 { name := tree.NewUnresolvedColName(yyDollar[1].str) yyLOCAL = &tree.FuncExpr{ @@ -29719,34 +30226,34 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1950: + case 1976: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13020 +//line mysql_sql.y:13172 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1951: + case 1977: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13024 +//line mysql_sql.y:13176 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1952: + case 1978: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13030 +//line mysql_sql.y:13182 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1953: + case 1979: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13034 +//line mysql_sql.y:13186 { ival, errStr := util.GetInt64(yyDollar[2].item) if errStr != "" { @@ -29757,20 +30264,20 @@ yydefault: yyLOCAL = tree.NewNumVal(ival, str, false, tree.P_int64) } yyVAL.union = yyLOCAL - case 1960: + case 1986: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:13053 +//line mysql_sql.y:13205 { } - case 1961: + case 1987: yyDollar = yyS[yypt-2 : yypt+1] -//line mysql_sql.y:13055 +//line mysql_sql.y:13207 { } - case 1995: + case 2021: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13096 +//line mysql_sql.y:13248 { name := tree.NewUnresolvedColName(yyDollar[1].str) str := strings.ToLower(yyDollar[3].str) @@ -29782,451 +30289,451 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1996: + case 2022: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.FuncType -//line mysql_sql.y:13108 +//line mysql_sql.y:13260 { yyLOCAL = tree.FUNC_TYPE_DEFAULT } yyVAL.union = yyLOCAL - case 1997: + case 2023: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.FuncType -//line mysql_sql.y:13112 +//line mysql_sql.y:13264 { yyLOCAL = tree.FUNC_TYPE_DISTINCT } yyVAL.union = yyLOCAL - case 1998: + case 2024: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.FuncType -//line mysql_sql.y:13116 +//line mysql_sql.y:13268 { yyLOCAL = tree.FUNC_TYPE_ALL } yyVAL.union = yyLOCAL - case 1999: + case 2025: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.Tuple -//line mysql_sql.y:13122 +//line mysql_sql.y:13274 { yyLOCAL = tree.NewTuple(yyDollar[2].exprsUnion()) } yyVAL.union = yyLOCAL - case 2000: + case 2026: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.Exprs -//line mysql_sql.y:13127 +//line mysql_sql.y:13279 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 2001: + case 2027: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Exprs -//line mysql_sql.y:13131 +//line mysql_sql.y:13283 { yyLOCAL = yyDollar[1].exprsUnion() } yyVAL.union = yyLOCAL - case 2002: + case 2028: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Exprs -//line mysql_sql.y:13137 +//line mysql_sql.y:13289 { yyLOCAL = tree.Exprs{yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 2003: + case 2029: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Exprs -//line mysql_sql.y:13141 +//line mysql_sql.y:13293 { yyLOCAL = append(yyDollar[1].exprsUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 2004: + case 2030: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Exprs -//line mysql_sql.y:13147 +//line mysql_sql.y:13299 { yyLOCAL = tree.Exprs{yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 2005: + case 2031: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Exprs -//line mysql_sql.y:13151 +//line mysql_sql.y:13303 { yyLOCAL = append(yyDollar[1].exprsUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 2006: + case 2032: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13158 +//line mysql_sql.y:13310 { yyLOCAL = tree.NewAndExpr(yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 2007: + case 2033: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13162 +//line mysql_sql.y:13314 { yyLOCAL = tree.NewOrExpr(yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 2008: + case 2034: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13166 +//line mysql_sql.y:13318 { yyLOCAL = tree.NewXorExpr(yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 2009: + case 2035: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13170 +//line mysql_sql.y:13322 { yyLOCAL = tree.NewNotExpr(yyDollar[2].exprUnion()) } yyVAL.union = yyLOCAL - case 2010: + case 2036: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13174 +//line mysql_sql.y:13326 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 2011: + case 2037: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13179 +//line mysql_sql.y:13331 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 2012: + case 2038: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13183 +//line mysql_sql.y:13335 { yyLOCAL = tree.NewMaxValue() } yyVAL.union = yyLOCAL - case 2013: + case 2039: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13189 +//line mysql_sql.y:13341 { yyLOCAL = tree.NewIsNullExpr(yyDollar[1].exprUnion()) } yyVAL.union = yyLOCAL - case 2014: + case 2040: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13193 +//line mysql_sql.y:13345 { yyLOCAL = tree.NewIsNotNullExpr(yyDollar[1].exprUnion()) } yyVAL.union = yyLOCAL - case 2015: + case 2041: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13197 +//line mysql_sql.y:13349 { yyLOCAL = tree.NewIsUnknownExpr(yyDollar[1].exprUnion()) } yyVAL.union = yyLOCAL - case 2016: + case 2042: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13201 +//line mysql_sql.y:13353 { yyLOCAL = tree.NewIsNotUnknownExpr(yyDollar[1].exprUnion()) } yyVAL.union = yyLOCAL - case 2017: + case 2043: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13205 +//line mysql_sql.y:13357 { yyLOCAL = tree.NewIsTrueExpr(yyDollar[1].exprUnion()) } yyVAL.union = yyLOCAL - case 2018: + case 2044: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13209 +//line mysql_sql.y:13361 { yyLOCAL = tree.NewIsNotTrueExpr(yyDollar[1].exprUnion()) } yyVAL.union = yyLOCAL - case 2019: + case 2045: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13213 +//line mysql_sql.y:13365 { yyLOCAL = tree.NewIsFalseExpr(yyDollar[1].exprUnion()) } yyVAL.union = yyLOCAL - case 2020: + case 2046: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13217 +//line mysql_sql.y:13369 { yyLOCAL = tree.NewIsNotFalseExpr(yyDollar[1].exprUnion()) } yyVAL.union = yyLOCAL - case 2021: + case 2047: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13221 +//line mysql_sql.y:13373 { yyLOCAL = tree.NewComparisonExpr(yyDollar[2].comparisonOpUnion(), yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 2022: + case 2048: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13225 +//line mysql_sql.y:13377 { yyLOCAL = tree.NewSubqueryComparisonExpr(yyDollar[2].comparisonOpUnion(), yyDollar[3].comparisonOpUnion(), yyDollar[1].exprUnion(), yyDollar[4].subqueryUnion()) yyLOCAL = tree.NewSubqueryComparisonExpr(yyDollar[2].comparisonOpUnion(), yyDollar[3].comparisonOpUnion(), yyDollar[1].exprUnion(), yyDollar[4].subqueryUnion()) } yyVAL.union = yyLOCAL - case 2024: + case 2050: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13233 +//line mysql_sql.y:13385 { yyLOCAL = tree.NewComparisonExpr(tree.IN, yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 2025: + case 2051: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13237 +//line mysql_sql.y:13389 { yyLOCAL = tree.NewComparisonExpr(tree.NOT_IN, yyDollar[1].exprUnion(), yyDollar[4].exprUnion()) } yyVAL.union = yyLOCAL - case 2026: + case 2052: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13241 +//line mysql_sql.y:13393 { yyLOCAL = tree.NewComparisonExprWithEscape(tree.LIKE, yyDollar[1].exprUnion(), yyDollar[3].exprUnion(), yyDollar[4].exprUnion()) } yyVAL.union = yyLOCAL - case 2027: + case 2053: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13245 +//line mysql_sql.y:13397 { yyLOCAL = tree.NewComparisonExprWithEscape(tree.NOT_LIKE, yyDollar[1].exprUnion(), yyDollar[4].exprUnion(), yyDollar[5].exprUnion()) } yyVAL.union = yyLOCAL - case 2028: + case 2054: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13249 +//line mysql_sql.y:13401 { yyLOCAL = tree.NewComparisonExprWithEscape(tree.ILIKE, yyDollar[1].exprUnion(), yyDollar[3].exprUnion(), yyDollar[4].exprUnion()) } yyVAL.union = yyLOCAL - case 2029: + case 2055: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13253 +//line mysql_sql.y:13405 { yyLOCAL = tree.NewComparisonExprWithEscape(tree.NOT_ILIKE, yyDollar[1].exprUnion(), yyDollar[4].exprUnion(), yyDollar[5].exprUnion()) } yyVAL.union = yyLOCAL - case 2030: + case 2056: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13257 +//line mysql_sql.y:13409 { yyLOCAL = tree.NewComparisonExpr(tree.REG_MATCH, yyDollar[1].exprUnion(), yyDollar[3].exprUnion()) } yyVAL.union = yyLOCAL - case 2031: + case 2057: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13261 +//line mysql_sql.y:13413 { yyLOCAL = tree.NewComparisonExpr(tree.NOT_REG_MATCH, yyDollar[1].exprUnion(), yyDollar[4].exprUnion()) } yyVAL.union = yyLOCAL - case 2032: + case 2058: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13265 +//line mysql_sql.y:13417 { yyLOCAL = tree.NewRangeCond(false, yyDollar[1].exprUnion(), yyDollar[3].exprUnion(), yyDollar[5].exprUnion()) } yyVAL.union = yyLOCAL - case 2033: + case 2059: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13269 +//line mysql_sql.y:13421 { yyLOCAL = tree.NewRangeCond(true, yyDollar[1].exprUnion(), yyDollar[4].exprUnion(), yyDollar[6].exprUnion()) } yyVAL.union = yyLOCAL - case 2035: + case 2061: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13275 +//line mysql_sql.y:13427 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 2036: + case 2062: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13279 +//line mysql_sql.y:13431 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 2037: + case 2063: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13285 +//line mysql_sql.y:13437 { yyLOCAL = yyDollar[1].tupleUnion() } yyVAL.union = yyLOCAL - case 2038: + case 2064: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13289 +//line mysql_sql.y:13441 { yyLOCAL = yyDollar[1].subqueryUnion() } yyVAL.union = yyLOCAL - case 2039: + case 2065: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ComparisonOp -//line mysql_sql.y:13296 +//line mysql_sql.y:13448 { yyLOCAL = tree.ALL } yyVAL.union = yyLOCAL - case 2040: + case 2066: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ComparisonOp -//line mysql_sql.y:13300 +//line mysql_sql.y:13452 { yyLOCAL = tree.ANY } yyVAL.union = yyLOCAL - case 2041: + case 2067: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ComparisonOp -//line mysql_sql.y:13304 +//line mysql_sql.y:13456 { yyLOCAL = tree.SOME } yyVAL.union = yyLOCAL - case 2042: + case 2068: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ComparisonOp -//line mysql_sql.y:13310 +//line mysql_sql.y:13462 { yyLOCAL = tree.EQUAL } yyVAL.union = yyLOCAL - case 2043: + case 2069: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ComparisonOp -//line mysql_sql.y:13314 +//line mysql_sql.y:13466 { yyLOCAL = tree.LESS_THAN } yyVAL.union = yyLOCAL - case 2044: + case 2070: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ComparisonOp -//line mysql_sql.y:13318 +//line mysql_sql.y:13470 { yyLOCAL = tree.GREAT_THAN } yyVAL.union = yyLOCAL - case 2045: + case 2071: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ComparisonOp -//line mysql_sql.y:13322 +//line mysql_sql.y:13474 { yyLOCAL = tree.LESS_THAN_EQUAL } yyVAL.union = yyLOCAL - case 2046: + case 2072: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ComparisonOp -//line mysql_sql.y:13326 +//line mysql_sql.y:13478 { yyLOCAL = tree.GREAT_THAN_EQUAL } yyVAL.union = yyLOCAL - case 2047: + case 2073: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ComparisonOp -//line mysql_sql.y:13330 +//line mysql_sql.y:13482 { yyLOCAL = tree.NOT_EQUAL } yyVAL.union = yyLOCAL - case 2048: + case 2074: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ComparisonOp -//line mysql_sql.y:13334 +//line mysql_sql.y:13486 { yyLOCAL = tree.NULL_SAFE_EQUAL } yyVAL.union = yyLOCAL - case 2049: + case 2075: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:13340 +//line mysql_sql.y:13492 { yyLOCAL = tree.NewAttributePrimaryKey() } yyVAL.union = yyLOCAL - case 2050: + case 2076: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:13344 +//line mysql_sql.y:13496 { yyLOCAL = tree.NewAttributeUniqueKey() } yyVAL.union = yyLOCAL - case 2051: + case 2077: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:13348 +//line mysql_sql.y:13500 { yyLOCAL = tree.NewAttributeUnique() } yyVAL.union = yyLOCAL - case 2052: + case 2078: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.ColumnAttribute -//line mysql_sql.y:13352 +//line mysql_sql.y:13504 { yyLOCAL = tree.NewAttributeKey() } yyVAL.union = yyLOCAL - case 2053: + case 2079: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13358 +//line mysql_sql.y:13510 { str := fmt.Sprintf("%v", yyDollar[1].item) switch v := yyDollar[1].item.(type) { @@ -30240,35 +30747,35 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2054: + case 2080: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13371 +//line mysql_sql.y:13523 { fval := yyDollar[1].item.(float64) yyLOCAL = tree.NewNumVal(fval, yylex.(*Lexer).scanner.LastToken, false, tree.P_float64) } yyVAL.union = yyLOCAL - case 2055: + case 2081: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13376 +//line mysql_sql.y:13528 { yyLOCAL = tree.NewNumVal(yyDollar[1].str, yyDollar[1].str, false, tree.P_decimal) } yyVAL.union = yyLOCAL - case 2056: + case 2082: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13382 +//line mysql_sql.y:13534 { yyLOCAL = tree.NewNumVal(yyDollar[1].str, yyDollar[1].str, false, tree.P_char) } yyVAL.union = yyLOCAL - case 2057: + case 2083: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13386 +//line mysql_sql.y:13538 { str := fmt.Sprintf("%v", yyDollar[1].item) switch v := yyDollar[1].item.(type) { @@ -30282,101 +30789,101 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2058: + case 2084: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13399 +//line mysql_sql.y:13551 { fval := yyDollar[1].item.(float64) yyLOCAL = tree.NewNumVal(fval, yylex.(*Lexer).scanner.LastToken, false, tree.P_float64) } yyVAL.union = yyLOCAL - case 2059: + case 2085: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13404 +//line mysql_sql.y:13556 { yyLOCAL = tree.NewNumVal(true, "true", false, tree.P_bool) } yyVAL.union = yyLOCAL - case 2060: + case 2086: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13408 +//line mysql_sql.y:13560 { yyLOCAL = tree.NewNumVal(false, "false", false, tree.P_bool) } yyVAL.union = yyLOCAL - case 2061: + case 2087: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13412 +//line mysql_sql.y:13564 { yyLOCAL = tree.NewNumVal("null", "null", false, tree.P_null) } yyVAL.union = yyLOCAL - case 2062: + case 2088: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13416 +//line mysql_sql.y:13568 { yyLOCAL = tree.NewNumVal(yyDollar[1].str, yyDollar[1].str, false, tree.P_hexnum) } yyVAL.union = yyLOCAL - case 2063: + case 2089: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13420 +//line mysql_sql.y:13572 { yyLOCAL = tree.NewNumVal(yyDollar[2].str, yyDollar[2].str, false, tree.P_ScoreBinaryHexnum) } yyVAL.union = yyLOCAL - case 2064: + case 2090: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13424 +//line mysql_sql.y:13576 { yyLOCAL = tree.NewNumVal(yyDollar[1].str, yyDollar[1].str, false, tree.P_decimal) } yyVAL.union = yyLOCAL - case 2065: + case 2091: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13428 +//line mysql_sql.y:13580 { yyLOCAL = tree.NewNumVal(yyDollar[1].str, yyDollar[1].str, false, tree.P_bit) } yyVAL.union = yyLOCAL - case 2066: + case 2092: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13432 +//line mysql_sql.y:13584 { yyLOCAL = tree.NewParamExpr(yylex.(*Lexer).GetParamIndex()) } yyVAL.union = yyLOCAL - case 2067: + case 2093: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Expr -//line mysql_sql.y:13436 +//line mysql_sql.y:13588 { yyLOCAL = tree.NewNumVal(yyDollar[2].str, yyDollar[2].str, false, tree.P_ScoreBinary) } yyVAL.union = yyLOCAL - case 2068: + case 2094: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13442 +//line mysql_sql.y:13594 { yyLOCAL = yyDollar[1].columnTypeUnion() yyLOCAL.InternalType.Unsigned = yyDollar[2].unsignedOptUnion() yyLOCAL.InternalType.Zerofill = yyDollar[3].zeroFillOptUnion() } yyVAL.union = yyLOCAL - case 2072: + case 2098: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13451 +//line mysql_sql.y:13603 { locale := "" yyLOCAL = &tree.T{ @@ -30390,27 +30897,27 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2073: + case 2099: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13466 +//line mysql_sql.y:13618 { yyLOCAL = yyDollar[1].columnTypeUnion() yyLOCAL.InternalType.DisplayWith = yyDollar[2].lengthOptUnion() } yyVAL.union = yyLOCAL - case 2074: + case 2100: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13471 +//line mysql_sql.y:13623 { yyLOCAL = yyDollar[1].columnTypeUnion() } yyVAL.union = yyLOCAL - case 2075: + case 2101: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13477 +//line mysql_sql.y:13629 { locale := "" yyLOCAL = &tree.T{ @@ -30423,10 +30930,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2076: + case 2102: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13489 +//line mysql_sql.y:13641 { locale := "" yyLOCAL = &tree.T{ @@ -30439,10 +30946,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2077: + case 2103: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13501 +//line mysql_sql.y:13653 { locale := "" yyLOCAL = &tree.T{ @@ -30455,10 +30962,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2078: + case 2104: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13513 +//line mysql_sql.y:13665 { locale := "" yyLOCAL = &tree.T{ @@ -30472,10 +30979,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2079: + case 2105: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13526 +//line mysql_sql.y:13678 { locale := "" yyLOCAL = &tree.T{ @@ -30489,10 +30996,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2080: + case 2106: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13539 +//line mysql_sql.y:13691 { locale := "" yyLOCAL = &tree.T{ @@ -30506,10 +31013,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2081: + case 2107: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13552 +//line mysql_sql.y:13704 { locale := "" yyLOCAL = &tree.T{ @@ -30523,10 +31030,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2082: + case 2108: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13565 +//line mysql_sql.y:13717 { locale := "" yyLOCAL = &tree.T{ @@ -30540,10 +31047,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2083: + case 2109: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13578 +//line mysql_sql.y:13730 { locale := "" yyLOCAL = &tree.T{ @@ -30557,10 +31064,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2084: + case 2110: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13591 +//line mysql_sql.y:13743 { locale := "" yyLOCAL = &tree.T{ @@ -30574,10 +31081,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2085: + case 2111: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13604 +//line mysql_sql.y:13756 { locale := "" yyLOCAL = &tree.T{ @@ -30591,10 +31098,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2086: + case 2112: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13617 +//line mysql_sql.y:13769 { locale := "" yyLOCAL = &tree.T{ @@ -30608,10 +31115,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2087: + case 2113: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13630 +//line mysql_sql.y:13782 { locale := "" yyLOCAL = &tree.T{ @@ -30625,10 +31132,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2088: + case 2114: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13643 +//line mysql_sql.y:13795 { locale := "" yyLOCAL = &tree.T{ @@ -30642,10 +31149,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2089: + case 2115: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13658 +//line mysql_sql.y:13810 { locale := "" if yyDollar[2].lengthScaleOptUnion().DisplayWith > 255 { @@ -30673,10 +31180,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2090: + case 2116: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13685 +//line mysql_sql.y:13837 { // DOUBLE PRECISION is the SQL-standard synonym for DOUBLE (float64). locale := "" @@ -30705,10 +31212,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2091: + case 2117: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13713 +//line mysql_sql.y:13865 { locale := "" if yyDollar[2].lengthScaleOptUnion().DisplayWith > 255 { @@ -30750,10 +31257,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2092: + case 2118: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13755 +//line mysql_sql.y:13907 { locale := "" if yyDollar[2].lengthScaleOptUnion().Scale != tree.NotDefineDec && yyDollar[2].lengthScaleOptUnion().Scale > yyDollar[2].lengthScaleOptUnion().DisplayWith { @@ -30802,10 +31309,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2093: + case 2119: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13803 +//line mysql_sql.y:13955 { locale := "" if yyDollar[2].lengthScaleOptUnion().Scale != tree.NotDefineDec && yyDollar[2].lengthScaleOptUnion().Scale > yyDollar[2].lengthScaleOptUnion().DisplayWith { @@ -30854,10 +31361,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2094: + case 2120: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13851 +//line mysql_sql.y:14003 { locale := "" width := int32(64) @@ -30879,10 +31386,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2095: + case 2121: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13874 +//line mysql_sql.y:14026 { locale := "" yyLOCAL = &tree.T{ @@ -30895,10 +31402,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2096: + case 2122: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13886 +//line mysql_sql.y:14038 { locale := "" if yyDollar[2].lengthOptUnion() < 0 || yyDollar[2].lengthOptUnion() > 6 { @@ -30919,10 +31426,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2097: + case 2123: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13906 +//line mysql_sql.y:14058 { locale := "" if yyDollar[2].lengthOptUnion() < 0 || yyDollar[2].lengthOptUnion() > 6 { @@ -30943,10 +31450,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2098: + case 2124: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13926 +//line mysql_sql.y:14078 { locale := "" if yyDollar[2].lengthOptUnion() < 0 || yyDollar[2].lengthOptUnion() > 6 { @@ -30967,10 +31474,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2099: + case 2125: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13946 +//line mysql_sql.y:14098 { locale := "" yyLOCAL = &tree.T{ @@ -30985,10 +31492,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2100: + case 2126: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13962 +//line mysql_sql.y:14114 { locale := "" yyLOCAL = &tree.T{ @@ -31002,10 +31509,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2101: + case 2127: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13975 +//line mysql_sql.y:14127 { locale := "" yyLOCAL = &tree.T{ @@ -31019,10 +31526,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2102: + case 2128: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:13988 +//line mysql_sql.y:14140 { locale := "" yyLOCAL = &tree.T{ @@ -31036,10 +31543,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2103: + case 2129: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14001 +//line mysql_sql.y:14153 { locale := "" yyLOCAL = &tree.T{ @@ -31053,10 +31560,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2104: + case 2130: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14014 +//line mysql_sql.y:14166 { locale := "" yyLOCAL = &tree.T{ @@ -31069,10 +31576,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2105: + case 2131: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14026 +//line mysql_sql.y:14178 { locale := "" yyLOCAL = &tree.T{ @@ -31085,10 +31592,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2106: + case 2132: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14038 +//line mysql_sql.y:14190 { locale := "" yyLOCAL = &tree.T{ @@ -31101,10 +31608,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2107: + case 2133: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14050 +//line mysql_sql.y:14202 { locale := "" yyLOCAL = &tree.T{ @@ -31117,10 +31624,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2108: + case 2134: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14062 +//line mysql_sql.y:14214 { locale := "" yyLOCAL = &tree.T{ @@ -31133,10 +31640,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2109: + case 2135: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14074 +//line mysql_sql.y:14226 { locale := "" yyLOCAL = &tree.T{ @@ -31149,10 +31656,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2110: + case 2136: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14086 +//line mysql_sql.y:14238 { locale := "" yyLOCAL = &tree.T{ @@ -31165,10 +31672,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2111: + case 2137: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14098 +//line mysql_sql.y:14250 { locale := "" yyLOCAL = &tree.T{ @@ -31181,10 +31688,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2112: + case 2138: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14110 +//line mysql_sql.y:14262 { locale := "" yyLOCAL = &tree.T{ @@ -31197,10 +31704,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2113: + case 2139: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14122 +//line mysql_sql.y:14274 { locale := "" yyLOCAL = &tree.T{ @@ -31213,10 +31720,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2114: + case 2140: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14134 +//line mysql_sql.y:14286 { locale := "" yyLOCAL = &tree.T{ @@ -31230,10 +31737,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2115: + case 2141: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14147 +//line mysql_sql.y:14299 { locale := "" yyLOCAL = &tree.T{ @@ -31247,10 +31754,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2116: + case 2142: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14160 +//line mysql_sql.y:14312 { locale := "" yyLOCAL = &tree.T{ @@ -31264,10 +31771,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2117: + case 2143: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14173 +//line mysql_sql.y:14325 { locale := "" yyLOCAL = &tree.T{ @@ -31281,10 +31788,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2118: + case 2144: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14186 +//line mysql_sql.y:14338 { locale := "" yyLOCAL = &tree.T{ @@ -31298,20 +31805,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2119: + case 2145: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:14201 +//line mysql_sql.y:14353 { yyLOCAL = &tree.Do{ Exprs: yyDollar[2].exprsUnion(), } } yyVAL.union = yyLOCAL - case 2120: + case 2146: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:14209 +//line mysql_sql.y:14361 { yyLOCAL = &tree.Declare{ Variables: yyDollar[2].strsUnion(), @@ -31320,10 +31827,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2121: + case 2147: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.Statement -//line mysql_sql.y:14218 +//line mysql_sql.y:14370 { yyLOCAL = &tree.Declare{ Variables: yyDollar[2].strsUnion(), @@ -31332,83 +31839,83 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2122: + case 2148: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *tree.T -//line mysql_sql.y:14228 +//line mysql_sql.y:14380 { yyLOCAL = tree.NewSpatialType(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 2141: + case 2167: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:14256 +//line mysql_sql.y:14408 { yyLOCAL = make([]string, 0, 4) yyLOCAL = append(yyLOCAL, yyDollar[1].str) } yyVAL.union = yyLOCAL - case 2142: + case 2168: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []string -//line mysql_sql.y:14261 +//line mysql_sql.y:14413 { yyLOCAL = append(yyDollar[1].strsUnion(), yyDollar[3].str) } yyVAL.union = yyLOCAL - case 2143: + case 2169: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int32 -//line mysql_sql.y:14267 +//line mysql_sql.y:14419 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 2145: + case 2171: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int32 -//line mysql_sql.y:14274 +//line mysql_sql.y:14426 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 2146: + case 2172: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int32 -//line mysql_sql.y:14278 +//line mysql_sql.y:14430 { yyLOCAL = int32(yyDollar[2].item.(int64)) } yyVAL.union = yyLOCAL - case 2147: + case 2173: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int32 -//line mysql_sql.y:14283 +//line mysql_sql.y:14435 { yyLOCAL = int32(-1) } yyVAL.union = yyLOCAL - case 2148: + case 2174: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int32 -//line mysql_sql.y:14287 +//line mysql_sql.y:14439 { yyLOCAL = int32(yyDollar[2].item.(int64)) } yyVAL.union = yyLOCAL - case 2149: + case 2175: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int32 -//line mysql_sql.y:14293 +//line mysql_sql.y:14445 { yyLOCAL = tree.GetDisplayWith(int32(yyDollar[2].item.(int64))) } yyVAL.union = yyLOCAL - case 2150: + case 2176: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.LengthScaleOpt -//line mysql_sql.y:14299 +//line mysql_sql.y:14451 { yyLOCAL = tree.LengthScaleOpt{ DisplayWith: tree.NotDefineDisplayWidth, @@ -31416,10 +31923,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2151: + case 2177: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.LengthScaleOpt -//line mysql_sql.y:14306 +//line mysql_sql.y:14458 { yyLOCAL = tree.LengthScaleOpt{ DisplayWith: tree.GetDisplayWith(int32(yyDollar[2].item.(int64))), @@ -31427,10 +31934,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2152: + case 2178: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.LengthScaleOpt -//line mysql_sql.y:14313 +//line mysql_sql.y:14465 { yyLOCAL = tree.LengthScaleOpt{ DisplayWith: tree.GetDisplayWith(int32(yyDollar[2].item.(int64))), @@ -31438,10 +31945,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2153: + case 2179: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL tree.LengthScaleOpt -//line mysql_sql.y:14322 +//line mysql_sql.y:14474 { yyLOCAL = tree.LengthScaleOpt{ DisplayWith: 38, // this is the default precision for decimal @@ -31449,10 +31956,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2154: + case 2180: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL tree.LengthScaleOpt -//line mysql_sql.y:14329 +//line mysql_sql.y:14481 { yyLOCAL = tree.LengthScaleOpt{ DisplayWith: tree.GetDisplayWith(int32(yyDollar[2].item.(int64))), @@ -31460,10 +31967,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2155: + case 2181: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL tree.LengthScaleOpt -//line mysql_sql.y:14336 +//line mysql_sql.y:14488 { yyLOCAL = tree.LengthScaleOpt{ DisplayWith: tree.GetDisplayWith(int32(yyDollar[2].item.(int64))), @@ -31471,52 +31978,52 @@ yydefault: } } yyVAL.union = yyLOCAL - case 2156: + case 2182: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:14345 +//line mysql_sql.y:14497 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 2157: + case 2183: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:14349 +//line mysql_sql.y:14501 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 2158: + case 2184: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:14353 +//line mysql_sql.y:14505 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 2159: + case 2185: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:14359 +//line mysql_sql.y:14511 { } - case 2160: + case 2186: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line mysql_sql.y:14361 +//line mysql_sql.y:14513 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 2164: + case 2190: yyDollar = yyS[yypt-0 : yypt+1] -//line mysql_sql.y:14371 +//line mysql_sql.y:14523 { yyVAL.str = "" } - case 2165: + case 2191: yyDollar = yyS[yypt-1 : yypt+1] -//line mysql_sql.y:14375 +//line mysql_sql.y:14527 { yyVAL.str = string(yyDollar[1].str) } diff --git a/pkg/sql/parsers/dialect/mysql/mysql_sql.y b/pkg/sql/parsers/dialect/mysql/mysql_sql.y index fea9bcc9a70ee..0bcb4dabda7e6 100644 --- a/pkg/sql/parsers/dialect/mysql/mysql_sql.y +++ b/pkg/sql/parsers/dialect/mysql/mysql_sql.y @@ -116,6 +116,9 @@ func sqlTaskInt64(v any) int64 { icebergOptions tree.IcebergOptions icebergTableParam *tree.IcebergTableParam icebergRefSpec *tree.IcebergRefSpec + mongodbOption *tree.MongoDBOption + mongodbOptions tree.MongoDBOptions + mongodbTableParam *tree.MongoDBTableParam functionName *tree.FunctionName funcArg tree.FunctionArg @@ -553,7 +556,7 @@ func sqlTaskInt64(v any) int64 { %token CALL // Time window -%token PREV SLIDING FILL +%token PREV SLIDING FILL GAPFILL // sp_begin_sym %token SPBEGIN @@ -579,6 +582,7 @@ func sqlTaskInt64(v any) int64 { // Iceberg %token ICEBERG CATALOG CATALOGS NAMESPACE NAMESPACES REF FOR_ICEBERG +%token MONGODB MONGODB_PATH MONGODB_CONVERT CONNECTIONS // ROLLUP %token GROUPING SETS CUBE ROLLUP @@ -590,18 +594,18 @@ func sqlTaskInt64(v any) int64 { %type stmt_list stmt_list_return %type create_stmt insert_stmt insert_no_with_stmt delete_stmt merge_stmt drop_stmt alter_stmt truncate_table_stmt alter_sequence_stmt upgrade_stmt %type delete_without_using_stmt delete_with_using_stmt -%type drop_ddl_stmt drop_database_stmt drop_table_stmt drop_index_stmt drop_prepare_stmt drop_view_stmt drop_connector_stmt drop_function_stmt drop_procedure_stmt drop_sequence_stmt drop_iceberg_catalog_stmt +%type drop_ddl_stmt drop_database_stmt drop_table_stmt drop_index_stmt drop_prepare_stmt drop_view_stmt drop_connector_stmt drop_function_stmt drop_procedure_stmt drop_sequence_stmt drop_iceberg_catalog_stmt drop_mongodb_connection_stmt %type drop_account_stmt drop_role_stmt drop_user_stmt %type create_account_stmt create_user_stmt create_role_stmt -%type create_ddl_stmt create_table_stmt create_database_stmt create_index_stmt create_view_stmt create_function_stmt create_extension_stmt create_procedure_stmt create_sequence_stmt create_iceberg_catalog_stmt +%type create_ddl_stmt create_table_stmt create_database_stmt create_index_stmt create_view_stmt create_function_stmt create_extension_stmt create_procedure_stmt create_sequence_stmt create_iceberg_catalog_stmt create_mongodb_connection_stmt %type create_source_stmt create_connector_stmt pause_daemon_task_stmt cancel_daemon_task_stmt resume_daemon_task_stmt create_sql_task_stmt drop_sql_task_stmt alter_sql_task_stmt show_sql_tasks_stmt show_sql_task_runs_stmt -%type show_stmt show_create_stmt show_columns_stmt show_databases_stmt show_target_filter_stmt show_table_status_stmt show_grants_stmt show_collation_stmt show_accounts_stmt show_roles_stmt show_stages_stmt show_snapshots_stmt show_upgrade_stmt show_rules_on_role_stmt show_iceberg_stmt +%type show_stmt show_create_stmt show_columns_stmt show_databases_stmt show_target_filter_stmt show_table_status_stmt show_grants_stmt show_collation_stmt show_accounts_stmt show_roles_stmt show_stages_stmt show_snapshots_stmt show_upgrade_stmt show_rules_on_role_stmt show_iceberg_stmt show_mongodb_connections_stmt %type show_tables_stmt show_sequences_stmt show_process_stmt show_errors_stmt show_warnings_stmt show_target %type show_procedure_status_stmt show_function_status_stmt show_node_list_stmt show_locks_stmt %type show_table_num_stmt show_column_num_stmt show_table_values_stmt show_table_size_stmt %type show_variables_stmt show_status_stmt show_index_stmt %type show_servers_stmt show_connectors_stmt show_logservice_replicas_stmt show_logservice_stores_stmt show_logservice_settings_stmt -%type alter_account_stmt alter_user_stmt alter_view_stmt update_stmt use_stmt update_no_with_stmt alter_database_config_stmt alter_table_stmt alter_role_stmt rename_stmt alter_iceberg_catalog_stmt +%type alter_account_stmt alter_user_stmt alter_view_stmt update_stmt use_stmt update_no_with_stmt alter_database_config_stmt alter_table_stmt alter_role_stmt rename_stmt alter_iceberg_catalog_stmt alter_mongodb_connection_stmt %type merge_no_with_stmt %type merge_when_list %type merge_when_clause @@ -725,6 +729,10 @@ func sqlTaskInt64(v any) int64 { %type iceberg_table_param %type iceberg_option_list_opt iceberg_option_list %type iceberg_option +%type mongodb_table_param +%type mongodb_option_list_opt mongodb_option_list +%type mongodb_option +%type mongodb_option_key mongodb_option_value %type charset_name storage_opt collate_name column_format storage_media algorithm_type able_type space_type lock_type with_type rename_type algorithm_type_2 load_charset %type row_format_options %type field_length_opt max_file_size_opt @@ -951,6 +959,7 @@ func sqlTaskInt64(v any) int64 { %type time_window_opt time_window %type interval %type sliding_opt +%type gapfill_opt %type fill_opt %type fill_mode @@ -3672,6 +3681,7 @@ alter_stmt: | alter_role_stmt | alter_sql_task_stmt | alter_iceberg_catalog_stmt +| alter_mongodb_connection_stmt | rename_stmt // | alter_ddl_stmt @@ -3691,6 +3701,38 @@ alter_iceberg_catalog_stmt: } } +alter_mongodb_connection_stmt: + ALTER MONGODB CONNECTION ident SET mongodb_option_list + { + $$ = &tree.AlterMongoDBConnection{ + Name: tree.Identifier($4.Compare()), + Action: tree.AlterMongoDBConnectionSet, + Options: $6, + } + } +| ALTER MONGODB CONNECTION ident SET '(' mongodb_option_list ')' + { + $$ = &tree.AlterMongoDBConnection{ + Name: tree.Identifier($4.Compare()), + Action: tree.AlterMongoDBConnectionSet, + Options: $7, + } + } +| ALTER MONGODB CONNECTION ident ENABLE + { + $$ = &tree.AlterMongoDBConnection{ + Name: tree.Identifier($4.Compare()), + Action: tree.AlterMongoDBConnectionEnable, + } + } +| ALTER MONGODB CONNECTION ident DISABLE + { + $$ = &tree.AlterMongoDBConnection{ + Name: tree.Identifier($4.Compare()), + Action: tree.AlterMongoDBConnectionDisable, + } + } + alter_sequence_stmt: ALTER SEQUENCE exists_opt table_name alter_as_datatype_opt increment_by_opt min_value_opt max_value_opt start_with_opt alter_cycle_opt { @@ -4635,6 +4677,7 @@ show_stmt: | show_sql_tasks_stmt | show_sql_task_runs_stmt | show_iceberg_stmt +| show_mongodb_connections_stmt show_sql_tasks_stmt: SHOW TASKS @@ -4683,6 +4726,7 @@ show_iceberg_stmt: Where: $5, } } + | SHOW ICEBERG NAMESPACES FROM ident like_opt where_expression_opt { $$ = &tree.ShowIcebergNamespaces{ @@ -4756,6 +4800,15 @@ show_iceberg_stmt: } } +show_mongodb_connections_stmt: + SHOW MONGODB CONNECTIONS like_opt where_expression_opt + { + $$ = &tree.ShowMongoDBConnections{ + Like: $4, + Where: $5, + } + } + iceberg_namespace_value: iceberg_option_value { @@ -5338,6 +5391,7 @@ drop_ddl_stmt: | drop_cdc_stmt | drop_sql_task_stmt | drop_iceberg_catalog_stmt +| drop_mongodb_connection_stmt drop_sql_task_stmt: DROP TASK exists_opt ident @@ -5357,6 +5411,15 @@ drop_iceberg_catalog_stmt: } } +drop_mongodb_connection_stmt: + DROP MONGODB CONNECTION exists_opt ident + { + $$ = &tree.DropMongoDBConnection{ + IfExists: $4, + Name: tree.Identifier($5.Compare()), + } + } + drop_sequence_stmt: DROP SEQUENCE exists_opt table_name_list { @@ -6259,12 +6322,13 @@ time_window_opt: } time_window: - interval sliding_opt fill_opt + interval sliding_opt gapfill_opt fill_opt { $$ = &tree.TimeWindow{ Interval: $1, Sliding: $2, - Fill: $3, + GapFill: $3, + Fill: $4, } } @@ -6302,6 +6366,15 @@ sliding_opt: } } +gapfill_opt: + { + $$ = false + } +| GAPFILL '(' PARTITION ')' + { + $$ = true + } + fill_opt: { $$ = nil @@ -7390,6 +7463,7 @@ create_ddl_stmt: | create_source_stmt | create_connector_stmt | create_iceberg_catalog_stmt +| create_mongodb_connection_stmt | pause_daemon_task_stmt | cancel_daemon_task_stmt | resume_daemon_task_stmt @@ -7404,6 +7478,16 @@ create_iceberg_catalog_stmt: } } +create_mongodb_connection_stmt: + CREATE MONGODB CONNECTION not_exists_opt ident mongodb_option_list_opt + { + $$ = &tree.CreateMongoDBConnection{ + IfNotExists: $4, + Name: tree.Identifier($5.Compare()), + Options: $6, + } + } + create_sql_task_stmt: CREATE TASK not_exists_opt ident sql_task_schedule_opt sql_task_when_opt sql_task_retry_opt sql_task_timeout_opt AS block_stmt { @@ -9484,6 +9568,15 @@ create_table_stmt: t.IcebergParam = $9 $$ = t } +| CREATE EXTERNAL TABLE not_exists_opt table_name '(' table_elem_list_opt ')' mongodb_table_param + { + t := tree.NewCreateTable() + t.IfNotExists = $4 + t.Table = *$5 + t.Defs = $7 + t.MongoDBParam = $9 + $$ = t + } | CREATE EXTERNAL TABLE not_exists_opt table_name iceberg_table_param { t := tree.NewCreateTable() @@ -10325,6 +10418,57 @@ iceberg_option_value: $$ = $1 } +mongodb_table_param: + ENGINE equal_opt MONGODB mongodb_option_list_opt + { + $$ = tree.NewMongoDBTableParam($4) + } + +mongodb_option_list_opt: + { + $$ = nil + } +| WITH '(' mongodb_option_list ')' + { + $$ = $3 + } + +mongodb_option_list: + mongodb_option + { + $$ = tree.MongoDBOptions{$1} + } +| mongodb_option_list ',' mongodb_option + { + $$ = append($1, $3) + } + +mongodb_option: + mongodb_option_key '=' mongodb_option_value + { + $$ = tree.NewMongoDBOption(tree.Identifier($1), $3) + } + +mongodb_option_key: + ident + { + $$ = $1.Compare() + } +| STRING + { + $$ = $1 + } + +mongodb_option_value: + ident + { + $$ = $1.Compare() + } +| STRING + { + $$ = $1 + } + table_option_list_opt: { $$ = nil @@ -11115,6 +11259,14 @@ column_attribute_elem: str := util.DealCommentString($2) $$ = tree.NewAttributeComment(tree.NewNumVal(str, str, false, tree.P_char)) } +| MONGODB_PATH STRING + { + $$ = tree.NewAttributeMongoDBPath($2) + } +| MONGODB_CONVERT STRING + { + $$ = tree.NewAttributeMongoDBConvert($2) + } | COLLATE collate_name { $$ = tree.NewAttributeCollate($2) @@ -14672,6 +14824,10 @@ non_reserved_keyword: | INTEGER | INDEXES | ICEBERG +| MONGODB +| MONGODB_PATH +| MONGODB_CONVERT +| CONNECTIONS | INTERMEDIATE_GRAPH_DEGREE | ISOLATION | ITOPK_SIZE @@ -14958,6 +15114,8 @@ non_reserved_keyword: | PRECEDING | FOLLOWING | FILL + +| GAPFILL | TABLE_NUMBER | TABLE_VALUES | TABLE_SIZE diff --git a/pkg/sql/parsers/tree/create.go b/pkg/sql/parsers/tree/create.go index 10c237efccc50..7c8b092d54e09 100644 --- a/pkg/sql/parsers/tree/create.go +++ b/pkg/sql/parsers/tree/create.go @@ -943,6 +943,7 @@ type CreateTable struct { ClusterByOption *ClusterByOption Param *ExternParam IcebergParam *IcebergTableParam + MongoDBParam *MongoDBTableParam AsSource *Select IsDynamicTable bool DTOptions []TableOption @@ -964,7 +965,7 @@ func (node *CreateTable) Format(ctx *FmtCtx) { if node.IsClusterTable { ctx.WriteString(" cluster") } - if node.Param != nil || node.IcebergParam != nil { + if node.Param != nil || node.IcebergParam != nil || node.MongoDBParam != nil { ctx.WriteString(" external") } if node.IsDynamicTable { @@ -1033,6 +1034,10 @@ func (node *CreateTable) Format(ctx *FmtCtx) { ctx.WriteByte(' ') node.IcebergParam.Format(ctx) } + if node.MongoDBParam != nil { + ctx.WriteByte(' ') + node.MongoDBParam.Format(ctx) + } if node.PartitionOption != nil { ctx.WriteByte(' ') @@ -1396,6 +1401,10 @@ func (node *ColumnTableDef) reset() { opt.Free() case *AttributeVisable: opt.Free() + case *AttributeMongoDBPath: + opt.Free() + case *AttributeMongoDBConvert: + opt.Free() case *KeyPart: opt.Free() default: diff --git a/pkg/sql/parsers/tree/mongodb.go b/pkg/sql/parsers/tree/mongodb.go new file mode 100644 index 0000000000000..5a586ff75c061 --- /dev/null +++ b/pkg/sql/parsers/tree/mongodb.go @@ -0,0 +1,200 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tree + +import "strings" + +type MongoDBOption struct { + Key Identifier + Val string +} + +type MongoDBOptions []*MongoDBOption + +func NewMongoDBOption(key Identifier, value string) *MongoDBOption { + return &MongoDBOption{Key: key, Val: value} +} + +func (option *MongoDBOption) Format(ctx *FmtCtx) { + ctx.WriteString("\"") + ctx.WriteString(string(option.Key)) + ctx.WriteString("\" = '") + value := option.Val + key := strings.ToLower(strings.ReplaceAll(string(option.Key), "_", "")) + if key == "hosts" || key == "srvhost" || strings.Contains(key, "password") || strings.Contains(key, "credential") || + strings.Contains(key, "token") || strings.Contains(key, "secret") || key == "optionsjson" { + value = "" + } + ctx.WriteString(strings.ReplaceAll(FormatString(value), "'", "''")) + ctx.WriteByte('\'') +} + +func (options MongoDBOptions) Format(ctx *FmtCtx) { + for i, option := range options { + if i > 0 { + ctx.WriteString(", ") + } + option.Format(ctx) + } +} + +type MongoDBTableParam struct { + Options MongoDBOptions +} + +func NewMongoDBTableParam(options MongoDBOptions) *MongoDBTableParam { + return &MongoDBTableParam{Options: options} +} + +func (param *MongoDBTableParam) Format(ctx *FmtCtx) { + ctx.WriteString("engine = mongodb") + if len(param.Options) > 0 { + ctx.WriteString(" with (") + param.Options.Format(ctx) + ctx.WriteByte(')') + } +} + +type AttributeMongoDBPath struct { + columnAttributeImpl + Path string +} + +func NewAttributeMongoDBPath(path string) *AttributeMongoDBPath { + return &AttributeMongoDBPath{Path: path} +} + +func (attribute *AttributeMongoDBPath) Format(ctx *FmtCtx) { + ctx.WriteString("mongodb_path '") + ctx.WriteString(strings.ReplaceAll(FormatString(attribute.Path), "'", "''")) + ctx.WriteByte('\'') +} + +func (attribute *AttributeMongoDBPath) Free() {} + +type AttributeMongoDBConvert struct { + columnAttributeImpl + Mode string +} + +func NewAttributeMongoDBConvert(mode string) *AttributeMongoDBConvert { + return &AttributeMongoDBConvert{Mode: mode} +} + +func (attribute *AttributeMongoDBConvert) Format(ctx *FmtCtx) { + ctx.WriteString("mongodb_convert '") + ctx.WriteString(strings.ReplaceAll(FormatString(attribute.Mode), "'", "''")) + ctx.WriteByte('\'') +} + +func (attribute *AttributeMongoDBConvert) Free() {} + +type CreateMongoDBConnection struct { + statementImpl + Name Identifier + IfNotExists bool + Options MongoDBOptions +} + +func (stmt *CreateMongoDBConnection) Format(ctx *FmtCtx) { + ctx.WriteString("create mongodb connection ") + if stmt.IfNotExists { + ctx.WriteString("if not exists ") + } + ctx.WriteIdentifier(stmt.Name) + if len(stmt.Options) > 0 { + ctx.WriteString(" with (") + stmt.Options.Format(ctx) + ctx.WriteByte(')') + } +} +func (*CreateMongoDBConnection) GetStatementType() string { return "Create MongoDB Connection" } +func (*CreateMongoDBConnection) GetQueryType() string { return QueryTypeDDL } +func (*CreateMongoDBConnection) StmtKind() StmtKind { return frontendStatusTyp } +func (*CreateMongoDBConnection) Free() {} + +type AlterMongoDBConnection struct { + statementImpl + Name Identifier + Action AlterMongoDBConnectionAction + Options MongoDBOptions +} + +type AlterMongoDBConnectionAction uint8 + +const ( + AlterMongoDBConnectionSet AlterMongoDBConnectionAction = iota + AlterMongoDBConnectionEnable + AlterMongoDBConnectionDisable +) + +func (stmt *AlterMongoDBConnection) Format(ctx *FmtCtx) { + ctx.WriteString("alter mongodb connection ") + ctx.WriteIdentifier(stmt.Name) + switch stmt.Action { + case AlterMongoDBConnectionEnable: + ctx.WriteString(" enable") + case AlterMongoDBConnectionDisable: + ctx.WriteString(" disable") + default: + ctx.WriteString(" set (") + stmt.Options.Format(ctx) + ctx.WriteByte(')') + } +} +func (*AlterMongoDBConnection) GetStatementType() string { return "Alter MongoDB Connection" } +func (*AlterMongoDBConnection) GetQueryType() string { return QueryTypeDDL } +func (*AlterMongoDBConnection) StmtKind() StmtKind { return frontendStatusTyp } +func (*AlterMongoDBConnection) Free() {} + +type DropMongoDBConnection struct { + statementImpl + Name Identifier + IfExists bool +} + +func (stmt *DropMongoDBConnection) Format(ctx *FmtCtx) { + ctx.WriteString("drop mongodb connection ") + if stmt.IfExists { + ctx.WriteString("if exists ") + } + ctx.WriteIdentifier(stmt.Name) +} +func (*DropMongoDBConnection) GetStatementType() string { return "Drop MongoDB Connection" } +func (*DropMongoDBConnection) GetQueryType() string { return QueryTypeDDL } +func (*DropMongoDBConnection) StmtKind() StmtKind { return frontendStatusTyp } +func (*DropMongoDBConnection) Free() {} + +type ShowMongoDBConnections struct { + statementImpl + Like *ComparisonExpr + Where *Where +} + +func (stmt *ShowMongoDBConnections) Format(ctx *FmtCtx) { + ctx.WriteString("show mongodb connections") + if stmt.Like != nil { + ctx.WriteByte(' ') + stmt.Like.Format(ctx) + } + if stmt.Where != nil { + ctx.WriteByte(' ') + stmt.Where.Format(ctx) + } +} +func (*ShowMongoDBConnections) GetStatementType() string { return "Show MongoDB Connections" } +func (*ShowMongoDBConnections) GetQueryType() string { return QueryTypeOth } +func (*ShowMongoDBConnections) StmtKind() StmtKind { return compositeResRowType } +func (*ShowMongoDBConnections) Free() {} diff --git a/pkg/sql/parsers/tree/select.go b/pkg/sql/parsers/tree/select.go index 93be5b0ba332a..3cfd32d066eae 100644 --- a/pkg/sql/parsers/tree/select.go +++ b/pkg/sql/parsers/tree/select.go @@ -106,6 +106,7 @@ type Rewrite struct { type TimeWindow struct { Interval *Interval Sliding *Sliding + GapFill bool Fill *Fill } @@ -115,6 +116,9 @@ func (node *TimeWindow) Format(ctx *FmtCtx) { ctx.WriteByte(' ') node.Sliding.Format(ctx) } + if node.GapFill { + ctx.WriteString(" gapfill(partition)") + } if node.Fill != nil { ctx.WriteByte(' ') node.Fill.Format(ctx) diff --git a/pkg/sql/plan/build_alter_table.go b/pkg/sql/plan/build_alter_table.go index 69be1c25d60cd..c09383b68c866 100644 --- a/pkg/sql/plan/build_alter_table.go +++ b/pkg/sql/plan/build_alter_table.go @@ -425,6 +425,14 @@ func buildAlterTable(stmt *tree.AlterTable, ctx CompilerContext) (*Plan, error) if tableDef == nil { return nil, moerr.NewNoSuchTable(ctx.GetContext(), schemaName, tableName) } + isMongoDB, err := IsMongoDBTableDef(ctx.GetContext(), tableDef) + if err != nil { + return nil, err + } + if isMongoDB { + return nil, moerr.NewNotSupported(ctx.GetContext(), + "ALTER TABLE on a MongoDB external table; drop and recreate the external table to change its schema") + } if tableDef.IsTemporary { // Only allow a safe subset of alter operations on temporary tables. diff --git a/pkg/sql/plan/build_ddl.go b/pkg/sql/plan/build_ddl.go index 049450ef2e2be..eb61f40831bea 100644 --- a/pkg/sql/plan/build_ddl.go +++ b/pkg/sql/plan/build_ddl.go @@ -40,6 +40,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/sql/colexec/externalwrite" "github.com/matrixorigin/matrixone/pkg/sql/features" sqliceberg "github.com/matrixorigin/matrixone/pkg/sql/iceberg" + sqlmongodb "github.com/matrixorigin/matrixone/pkg/sql/mongodb" "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect" "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect/mysql" "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" @@ -1046,6 +1047,24 @@ func buildCreateTable( Properties: properties, }, }}) + } else if stmt.MongoDBParam != nil { + if err := ensureMongoDBTableSurfaceEnabled(ctx.GetContext()); err != nil { + return nil, err + } + spec, err := sqlmongodb.ParseTableMappingSpec(ctx.GetContext(), stmt.MongoDBParam, stmt.Defs, createTable.TableDef) + if err != nil { + return nil, err + } + properties := []*plan.Property{ + {Key: catalog.SystemRelAttr_Kind, Value: catalog.SystemExternalRel}, + {Key: catalog.SystemRelAttr_CreateSQL, Value: sqlmongodb.BuildCreateSQLEnvelope(spec.Mapping)}, + } + createTable.TableDef.TableType = catalog.SystemExternalRel + createTable.TableDef.Defs = append(createTable.TableDef.Defs, &plan.TableDef_DefType{ + Def: &plan.TableDef_DefType_Properties{ + Properties: &plan.PropertiesDef{Properties: properties}, + }, + }) } else if stmt.Param != nil { for i := 0; i < len(stmt.Param.Option); i += 2 { switch strings.ToLower(stmt.Param.Option[i]) { @@ -1176,7 +1195,7 @@ func buildTableDefs(stmt *tree.CreateTable, ctx CompilerContext, createTable *pl fkDatasOfFKSelfRefer := make([]*FkData, 0) dedupFkName := make(UnorderedSet[string]) - if stmt.Param != nil || stmt.IcebergParam != nil { + if stmt.Param != nil || stmt.IcebergParam != nil || stmt.MongoDBParam != nil { if err := rejectExternalTableInlineIndexes(ctx.GetContext(), stmt); err != nil { return err } diff --git a/pkg/sql/plan/build_ddl_test.go b/pkg/sql/plan/build_ddl_test.go index 5c72a457a6960..b69a7f0769744 100644 --- a/pkg/sql/plan/build_ddl_test.go +++ b/pkg/sql/plan/build_ddl_test.go @@ -28,8 +28,10 @@ import ( "github.com/matrixorigin/matrixone/pkg/catalog" "github.com/matrixorigin/matrixone/pkg/common/moerr" moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" + "github.com/matrixorigin/matrixone/pkg/config" "github.com/matrixorigin/matrixone/pkg/container/types" "github.com/matrixorigin/matrixone/pkg/pb/plan" + sqlmongodb "github.com/matrixorigin/matrixone/pkg/sql/mongodb" "github.com/matrixorigin/matrixone/pkg/sql/parsers" "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect" "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" @@ -465,6 +467,75 @@ func TestBuildCreateIndexOnExternalTableError(t *testing.T) { } } +func TestBuildAlterTableRejectsMongoDBExternalTable(t *testing.T) { + mock := NewEmptyMockOptimizer() + ctx := mock.CurrentContext().(*MockCompilerContext) + ctx.objects["mongo_ext"] = &plan.ObjectRef{SchemaName: "tpch", ObjName: "mongo_ext"} + ctx.tables["mongo_ext"] = &plan.TableDef{ + Name: "mongo_ext", + TableType: catalog.SystemExternalRel, + Cols: []*plan.ColDef{ + {Name: "device_id", Typ: plan.Type{Id: int32(types.T_varchar), Width: 64}}, + {Name: "measurement", Typ: plan.Type{Id: int32(types.T_float64)}}, + }, + Createsql: sqlmongodb.BuildCreateSQLEnvelope(sqlmongodb.TableMapping{ + Connection: "source", Database: "telemetry", Collection: "samples", + SchemaMode: sqlmongodb.SchemaExplicit, Conversion: sqlmongodb.ConversionStrict, + MaxParallelism: 1, + Columns: []sqlmongodb.ColumnMapping{ + {Name: "device_id", Path: "metadata.device_id", TypeID: int32(types.T_varchar), Width: 64}, + {Name: "measurement", Path: "reading.measurement", TypeID: int32(types.T_float64)}, + }, + }), + } + + for _, sql := range []string{ + "ALTER TABLE mongo_ext RENAME COLUMN device_id TO device_key", + "ALTER TABLE mongo_ext MODIFY COLUMN measurement DECIMAL(18, 6)", + "ALTER TABLE mongo_ext ADD COLUMN site_id VARCHAR(32)", + "ALTER TABLE mongo_ext DROP COLUMN measurement", + } { + _, err := runOneStmt(mock, t, sql) + require.ErrorContains(t, err, "ALTER TABLE on a MongoDB external table", sql) + } +} + +func TestBuildMongoDBExternalTablePreservesNotNullMapping(t *testing.T) { + mock := NewMockOptimizer(false) + ctx := mock.CurrentContext().(*MockCompilerContext) + ctx.SetContext(context.WithValue(context.Background(), config.ParameterUnitKey, &config.ParameterUnit{ + SV: &config.FrontendParameters{MongoDB: config.MongoDBParameters{Enable: true}}, + })) + + logicPlan, err := runOneStmt(mock, t, ` + CREATE EXTERNAL TABLE tpch.mongo_not_null ( + v BIGINT NOT NULL MONGODB_PATH 'payload.value' MONGODB_CONVERT 'try_null' + ) ENGINE=MONGODB WITH ( + "connection"='source', "database"='telemetry', "collection"='samples' + )`) + require.NoError(t, err) + tableDef := logicPlan.GetDdl().GetCreateTable().GetTableDef() + require.NotEmpty(t, tableDef.Cols) + require.Equal(t, "v", tableDef.Cols[0].Name) + require.False(t, tableDef.Cols[0].Default.NullAbility) + + var createSQL string + for _, def := range tableDef.Defs { + for _, property := range def.GetProperties().GetProperties() { + if property.Key == catalog.SystemRelAttr_CreateSQL { + createSQL = property.Value + } + } + } + require.NotEmpty(t, createSQL) + envelope, found, err := sqlmongodb.ParseCreateSQLEnvelope(t.Context(), createSQL) + require.NoError(t, err) + require.True(t, found) + require.Len(t, envelope.Columns, 1) + require.True(t, envelope.Columns[0].NotNullable) + require.True(t, sqlmongodb.ColumnsToPlan(envelope.Columns)[0].MoType.NotNullable) +} + func TestBuildCreateExternalTableInlineIndexError(t *testing.T) { mock := NewMockOptimizer(false) sqls := []string{ diff --git a/pkg/sql/plan/build_show_util.go b/pkg/sql/plan/build_show_util.go index a35af6bae4419..8a571433bad6d 100644 --- a/pkg/sql/plan/build_show_util.go +++ b/pkg/sql/plan/build_show_util.go @@ -28,6 +28,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/pb/partition" "github.com/matrixorigin/matrixone/pkg/pb/plan" sqliceberg "github.com/matrixorigin/matrixone/pkg/sql/iceberg" + sqlmongodb "github.com/matrixorigin/matrixone/pkg/sql/mongodb" "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" "github.com/matrixorigin/matrixone/pkg/sql/util" ) @@ -48,6 +49,20 @@ func ConstructCreateTableSQL( rewrite string }, 0) checkDefs := extractTopLevelCheckDefs(tableDef) + var mongoEnvelope sqlmongodb.CreateSQLEnvelope + mongoColumns := make(map[string]sqlmongodb.ColumnMapping) + if tableDef.TableType == catalog.SystemExternalRel { + var found bool + mongoEnvelope, found, err = sqlmongodb.ParseCreateSQLEnvelope(ctx.GetContext(), tableDef.Createsql) + if err != nil { + return "", nil, err + } + if found { + for _, column := range mongoEnvelope.Columns { + mongoColumns[strings.ToLower(column.Name)] = column + } + } + } tblName := tableDef.Name schemaName := tableDef.DbName @@ -153,6 +168,13 @@ func ConstructCreateTableSQL( if col.Comment != "" { buf.WriteString(" COMMENT '" + col.Comment + "'") } + if mapping, ok := mongoColumns[strings.ToLower(col.Name)]; ok { + buf.WriteString(" MONGODB_PATH '") + buf.WriteString(formatStrInSingleQuotes(mapping.Path)) + buf.WriteString("' MONGODB_CONVERT '") + buf.WriteString(formatStrInSingleQuotes(mapping.Conversion)) + buf.WriteString("'") + } createStr += buf.String() rowCount++ @@ -588,6 +610,14 @@ func ConstructCreateTableSQL( } return createStr, stmt, err } + if len(mongoColumns) > 0 { + createStr += formatMongoDBTableOptionsForShowCreate(mongoEnvelope) + var stmt tree.Statement + if ctx != nil { + stmt, err = getRewriteSQLStmt(ctx, createStr) + } + return createStr, stmt, err + } param := &tree.ExternParam{} if err = json.Unmarshal([]byte(tableDef.Createsql), param); err != nil { @@ -1022,6 +1052,40 @@ func formatIcebergTableOptionsForShowCreate(env sqliceberg.CreateSQLEnvelope) st return builder.String() } +func formatMongoDBTableOptionsForShowCreate(env sqlmongodb.CreateSQLEnvelope) string { + options := []struct { + key string + value string + }{ + {key: "connection", value: env.Connection}, + {key: "database", value: env.Database}, + {key: "collection", value: env.Collection}, + {key: "schema_mode", value: env.SchemaMode}, + {key: "conversion_mode", value: env.ConversionMode}, + {key: "max_parallelism", value: fmt.Sprintf("%d", env.MaxParallelism)}, + } + if env.SplitKey != "" { + options = append(options, struct { + key string + value string + }{key: "split_key", value: env.SplitKey}) + } + var builder strings.Builder + builder.WriteString(" ENGINE = MONGODB WITH (") + for i, option := range options { + if i > 0 { + builder.WriteString(", ") + } + builder.WriteString("\"") + builder.WriteString(option.key) + builder.WriteString("\" = '") + builder.WriteString(formatStrInSingleQuotes(option.value)) + builder.WriteString("'") + } + builder.WriteString(")") + return builder.String() +} + func formatInfileExternalOptionsForShowCreate(param *tree.ExternParam) string { if pattern, writable := GetWriteFilePattern(param); writable { // Writable external tables must be recreatable from their own DDL: diff --git a/pkg/sql/plan/build_show_util_test.go b/pkg/sql/plan/build_show_util_test.go index 01d39d94da6c0..743d498244304 100644 --- a/pkg/sql/plan/build_show_util_test.go +++ b/pkg/sql/plan/build_show_util_test.go @@ -24,6 +24,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/iceberg/model" "github.com/matrixorigin/matrixone/pkg/pb/plan" sqliceberg "github.com/matrixorigin/matrixone/pkg/sql/iceberg" + sqlmongodb "github.com/matrixorigin/matrixone/pkg/sql/mongodb" "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect/mysql" "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" "github.com/stretchr/testify/require" @@ -384,6 +385,46 @@ func TestShowCreateIcebergExternalTable(t *testing.T) { require.Equal(t, "CREATE EXTERNAL TABLE `gold_orders` (\n `id` int DEFAULT NULL\n) ENGINE = ICEBERG WITH (\"catalog\" = 'ksa_gold', \"namespace\" = 'sales', \"table\" = 'orders', \"ref\" = 'main', \"read_mode\" = 'append_only', \"write_mode\" = 'read_only')", showSQL) } +func TestShowCreateMongoDBExternalTable(t *testing.T) { + mock := NewMockOptimizer(false) + tableDef := &plan.TableDef{ + Name: "events", + TableType: catalog.SystemExternalRel, + Createsql: sqlmongodb.BuildCreateSQLEnvelope(sqlmongodb.TableMapping{ + Connection: "telemetry_source", + Database: "telemetry", + Collection: "measurements", + SchemaMode: sqlmongodb.SchemaExplicit, + Conversion: sqlmongodb.ConversionStrict, + MaxParallelism: 1, + Columns: []sqlmongodb.ColumnMapping{ + {Name: "device_id", Path: "metadata.device_id", TypeID: int32(types.T_varchar), Conversion: sqlmongodb.ConversionStrict}, + {Name: "measurement", Path: "reading.measurement", TypeID: int32(types.T_float64), Conversion: sqlmongodb.ConversionTryNull}, + }, + }), + Cols: []*plan.ColDef{ + { + Name: "device_id", + OriginName: "DeviceID", + Typ: plan.Type{Id: int32(types.T_varchar), Width: 64}, + Default: &plan.Default{NullAbility: true}, + }, + { + Name: "measurement", + Typ: plan.Type{Id: int32(types.T_float64)}, + Default: &plan.Default{NullAbility: true}, + }, + }, + } + + showSQL, stmt, err := ConstructCreateTableSQL(&mock.ctxt, tableDef, nil, false, nil) + require.NoError(t, err) + require.NotNil(t, stmt) + require.Equal(t, "CREATE EXTERNAL TABLE `events` (\n `DeviceID` varchar(64) DEFAULT NULL MONGODB_PATH 'metadata.device_id' MONGODB_CONVERT 'strict',\n `measurement` double DEFAULT NULL MONGODB_PATH 'reading.measurement' MONGODB_CONVERT 'try_null'\n) ENGINE = MONGODB WITH (\"connection\" = 'telemetry_source', \"database\" = 'telemetry', \"collection\" = 'measurements', \"schema_mode\" = 'explicit', \"conversion_mode\" = 'strict', \"max_parallelism\" = '1')", showSQL) + require.NotContains(t, strings.ToLower(showSQL), "credential") + require.NotContains(t, strings.ToLower(showSQL), "password") +} + func TestShowCreateLegacyExternalTablesIgnoreIcebergEnvelope(t *testing.T) { tests := []struct { name string diff --git a/pkg/sql/plan/deepcopy.go b/pkg/sql/plan/deepcopy.go index 6584eeacddc97..a90b4ad0d12c6 100644 --- a/pkg/sql/plan/deepcopy.go +++ b/pkg/sql/plan/deepcopy.go @@ -18,6 +18,7 @@ import ( "bytes" "slices" + "github.com/gogo/protobuf/proto" "github.com/matrixorigin/matrixone/pkg/pb/plan" ) @@ -196,23 +197,34 @@ func DeepCopyRankOption(opt *plan.RankOption) *plan.RankOption { func DeepCopyNode(node *plan.Node) *plan.Node { newNode := &Node{ - NodeType: node.NodeType, - NodeId: node.NodeId, - ExtraOptions: node.ExtraOptions, - Children: slices.Clone(node.Children), - JoinType: node.JoinType, - IsRightJoin: node.IsRightJoin, - BindingTags: slices.Clone(node.BindingTags), - Limit: DeepCopyExpr(node.Limit), - Offset: DeepCopyExpr(node.Offset), - ProjectList: DeepCopyExprList(node.ProjectList), - OnList: DeepCopyExprList(node.OnList), - FilterList: DeepCopyExprList(node.FilterList), - BlockFilterList: DeepCopyExprList(node.BlockFilterList), - GroupBy: DeepCopyExprList(node.GroupBy), - GroupingFlag: slices.Clone(node.GroupingFlag), - AggList: DeepCopyExprList(node.AggList), - OrderBy: DeepCopyOrderBySpecList(node.OrderBy), + NodeType: node.NodeType, + NodeId: node.NodeId, + ExtraOptions: node.ExtraOptions, + Children: slices.Clone(node.Children), + JoinType: node.JoinType, + IsRightJoin: node.IsRightJoin, + BindingTags: slices.Clone(node.BindingTags), + Limit: DeepCopyExpr(node.Limit), + Offset: DeepCopyExpr(node.Offset), + ProjectList: DeepCopyExprList(node.ProjectList), + OnList: DeepCopyExprList(node.OnList), + FilterList: DeepCopyExprList(node.FilterList), + BlockFilterList: DeepCopyExprList(node.BlockFilterList), + GroupBy: DeepCopyExprList(node.GroupBy), + GroupingFlag: slices.Clone(node.GroupingFlag), + AggList: DeepCopyExprList(node.AggList), + OrderBy: DeepCopyOrderBySpecList(node.OrderBy), + Interval: DeepCopyExpr(node.Interval), + Sliding: DeepCopyExpr(node.Sliding), + Timestamp: DeepCopyExpr(node.Timestamp), + WEnd: DeepCopyExpr(node.WEnd), + FillType: node.FillType, + FillVal: DeepCopyExprList(node.FillVal), + GapFillMode: node.GapFillMode, + + TimeWindowPartitionBy: DeepCopyExprList(node.TimeWindowPartitionBy), + TimeWindowPartitionColPos: slices.Clone(node.TimeWindowPartitionColPos), + DeleteCtx: DeepCopyDeleteCtx(node.DeleteCtx), TblFuncExprList: DeepCopyExprList(node.TblFuncExprList), ClusterTable: DeepCopyClusterTable(node.GetClusterTable()), @@ -224,7 +236,7 @@ func DeepCopyNode(node *plan.Node) *plan.Node { LockTargets: make([]*plan.LockTarget, len(node.LockTargets)), AnalyzeInfo: DeepCopyAnalyzeInfo(node.AnalyzeInfo), IsEnd: node.IsEnd, - ExternScan: node.ExternScan, + ExternScan: deepCopyExternScan(node.ExternScan), SampleFunc: DeepCopySampleFuncSpec(node.SampleFunc), OnUpdateExprs: DeepCopyExprList(node.OnUpdateExprs), DedupColName: node.DedupColName, @@ -281,6 +293,13 @@ func DeepCopyNode(node *plan.Node) *plan.Node { return newNode } +func deepCopyExternScan(scan *plan.ExternScan) *plan.ExternScan { + if scan == nil { + return nil + } + return proto.Clone(scan).(*plan.ExternScan) +} + func DeepCopyIndexReaderParam(oldParam *plan.IndexReaderParam) *plan.IndexReaderParam { if oldParam == nil { return nil diff --git a/pkg/sql/plan/deepcopy_mongodb_test.go b/pkg/sql/plan/deepcopy_mongodb_test.go new file mode 100644 index 0000000000000..8d5b1f0b92b46 --- /dev/null +++ b/pkg/sql/plan/deepcopy_mongodb_test.go @@ -0,0 +1,58 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package plan + +import ( + "bytes" + "context" + "testing" + + "github.com/gogo/protobuf/proto" + pb "github.com/matrixorigin/matrixone/pkg/pb/plan" + "github.com/stretchr/testify/require" +) + +func TestMongoDBTableSurfaceFailsClosedWithoutRuntimeConfig(t *testing.T) { + require.Error(t, ensureMongoDBTableSurfaceEnabled(context.Background())) +} + +func TestMongoScanDeepCopyAndCredentialFreeProto(t *testing.T) { + original := &pb.Node{ExternScan: &pb.ExternScan{ + Type: int32(pb.ExternType_MONGODB_TB), + MongodbScan: &pb.MongoScan{ + TableId: 99, MappingId: 1, MappingVersion: 4, ConnectionId: 2, ConnectionVersion: 3, + Database: "telemetry", Collection: "events", ProjectedPaths: []string{"meta.device_id"}, + Columns: []*pb.MongoColumnMapping{{Name: "device_id", Path: "meta.device_id"}}, + PushedPredicate: &pb.MongoPredicate{Op: pb.MongoPredicateOp_MONGO_PREDICATE_EQUAL, Path: "meta.device_id", ValueBson: []byte{1, 2, 3}}, + }, + }} + copied := DeepCopyNode(original) + require.Equal(t, original.ExternScan, copied.ExternScan) + copied.ExternScan.MongodbScan.Columns[0].Path = "changed" + copied.ExternScan.MongodbScan.ProjectedPaths[0] = "changed" + copied.ExternScan.MongodbScan.PushedPredicate.ValueBson[0] = 9 + require.Equal(t, "meta.device_id", original.ExternScan.MongodbScan.Columns[0].Path) + require.Equal(t, "meta.device_id", original.ExternScan.MongodbScan.ProjectedPaths[0]) + require.Equal(t, byte(1), original.ExternScan.MongodbScan.PushedPredicate.ValueBson[0]) + + payload, err := proto.Marshal(original) + require.NoError(t, err) + for _, forbidden := range [][]byte{[]byte("mongodb://"), []byte("username"), []byte("password"), []byte("secret://")} { + require.False(t, bytes.Contains(bytes.ToLower(payload), forbidden)) + } + decoded := new(pb.Node) + require.NoError(t, proto.Unmarshal(payload, decoded)) + require.Equal(t, original, decoded) +} diff --git a/pkg/sql/plan/deepcopy_time_window_test.go b/pkg/sql/plan/deepcopy_time_window_test.go new file mode 100644 index 0000000000000..53e5fc64e5e09 --- /dev/null +++ b/pkg/sql/plan/deepcopy_time_window_test.go @@ -0,0 +1,117 @@ +// Copyright 2021 - 2022 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package plan + +import ( + "testing" + + "github.com/matrixorigin/matrixone/pkg/pb/plan" + "github.com/stretchr/testify/require" +) + +func twTestColExpr(relPos, colPos int32) *plan.Expr { + return &plan.Expr{ + Typ: plan.Type{Id: 1}, + Expr: &plan.Expr_Col{ + Col: &plan.ColRef{RelPos: relPos, ColPos: colPos}, + }, + } +} + +// DeepCopyNode historically skipped every TIME_WINDOW/FILL field, so copying a +// subtree silently dropped the window definition and partition metadata. This +// pins the round-trip: all fields survive, and mutating the copy cannot reach +// the original. +func TestDeepCopyNodeTimeWindowFields(t *testing.T) { + node := &plan.Node{ + NodeType: plan.Node_TIME_WINDOW, + Interval: twTestColExpr(1, 0), + Sliding: twTestColExpr(1, 1), + Timestamp: twTestColExpr(1, 2), + WEnd: twTestColExpr(1, 3), + FillType: plan.Node_PREV, + FillVal: []*plan.Expr{twTestColExpr(2, 0)}, + TimeWindowPartitionBy: []*plan.Expr{twTestColExpr(3, 0), twTestColExpr(3, 1)}, + } + + copied := DeepCopyNode(node) + + require.Equal(t, node.Interval, copied.Interval) + require.Equal(t, node.Sliding, copied.Sliding) + require.Equal(t, node.Timestamp, copied.Timestamp) + require.Equal(t, node.WEnd, copied.WEnd) + require.Equal(t, node.FillType, copied.FillType) + require.Equal(t, node.FillVal, copied.FillVal) + require.Equal(t, node.TimeWindowPartitionBy, copied.TimeWindowPartitionBy) + + // Deep, not shallow: the copy must not alias the original's expressions. + copied.TimeWindowPartitionBy[0].GetCol().ColPos = 99 + copied.WEnd.GetCol().ColPos = 99 + copied.FillVal[0].GetCol().ColPos = 99 + require.Equal(t, int32(0), node.TimeWindowPartitionBy[0].GetCol().ColPos) + require.Equal(t, int32(3), node.WEnd.GetCol().ColPos) + require.Equal(t, int32(0), node.FillVal[0].GetCol().ColPos) +} + +// twMarkVisitRule flags every expression it is offered, so a test can prove a +// node field is (or is not) reachable from the plan visitor. +type twMarkVisitRule struct { + seen map[*plan.Expr]bool +} + +func (r *twMarkVisitRule) MatchNode(*Node) bool { return false } +func (r *twMarkVisitRule) IsApplyExpr() bool { return true } +func (r *twMarkVisitRule) ApplyNode(*Node) error { return nil } +func (r *twMarkVisitRule) ApplyExpr(e *Expr) (*Expr, error) { + r.seen[e] = true + return e, nil +} + +// The plan visitor rewrites expressions in place (parameter binding, constant +// folding); a partition key it cannot reach would keep stale references. +func TestVisitPlanReachesTimeWindowPartitionBy(t *testing.T) { + partExpr := twTestColExpr(3, 0) + node := &plan.Node{ + NodeType: plan.Node_TIME_WINDOW, + TimeWindowPartitionBy: []*plan.Expr{partExpr}, + } + pl := &Plan{Plan: &plan.Plan_Query{Query: &Query{ + Steps: []int32{0}, + Nodes: []*plan.Node{node}, + }}} + + rule := &twMarkVisitRule{seen: make(map[*plan.Expr]bool)} + require.NoError(t, NewVisitPlan(pl, []VisitPlanRule{rule}).Visit(t.Context())) + require.True(t, rule.seen[partExpr], "partition keys must be visited") +} + +// replaceColumnsForNode rewrites column references when a projection is +// inlined; partition keys decide row grouping, so missing them would leave +// stale references behind. +func TestReplaceColumnsForNodeTimeWindowPartitionBy(t *testing.T) { + node := &plan.Node{ + NodeType: plan.Node_TIME_WINDOW, + TimeWindowPartitionBy: []*plan.Expr{twTestColExpr(5, 2)}, + } + projMap := map[[2]int32]*plan.Expr{ + {5, 2}: twTestColExpr(7, 4), + } + + replaceColumnsForNode(node, projMap) + + col := node.TimeWindowPartitionBy[0].GetCol() + require.Equal(t, int32(7), col.RelPos) + require.Equal(t, int32(4), col.ColPos) +} diff --git a/pkg/sql/plan/explain/explain_node.go b/pkg/sql/plan/explain/explain_node.go index 37b90dac52b4c..6beb785e06bc8 100644 --- a/pkg/sql/plan/explain/explain_node.go +++ b/pkg/sql/plan/explain/explain_node.go @@ -303,6 +303,26 @@ func (ndesc *NodeDescribeImpl) GetExtraInfo(ctx context.Context, options *Explai } lines = append(lines, icebergInfo) } + if ndesc.Node.NodeType == plan.Node_EXTERNAL_SCAN && + ndesc.Node.GetExternScan() != nil && ndesc.Node.GetExternScan().GetMongodbScan() != nil { + scan := ndesc.Node.GetExternScan().GetMongodbScan() + pushed := 0 + var countPredicate func(*plan.MongoPredicate) + countPredicate = func(predicate *plan.MongoPredicate) { + if predicate == nil { + return + } + if predicate.Op != plan.MongoPredicateOp_MONGO_PREDICATE_AND { + pushed++ + } + for _, child := range predicate.Children { + countPredicate(child) + } + } + countPredicate(scan.PushedPredicate) + lines = append(lines, fmt.Sprintf("MongoDB Scan: table=%d columns=%d pushed=%d residual=%s", + scan.TableId, len(scan.Columns), pushed, scan.ResidualFilterDigest)) + } // Get Sort list info if len(ndesc.Node.OrderBy) > 0 { @@ -348,6 +368,9 @@ func (ndesc *NodeDescribeImpl) GetExtraInfo(ctx context.Context, options *Explai } lines = append(lines, groupByInfo) } + if ndesc.Node.NodeType == plan.Node_TIME_WINDOW && ndesc.Node.GapFillMode == plan.Node_GAP_FILL_PARTITION { + lines = append(lines, "Gap Fill: Partition") + } if ndesc.Node.NodeType == plan.Node_FILL { fillCoslInfo, err := ndesc.GetFillColsInfo(ctx, options) diff --git a/pkg/sql/plan/explain/time_window_prune_test.go b/pkg/sql/plan/explain/time_window_prune_test.go new file mode 100644 index 0000000000000..14f94a2b3461b --- /dev/null +++ b/pkg/sql/plan/explain/time_window_prune_test.go @@ -0,0 +1,295 @@ +// Copyright 2021 - 2022 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package explain + +import ( + "testing" + + "github.com/matrixorigin/matrixone/pkg/pb/plan" + plan2 "github.com/matrixorigin/matrixone/pkg/sql/plan" + "github.com/stretchr/testify/require" +) + +// timeWindowNode returns the single TIME_WINDOW node of a built plan. +func timeWindowNode(t *testing.T, sql string) *plan.Node { + t.Helper() + logicPlan, err := buildOneStmt(plan2.NewMockOptimizer(false), t, sql) + require.NoError(t, err) + + var found *plan.Node + for _, node := range reachablePlanNodes(logicPlan.GetQuery()) { + if node.NodeType == plan.Node_TIME_WINDOW { + require.Nil(t, found, "expected exactly one TIME_WINDOW node") + found = node + } + } + require.NotNil(t, found) + return found +} + +func fillNode(t *testing.T, sql string) *plan.Node { + t.Helper() + logicPlan, err := buildOneStmt(plan2.NewMockOptimizer(false), t, sql) + require.NoError(t, err) + + for _, node := range reachablePlanNodes(logicPlan.GetQuery()) { + if node.NodeType == plan.Node_FILL { + return node + } + } + t.Fatal("no FILL node found") + return nil +} + +// projectedSlots lists the operator output positions a node's ProjectList +// reads, in projection order. +func projectedSlots(node *plan.Node) []int32 { + slots := make([]int32, 0, len(node.ProjectList)) + for _, expr := range node.ProjectList { + if col := expr.GetCol(); col != nil { + slots = append(slots, col.ColPos) + } + } + return slots +} + +const twTable = "constraint_test.t_on_update" + +// A TIME_WINDOW ProjectList addresses the operator's output batch, which is +// laid out from the (pruned) AggList. Every projected slot must therefore be +// inside the layout the operator will actually build. +func requireSlotsWithinLayout(t *testing.T, node *plan.Node) { + t.Helper() + layout := plan2.BuildTimeWindowLayout(node) + for _, slot := range projectedSlots(node) { + require.Less(t, slot, layout.ColCnt, + "projected slot %d is outside the operator's %d output columns", slot, layout.ColCnt) + } +} + +func TestTimeWindowPruneOperatorShape(t *testing.T) { + t.Run("discarded aggregates are pruned and slots compact", func(t *testing.T) { + // Only min(val) survives, so it must move to slot 0 rather than keep + // max(val)'s original position. Reading slot 0 while max(val) still + // occupied it returned max's values under the min alias. + node := timeWindowNode(t, + "select c from (select _wstart as a, max(val) as b, min(val) as c from "+twTable+ + " interval(updated_at, 5, second)) x") + + require.Len(t, node.AggList, 1) + require.Equal(t, "min", node.AggList[0].GetF().Func.ObjName) + require.Equal(t, []int32{0}, projectedSlots(node)) + requireSlotsWithinLayout(t, node) + }) + + t.Run("boundary output survives when aggregates are pruned", func(t *testing.T) { + // _wstart is the only consumed output; it must be addressed at the + // boundary slot, not at slot 0 where an aggregate used to sit. + node := timeWindowNode(t, + "select a from (select _wstart as a, max(val) as b, min(val) as c from "+twTable+ + " interval(updated_at, 5, second)) x") + + require.Len(t, node.AggList, 1) + layout := plan2.BuildTimeWindowLayout(node) + require.Equal(t, []int32{layout.WStartSlot}, projectedSlots(node)) + requireSlotsWithinLayout(t, node) + }) + + t.Run("wend survives when wstart is pruned", func(t *testing.T) { + // Pruning _wstart must not abandon the rest of the remapping: _wend + // used to be skipped entirely, leaving the parent unable to resolve it. + node := timeWindowNode(t, + "select d from (select _wstart as a, _wend as d, max(val) as b from "+twTable+ + " interval(updated_at, 5, second)) x") + + require.Len(t, node.AggList, 1) + layout := plan2.BuildTimeWindowLayout(node) + require.Equal(t, plan2.TimeWindowSlotNone, layout.WStartSlot) + require.Equal(t, []int32{layout.WEndSlot}, projectedSlots(node)) + requireSlotsWithinLayout(t, node) + }) + + t.Run("aggregates stay a prefix ahead of the boundaries", func(t *testing.T) { + node := timeWindowNode(t, + "select _wstart, _wend, max(val) from "+twTable+ + " interval(updated_at, 10, minute) sliding(5, minute)") + + // Projection order must be [aggregate, _wstart, _wend]: FILL and the + // operator both read this batch positionally. + require.Equal(t, []int32{0, 1, 2}, projectedSlots(node)) + requireSlotsWithinLayout(t, node) + }) + + t.Run("everything discarded keeps a boundary row carrier", func(t *testing.T) { + // The window count is still the row count, and the operator sizes its + // batch off Vecs[0], so one column has to survive -- preferably the + // boundary, which runs no aggregate. + node := timeWindowNode(t, + "select 1 from (select _wstart as a, max(val) as b from "+twTable+ + " interval(updated_at, 5, second)) x") + + require.Len(t, node.AggList, 1) + isBoundary := node.AggList[0].GetCol() != nil + require.True(t, isBoundary, "expected the boundary to be kept as the carrier") + layout := plan2.BuildTimeWindowLayout(node) + require.Equal(t, int32(1), layout.ColCnt) + }) + + t.Run("everything discarded without a boundary keeps an aggregate carrier", func(t *testing.T) { + node := timeWindowNode(t, + "select 1 from (select max(val) as b from "+twTable+ + " interval(updated_at, 5, second)) x") + + require.Len(t, node.AggList, 1) + layout := plan2.BuildTimeWindowLayout(node) + require.Equal(t, int32(1), layout.ColCnt) + }) + + t.Run("pruning a window aggregate keeps its side effect running below", func(t *testing.T) { + // The binder rewrites a time-window aggregate's argument to a plain + // reference to the child AGG's result, so sleep(0) lives in the AGG + // node. Pruning max(...) here is safe only because AGG retains a + // side-effecting aggregate regardless of who reads it. + sql := "select a from (select _wstart as a, max(sleep(0)) as b from " + twTable + + " interval(updated_at, 5, second)) x" + + tw := timeWindowNode(t, sql) + require.Len(t, tw.AggList, 1, "the window's max(col) reference itself is inert and prunable") + requireSlotsWithinLayout(t, tw) + + logicPlan, err := buildOneStmt(plan2.NewMockOptimizer(false), t, sql) + require.NoError(t, err) + aggFound := false + for _, node := range reachablePlanNodes(logicPlan.GetQuery()) { + if node.NodeType != plan.Node_AGG { + continue + } + aggFound = true + require.Len(t, node.AggList, 1, "the side-effecting aggregate must survive") + } + require.True(t, aggFound, "the sleep(0) call must still be evaluated somewhere") + }) + + t.Run("fill columns are pruned in lockstep with the window", func(t *testing.T) { + // constructFill derives ColLen from this AggList and the operator fills + // Vecs[0..ColLen) of the window's projected batch. If the window drops + // max(val) but FILL still claims two columns, it runs off the batch. + sql := "select c from (select _wstart as a, _wend as d, max(val) as b, min(val) as c from " + + twTable + " interval(updated_at, 5, second) fill(prev)) x" + + tw := timeWindowNode(t, sql) + fill := fillNode(t, sql) + + require.Len(t, tw.AggList, 1) + require.Len(t, fill.AggList, 1) + require.Equal(t, "min", fill.AggList[0].GetF().Func.ObjName) + + // FILL's ColLen must not exceed the aggregate prefix the window emits. + layout := plan2.BuildTimeWindowLayout(tw) + require.LessOrEqual(t, len(fill.AggList), len(layout.AggIdx)) + requireSlotsWithinLayout(t, tw) + }) + + t.Run("fill(linear) values are pruned with their columns", func(t *testing.T) { + // fill(linear) builds FillVal out of references to the window's + // aggregates. Counting those references as consumers would keep every + // aggregate alive and defeat pruning entirely. + sql := "select c from (select _wstart as a, max(val) as b, min(val) as c from " + + twTable + " interval(updated_at, 5, second) fill(linear)) x" + + tw := timeWindowNode(t, sql) + fill := fillNode(t, sql) + + require.Len(t, tw.AggList, 1) + require.Len(t, fill.AggList, 1) + require.Len(t, fill.FillVal, 1) + }) +} + +func TestTimeWindowPartitionShape(t *testing.T) { + t.Run("gapfill row count keeps timestamp and partition input slots aligned", func(t *testing.T) { + // The MongoDB E2E query has this shape: an outer row count discards all + // subquery outputs while GAPFILL still needs both the partition key and + // timestamp. If pruning remaps those inputs independently, TimeWin can + // read the integer partition vector as a datetime and panic. + logicPlan, err := buildOneStmt(plan2.NewMockOptimizer(false), t, + "select count(*) from (select _wstart, id, max(val) from "+twTable+ + " group by id interval(updated_at, 1, minute) gapfill(partition) fill(null)) x") + require.NoError(t, err) + + var node *plan.Node + query := logicPlan.GetQuery() + for _, candidate := range reachablePlanNodes(query) { + if candidate.NodeType == plan.Node_TIME_WINDOW { + node = candidate + break + } + } + require.NotNil(t, node) + require.Equal(t, plan.Node_GAP_FILL_PARTITION, node.GapFillMode) + require.Len(t, node.TimeWindowPartitionBy, 1) + require.Len(t, node.GroupBy, 1) + requireSlotsWithinLayout(t, node) + + child := query.Nodes[node.Children[0]] + tsCol := node.GroupBy[0].GetCol() + require.NotNil(t, tsCol) + require.Less(t, int(tsCol.ColPos), len(child.ProjectList)) + require.Equal(t, node.GroupBy[0].Typ.Id, child.ProjectList[tsCol.ColPos].Typ.Id) + + partitionCol := node.TimeWindowPartitionBy[0].GetCol() + require.NotNil(t, partitionCol) + require.Less(t, int(partitionCol.ColPos), len(child.ProjectList)) + require.Equal(t, node.TimeWindowPartitionBy[0].Typ.Id, child.ProjectList[partitionCol.ColPos].Typ.Id) + require.NotEqual(t, tsCol.ColPos, partitionCol.ColPos) + }) + + t.Run("group by keys become partition keys ordered ahead of the timestamp", func(t *testing.T) { + node := timeWindowNode(t, + "select _wstart, id, max(val) from "+twTable+" group by id interval(updated_at, 5, second)") + + require.Len(t, node.TimeWindowPartitionBy, 1) + // The operator finds boundaries by watching consecutive rows, so the + // partition key has to sort ahead of the window's timestamp. + require.Len(t, node.OrderBy, 2) + requireSlotsWithinLayout(t, node) + + // The partition key is carried in the tail slots, leaving the + // aggregates a prefix. + layout := plan2.BuildTimeWindowLayout(node) + require.Equal(t, []int32{2}, layout.PartitionSlot) + require.Equal(t, int32(3), layout.ColCnt) + }) + + t.Run("partition keys survive even when the outer query discards them", func(t *testing.T) { + // Dropping a partition key would merge groups that must stay apart, so + // it is retained for grouping even with its output unused. + node := timeWindowNode(t, + "select b from (select _wstart as a, id, max(val) as b from "+twTable+ + " group by id interval(updated_at, 5, second)) x") + + require.Len(t, node.TimeWindowPartitionBy, 1) + requireSlotsWithinLayout(t, node) + }) + + t.Run("no group by means no partitioning", func(t *testing.T) { + node := timeWindowNode(t, + "select _wstart, max(val) from "+twTable+" interval(updated_at, 5, second)") + + require.Empty(t, node.TimeWindowPartitionBy) + require.Len(t, node.OrderBy, 1) + requireSlotsWithinLayout(t, node) + }) +} diff --git a/pkg/sql/plan/function/function_id.go b/pkg/sql/plan/function/function_id.go index 5d9121ae70a25..b628fe79ce169 100644 --- a/pkg/sql/plan/function/function_id.go +++ b/pkg/sql/plan/function/function_id.go @@ -769,9 +769,12 @@ const ( JSON_MERGE_PATCH = 547 JSON_MERGE_PRESERVE = 548 + MAX_BY = 559 + MAX_BY_NON_NULL = 560 + // FUNCTION_END_NUMBER is not a function, just a flag to record the max number of function. // TODO: every one should put the new function id in front of this one if you want to make a new function. - FUNCTION_END_NUMBER = 549 + FUNCTION_END_NUMBER = 561 ) // functionIdRegister is what function we have registered already. @@ -866,6 +869,8 @@ var functionIdRegister = map[string]int32{ "hll_merge_agg": HLL_MERGE_AGG, "any_value": ANY_VALUE, "median": MEDIAN, + "max_by": MAX_BY, + "max_by_non_null": MAX_BY_NON_NULL, // count window "rank": RANK, "row_number": ROW_NUMBER, diff --git a/pkg/sql/plan/function/function_id_test.go b/pkg/sql/plan/function/function_id_test.go index a4a92f5008981..c0b25328f3e7c 100644 --- a/pkg/sql/plan/function/function_id_test.go +++ b/pkg/sql/plan/function/function_id_test.go @@ -602,10 +602,11 @@ var predefinedFunids = map[int]int{ INTERNAL_JSON_ORDERING_PARAM: 546, JSON_MERGE_PATCH: 547, JSON_MERGE_PRESERVE: 548, - + MAX_BY: 559, + MAX_BY_NON_NULL: 560, // FUNCTION_END_NUMBER is not a function, just a flag to record the max number of function. // TODO: every one should put the new function id in front of this one if you want to make a new function. - FUNCTION_END_NUMBER: 549, + FUNCTION_END_NUMBER: 561, } func Test_funids(t *testing.T) { diff --git a/pkg/sql/plan/function/list_agg.go b/pkg/sql/plan/function/list_agg.go index 0c4c5c6b2f04c..4293b33f4db69 100644 --- a/pkg/sql/plan/function/list_agg.go +++ b/pkg/sql/plan/function/list_agg.go @@ -695,6 +695,72 @@ var supportedAggInNewFramework = []FuncNew{ }, }, }, + { + functionId: MAX_BY, + class: plan.Function_AGG, + layout: STANDARD_FUNCTION, + checkFn: maxByTypeCheck, + Overloads: []overload{{ + overloadId: 0, + isAgg: true, + retType: ReturnFirstArgType, + aggFramework: aggregationLogicOfOverload{ + str: "max_by", + aggRegister: aggexec.RegisterMaxBy, + }, + }}, + }, + { + functionId: MAX_BY_NON_NULL, + class: plan.Function_AGG, + layout: STANDARD_FUNCTION, + checkFn: maxByTypeCheck, + Overloads: []overload{{ + overloadId: 0, + isAgg: true, + retType: ReturnFirstArgType, + aggFramework: aggregationLogicOfOverload{ + str: "max_by_non_null", + aggRegister: aggexec.RegisterMaxByNonNull, + }, + }}, + }, +} + +func maxByTypeCheck(_ []overload, inputs []types.Type) checkResult { + if len(inputs) != 3 { + return newCheckResultWithFailure(failedAggParametersWrong) + } + casts := append([]types.Type(nil), inputs...) + needCast := false + for i := range casts { + if casts[i].Oid == types.T_any { + needCast = true + if i == 0 { + casts[i] = types.T_varchar.ToType() + } else { + casts[i] = types.T_int64.ToType() + } + } + } + if !typeInList(casts[0].Oid, AnyValueSupportedTypes) || + !typeInList(casts[1].Oid, MinMaxSupportedTypes) || + !typeInList(casts[2].Oid, MinMaxSupportedTypes) { + return newCheckResultWithFailure(failedAggParametersWrong) + } + if needCast { + return newCheckResultWithCast(0, casts) + } + return newCheckResultWithSuccess(0) +} + +func typeInList(typ types.T, supported []types.T) bool { + for _, candidate := range supported { + if typ == candidate { + return true + } + } + return false } var SumSupportedTypes = []types.T{ diff --git a/pkg/sql/plan/having_binder.go b/pkg/sql/plan/having_binder.go index 7600e9b30542b..8b6ab46242838 100644 --- a/pkg/sql/plan/having_binder.go +++ b/pkg/sql/plan/having_binder.go @@ -266,6 +266,15 @@ func (b *HavingBinder) remapAggToTimeWindowCacheAgg(expr *Expr) (*Expr, error) { expr.Typ.Id = int32(fGet.GetReturnType().Oid) expr.Typ.Width = fGet.GetReturnType().Width expr.Typ.Scale = fGet.GetReturnType().Scale + case function.MAX_BY, function.MAX_BY_NON_NULL: + if b.ctx == nil || !b.ctx.explicitSliding { + return expr, nil + } + // A sliding window combines winners from several child buckets. The + // value alone is not a mergeable max_by state because its order/tie + // columns have already been consumed by the child aggregate. Refuse the + // query until a typed cache/result pair (like AVG_TW_*) is available. + return nil, moerr.NewNotSupported(b.GetContext(), "max_by aggregates in a sliding time window") } return expr, nil } @@ -287,7 +296,11 @@ func (b *HavingBinder) remapAggToTimeWindowResultAgg(expr *Expr) (*Expr, error) expr.Typ.Id = int32(fGet.GetReturnType().Oid) expr.Typ.Width = fGet.GetReturnType().Width expr.Typ.Scale = fGet.GetReturnType().Scale - case function.COUNT: + case function.COUNT, function.STARCOUNT: + // COUNT(*) is bound as STARCOUNT in the child Aggregate. A GAPFILL + // tumbling window consumes one partial row per existing bucket, so the + // second stage must merge that partial count instead of counting the + // partial row itself (which would return 1 for every non-empty bucket). fGet, err := function.GetFunctionByName(b.GetContext(), "sum", []types.Type{types.T_int64.ToType()}) if err != nil { return nil, err @@ -308,6 +321,23 @@ func (b *HavingBinder) remapAggToTimeWindowResultAgg(expr *Expr) (*Expr, error) expr.Typ.Id = int32(fGet.GetReturnType().Oid) expr.Typ.Width = fGet.GetReturnType().Width expr.Typ.Scale = fGet.GetReturnType().Scale + case function.MAX_BY, function.MAX_BY_NON_NULL: + // For a tumbling window the child Aggregate has already produced exactly + // one fully merged winner for each (partition, bucket). TimeWin either + // forwards that row or runs the GAPFILL state machine over that one row, + // so the outer aggregate is an identity operation. Retaining max_by here + // would construct a one-argument max_by and fail during Prepare. + arg := expr.GetF().Args[0] + typ := types.New(types.T(arg.Typ.Id), arg.Typ.Width, arg.Typ.Scale) + fGet, err := function.GetFunctionByName(b.GetContext(), "any_value", []types.Type{typ}) + if err != nil { + return nil, err + } + obj.Obj = fGet.GetEncodedOverloadID() + obj.ObjName = "any_value" + expr.Typ.Id = int32(fGet.GetReturnType().Oid) + expr.Typ.Width = fGet.GetReturnType().Width + expr.Typ.Scale = fGet.GetReturnType().Scale } return expr, nil } diff --git a/pkg/sql/plan/having_binder_test.go b/pkg/sql/plan/having_binder_test.go index ae8edabc5b61d..44f8ce4841b38 100644 --- a/pkg/sql/plan/having_binder_test.go +++ b/pkg/sql/plan/having_binder_test.go @@ -53,29 +53,90 @@ func TestRemapAggToTimeWindowResultAggUsesRegularSumForPartialSums(t *testing.T) } func TestRemapAggToTimeWindowResultAggUsesRegularSumForCountCache(t *testing.T) { - countFn, err := function.GetFunctionByName(context.Background(), "count", []types.Type{types.T_int64.ToType()}) - require.NoError(t, err) + for _, name := range []string{"count", "starcount"} { + t.Run(name, func(t *testing.T) { + countFn, err := function.GetFunctionByName(context.Background(), name, []types.Type{types.T_int64.ToType()}) + require.NoError(t, err) - expr := &plan.Expr{ - Typ: plan.Type{Id: int32(types.T_int64), Width: 64}, - Expr: &plan.Expr_F{ - F: &plan.Function{ - Func: &plan.ObjectRef{ - Obj: countFn.GetEncodedOverloadID(), - ObjName: "count", + expr := &plan.Expr{ + Typ: plan.Type{Id: int32(types.T_int64), Width: 64}, + Expr: &plan.Expr_F{ + F: &plan.Function{ + Func: &plan.ObjectRef{ + Obj: countFn.GetEncodedOverloadID(), + ObjName: name, + }, + Args: []*plan.Expr{{ + Typ: plan.Type{Id: int32(types.T_int64), Width: 64}, + }}, + }, }, - Args: []*plan.Expr{{ - Typ: plan.Type{Id: int32(types.T_int64), Width: 64}, + } + + got, err := (&HavingBinder{baseBinder: baseBinder{sysCtx: context.Background()}}).remapAggToTimeWindowResultAgg(expr) + require.NoError(t, err) + require.Equal(t, "sum", got.Expr.(*plan.Expr_F).F.Func.ObjName) + require.Equal(t, int32(types.T_decimal128), got.Typ.Id) + require.Equal(t, int32(0), got.Typ.Scale) + }) + } +} + +func TestRemapMaxByToTimeWindowIdentity(t *testing.T) { + for _, tc := range []struct { + name string + id int32 + }{ + {name: "max_by", id: function.MAX_BY}, + {name: "max_by_non_null", id: function.MAX_BY_NON_NULL}, + } { + t.Run(tc.name, func(t *testing.T) { + valueType := types.New(types.T_varchar, 42, 0) + expr := &plan.Expr{ + Typ: makePlan2Type(&valueType), + Expr: &plan.Expr_F{F: &plan.Function{ + Func: &plan.ObjectRef{Obj: function.EncodeOverloadID(tc.id, 0), ObjName: tc.name}, + Args: []*plan.Expr{{Typ: makePlan2Type(&valueType)}}, }}, - }, - }, + } + + got, err := (&HavingBinder{baseBinder: baseBinder{sysCtx: context.Background()}}).remapAggToTimeWindowResultAgg(expr) + require.NoError(t, err) + require.Equal(t, "any_value", got.GetF().Func.ObjName) + require.Equal(t, makePlan2Type(&valueType), got.Typ) + }) } +} + +func TestSlidingTimeWindowRejectsMaxByWithoutMergeableCache(t *testing.T) { + valueType := types.T_varchar.ToType() + expr := &plan.Expr{ + Typ: makePlan2Type(&valueType), + Expr: &plan.Expr_F{F: &plan.Function{ + Func: &plan.ObjectRef{Obj: function.EncodeOverloadID(function.MAX_BY, 0), ObjName: "max_by"}, + }}, + } + + ctx := NewBindContext(nil, nil) + ctx.explicitSliding = true + _, err := (&HavingBinder{baseBinder: baseBinder{sysCtx: context.Background(), ctx: ctx}}).remapAggToTimeWindowCacheAgg(expr) + require.ErrorContains(t, err, "sliding time window") +} + +func TestGapFillTimeWindowKeepsMaxByChildAggregate(t *testing.T) { + valueType := types.T_varchar.ToType() + expr := &plan.Expr{ + Typ: makePlan2Type(&valueType), + Expr: &plan.Expr_F{F: &plan.Function{ + Func: &plan.ObjectRef{Obj: function.EncodeOverloadID(function.MAX_BY, 0), ObjName: "max_by"}, + }}, + } + ctx := NewBindContext(nil, nil) + ctx.sliding = true - got, err := (&HavingBinder{baseBinder: baseBinder{sysCtx: context.Background()}}).remapAggToTimeWindowResultAgg(expr) + got, err := (&HavingBinder{baseBinder: baseBinder{sysCtx: context.Background(), ctx: ctx}}).remapAggToTimeWindowCacheAgg(expr) require.NoError(t, err) - require.Equal(t, "sum", got.Expr.(*plan.Expr_F).F.Func.ObjName) - require.Equal(t, int32(types.T_decimal128), got.Typ.Id) - require.Equal(t, int32(0), got.Typ.Scale) + require.Equal(t, "max_by", got.GetF().Func.ObjName) } func TestBindTimeWindowFuncCastsCountProjectionAfterDecimalCache(t *testing.T) { diff --git a/pkg/sql/plan/mongodb_util.go b/pkg/sql/plan/mongodb_util.go new file mode 100644 index 0000000000000..43c3902d65912 --- /dev/null +++ b/pkg/sql/plan/mongodb_util.go @@ -0,0 +1,64 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package plan + +import ( + "context" + + "github.com/matrixorigin/matrixone/pkg/catalog" + "github.com/matrixorigin/matrixone/pkg/common/moerr" + "github.com/matrixorigin/matrixone/pkg/config" + "github.com/matrixorigin/matrixone/pkg/defines" + sqlmongodb "github.com/matrixorigin/matrixone/pkg/sql/mongodb" +) + +func ensureMongoDBTableSurfaceEnabled(ctx context.Context) error { + value := ctx.Value(config.ParameterUnitKey) + pu, _ := value.(*config.ParameterUnit) + if pu == nil || pu.SV == nil { + return moerr.NewNotSupported(ctx, "MongoDB external tables are disabled because runtime configuration is unavailable") + } + parameters := pu.SV.MongoDB + if !parameters.Enable { + return moerr.NewNotSupported(ctx, "MongoDB external tables are disabled") + } + if !parameters.EnablePerAccount { + return nil + } + accountID, err := defines.GetAccountId(ctx) + if err != nil { + return err + } + if accountID == 0 { + return nil + } + for _, allowed := range parameters.AllowedAccounts { + if allowed == accountID { + return nil + } + } + return moerr.NewNotSupported(ctx, "MongoDB external tables are disabled for this account") +} + +func IsMongoDBTableDef(ctx context.Context, tableDef *TableDef) (bool, error) { + if tableDef == nil || tableDef.TableType != catalog.SystemExternalRel { + return false, nil + } + _, found, err := sqlmongodb.ParseCreateSQLEnvelope(ctx, tableDef.Createsql) + if err != nil { + return false, err + } + return found, nil +} diff --git a/pkg/sql/plan/opt_misc.go b/pkg/sql/plan/opt_misc.go index 7665a52022a31..ad018e74770e2 100644 --- a/pkg/sql/plan/opt_misc.go +++ b/pkg/sql/plan/opt_misc.go @@ -272,6 +272,7 @@ func replaceColumnsForNode(node *plan.Node, projMap map[[2]int32]*plan.Expr) { replaceColumnsForExprList(node.GroupBy, projMap) replaceColumnsForExprList(node.AggList, projMap) replaceColumnsForExprList(node.WinSpecList, projMap) + replaceColumnsForExprList(node.TimeWindowPartitionBy, projMap) for i := range node.OrderBy { node.OrderBy[i].Expr = replaceColumnsForExpr(node.OrderBy[i].Expr, projMap) diff --git a/pkg/sql/plan/query_builder.go b/pkg/sql/plan/query_builder.go index c5c481ca327be..e304a18c106ac 100644 --- a/pkg/sql/plan/query_builder.go +++ b/pkg/sql/plan/query_builder.go @@ -33,6 +33,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/pb/plan" "github.com/matrixorigin/matrixone/pkg/pb/timestamp" sqliceberg "github.com/matrixorigin/matrixone/pkg/sql/iceberg" + sqlmongodb "github.com/matrixorigin/matrixone/pkg/sql/mongodb" "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect" "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect/mysql" "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" @@ -853,6 +854,10 @@ func (builder *QueryBuilder) remapAllColRefs(nodeID int32, step int32, colRefCnt }) } + if err := builder.refreshMongoScanPushdown(node); err != nil { + return nil, err + } + case plan.Node_INTERSECT, plan.Node_INTERSECT_ALL, plan.Node_UNION, plan.Node_UNION_ALL, plan.Node_MINUS, plan.Node_MINUS_ALL: @@ -1500,126 +1505,171 @@ func (builder *QueryBuilder) remapAllColRefs(nodeID int32, step int32, colRefCnt } case plan.Node_TIME_WINDOW: - for _, expr := range node.AggList { + timeTag := node.BindingTags[0] + + // Decide what survives before touching colRefCnt: a `_wstart`/`_wend` + // entry of AggList is a column reference to its own {timeTag, k}, so + // counting the AggList as a consumer would make every boundary look + // referenced by itself. + retained := make([]bool, len(node.AggList)) + anyRetained := false + for k, expr := range node.AggList { + if colRefCnt[[2]int32{timeTag, int32(k)}] > 0 || !exprCanRemoveProject(expr) { + retained[k] = true + anyRetained = true + } + } + // calRes sizes the output off Vecs[0], so the operator cannot emit a + // zero-column batch, and the window count is the row count an outer + // constant projection still depends on. Keep one carrier: a boundary + // first, since it runs no aggregate. + if !anyRetained && len(node.AggList) > 0 { + carrier := 0 + for k, expr := range node.AggList { + if isBoundary, _ := isTimeWindowBoundary(expr); isBoundary { + carrier = k + break + } + } + retained[carrier] = true + } + + // The partition keys decide which rows share a window, so they are + // never pruned: dropping one would merge groups that must stay apart. + // Record where each one came from before remapping rewrites it to a + // child-local reference. + partitionSrc := make([]int32, len(node.TimeWindowPartitionBy)) + for p, expr := range node.TimeWindowPartitionBy { + partitionSrc[p] = -1 + if col := expr.GetCol(); col != nil { + partitionSrc[p] = col.ColPos + } + } + + // Only retained aggregates consume child columns. Withholding the + // pruned ones here is what lets the child AGG drop their inputs too. + for k, expr := range node.AggList { + if isBoundary, _ := isTimeWindowBoundary(expr); isBoundary || !retained[k] { + continue + } + increaseRefCnt(expr, 1, colRefCnt) + } + increaseRefCnt(node.GroupBy[0], 1, colRefCnt) + for _, orderBy := range node.OrderBy { + increaseRefCnt(orderBy.Expr, 1, colRefCnt) + } + for _, expr := range node.TimeWindowPartitionBy { increaseRefCnt(expr, 1, colRefCnt) } - increaseRefCnt(node.OrderBy[0].Expr, 1, colRefCnt) childRemapping, err := builder.remapAllColRefs(node.Children[0], step, colRefCnt, colRefBool, sinkColRef) if err != nil { return nil, err } - timeTag := node.BindingTags[0] - groupTag := node.BindingTags[1] - - // order by - idx := 0 - increaseRefCnt(node.OrderBy[0].Expr, -1, colRefCnt) - remapInfo.tip = "OrderBy[0].Expr" + increaseRefCnt(node.GroupBy[0], -1, colRefCnt) + remapInfo.tip = "GroupBy[0]" remapInfo.srcExprIdx = 0 - err = builder.remapColRefForExpr(node.OrderBy[0].Expr, childRemapping.globalToLocal, &remapInfo) + err = builder.remapColRefForExpr(node.GroupBy[0], childRemapping.globalToLocal, &remapInfo) if err != nil { return nil, err } - globalRef := [2]int32{groupTag, int32(0)} - if colRefCnt[globalRef] != 0 { - remapping.addColRef(globalRef) - node.ProjectList = append(node.ProjectList, &plan.Expr{ - Typ: node.OrderBy[0].Expr.Typ, - Expr: &plan.Expr_Col{ - Col: &ColRef{ - RelPos: -1, - ColPos: int32(idx), - Name: builder.nameByColRef[globalRef], - }, - }, - }) - idx++ + remapInfo.tip = "OrderBy" + for idx, orderBy := range node.OrderBy { + increaseRefCnt(orderBy.Expr, -1, colRefCnt) + remapInfo.srcExprIdx = idx + err = builder.remapColRefForExpr(orderBy.Expr, childRemapping.globalToLocal, &remapInfo) + if err != nil { + return nil, err + } } - var wstart, wend *plan.Expr - var i, j int - remapInfo.tip = "AggList" - for k, expr := range node.AggList { - if e, ok := expr.Expr.(*plan.Expr_Col); ok { - if e.Col.Name == TimeWindowStart { - wstart = expr - i = k - } - if e.Col.Name == TimeWindowEnd { - wend = expr - j = k - } - continue - } + remapInfo.tip = "TimeWindowPartitionBy" + for idx, expr := range node.TimeWindowPartitionBy { increaseRefCnt(expr, -1, colRefCnt) - remapInfo.srcExprIdx = k + remapInfo.srcExprIdx = idx err = builder.remapColRefForExpr(expr, childRemapping.globalToLocal, &remapInfo) if err != nil { return nil, err } + } - globalRef := [2]int32{timeTag, int32(k)} - if colRefCnt[globalRef] == 0 { + remapInfo.tip = "AggList" + newAggList := make([]*plan.Expr, 0, len(node.AggList)) + // The outer query still addresses these values by their original + // AggList position, so keep the compacted index's origin. + newToOld := make([]int32, 0, len(node.AggList)) + for k, expr := range node.AggList { + if !retained[k] { continue } - - remapping.addColRef(globalRef) - - node.ProjectList = append(node.ProjectList, &plan.Expr{ - Typ: expr.Typ, - Expr: &plan.Expr_Col{ - Col: &ColRef{ - RelPos: -1, - ColPos: int32(idx), - Name: builder.nameByColRef[globalRef], - }, - }, - }) - idx++ - } - - if wstart != nil { - increaseRefCnt(wstart, -1, colRefCnt) - - globalRef := [2]int32{timeTag, int32(i)} - if colRefCnt[globalRef] == 0 { - break + if isBoundary, _ := isTimeWindowBoundary(expr); !isBoundary { + increaseRefCnt(expr, -1, colRefCnt) + remapInfo.srcExprIdx = k + err = builder.remapColRefForExpr(expr, childRemapping.globalToLocal, &remapInfo) + if err != nil { + return nil, err + } } + newAggList = append(newAggList, expr) + newToOld = append(newToOld, int32(k)) + } + node.AggList = newAggList - remapping.addColRef(globalRef) + // Address slots through the same layout the operator is built from, + // and emit in slot order so the aggregates stay a prefix -- FILL reads + // this projection positionally. + layout := BuildTimeWindowLayout(node) + for slot := int32(0); slot < layout.ColCnt; slot++ { + for k, expr := range node.AggList { + if layout.Slot[k] != slot { + continue + } + globalRef := [2]int32{timeTag, newToOld[k]} + if colRefCnt[globalRef] == 0 { + continue + } + remapping.addColRef(globalRef) - node.ProjectList = append(node.ProjectList, &plan.Expr{ - Typ: node.Timestamp.Typ, - Expr: &plan.Expr_Col{ - Col: &ColRef{ - RelPos: -1, - ColPos: int32(idx), - Name: builder.nameByColRef[globalRef], + typ := expr.Typ + if isBoundary, _ := isTimeWindowBoundary(expr); isBoundary { + typ = node.Timestamp.Typ + } + node.ProjectList = append(node.ProjectList, &plan.Expr{ + Typ: typ, + Expr: &plan.Expr_Col{ + Col: &ColRef{ + RelPos: -1, + ColPos: slot, + Name: builder.nameByColRef[globalRef], + }, }, - }, - }) - idx++ + }) + } } - if wend != nil { - increaseRefCnt(wend, -1, colRefCnt) - - globalRef := [2]int32{timeTag, int32(j)} + // Partition keys are carried through so a GROUP BY column stays + // selectable next to the window's aggregates. The operator always + // evaluates them to find its boundaries, so only their output is + // optional. + groupTag := node.BindingTags[1] + for p, slot := range layout.PartitionSlot { + if partitionSrc[p] < 0 { + continue + } + globalRef := [2]int32{groupTag, partitionSrc[p]} if colRefCnt[globalRef] == 0 { - break + continue } - remapping.addColRef(globalRef) node.ProjectList = append(node.ProjectList, &plan.Expr{ - Typ: node.Timestamp.Typ, + Typ: node.TimeWindowPartitionBy[p].Typ, Expr: &plan.Expr_Col{ Col: &ColRef{ RelPos: -1, - ColPos: int32(idx), + ColPos: slot, Name: builder.nameByColRef[globalRef], }, }, @@ -1786,6 +1836,76 @@ func (builder *QueryBuilder) remapAllColRefs(nodeID int32, step int32, colRefCnt case plan.Node_FILL: + // The fill operator addresses its input positionally: it fills + // Vecs[0..ColLen), which must line up with the aggregates the child + // TIME_WINDOW projects. That child prunes the aggregates the outer + // query does not reference, so drop the matching fill columns here or + // the operator walks off the end of the batch. + // + // The decision has to be made before the FillVal refcounts below, + // because fill(linear) builds its FillVal out of references to those + // very aggregates and would otherwise keep every one of them alive. + var sideEffectRefs [][2]int32 + // fill(prev/next/linear) must not carry values across a partition + // boundary, so the operator needs the partition keys in its input. + // Force the child window to project them -- the count is dropped after + // the child is remapped, exactly like the side-effect refs below -- and + // resolve their positions once the child's projection exists. + var fillPartitionRefs [][2]int32 + child := builder.qry.Nodes[node.Children[0]] + fillNeedsPartitions := node.FillType == plan.Node_PREV || + node.FillType == plan.Node_NEXT || node.FillType == plan.Node_LINEAR + if child.NodeType == plan.Node_TIME_WINDOW && len(child.TimeWindowPartitionBy) > 0 && fillNeedsPartitions { + childGroupTag := child.BindingTags[1] + for _, expr := range child.TimeWindowPartitionBy { + if col := expr.GetCol(); col != nil { + ref := [2]int32{childGroupTag, col.ColPos} + colRefCnt[ref]++ + fillPartitionRefs = append(fillPartitionRefs, ref) + } + } + } + if child.NodeType == plan.Node_TIME_WINDOW && len(node.AggList) > 0 { + timeTag := child.BindingTags[0] + childLayout := BuildTimeWindowLayout(child) + + newAggList := node.AggList[:0] + newFillVal := node.FillVal[:0] + for i := range node.AggList { + if i >= len(childLayout.AggIdx) { + break + } + // node.AggList[i] is the i'th real aggregate of the child's + // AggList: both were built from the same ctx.times, skipping + // the `_wstart`/`_wend` carriers. + if colRefCnt[[2]int32{timeTag, childLayout.AggIdx[i]}] == 0 { + // A side-effecting fill value (e.g. fill(value, sleep(1))) + // is observable even when the filled column is discarded. + // Keep the column and register this node as its consumer, + // so the child window retains the matching aggregate slot. + // The count is released after the child is remapped: no + // one above reads the column, so FILL must not project it. + if i < len(node.FillVal) && !exprCanRemoveProject(node.FillVal[i]) { + ref := [2]int32{timeTag, childLayout.AggIdx[i]} + colRefCnt[ref]++ + sideEffectRefs = append(sideEffectRefs, ref) + } else { + continue + } + } + newAggList = append(newAggList, node.AggList[i]) + if i < len(node.FillVal) { + newFillVal = append(newFillVal, node.FillVal[i]) + } + } + clear(node.AggList[len(newAggList):]) + node.AggList = newAggList + if node.FillVal != nil { + clear(node.FillVal[len(newFillVal):]) + node.FillVal = newFillVal + } + } + for _, expr := range node.FillVal { increaseRefCnt(expr, 1, colRefCnt) } @@ -1794,6 +1914,19 @@ func (builder *QueryBuilder) remapAllColRefs(nodeID int32, step int32, colRefCnt if err != nil { return nil, err } + for _, ref := range sideEffectRefs { + colRefCnt[ref]-- + } + node.TimeWindowPartitionColPos = node.TimeWindowPartitionColPos[:0] + for _, ref := range fillPartitionRefs { + colRefCnt[ref]-- + localRef, ok := childRemapping.globalToLocal[ref] + if !ok { + return nil, moerr.NewInternalError(builder.GetContext(), + "fill: partition key missing from the time window's projection") + } + node.TimeWindowPartitionColPos = append(node.TimeWindowPartitionColPos, localRef[1]) + } for _, expr := range node.FillVal { increaseRefCnt(expr, -1, colRefCnt) @@ -3424,9 +3557,15 @@ func (builder *QueryBuilder) bindSelect(stmt *tree.Select, ctx *BindContext, isR ctx.sampleTag = builder.genNewBindTag() if astTimeWindow != nil { ctx.timeTag = builder.genNewBindTag() // ctx.timeTag > 0 - if astTimeWindow.Sliding != nil { + // GAPFILL uses the same second-stage aggregate state machine as an + // explicit sliding window even when its external SQL is a tumbling + // INTERVAL. Mark it before aggregate binding so SUM/COUNT/AVG are + // remapped to consume the child aggregate's partial-result type and the + // projected type matches the executor's actual vector. + if astTimeWindow.Sliding != nil || astTimeWindow.GapFill { ctx.sliding = true } + ctx.explicitSliding = astTimeWindow.Sliding != nil if helpFunc, err = makeHelpFuncForTimeWindow(astTimeWindow); err != nil { return @@ -4895,8 +5034,11 @@ func (builder *QueryBuilder) bindTimeWindow( } } + // Copy rather than alias the group expression: remapping walks OrderBy and + // GroupBy separately, and rewriting one shared pointer twice would resolve + // an already-local column reference a second time. boundTimeWindowOrderBy = &plan.OrderBySpec{ - Expr: timeWindowGroup, + Expr: DeepCopyExpr(timeWindowGroup), Flag: plan.OrderBySpec_INTERNAL | plan.OrderBySpec_ASC | plan.OrderBySpec_NULLS_FIRST, } @@ -5313,17 +5455,55 @@ func (builder *QueryBuilder) appendTimeWindowNode( return } + // A GROUP BY alongside the window puts extra keys in ctx.groups next to the + // window's own truncated timestamp. Those keys partition the window: each + // group gets its own window sequence rather than one stream shared by all. + // Ordering by them first is what makes each partition contiguous for the + // operator. + var partitionBy []*plan.Expr + orderBy := []*plan.OrderBySpec{boundTimeWindowOrderBy} + if tsCol := boundTimeWindowGroupBy.GetCol(); tsCol != nil { + partitionOrderBy := make([]*plan.OrderBySpec, 0, len(ctx.groups)) + for i := range ctx.groups { + if int32(i) == tsCol.ColPos { + continue + } + partitionCol := &plan.Expr{ + Typ: ctx.groups[i].Typ, + Expr: &plan.Expr_Col{ + Col: &plan.ColRef{ + RelPos: ctx.groupTag, + ColPos: int32(i), + }, + }, + } + partitionBy = append(partitionBy, partitionCol) + partitionOrderBy = append(partitionOrderBy, &plan.OrderBySpec{ + Expr: DeepCopyExpr(partitionCol), + Flag: plan.OrderBySpec_INTERNAL | plan.OrderBySpec_ASC | plan.OrderBySpec_NULLS_FIRST, + }) + } + orderBy = append(partitionOrderBy, orderBy...) + } + nodeID = builder.appendNode(&plan.Node{ - NodeType: plan.Node_TIME_WINDOW, - Children: []int32{nodeID}, - AggList: ctx.times, - BindingTags: []int32{ctx.timeTag, ctx.groupTag}, - OrderBy: []*plan.OrderBySpec{boundTimeWindowOrderBy}, - Interval: interval, - Sliding: sliding, - GroupBy: []*plan.Expr{boundTimeWindowGroupBy}, - Timestamp: ts, - WEnd: wEnd, + NodeType: plan.Node_TIME_WINDOW, + Children: []int32{nodeID}, + AggList: ctx.times, + BindingTags: []int32{ctx.timeTag, ctx.groupTag}, + OrderBy: orderBy, + Interval: interval, + Sliding: sliding, + GroupBy: []*plan.Expr{boundTimeWindowGroupBy}, + TimeWindowPartitionBy: partitionBy, + Timestamp: ts, + WEnd: wEnd, + GapFillMode: func() plan.Node_GapFillMode { + if astTimeWindow.GapFill { + return plan.Node_GAP_FILL_PARTITION + } + return plan.Node_GAP_FILL_NONE + }(), }, ctx) for name, id := range ctx.timeByAst { @@ -6265,11 +6445,20 @@ func (builder *QueryBuilder) buildTable(stmt tree.TableExpr, ctx *BindContext, p nodeType = plan.Node_EXTERNAL_SCAN externType := plan.ExternType_EXTERNAL_TB var icebergEnv sqliceberg.CreateSQLEnvelope + var mongoEnv sqlmongodb.CreateSQLEnvelope if env, found, err := sqliceberg.ParseCreateSQLEnvelope(builder.GetContext(), tableDef.Createsql); err != nil { return 0, err } else if found { icebergEnv = env externType = plan.ExternType_ICEBERG_TB + } else if env, found, err := sqlmongodb.ParseCreateSQLEnvelope(builder.GetContext(), tableDef.Createsql); err != nil { + return 0, err + } else if found { + mongoEnv = env + externType = plan.ExternType_MONGODB_TB + if builder.isPrepareStatement { + return 0, moerr.NewNotSupported(builder.GetContext(), "prepared MongoDB external scans") + } } externScan = &plan.ExternScan{ Type: int32(externType), @@ -6288,6 +6477,15 @@ func (builder *QueryBuilder) buildTable(stmt tree.TableExpr, ctx *BindContext, p return 0, err } externScan.IcebergScan = icebergScan + } else if externType == plan.ExternType_MONGODB_TB { + externScan.MongodbScan = &plan.MongoScan{ + TableId: uint64(obj.Obj), + Database: mongoEnv.Database, + Collection: mongoEnv.Collection, + Columns: sqlmongodb.ColumnsToPlan(mongoEnv.Columns), + ProjectedPaths: projectedMongoPaths(mongoEnv.Columns), + MaxParallelism: 1, + } } else if tbl.IcebergRef != nil { return 0, moerr.NewInvalidInput(builder.GetContext(), "FOR ICEBERG requires an Iceberg external table") } @@ -6476,6 +6674,48 @@ func (builder *QueryBuilder) buildTable(stmt tree.TableExpr, ctx *BindContext, p return } +func projectedMongoPaths(columns []sqlmongodb.ColumnMapping) []string { + result := make([]string, 0, len(columns)) + seen := make(map[string]struct{}, len(columns)) + for _, column := range columns { + if _, ok := seen[column.Path]; ok { + continue + } + seen[column.Path] = struct{}{} + result = append(result, column.Path) + } + return result +} + +// refreshMongoScanPushdown produces plan-time EXPLAIN evidence from the DDL +// envelope. Compile re-runs the same translation after validating and loading +// the authoritative catalog mapping. Keep the full definition snapshot on the +// plan for that validation; use only the retained TableDef columns to interpret +// compact filter ColPos values here. +func (builder *QueryBuilder) refreshMongoScanPushdown(node *plan.Node) error { + if node == nil || node.ExternScan == nil || node.ExternScan.MongodbScan == nil { + return nil + } + if node.TableDef == nil { + return moerr.NewInternalError(builder.GetContext(), "MongoDB external scan is missing its table definition") + } + scan := node.ExternScan.MongodbScan + names := make([]string, 0, len(node.TableDef.Cols)) + for _, column := range node.TableDef.Cols { + if column != nil && !column.Hidden { + names = append(names, column.Name) + } + } + columns, err := sqlmongodb.ProjectColumnsByName( + builder.GetContext(), sqlmongodb.ColumnsFromPlan(scan.Columns), names) + if err != nil { + return err + } + scan.PushedPredicate, scan.ResidualFilterDigest = sqlmongodb.PushdownPlanFilters( + builder.GetContext(), node.FilterList, sqlmongodb.ColumnsToPlan(columns)) + return nil +} + func (builder *QueryBuilder) genNewBindTag() int32 { builder.nextBindTag++ return builder.nextBindTag diff --git a/pkg/sql/plan/query_builder_test.go b/pkg/sql/plan/query_builder_test.go index 2094bf7972083..88c1e3201b504 100644 --- a/pkg/sql/plan/query_builder_test.go +++ b/pkg/sql/plan/query_builder_test.go @@ -28,6 +28,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/iceberg/model" "github.com/matrixorigin/matrixone/pkg/pb/plan" sqliceberg "github.com/matrixorigin/matrixone/pkg/sql/iceberg" + sqlmongodb "github.com/matrixorigin/matrixone/pkg/sql/mongodb" "github.com/matrixorigin/matrixone/pkg/sql/parsers" "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect" "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" @@ -140,6 +141,46 @@ func TestChooseRowCarrier(t *testing.T) { }) } +func TestMongoDBExternalScanPruningKeepsResidualColumnsAndPlansPushdown(t *testing.T) { + mock := NewMockOptimizer(false) + mock.ctxt.dbs["telemetry_source"] = true + mock.ctxt.objects["events_external"] = &plan.ObjectRef{DbName: "telemetry_source", ObjName: "events_external", Obj: 42} + mapping := sqlmongodb.TableMapping{ + Connection: "telemetry_source", Database: "telemetry", Collection: "events", + SchemaMode: sqlmongodb.SchemaExplicit, Conversion: sqlmongodb.ConversionStrict, MaxParallelism: 1, + Columns: []sqlmongodb.ColumnMapping{ + {Name: "device_id", Path: "device_id", TypeID: int32(types.T_varchar), Width: 20, Conversion: sqlmongodb.ConversionStrict}, + {Name: "ts", Path: "ts", TypeID: int32(types.T_datetime), Scale: 3, Conversion: sqlmongodb.ConversionTryNull}, + }, + } + mock.ctxt.tables["events_external"] = &plan.TableDef{ + Name: "events_external", TableType: catalog.SystemExternalRel, + Createsql: sqlmongodb.BuildCreateSQLEnvelope(mapping), + Cols: []*plan.ColDef{ + {Name: "device_id", Typ: plan.Type{Id: int32(types.T_varchar), Width: 20}}, + {Name: "ts", Typ: plan.Type{Id: int32(types.T_datetime), Scale: 3}}, + }, + } + + logicPlan, err := runOneStmt(mock, t, + "select count(*) from telemetry_source.events_external where ts >= '2026-07-27 10:55:00' and ts < '2026-07-27 11:02:00'") + require.NoError(t, err) + var scanNode *plan.Node + for _, node := range logicPlan.GetQuery().Nodes { + if node.NodeType == plan.Node_EXTERNAL_SCAN { + scanNode = node + break + } + } + require.NotNil(t, scanNode) + require.Len(t, scanNode.TableDef.Cols, 1) + require.Equal(t, "ts", scanNode.TableDef.Cols[0].Name) + require.Len(t, scanNode.FilterList, 2) + require.NotNil(t, scanNode.ExternScan.MongodbScan.PushedPredicate) + require.Equal(t, plan.MongoPredicateOp_MONGO_PREDICATE_AND, scanNode.ExternScan.MongodbScan.PushedPredicate.Op) + require.Equal(t, "mo-residual:ff", scanNode.ExternScan.MongodbScan.ResidualFilterDigest) +} + func TestCanPruneSampleExprs(t *testing.T) { makeCol := func(tag, pos int32, notNullable bool) *plan.Expr { return &plan.Expr{ diff --git a/pkg/sql/plan/time_window_layout.go b/pkg/sql/plan/time_window_layout.go new file mode 100644 index 0000000000000..c2e7763a99832 --- /dev/null +++ b/pkg/sql/plan/time_window_layout.go @@ -0,0 +1,130 @@ +// Copyright 2021 - 2022 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package plan + +import ( + "github.com/matrixorigin/matrixone/pkg/pb/plan" +) + +// TimeWindowSlotNone marks an AggList entry that occupies no output slot. +const TimeWindowSlotNone = int32(-1) + +// TimeWindowLayout describes the output batch a TIME_WINDOW operator produces. +// +// The operator emits, in this order: +// +// [ aggregate results (AggList order) ..., _wstart?, _wend?, partition keys... ] +// +// Every `_wstart` entry in AggList maps to the single WStartSlot, and likewise +// for `_wend`, because the operator only carries one boolean per boundary +// rather than one column per reference. +// +// Partition keys go last so the aggregates stay a prefix: the fill operator +// addresses its input positionally as Vecs[0..ColLen). +// +// This is the single source of truth for that layout: the planner uses it to +// address slots from a TIME_WINDOW ProjectList, and the compiler uses it to +// build the operator that fills them. Deriving it in two places is what let +// the two drift apart and read each other's columns. +type TimeWindowLayout struct { + // Slot maps an AggList index to its output position, or TimeWindowSlotNone + // for entries that occupy none (every `_wstart`/`_wend` entry shares one + // slot, so only the boundary slots below are authoritative for them). + Slot []int32 + // AggIdx lists the AggList indices holding real aggregates, in slot order. + AggIdx []int32 + // WStartSlot / WEndSlot are the boundary positions, or TimeWindowSlotNone + // when the boundary is not produced. + WStartSlot int32 + WEndSlot int32 + // PartitionSlot maps a TimeWindowPartitionBy index to its output position. + PartitionSlot []int32 + // ColCnt is the number of vectors in the output batch. + ColCnt int32 +} + +// isTimeWindowBoundary reports whether an AggList entry is a `_wstart`/`_wend` +// carrier rather than an aggregate. It mirrors constructTimeWindow: any column +// reference is a carrier, and only the two known names produce a boundary. +func isTimeWindowBoundary(expr *plan.Expr) (isBoundary bool, name string) { + e, ok := expr.Expr.(*plan.Expr_Col) + if !ok { + return false, "" + } + return true, e.Col.Name +} + +// BuildTimeWindowLayout derives the output layout of the TIME_WINDOW operator +// for the given node. +func BuildTimeWindowLayout(node *plan.Node) TimeWindowLayout { + layout := buildTimeWindowAggLayout(node.AggList) + for range node.TimeWindowPartitionBy { + layout.PartitionSlot = append(layout.PartitionSlot, layout.ColCnt) + layout.ColCnt++ + } + return layout +} + +// buildTimeWindowAggLayout lays out the aggregate and boundary slots, which +// occupy the front of the batch regardless of partitioning. +func buildTimeWindowAggLayout(aggList []*plan.Expr) TimeWindowLayout { + layout := TimeWindowLayout{ + Slot: make([]int32, len(aggList)), + WStartSlot: TimeWindowSlotNone, + WEndSlot: TimeWindowSlotNone, + } + + hasWStart, hasWEnd := false, false + for i, expr := range aggList { + layout.Slot[i] = TimeWindowSlotNone + isBoundary, name := isTimeWindowBoundary(expr) + if !isBoundary { + layout.Slot[i] = int32(len(layout.AggIdx)) + layout.AggIdx = append(layout.AggIdx, int32(i)) + continue + } + switch name { + case TimeWindowStart: + hasWStart = true + case TimeWindowEnd: + hasWEnd = true + } + } + + layout.ColCnt = int32(len(layout.AggIdx)) + if hasWStart { + layout.WStartSlot = layout.ColCnt + layout.ColCnt++ + } + if hasWEnd { + layout.WEndSlot = layout.ColCnt + layout.ColCnt++ + } + + for i, expr := range aggList { + isBoundary, name := isTimeWindowBoundary(expr) + if !isBoundary { + continue + } + switch name { + case TimeWindowStart: + layout.Slot[i] = layout.WStartSlot + case TimeWindowEnd: + layout.Slot[i] = layout.WEndSlot + } + } + + return layout +} diff --git a/pkg/sql/plan/time_window_layout_test.go b/pkg/sql/plan/time_window_layout_test.go new file mode 100644 index 0000000000000..23c42e43c658a --- /dev/null +++ b/pkg/sql/plan/time_window_layout_test.go @@ -0,0 +1,176 @@ +// Copyright 2021 - 2022 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package plan + +import ( + "testing" + + "github.com/matrixorigin/matrixone/pkg/pb/plan" + "github.com/stretchr/testify/require" +) + +func twBoundary(name string) *plan.Expr { + return &plan.Expr{ + Expr: &plan.Expr_Col{Col: &plan.ColRef{Name: name}}, + } +} + +func twAgg(name string) *plan.Expr { + return &plan.Expr{ + Expr: &plan.Expr_F{ + F: &plan.Function{Func: &plan.ObjectRef{ObjName: name}}, + }, + } +} + +func TestBuildTimeWindowLayout(t *testing.T) { + cases := []struct { + name string + aggList []*plan.Expr + partitionBy int + wantSlot []int32 + wantAggIdx []int32 + wantWStart int32 + wantWEnd int32 + wantPartSlt []int32 + wantColCnt int32 + }{ + { + name: "aggregates only", + aggList: []*plan.Expr{twAgg("max"), twAgg("min")}, + wantSlot: []int32{0, 1}, + wantAggIdx: []int32{0, 1}, + wantWStart: TimeWindowSlotNone, + wantWEnd: TimeWindowSlotNone, + wantColCnt: 2, + }, + { + // Boundaries trail the aggregates no matter where they sit in + // AggList; the binder puts _wstart first for `select _wstart, max(v)`. + name: "boundaries follow aggregates regardless of AggList order", + aggList: []*plan.Expr{twBoundary(TimeWindowStart), twBoundary(TimeWindowEnd), twAgg("max")}, + wantSlot: []int32{1, 2, 0}, + wantAggIdx: []int32{2}, + wantWStart: 1, + wantWEnd: 2, + wantColCnt: 3, + }, + { + name: "wend without wstart takes the first boundary slot", + aggList: []*plan.Expr{twBoundary(TimeWindowEnd), twAgg("max")}, + wantSlot: []int32{1, 0}, + wantAggIdx: []int32{0 + 1}, + wantWStart: TimeWindowSlotNone, + wantWEnd: 1, + wantColCnt: 2, + }, + { + // The operator carries one flag per boundary, not one column per + // reference, so repeats collapse onto the same slot. + name: "repeated wstart references share one slot", + aggList: []*plan.Expr{twBoundary(TimeWindowStart), twAgg("max"), twBoundary(TimeWindowStart)}, + wantSlot: []int32{1, 0, 1}, + wantAggIdx: []int32{1}, + wantWStart: 1, + wantWEnd: TimeWindowSlotNone, + wantColCnt: 2, + }, + { + name: "boundary only", + aggList: []*plan.Expr{twBoundary(TimeWindowStart)}, + wantSlot: []int32{0}, + wantAggIdx: nil, + wantWStart: 0, + wantWEnd: TimeWindowSlotNone, + wantColCnt: 1, + }, + { + name: "partition keys come last", + aggList: []*plan.Expr{twBoundary(TimeWindowStart), twAgg("max")}, + partitionBy: 2, + wantSlot: []int32{1, 0}, + wantAggIdx: []int32{1}, + wantWStart: 1, + wantWEnd: TimeWindowSlotNone, + wantPartSlt: []int32{2, 3}, + wantColCnt: 4, + }, + { + name: "empty", + aggList: nil, + wantSlot: []int32{}, + wantAggIdx: nil, + wantWStart: TimeWindowSlotNone, + wantWEnd: TimeWindowSlotNone, + wantColCnt: 0, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + node := &plan.Node{AggList: c.aggList} + for i := 0; i < c.partitionBy; i++ { + node.TimeWindowPartitionBy = append(node.TimeWindowPartitionBy, twAgg("col")) + } + + layout := BuildTimeWindowLayout(node) + require.Equal(t, c.wantSlot, layout.Slot) + require.Equal(t, c.wantAggIdx, layout.AggIdx) + require.Equal(t, c.wantWStart, layout.WStartSlot) + require.Equal(t, c.wantWEnd, layout.WEndSlot) + require.Equal(t, c.wantPartSlt, layout.PartitionSlot) + require.Equal(t, c.wantColCnt, layout.ColCnt) + }) + } +} + +// The compiler builds the operator's columns from AggIdx and the boundary +// flags while the planner addresses them through Slot. If those two views ever +// disagree the projection reads someone else's column, which is exactly the +// drift this type exists to prevent. +func TestBuildTimeWindowLayoutSlotsAreConsistent(t *testing.T) { + node := &plan.Node{ + AggList: []*plan.Expr{ + twBoundary(TimeWindowEnd), + twAgg("max"), + twBoundary(TimeWindowStart), + twAgg("min"), + }, + TimeWindowPartitionBy: []*plan.Expr{twAgg("col")}, + } + layout := BuildTimeWindowLayout(node) + + // Aggregates occupy a dense prefix, in AggList order. + for want, aggIdx := range layout.AggIdx { + require.Equal(t, int32(want), layout.Slot[aggIdx]) + } + require.Equal(t, []int32{1, 3}, layout.AggIdx) + + // Boundaries sit immediately after, and every reference agrees with the + // authoritative boundary slot. + require.Equal(t, int32(2), layout.WStartSlot) + require.Equal(t, int32(3), layout.WEndSlot) + require.Equal(t, layout.WStartSlot, layout.Slot[2]) + require.Equal(t, layout.WEndSlot, layout.Slot[0]) + + // Partition keys take the tail, leaving the aggregates a prefix for FILL. + require.Equal(t, []int32{4}, layout.PartitionSlot) + require.Equal(t, int32(5), layout.ColCnt) + + for _, slot := range layout.Slot { + require.Less(t, slot, layout.ColCnt) + require.GreaterOrEqual(t, slot, int32(0)) + } +} diff --git a/pkg/sql/plan/types.go b/pkg/sql/plan/types.go index 3dc242f28530e..437f13cac3812 100644 --- a/pkg/sql/plan/types.go +++ b/pkg/sql/plan/types.go @@ -319,12 +319,13 @@ type BindContext struct { //cteByName saves all cte definitions in the current stmt cteByName map[string]*CTERef //cteState records state of binding cte - cteState CteBindState - sliding bool - isDistinct bool - isCorrelated bool - hasSingleRow bool - isGroupingSet bool + cteState CteBindState + sliding bool + explicitSliding bool + isDistinct bool + isCorrelated bool + hasSingleRow bool + isGroupingSet bool //cteName denotes the alias of this BindContext. //it may be from view name, cte name or subquery name diff --git a/pkg/sql/plan/visit_plan.go b/pkg/sql/plan/visit_plan.go index 53ae2239c810b..d8be2ecda1149 100644 --- a/pkg/sql/plan/visit_plan.go +++ b/pkg/sql/plan/visit_plan.go @@ -132,6 +132,13 @@ func (vq *VisitPlan) exploreNode(ctx context.Context, rule VisitPlanRule, node * } } + for i := range node.TimeWindowPartitionBy { + node.TimeWindowPartitionBy[i], err = rule.ApplyExpr(node.TimeWindowPartitionBy[i]) + if err != nil { + return err + } + } + for i := range node.BlockFilterList { node.BlockFilterList[i], err = rule.ApplyExpr(node.BlockFilterList[i]) if err != nil { diff --git a/pkg/util/metric/v2/metrics.go b/pkg/util/metric/v2/metrics.go index 56c7b900cfd5e..24cd00159afbe 100644 --- a/pkg/util/metric/v2/metrics.go +++ b/pkg/util/metric/v2/metrics.go @@ -51,6 +51,7 @@ func init() { initProxyMetrics() initFrontendMetrics() initPipelineMetrics() + initMongoDBMetrics() initScheduleMetrics() initLogServiceMetrics() initShardingMetrics() @@ -283,6 +284,22 @@ func initPipelineMetrics() { registry.MustRegister(PipelineRemoteNotifyRetryCounter) } +func initMongoDBMetrics() { + registry.MustRegister(MongoDBScanDocumentsCounter) + registry.MustRegister(MongoDBScanRawBytesCounter) + registry.MustRegister(MongoDBConversionErrorCounter) + registry.MustRegister(MongoDBCursorEventCounter) + registry.MustRegister(MongoDBPhaseDurationHistogram) + registry.MustRegister(MongoDBDriverCommandCounter) + registry.MustRegister(MongoDBDriverCommandDurationHistogram) + registry.MustRegister(MongoDBRetryableFindCounter) + registry.MustRegister(MongoDBPoolEventCounter) + registry.MustRegister(MongoDBPoolEventDurationHistogram) + registry.MustRegister(MongoDBPoolCheckedOutGauge) + registry.MustRegister(MongoDBSelectedServerRoleCounter) + registry.MustRegister(MongoDBServerHeartbeatDurationHistogram) +} + func initLogServiceMetrics() { registry.MustRegister(LogServiceAppendDurationHistogram) registry.MustRegister(LogServiceAppendCounter) diff --git a/pkg/util/metric/v2/mongodb.go b/pkg/util/metric/v2/mongodb.go new file mode 100644 index 0000000000000..cf435e0aa8988 --- /dev/null +++ b/pkg/util/metric/v2/mongodb.go @@ -0,0 +1,59 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v2 + +import "github.com/prometheus/client_golang/prometheus" + +var ( + MongoDBScanDocumentsCounter = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: "mo", Subsystem: "mongodb", Name: "scan_documents_total", + Help: "MongoDB documents converted by MongoScan."}) + MongoDBScanRawBytesCounter = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: "mo", Subsystem: "mongodb", Name: "scan_raw_bytes_total", + Help: "Raw BSON bytes converted by MongoScan."}) + MongoDBConversionErrorCounter = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: "mo", Subsystem: "mongodb", Name: "conversion_errors_total", + Help: "BSON values mapped to NULL by MongoDB try_null conversion."}) + MongoDBCursorEventCounter = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "mo", Subsystem: "mongodb", Name: "cursor_events_total", + Help: "MongoDB cursor lifecycle outcomes without source-identifying labels."}, []string{"event"}) + MongoDBPhaseDurationHistogram = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: "mo", Subsystem: "mongodb", Name: "phase_duration_seconds", + Help: "MongoDB source wait and BSON decode/vector append time.", Buckets: getDurationBuckets()}, []string{"phase"}) + MongoDBDriverCommandCounter = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "mo", Subsystem: "mongodb", Name: "driver_commands_total", + Help: "MongoDB driver command attempts and outcomes with bounded command labels."}, []string{"command", "outcome"}) + MongoDBDriverCommandDurationHistogram = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: "mo", Subsystem: "mongodb", Name: "driver_command_duration_seconds", + Help: "MongoDB driver command duration without namespace, endpoint, or query labels.", Buckets: getDurationBuckets()}, []string{"command", "outcome"}) + MongoDBRetryableFindCounter = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: "mo", Subsystem: "mongodb", Name: "retryable_find_failures_total", + Help: "Find command attempts that failed with a retryable network error."}) + MongoDBPoolEventCounter = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "mo", Subsystem: "mongodb", Name: "pool_events_total", + Help: "MongoDB driver connection-pool events with bounded labels."}, []string{"event", "reason"}) + MongoDBPoolEventDurationHistogram = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: "mo", Subsystem: "mongodb", Name: "pool_event_duration_seconds", + Help: "MongoDB connection-pool checkout and connection event duration.", Buckets: getDurationBuckets()}, []string{"event"}) + MongoDBPoolCheckedOutGauge = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: "mo", Subsystem: "mongodb", Name: "pool_checked_out_connections", + Help: "MongoDB driver connections currently checked out across CN-local clients."}) + MongoDBSelectedServerRoleCounter = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "mo", Subsystem: "mongodb", Name: "selected_server_roles_total", + Help: "MongoDB commands by selected server role; endpoint identity is never exported."}, []string{"role"}) + MongoDBServerHeartbeatDurationHistogram = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: "mo", Subsystem: "mongodb", Name: "server_heartbeat_duration_seconds", + Help: "MongoDB server heartbeat duration and outcome without endpoint labels.", Buckets: getDurationBuckets()}, []string{"outcome"}) +) diff --git a/pkg/vm/engine/test/change_handle_test.go b/pkg/vm/engine/test/change_handle_test.go index 1f851134ee285..30b4b4f924e09 100644 --- a/pkg/vm/engine/test/change_handle_test.go +++ b/pkg/vm/engine/test/change_handle_test.go @@ -2399,7 +2399,7 @@ func TestISCPExecutor4(t *testing.T) { tableID := rel.GetTableID(ctxWithTimeout) - txn.Commit(ctxWithTimeout) + require.NoError(t, txn.Commit(ctxWithTimeout)) // init cdc executor checkLeaseStub := gostub.Stub( @@ -2431,11 +2431,80 @@ func TestISCPExecutor4(t *testing.T) { require.NoError(t, err) cdcExecutor.SetRpcHandleFn(taeHandler.GetRPCHandle().HandleGetChangedTableList) - cdcExecutor.Start() + require.NoError(t, cdcExecutor.Start()) defer cdcExecutor.Stop() - fault.Enable() - defer fault.Disable() + require.True(t, fault.Enable(), "fault injection was already enabled before TestISCPExecutor4") + t.Cleanup(func() { + fault.Disable() + }) + + registerFaultCleanup := func(remove func() (bool, error)) func() { + var ( + once sync.Once + removeOK bool + removeErr error + ) + cleanup := func() { + once.Do(func() { + removeOK, removeErr = remove() + }) + require.NoError(t, removeErr) + require.True(t, removeOK) + } + t.Cleanup(cleanup) + return cleanup + } + + addFaultPoint := func(name, action, arg string) func() { + require.NoError(t, fault.AddFaultPoint( + ctx, + name, + ":::", + action, + 0, + arg, + false, + )) + return registerFaultCleanup(func() (bool, error) { + return fault.RemoveFaultPoint(context.Background(), name) + }) + } + + injectCDCExecutorFault := func(name string) (waitUntilHit func(time.Time), remove func()) { + waitKey := objectio.ISCPExecutorFaultWaitKey(name) + waitersKey := waitKey + ":waiters" + notifyKey := waitKey + ":notify" + removeWait := addFaultPoint(waitKey, "wait", "") + removeWaitersProbe := addFaultPoint(waitersKey, "getwaiters", waitKey) + removeNotify := addFaultPoint(notifyKey, "notifyall", waitKey) + + removeInjection, err := objectio.InjectCDCExecutor(name) + require.NoError(t, err) + removeInjectedFault := registerFaultCleanup(removeInjection) + + waitUntilHit = func(deadline time.Time) { + remaining := time.Until(deadline) + if remaining <= 0 { + require.FailNowf(t, "ISCP fault phase budget exhausted", "fault=%s", name) + } + require.Eventually(t, func() bool { + waiters, _, ok := fault.TriggerFault(waitersKey) + return ok && waiters > 0 + }, remaining, 10*time.Millisecond, "ISCP worker did not reach injected fault %s", name) + } + remove = registerFaultCleanup(func() (bool, error) { + // Stop new failures before releasing the worker already parked at + // the exact injected failure point. + removeInjectedFault() + fault.TriggerFault(notifyKey) + removeWait() + removeWaitersProbe() + removeNotify() + return true, nil + }) + return waitUntilHit, remove + } registerFn := func(jobName string) { txn, err := disttaeEngine.NewTxnOperator(ctx, disttaeEngine.Engine.LatestLogtailAppliedTime()) @@ -2454,39 +2523,97 @@ func TestISCPExecutor4(t *testing.T) { }, false, ) - assert.True(t, ok) - assert.NoError(t, err) - assert.NoError(t, txn.Commit(ctxWithTimeout)) + require.True(t, ok) + require.NoError(t, err) + require.NoError(t, txn.Commit(ctxWithTimeout)) } - appendFn := func(idx int) { + appendFn := func(idx int) types.TS { _, rel, txn, err := disttaeEngine.GetTable(ctxWithTimeout, "srcdb", "src_table") - require.Nil(t, err) + require.NoError(t, err) err = rel.Write(ctxWithTimeout, containers.ToCNBatch(bats[idx])) - require.Nil(t, err) + require.NoError(t, err) - txn.Commit(ctxWithTimeout) + require.NoError(t, txn.Commit(ctxWithTimeout)) + return types.TimestampToTS(txn.Txn().CommitTS) } - checkWaterMarkFn := func(indexName string, waitTime int, expectResult bool) { - now := taeHandler.GetDB().TxnMgr.Now() - testutils.WaitExpect( - waitTime, - func() bool { - ts, _ := cdcExecutor.GetWatermark(accountId, tableID, indexName) - return ts.GE(&now) - }, - ) - ts, _ := cdcExecutor.GetWatermark(accountId, tableID, indexName) - if expectResult { - assert.True(t, ts.GE(&now), indexName) - } else { - assert.False(t, ts.GE(&now), indexName) + const ( + indexCount = 3 + // Observable state transitions, rather than this duration, are the + // correctness oracle. This only bounds a broken asynchronous phase; + // successful phases return as soon as every watermark is durable. + iscpPhaseHangGuard = 30 * time.Second + ) + waitForAllWatermarks := func(target types.TS, deadline time.Time) { + remaining := time.Until(deadline) + if remaining <= 0 { + require.FailNowf( + t, + "ISCP phase budget exhausted before watermark wait", + "account=%d table=%d target=%s", + accountId, + tableID, + target.ToString(), + ) + } + + reached := assert.Eventually(t, func() bool { + for i := 0; i < indexCount; i++ { + current, found := cdcExecutor.GetWatermark( + accountId, + tableID, + fmt.Sprintf("hnsw_idx_%d", i), + ) + if !found || current.LT(&target) { + return false + } + } + return true + }, remaining, 10*time.Millisecond) + if reached { + return } + + for i := 0; i < indexCount; i++ { + indexName := fmt.Sprintf("hnsw_idx_%d", i) + current, found := cdcExecutor.GetWatermark(accountId, tableID, indexName) + t.Logf( + "ISCP watermark timeout: account=%d table=%d job=%s found=%t current=%s target=%s", + accountId, + tableID, + indexName, + found, + current.ToString(), + target.ToString(), + ) + } + require.FailNow(t, "not all ISCP watermarks reached the target") + } + + exerciseFaultRecovery := func(name string, batchIndex int) { + deadline := time.Now().Add(iscpPhaseHangGuard) + waitUntilHit, removeFault := injectCDCExecutorFault(name) + defer removeFault() + target := appendFn(batchIndex) + waitUntilHit(deadline) + + current, found := cdcExecutor.GetWatermark(accountId, tableID, "hnsw_idx_0") + require.True(t, found) + require.Truef( + t, + current.LT(&target), + "fault %s did not stop hnsw_idx_0 before target: current=%s target=%s", + name, + current.ToString(), + target.ToString(), + ) + + removeFault() + waitForAllWatermarks(target, deadline) } - indexCount := 3 for i := 0; i < indexCount; i++ { registerFn(fmt.Sprintf("hnsw_idx_%d", i)) } @@ -2495,52 +2622,21 @@ func TestISCPExecutor4(t *testing.T) { appendFn(1) // insertAsyncIndexIterations failed - appendFn(2) - for i := 0; i < indexCount; i++ { - checkWaterMarkFn(fmt.Sprintf("hnsw_idx_%d", i), 4000, true) - } + deadline := time.Now().Add(iscpPhaseHangGuard) + target := appendFn(2) + waitForAllWatermarks(target, deadline) // collectChanges failed - rmFn, err := objectio.InjectCDCExecutor("collectChanges") - assert.NoError(t, err) - appendFn(3) - checkWaterMarkFn("hnsw_idx_0", 100, false) - rmFn() - for i := 0; i < indexCount; i++ { - checkWaterMarkFn(fmt.Sprintf("hnsw_idx_%d", i), 4000, true) - } + exerciseFaultRecovery("collectChanges", 3) // changesNext failed - rmFn, err = objectio.InjectCDCExecutor("changesNext") - assert.NoError(t, err) - appendFn(6) - checkWaterMarkFn("hnsw_idx_0", 100, false) - rmFn() - for i := 0; i < indexCount; i++ { - checkWaterMarkFn(fmt.Sprintf("hnsw_idx_%d", i), 1000, true) - } + exerciseFaultRecovery("changesNext", 6) // consume failed - rmFn, err = objectio.InjectCDCExecutor("consume") - assert.NoError(t, err) - appendFn(7) - checkWaterMarkFn("hnsw_idx_0", 100, false) - rmFn() - for i := 0; i < indexCount; i++ { - checkWaterMarkFn(fmt.Sprintf("hnsw_idx_%d", i), 1000, true) - } + exerciseFaultRecovery("consume", 7) + // consume, firstTxn failed - rmFn, err = objectio.InjectCDCExecutor("consumeWithJobName:hnsw_idx_0") - assert.NoError(t, err) - appendFn(8) - checkWaterMarkFn("hnsw_idx_0", 100, false) - // for i := 1; i < indexCount; i++ { - // CheckTableData(t, disttaeEngine, ctxWithTimeout, "srcdb", "src_table", tableID, fmt.Sprintf("hnsw_idx_%d", i)) - // } - rmFn() - for i := 1; i < indexCount; i++ { - checkWaterMarkFn(fmt.Sprintf("hnsw_idx_%d", i), 1000, true) - } + exerciseFaultRecovery("consumeWithJobName:hnsw_idx_0", 8) for i := 0; i < indexCount; i++ { CheckTableData(t, disttaeEngine, ctxWithTimeout, "srcdb", "src_table", tableID, fmt.Sprintf("hnsw_idx_%d", i)) diff --git a/pkg/vm/types.go b/pkg/vm/types.go index 3dcc0be4aceb0..51b383db3334b 100644 --- a/pkg/vm/types.go +++ b/pkg/vm/types.go @@ -105,6 +105,7 @@ const ( Apply PostDml IcebergWrite + MongoScan ) var OperatorToStrMap map[OpType]string @@ -169,6 +170,7 @@ func init() { Apply: "Apply", PostDml: "PostDml", IcebergWrite: "IcebergWrite", + MongoScan: "MongoScan", } // Initialize StrToOperatorMap @@ -190,6 +192,7 @@ func init() { MajorOpMap = map[string]bool{ OperatorToStrMap[TableScan]: true, OperatorToStrMap[External]: true, + OperatorToStrMap[MongoScan]: true, OperatorToStrMap[Order]: true, OperatorToStrMap[Window]: true, OperatorToStrMap[Group]: true, diff --git a/proto/pipeline.proto b/proto/pipeline.proto index 875a64a743c18..c832d90880d1c 100644 --- a/proto/pipeline.proto +++ b/proto/pipeline.proto @@ -584,6 +584,7 @@ message Instruction { MultiUpdate multi_update = 52; PostDml post_dml = 53; int64 spill_mem = 54; + plan.MongoScan mongodb_scan = 55; } message AnalysisList { diff --git a/proto/plan.proto b/proto/plan.proto index 112d813a3c76c..5e4c40e150d66 100644 --- a/proto/plan.proto +++ b/proto/plan.proto @@ -814,6 +814,11 @@ message Node { LINEAR = 5; } + enum GapFillMode { + GAP_FILL_NONE = 0; + GAP_FILL_PARTITION = 1; + } + enum OnDuplicateAction { FAIL = 0; IGNORE = 1; @@ -941,6 +946,21 @@ message Node { int64 spill_mem = 70; repeated string origin_views = 71; string direct_view = 72; + + // TIME_WINDOW only: the GROUP BY columns other than the window's own + // timestamp key. The operator restarts its window state whenever these + // change, so each group gets its own windows instead of one global stream. + repeated Expr time_window_partition_by = 73; + + // FILL only: positions of the partition keys inside this node's input batch + // (the child TIME_WINDOW's projection). fill(prev/next/linear) must not + // carry values across a partition boundary, so the operator compares these + // columns to find where one group ends and the next begins. + repeated int32 time_window_partition_col_pos = 74; + + // TIME_WINDOW only: explicitly generate missing buckets between each + // partition's observed minimum and maximum timestamp. + GapFillMode gap_fill_mode = 75; } message SnapshotExtraInfo { @@ -970,6 +990,7 @@ enum ExternType { EXTERNAL_TB = 1; RESULT_SCAN = 2; ICEBERG_TB = 3; + MONGODB_TB = 4; } message ExternScan { @@ -984,6 +1005,7 @@ message ExternScan { bytes escaped_by = 9; map TbColToDataCol = 10; IcebergScan iceberg_scan = 11; + MongoScan mongodb_scan = 12; } message IcebergScan { @@ -999,6 +1021,70 @@ message IcebergScan { string filter_digest = 10; } +// MongoScan is a credential-free scan description. Authentication and TLS +// material are resolved on the execution CN from connection_id/version. +message MongoScan { + uint64 mapping_id = 1; + uint64 connection_id = 2; + uint64 connection_version = 3; + string database = 4; + string collection = 5; + repeated MongoColumnMapping columns = 6; + MongoPredicate pushed_predicate = 7; + repeated string projected_paths = 8; + string residual_filter_digest = 9; + int32 max_parallelism = 10; + MongoSplit split = 11; + int64 max_scan_rows = 12; + int64 max_scan_bytes = 13; + // mapping_version pins the tenant-scoped mapping row that was validated at + // compile time. The execution CN re-reads that exact catalog generation. + uint64 mapping_version = 14; + // table_id is the stable MO relation identity used to locate the mapping + // during compilation. It remains distinct from the catalog mapping_id so a + // cached logical plan can be compiled more than once without identity drift. + uint64 table_id = 15; +} + +message MongoColumnMapping { + string name = 1; + string path = 2; + Type mo_type = 3 [(gogoproto.nullable) = false]; + string conversion_mode = 4; +} + +enum MongoPredicateOp { + MONGO_PREDICATE_INVALID = 0; + MONGO_PREDICATE_AND = 1; + MONGO_PREDICATE_EQUAL = 2; + MONGO_PREDICATE_NOT_EQUAL = 3; + MONGO_PREDICATE_LESS = 4; + MONGO_PREDICATE_LESS_EQUAL = 5; + MONGO_PREDICATE_GREATER = 6; + MONGO_PREDICATE_GREATER_EQUAL = 7; + MONGO_PREDICATE_IN = 8; + MONGO_PREDICATE_IS_NULL = 9; + MONGO_PREDICATE_IS_NOT_NULL = 10; +} + +message MongoPredicate { + MongoPredicateOp op = 1; + string path = 2; + // Canonical BSON value bytes retain Mongo numeric and temporal types while + // keeping the protobuf independent from the Go driver. + bytes value_bson = 3; + repeated bytes values_bson = 4; + repeated MongoPredicate children = 5; +} + +message MongoSplit { + string key_path = 1; + bytes lower_bson = 2; + bytes upper_bson = 3; + bool lower_inclusive = 4; + bool upper_inclusive = 5; +} + message ExternAttr { string col_name = 1; int32 col_index = 2; diff --git a/proto/query.proto b/proto/query.proto index c019851413941..6820b1dfc2dcd 100644 --- a/proto/query.proto +++ b/proto/query.proto @@ -104,6 +104,8 @@ enum CmdMethod { CtlPrefetchOnSubscribed = 36; // IcebergCacheInvalidate invalidates Iceberg metadata/manifest cache after commit. IcebergCacheInvalidate = 37; + // MongoDBClientRetire drains obsolete MongoDB driver clients after catalog DDL. + MongoDBClientRetire = 39; } // QueryRequest is the common query request. It contains the query @@ -245,6 +247,7 @@ message Request { WorkspaceThresholdRequest WorkspaceThresholdRequest = 37; CtlPrefetchOnSubscribedRequest CtlPrefetchOnSubscribedRequest = 38; IcebergCacheInvalidateRequest IcebergCacheInvalidateRequest = 39 [ (gogoproto.nullable) = false ]; + MongoDBClientRetireRequest MongoDBClientRetireRequest = 41 [ (gogoproto.nullable) = false ]; } // ShowProcessListResponse is the response of command ShowProcessList. @@ -311,6 +314,7 @@ message Response { MinTimestampResponse MinTimestampResponse = 38; CtlPrefetchOnSubscribedResponse CtlPrefetchOnSubscribedResponse = 39; IcebergCacheInvalidateResponse IcebergCacheInvalidateResponse = 40 [ (gogoproto.nullable) = false ]; + MongoDBClientRetireResponse MongoDBClientRetireResponse = 42 [ (gogoproto.nullable) = false ]; } // AlterAccountRequest is the "alter account restricted" query request. @@ -689,3 +693,15 @@ message MinTimestampResponse { // LatestCommitTS update latest commit ts. timestamp.Timestamp MinTimestamp = 1 [(gogoproto.nullable) = false]; } + +message MongoDBClientRetireRequest { + uint32 AccountID = 1; + // Zero retires every MongoDB client for AccountID. + uint64 ConnectionID = 2; + // Zero retires the whole connection; otherwise generations below this value. + uint64 VersionExclusive = 3; +} + +message MongoDBClientRetireResponse { + bool Success = 1; +} diff --git a/test/distributed/cases/dml/select/sp_table.result b/test/distributed/cases/dml/select/sp_table.result index 26f602913c643..d483ca5b07772 100644 --- a/test/distributed/cases/dml/select/sp_table.result +++ b/test/distributed/cases/dml/select/sp_table.result @@ -32,6 +32,8 @@ mo_indexes r mo_iscp_log r mo_locks v mo_merge_settings r +mo_mongodb_connections r +mo_mongodb_tables r mo_mysql_compatibility_mode r mo_partition_metadata r mo_partition_tables r diff --git a/test/distributed/cases/dml/show/database_statistics.result b/test/distributed/cases/dml/show/database_statistics.result index 406dea1815e23..8f43d6ff8c4de 100644 --- a/test/distributed/cases/dml/show/database_statistics.result +++ b/test/distributed/cases/dml/show/database_statistics.result @@ -9,7 +9,7 @@ show table_number from mysql; 6 show table_number from mo_catalog; Number of tables in mo_catalog -55 +57 show table_number from system; [unknown result because it is related to issue#23182] use mo_task; @@ -350,7 +350,7 @@ show table_number from mysql; 6 show table_number from mo_catalog; ➤ Number of tables in mo_catalog[-5,64,0] 𝄀 -33 +35 show table_number from system_metrics; ➤ Number of tables in system_metrics[-5,64,0] 𝄀 11 diff --git a/test/distributed/cases/dml/show/show.result b/test/distributed/cases/dml/show/show.result index 0a332632fedb7..66a105051452c 100644 --- a/test/distributed/cases/dml/show/show.result +++ b/test/distributed/cases/dml/show/show.result @@ -281,6 +281,8 @@ mo_indexes 𝄀 mo_iscp_log 𝄀 mo_locks 𝄀 mo_merge_settings 𝄀 +mo_mongodb_connections 𝄀 +mo_mongodb_tables 𝄀 mo_mysql_compatibility_mode 𝄀 mo_partition_metadata 𝄀 mo_partition_tables 𝄀 @@ -310,7 +312,7 @@ mo_variables 𝄀 mo_version show table_number from mo_catalog; ➤ Number of tables in mo_catalog[-5,64,0] 𝄀 -55 +57 show column_number from mo_database; ➤ Number of columns in mo_database[-5,64,0] 𝄀 9 diff --git a/test/distributed/cases/function/func_aggr_max_by.result b/test/distributed/cases/function/func_aggr_max_by.result new file mode 100644 index 0000000000000..4ccb3a5bb56cd --- /dev/null +++ b/test/distributed/cases/function/func_aggr_max_by.result @@ -0,0 +1,41 @@ +drop database if exists max_by_bvt; +create database max_by_bvt; +use max_by_bvt; +create table readings(grp int, value varchar(20), ts bigint, tie varchar(20)); +insert into readings values +(1, 'older', 10, 'a'), +(1, null, 11, 'b'), +(1, 'latest-tie-a', 12, 'a'), +(1, 'latest-tie-z', 12, 'z'), +(2, null, 2, 'b'), +(2, 'kept', 1, 'a'), +(3, 'alpha', 5, 'same'), +(3, 'beta', 5, 'same'), +(4, 'ignored-null-order', null, 'z'); +select grp, +max_by(value, ts, tie) as latest_value, +max_by_non_null(value, ts, tie) as latest_non_null_value +from readings +group by grp +order by grp; +➤ grp[4,32,0] ¦ latest_value[12,-1,0] ¦ latest_non_null_value[12,-1,0] 𝄀 +1 ¦ latest-tie-z ¦ latest-tie-z 𝄀 +2 ¦ null ¦ kept 𝄀 +3 ¦ beta ¦ beta 𝄀 +4 ¦ null ¦ null +create table window_readings(pump varchar(8), ts datetime, tie varchar(20), value varchar(20)); +insert into window_readings values +('p1', '2026-01-01 10:00:05', 'a', 'first'), +('p1', '2026-01-01 10:00:05', 'z', null), +('p1', '2026-01-01 10:02:05', 'a', 'last'); +select pump, _wstart, +max_by(value, ts, tie) as latest_value, +max_by_non_null(value, ts, tie) as latest_non_null_value +from window_readings +group by pump interval(ts, 1, minute) gapfill(partition) fill(null) +order by pump, _wstart; +➤ pump[12,-1,0] ¦ _wstart[93,64,0] ¦ latest_value[12,-1,0] ¦ latest_non_null_value[12,-1,0] 𝄀 +p1 ¦ 2026-01-01 10:00:00 ¦ null ¦ first 𝄀 +p1 ¦ 2026-01-01 10:01:00 ¦ null ¦ null 𝄀 +p1 ¦ 2026-01-01 10:02:00 ¦ last ¦ last +drop database max_by_bvt; diff --git a/test/distributed/cases/function/func_aggr_max_by.test b/test/distributed/cases/function/func_aggr_max_by.test new file mode 100644 index 0000000000000..d1b52f31e47a3 --- /dev/null +++ b/test/distributed/cases/function/func_aggr_max_by.test @@ -0,0 +1,37 @@ +drop database if exists max_by_bvt; +create database max_by_bvt; +use max_by_bvt; + +create table readings(grp int, value varchar(20), ts bigint, tie varchar(20)); +insert into readings values + (1, 'older', 10, 'a'), + (1, null, 11, 'b'), + (1, 'latest-tie-a', 12, 'a'), + (1, 'latest-tie-z', 12, 'z'), + (2, null, 2, 'b'), + (2, 'kept', 1, 'a'), + (3, 'alpha', 5, 'same'), + (3, 'beta', 5, 'same'), + (4, 'ignored-null-order', null, 'z'); + +select grp, + max_by(value, ts, tie) as latest_value, + max_by_non_null(value, ts, tie) as latest_non_null_value +from readings +group by grp +order by grp; + +create table window_readings(pump varchar(8), ts datetime, tie varchar(20), value varchar(20)); +insert into window_readings values + ('p1', '2026-01-01 10:00:05', 'a', 'first'), + ('p1', '2026-01-01 10:00:05', 'z', null), + ('p1', '2026-01-01 10:02:05', 'a', 'last'); + +select pump, _wstart, + max_by(value, ts, tie) as latest_value, + max_by_non_null(value, ts, tie) as latest_non_null_value +from window_readings +group by pump interval(ts, 1, minute) gapfill(partition) fill(null) +order by pump, _wstart; + +drop database max_by_bvt; diff --git a/test/distributed/cases/function/func_avg_numeric_contract.result b/test/distributed/cases/function/func_avg_numeric_contract.result new file mode 100644 index 0000000000000..0a670cfec8723 --- /dev/null +++ b/test/distributed/cases/function/func_avg_numeric_contract.result @@ -0,0 +1,14 @@ +select round(cast(0.125 as double), 2) as p0125, +round(cast(2.675 as double), 2) as p2675, +round(cast(-0.125 as double), 2) as n0125, +round(cast(-2.675 as double), 2) as n2675; +➤ p0125[8,54,0] ¦ p2675[8,54,0] ¦ n0125[8,54,0] ¦ n2675[8,54,0] 𝄀 +0.12 ¦ 2.68 ¦ -0.12 ¦ -2.68 +select cast(avg(v) as char) as decimal_avg +from ( +select cast(0.10 as decimal(18,2)) v +union all +select cast(0.20 as decimal(18,2)) +) x; +➤ decimal_avg[12,-1,0] 𝄀 +0.15000000 diff --git a/test/distributed/cases/function/func_avg_numeric_contract.test b/test/distributed/cases/function/func_avg_numeric_contract.test new file mode 100644 index 0000000000000..a434dfcbc0b55 --- /dev/null +++ b/test/distributed/cases/function/func_avg_numeric_contract.test @@ -0,0 +1,14 @@ +# MongoDB aggregate-v1 uses the existing MO numeric contract. These are +# ordinary SQL regressions and intentionally do not require MongoDB. + +select round(cast(0.125 as double), 2) as p0125, + round(cast(2.675 as double), 2) as p2675, + round(cast(-0.125 as double), 2) as n0125, + round(cast(-2.675 as double), 2) as n2675; + +select cast(avg(v) as char) as decimal_avg +from ( + select cast(0.10 as decimal(18,2)) v + union all + select cast(0.20 as decimal(18,2)) +) x; diff --git a/test/distributed/cases/git4data/clone/clone_sys_db_table_to_new_db_table.result b/test/distributed/cases/git4data/clone/clone_sys_db_table_to_new_db_table.result index 7d78c9de59d47..6089edbe3c921 100644 --- a/test/distributed/cases/git4data/clone/clone_sys_db_table_to_new_db_table.result +++ b/test/distributed/cases/git4data/clone/clone_sys_db_table_to_new_db_table.result @@ -156,6 +156,8 @@ mo_indexes mo_iscp_log mo_locks mo_merge_settings +mo_mongodb_connections +mo_mongodb_tables mo_mysql_compatibility_mode mo_partition_metadata mo_partition_tables @@ -221,6 +223,8 @@ mo_indexes mo_iscp_log mo_locks mo_merge_settings +mo_mongodb_connections +mo_mongodb_tables mo_mysql_compatibility_mode mo_partition_metadata mo_partition_tables diff --git a/test/distributed/cases/metadata/information_schema.result b/test/distributed/cases/metadata/information_schema.result index 54f4914d05401..fdd40f51ae2cc 100644 --- a/test/distributed/cases/metadata/information_schema.result +++ b/test/distributed/cases/metadata/information_schema.result @@ -49,6 +49,8 @@ def mo_catalog mo_index_update BASE TABLE Tae def mo_catalog mo_indexes BASE TABLE Tae def mo_catalog mo_iscp_log BASE TABLE Tae def mo_catalog mo_merge_settings BASE TABLE Tae +def mo_catalog mo_mongodb_connections BASE TABLE Tae +def mo_catalog mo_mongodb_tables BASE TABLE Tae def mo_catalog mo_mysql_compatibility_mode BASE TABLE Tae def mo_catalog mo_partition_metadata BASE TABLE Tae def mo_catalog mo_partition_tables BASE TABLE Tae diff --git a/test/distributed/cases/mo_cloud/mo_cloud.result b/test/distributed/cases/mo_cloud/mo_cloud.result index 80c6e908821ba..75351f466f315 100644 --- a/test/distributed/cases/mo_cloud/mo_cloud.result +++ b/test/distributed/cases/mo_cloud/mo_cloud.result @@ -832,6 +832,8 @@ mo_catalog ¦ mo_iceberg_tables ¦ r ¦ accountadmin 𝄀 mo_catalog ¦ mo_increment_columns ¦ ¦ accountadmin 𝄀 mo_catalog ¦ mo_indexes ¦ r ¦ accountadmin 𝄀 mo_catalog ¦ mo_locks ¦ v ¦ accountadmin 𝄀 +mo_catalog ¦ mo_mongodb_connections ¦ r ¦ accountadmin 𝄀 +mo_catalog ¦ mo_mongodb_tables ¦ r ¦ accountadmin 𝄀 mo_catalog ¦ mo_mysql_compatibility_mode ¦ r ¦ accountadmin 𝄀 mo_catalog ¦ mo_partition_metadata ¦ r ¦ accountadmin 𝄀 mo_catalog ¦ mo_partition_tables ¦ r ¦ accountadmin 𝄀 diff --git a/test/distributed/cases/optimizer/column_pruning.result b/test/distributed/cases/optimizer/column_pruning.result index c21d43bbac63b..1f884f516f217 100644 --- a/test/distributed/cases/optimizer/column_pruning.result +++ b/test/distributed/cases/optimizer/column_pruning.result @@ -126,4 +126,126 @@ insert into tw values ('2024-01-01 00:00:00', 1), ('2024-01-01 12:00:00', 2); select _wend, max(v) from tw interval(ts, 1, day); _wend max(v) 2024-01-02 00:00:00 2 +create table tws(ts timestamp(3) primary key, v int); +insert into tws values +('2023-08-01 00:00:00', 10), ('2023-08-01 00:00:01', 20), +('2023-08-01 00:00:06', 30), ('2023-08-01 00:00:07', 40); +select _wstart, _wend, max(v), min(v) from tws interval(ts, 5, second); +➤ _wstart[93,64,0] ¦ _wend[93,64,0] ¦ max(v)[4,32,0] ¦ min(v)[4,32,0] 𝄀 +2023-08-01 00:00:00 ¦ 2023-08-01 00:00:05 ¦ 20 ¦ 10 𝄀 +2023-08-01 00:00:05 ¦ 2023-08-01 00:00:10 ¦ 40 ¦ 30 +select c from (select _wstart as a, max(v) as b, min(v) as c from tws interval(ts, 5, second)) x; +➤ c[4,32,0] 𝄀 +10 𝄀 +30 +select a from (select _wstart as a, max(v) as b, min(v) as c from tws interval(ts, 5, second)) x; +➤ a[93,64,0] 𝄀 +2023-08-01 00:00:00 𝄀 +2023-08-01 00:00:05 +select d from (select _wstart as a, _wend as d, max(v) as b from tws interval(ts, 5, second)) x; +➤ d[93,64,0] 𝄀 +2023-08-01 00:00:05 𝄀 +2023-08-01 00:00:10 +select c from (select _wstart as a, max(v) as b, min(v) as c from tws interval(ts, 10, second) sliding(5, second)) x; +➤ c[4,32,0] 𝄀 +10 𝄀 +30 +select a from (select _wstart as a, max(v) as b, min(v) as c from tws interval(ts, 10, second) sliding(5, second)) x; +➤ a[93,64,0] 𝄀 +2023-08-01 00:00:00 𝄀 +2023-08-01 00:00:05 +select c from (select _wstart as a, _wend as d, max(v) as b, min(v) as c from tws interval(ts, 5, second) fill(prev)) x; +➤ c[4,32,0] 𝄀 +10 𝄀 +30 +select c from (select _wstart as a, max(v) as b, min(v) as c from tws interval(ts, 5, second) fill(linear)) x; +➤ c[4,32,0] 𝄀 +10 𝄀 +30 +select c from (select _wstart as a, max(v) as b, min(v) as c from tws interval(ts, 5, second) fill(value, 99)) x; +➤ c[4,32,0] 𝄀 +10 𝄀 +30 +select 1 from (select _wstart as a, max(v) as b from tws interval(ts, 5, second)) x; +➤ 1[-5,64,0] 𝄀 +1 𝄀 +1 +select count(*) from (select _wstart as a, max(v) as b from tws interval(ts, 5, second)) x; +➤ count(*)[-5,64,0] 𝄀 +2 +select 1 from (select max(v) as b from tws interval(ts, 5, second)) x; +➤ 1[-5,64,0] 𝄀 +1 𝄀 +1 +create table tw_empty(ts timestamp(3) primary key, v int); +select _wstart, max(v) from tw_empty interval(ts, 5, second); +➤ _wstart[93,64,0] ¦ max(v)[4,32,0] +select 1 from (select _wstart as a, max(v) as b from tw_empty interval(ts, 5, second)) x; +➤ 1[-5,64,0] +create table twp(ts timestamp(3), p int, v int); +insert into twp values +('2023-08-01 00:00:00', 1, 10), ('2023-08-01 00:00:01', 1, 20), +('2023-08-01 00:00:06', 1, 30), ('2023-08-01 00:00:00', 2, 100), +('2023-08-01 00:00:07', 2, 400); +select _wstart, p, max(v) from twp group by p interval(ts, 5, second) order by p, _wstart; +➤ _wstart[93,64,0] ¦ p[4,32,0] ¦ max(v)[4,32,0] 𝄀 +2023-08-01 00:00:00 ¦ 1 ¦ 20 𝄀 +2023-08-01 00:00:05 ¦ 1 ¦ 30 𝄀 +2023-08-01 00:00:00 ¦ 2 ¦ 100 𝄀 +2023-08-01 00:00:05 ¦ 2 ¦ 400 +select _wstart, _wend, p, max(v), min(v) from twp group by p interval(ts, 5, second) order by p, _wstart; +➤ _wstart[93,64,0] ¦ _wend[93,64,0] ¦ p[4,32,0] ¦ max(v)[4,32,0] ¦ min(v)[4,32,0] 𝄀 +2023-08-01 00:00:00 ¦ 2023-08-01 00:00:05 ¦ 1 ¦ 20 ¦ 10 𝄀 +2023-08-01 00:00:05 ¦ 2023-08-01 00:00:10 ¦ 1 ¦ 30 ¦ 30 𝄀 +2023-08-01 00:00:00 ¦ 2023-08-01 00:00:05 ¦ 2 ¦ 100 ¦ 100 𝄀 +2023-08-01 00:00:05 ¦ 2023-08-01 00:00:10 ¦ 2 ¦ 400 ¦ 400 +select p, _wstart, max(v), min(v) from twp group by p interval(ts, 10, second) sliding(5, second) order by p, _wstart; +➤ p[4,32,0] ¦ _wstart[93,64,0] ¦ max(v)[4,32,0] ¦ min(v)[4,32,0] 𝄀 +1 ¦ 2023-08-01 00:00:00 ¦ 30 ¦ 10 𝄀 +1 ¦ 2023-08-01 00:00:05 ¦ 30 ¦ 30 𝄀 +2 ¦ 2023-08-01 00:00:00 ¦ 400 ¦ 100 𝄀 +2 ¦ 2023-08-01 00:00:05 ¦ 400 ¦ 400 +select b from (select _wstart as a, p, max(v) as b from twp group by p interval(ts, 5, second)) x order by b; +➤ b[4,32,0] 𝄀 +20 𝄀 +30 𝄀 +100 𝄀 +400 +select count(*) from (select _wstart as a, p, max(v) as b from twp group by p interval(ts, 5, second)) x; +➤ count(*)[-5,64,0] 𝄀 +4 +create table twf(ts datetime, p int, v int); +insert into twf values +('2026-01-01 00:00:00', 1, 10), ('2026-01-01 00:00:07', 1, null), +('2026-01-01 00:00:00', 2, null), ('2026-01-01 00:00:07', 2, 40); +select p, _wstart, max(v) from twf group by p interval(ts, 5, second) order by p, _wstart; +➤ p[4,32,0] ¦ _wstart[93,64,0] ¦ max(v)[4,32,0] 𝄀 +1 ¦ 2026-01-01 00:00:00 ¦ 10 𝄀 +1 ¦ 2026-01-01 00:00:05 ¦ null 𝄀 +2 ¦ 2026-01-01 00:00:00 ¦ null 𝄀 +2 ¦ 2026-01-01 00:00:05 ¦ 40 +select p, _wstart, max(v) from twf group by p interval(ts, 5, second) fill(prev) order by p, _wstart; +➤ p[4,32,0] ¦ _wstart[93,64,0] ¦ max(v)[4,32,0] 𝄀 +1 ¦ 2026-01-01 00:00:00 ¦ 10 𝄀 +1 ¦ 2026-01-01 00:00:05 ¦ 10 𝄀 +2 ¦ 2026-01-01 00:00:00 ¦ null 𝄀 +2 ¦ 2026-01-01 00:00:05 ¦ 40 +select p, _wstart, max(v) from twf group by p interval(ts, 5, second) fill(next) order by p, _wstart; +➤ p[4,32,0] ¦ _wstart[93,64,0] ¦ max(v)[4,32,0] 𝄀 +1 ¦ 2026-01-01 00:00:00 ¦ 10 𝄀 +1 ¦ 2026-01-01 00:00:05 ¦ null 𝄀 +2 ¦ 2026-01-01 00:00:00 ¦ 40 𝄀 +2 ¦ 2026-01-01 00:00:05 ¦ 40 +select p, _wstart, max(v) from twf group by p interval(ts, 5, second) fill(value, 99) order by p, _wstart; +➤ p[4,32,0] ¦ _wstart[93,64,0] ¦ max(v)[4,32,0] 𝄀 +1 ¦ 2026-01-01 00:00:00 ¦ 10 𝄀 +1 ¦ 2026-01-01 00:00:05 ¦ 99 𝄀 +2 ¦ 2026-01-01 00:00:00 ¦ 99 𝄀 +2 ¦ 2026-01-01 00:00:05 ¦ 40 +select p, _wstart, max(v) from twf group by p interval(ts, 10, second) sliding(5, second) fill(prev) order by p, _wstart; +➤ p[4,32,0] ¦ _wstart[93,64,0] ¦ max(v)[4,32,0] 𝄀 +1 ¦ 2026-01-01 00:00:00 ¦ 10 𝄀 +1 ¦ 2026-01-01 00:00:05 ¦ 10 𝄀 +2 ¦ 2026-01-01 00:00:00 ¦ 40 𝄀 +2 ¦ 2026-01-01 00:00:05 ¦ 40 drop database column_pruning; diff --git a/test/distributed/cases/optimizer/column_pruning.test b/test/distributed/cases/optimizer/column_pruning.test index ac8f758e88cb6..281c3c4818d38 100644 --- a/test/distributed/cases/optimizer/column_pruning.test +++ b/test/distributed/cases/optimizer/column_pruning.test @@ -90,4 +90,69 @@ create table tw(ts timestamp, v int); insert into tw values ('2024-01-01 00:00:00', 1), ('2024-01-01 12:00:00', 2); select _wend, max(v) from tw interval(ts, 1, day); +-- A time window's outputs are addressed by physical slot. Discarding any of +-- them compacts those slots, so each surviving output must still resolve to +-- its own value rather than to the neighbour that used to occupy the position. +create table tws(ts timestamp(3) primary key, v int); +insert into tws values + ('2023-08-01 00:00:00', 10), ('2023-08-01 00:00:01', 20), + ('2023-08-01 00:00:06', 30), ('2023-08-01 00:00:07', 40); + +-- baseline: every output consumed +select _wstart, _wend, max(v), min(v) from tws interval(ts, 5, second); + +-- only the trailing aggregate survives +select c from (select _wstart as a, max(v) as b, min(v) as c from tws interval(ts, 5, second)) x; +-- only the leading boundary survives +select a from (select _wstart as a, max(v) as b, min(v) as c from tws interval(ts, 5, second)) x; +-- _wstart discarded, _wend kept +select d from (select _wstart as a, _wend as d, max(v) as b from tws interval(ts, 5, second)) x; +-- same shapes with sliding windows +select c from (select _wstart as a, max(v) as b, min(v) as c from tws interval(ts, 10, second) sliding(5, second)) x; +select a from (select _wstart as a, max(v) as b, min(v) as c from tws interval(ts, 10, second) sliding(5, second)) x; + +-- fill() reads the window's aggregates by position, so its columns have to be +-- pruned in step with them. +select c from (select _wstart as a, _wend as d, max(v) as b, min(v) as c from tws interval(ts, 5, second) fill(prev)) x; +select c from (select _wstart as a, max(v) as b, min(v) as c from tws interval(ts, 5, second) fill(linear)) x; +select c from (select _wstart as a, max(v) as b, min(v) as c from tws interval(ts, 5, second) fill(value, 99)) x; + +-- Every value is discarded, but one row per window must still be produced. +select 1 from (select _wstart as a, max(v) as b from tws interval(ts, 5, second)) x; +select count(*) from (select _wstart as a, max(v) as b from tws interval(ts, 5, second)) x; +select 1 from (select max(v) as b from tws interval(ts, 5, second)) x; + +-- Empty input produces no windows. +create table tw_empty(ts timestamp(3) primary key, v int); +select _wstart, max(v) from tw_empty interval(ts, 5, second); +select 1 from (select _wstart as a, max(v) as b from tw_empty interval(ts, 5, second)) x; + +-- GROUP BY alongside a time window partitions it: each group gets its own +-- windows rather than sharing one stream with the others. +create table twp(ts timestamp(3), p int, v int); +insert into twp values + ('2023-08-01 00:00:00', 1, 10), ('2023-08-01 00:00:01', 1, 20), + ('2023-08-01 00:00:06', 1, 30), ('2023-08-01 00:00:00', 2, 100), + ('2023-08-01 00:00:07', 2, 400); + +select _wstart, p, max(v) from twp group by p interval(ts, 5, second) order by p, _wstart; +select _wstart, _wend, p, max(v), min(v) from twp group by p interval(ts, 5, second) order by p, _wstart; +select p, _wstart, max(v), min(v) from twp group by p interval(ts, 10, second) sliding(5, second) order by p, _wstart; +-- the partition key decides row grouping, so it is kept even when unselected +select b from (select _wstart as a, p, max(v) as b from twp group by p interval(ts, 5, second)) x order by b; +select count(*) from (select _wstart as a, p, max(v) as b from twp group by p interval(ts, 5, second)) x; + +-- fill() must not carry values across partitions: each group's leading NULL +-- has no previous value and its trailing NULL has no next value. +create table twf(ts datetime, p int, v int); +insert into twf values + ('2026-01-01 00:00:00', 1, 10), ('2026-01-01 00:00:07', 1, null), + ('2026-01-01 00:00:00', 2, null), ('2026-01-01 00:00:07', 2, 40); + +select p, _wstart, max(v) from twf group by p interval(ts, 5, second) order by p, _wstart; +select p, _wstart, max(v) from twf group by p interval(ts, 5, second) fill(prev) order by p, _wstart; +select p, _wstart, max(v) from twf group by p interval(ts, 5, second) fill(next) order by p, _wstart; +select p, _wstart, max(v) from twf group by p interval(ts, 5, second) fill(value, 99) order by p, _wstart; +select p, _wstart, max(v) from twf group by p interval(ts, 10, second) sliding(5, second) fill(prev) order by p, _wstart; + drop database column_pruning; diff --git a/test/distributed/cases/snapshot/cluster/restore_cluster_table.result b/test/distributed/cases/snapshot/cluster/restore_cluster_table.result index 5fab60c5c59d6..5ed20b2bfc650 100644 --- a/test/distributed/cases/snapshot/cluster/restore_cluster_table.result +++ b/test/distributed/cases/snapshot/cluster/restore_cluster_table.result @@ -433,6 +433,8 @@ mo_indexes mo_iscp_log mo_locks mo_merge_settings +mo_mongodb_connections +mo_mongodb_tables mo_mysql_compatibility_mode mo_partition_metadata mo_partition_tables @@ -559,6 +561,8 @@ mo_indexes mo_iscp_log mo_locks mo_merge_settings +mo_mongodb_connections +mo_mongodb_tables mo_mysql_compatibility_mode mo_partition_metadata mo_partition_tables diff --git a/test/distributed/cases/snapshot/cluster_level_snapshot_restore_cluster.result b/test/distributed/cases/snapshot/cluster_level_snapshot_restore_cluster.result index ed5a481765ad5..c15e4d562cf15 100644 --- a/test/distributed/cases/snapshot/cluster_level_snapshot_restore_cluster.result +++ b/test/distributed/cases/snapshot/cluster_level_snapshot_restore_cluster.result @@ -468,6 +468,8 @@ mo_indexes mo_iscp_log mo_locks mo_merge_settings +mo_mongodb_connections +mo_mongodb_tables mo_mysql_compatibility_mode mo_partition_metadata mo_partition_tables @@ -600,6 +602,8 @@ mo_indexes mo_iscp_log mo_locks mo_merge_settings +mo_mongodb_connections +mo_mongodb_tables mo_mysql_compatibility_mode mo_partition_metadata mo_partition_tables diff --git a/test/distributed/cases/snapshot/snapshotRead.result b/test/distributed/cases/snapshot/snapshotRead.result index 3542d7f4f5d08..39d082f7d36a7 100644 --- a/test/distributed/cases/snapshot/snapshotRead.result +++ b/test/distributed/cases/snapshot/snapshotRead.result @@ -607,7 +607,7 @@ drop snapshot if exists sp06; create snapshot sp06 for account; select count(*) from mo_catalog.mo_tables{snapshot = sp06} where reldatabase = 'mo_catalog'; count(*) -76 +78 select * from mo_catalog.mo_database{snapshot = sp06} where datname = 'mo_catalog'; dat_id datname dat_catalog_name dat_createsql owner creator created_time account_id dat_type 1 mo_catalog mo_catalog 0 0 2025-11-21 09:44:39 0 diff --git a/test/distributed/cases/table/system_table_cases.result b/test/distributed/cases/table/system_table_cases.result index edd058eac7e7a..68e05bf175f22 100644 --- a/test/distributed/cases/table/system_table_cases.result +++ b/test/distributed/cases/table/system_table_cases.result @@ -158,7 +158,7 @@ SELECT COUNT(NULL) FROM (SELECT * FROM tables LIMIT 10) AS temp; 0 SELECT COUNT(*) FROM table_constraints; ➤ COUNT(*)[-5,64,0] 𝄀 -182 +191 USE mo_catalog; SHOW CREATE TABLE mo_columns; ➤ Table[12,-1,0] ¦ Create Table[12,-1,0] 𝄀 diff --git a/test/distributed/cases/task/sql_task_procedure_atomic.result b/test/distributed/cases/task/sql_task_procedure_atomic.result new file mode 100644 index 0000000000000..8c094a0965ba9 --- /dev/null +++ b/test/distributed/cases/task/sql_task_procedure_atomic.result @@ -0,0 +1,39 @@ +drop database if exists sql_task_procedure_atomic; +create database sql_task_procedure_atomic; +use sql_task_procedure_atomic; +create table target_rows(id int primary key); +create table ingest_control(id int primary key, watermark int not null); +insert into ingest_control values (1, 0); +create procedure ingest_once() ' +begin +insert into target_rows values (1); +update ingest_control set watermark = 1 where id = 1; +insert into table_that_does_not_exist values (1); +end'; +call ingest_once(); +no such table sql_task_procedure_atomic.table_that_does_not_exist +select count(*) as target_count from target_rows; +target_count +0 +select watermark from ingest_control where id = 1; +watermark +0 +create task task_ingest_once as begin call ingest_once(); end; +execute task task_ingest_once; +no such table sql_task_procedure_atomic.table_that_does_not_exist +select count(*) as target_count from target_rows; +target_count +0 +select watermark from ingest_control where id = 1; +watermark +0 +select status +from mo_task.sql_task_run +where task_name = 'task_ingest_once' +order by run_id desc +limit 1; +status +FAILED +drop task task_ingest_once; +drop procedure ingest_once; +drop database sql_task_procedure_atomic; diff --git a/test/distributed/cases/task/sql_task_procedure_atomic.sql b/test/distributed/cases/task/sql_task_procedure_atomic.sql new file mode 100644 index 0000000000000..d02174d25f665 --- /dev/null +++ b/test/distributed/cases/task/sql_task_procedure_atomic.sql @@ -0,0 +1,38 @@ +-- Copyright 2026 Matrix Origin +-- Licensed under the Apache License, Version 2.0. + +drop database if exists sql_task_procedure_atomic; +create database sql_task_procedure_atomic; +use sql_task_procedure_atomic; + +create table target_rows(id int primary key); +create table ingest_control(id int primary key, watermark int not null); +insert into ingest_control values (1, 0); + +create procedure ingest_once() ' +begin + insert into target_rows values (1); + update ingest_control set watermark = 1 where id = 1; + insert into table_that_does_not_exist values (1); +end'; + +-- A direct CALL must roll back both the target and the checkpoint. +call ingest_once(); +select count(*) as target_count from target_rows; +select watermark from ingest_control where id = 1; + +-- SQL TASK must preserve the same all-or-nothing contract when its body is a +-- single CALL. This is the transaction shape used by MongoDB ingestion. +create task task_ingest_once as begin call ingest_once(); end; +execute task task_ingest_once; +select count(*) as target_count from target_rows; +select watermark from ingest_control where id = 1; +select status + from mo_task.sql_task_run + where task_name = 'task_ingest_once' + order by run_id desc + limit 1; + +drop task task_ingest_once; +drop procedure ingest_once; +drop database sql_task_procedure_atomic; diff --git a/test/distributed/cases/tenant/privilege/create_user_default_role.result b/test/distributed/cases/tenant/privilege/create_user_default_role.result index 6be95a1f68a83..646d1f358b76c 100644 --- a/test/distributed/cases/tenant/privilege/create_user_default_role.result +++ b/test/distributed/cases/tenant/privilege/create_user_default_role.result @@ -49,6 +49,8 @@ mo_indexes mo_iscp_log mo_locks mo_merge_settings +mo_mongodb_connections +mo_mongodb_tables mo_mysql_compatibility_mode mo_partition_metadata mo_partition_tables diff --git a/test/distributed/cases/window/time_window_gapfill.result b/test/distributed/cases/window/time_window_gapfill.result new file mode 100644 index 0000000000000..97d2a06064a87 --- /dev/null +++ b/test/distributed/cases/window/time_window_gapfill.result @@ -0,0 +1,93 @@ +drop database if exists time_window_gapfill_bvt; +create database time_window_gapfill_bvt; +use time_window_gapfill_bvt; +create table readings(pump varchar(8), ts datetime, value int); +insert into readings values +('p1', '2026-01-01 10:00:00', 1), +('p1', '2026-01-01 10:02:00', 3), +('p2', '2026-01-01 11:00:00', 7), +('p3', '2026-01-01 23:59:00', 10), +('p3', '2026-01-02 00:01:00', 30); +select pump, _wstart, _wend, sum(value) as value_sum +from readings +group by pump interval(ts, 1, minute) gapfill(partition) +order by pump, _wstart; +➤ pump[12,-1,0] ¦ _wstart[93,64,0] ¦ _wend[93,64,0] ¦ value_sum[3,38,0] 𝄀 +p1 ¦ 2026-01-01 10:00:00 ¦ 2026-01-01 10:01:00 ¦ 1 𝄀 +p1 ¦ 2026-01-01 10:01:00 ¦ 2026-01-01 10:02:00 ¦ null 𝄀 +p1 ¦ 2026-01-01 10:02:00 ¦ 2026-01-01 10:03:00 ¦ 3 𝄀 +p2 ¦ 2026-01-01 11:00:00 ¦ 2026-01-01 11:01:00 ¦ 7 𝄀 +p3 ¦ 2026-01-01 23:59:00 ¦ 2026-01-02 00:00:00 ¦ 10 𝄀 +p3 ¦ 2026-01-02 00:00:00 ¦ 2026-01-02 00:01:00 ¦ null 𝄀 +p3 ¦ 2026-01-02 00:01:00 ¦ 2026-01-02 00:02:00 ¦ 30 +select pump, _wstart, coalesce(count(*), 0) as reading_count +from readings +group by pump interval(ts, 1, minute) gapfill(partition) fill(null) +order by pump, _wstart; +➤ pump[12,-1,0] ¦ _wstart[93,64,0] ¦ reading_count[-5,64,0] 𝄀 +p1 ¦ 2026-01-01 10:00:00 ¦ 1 𝄀 +p1 ¦ 2026-01-01 10:01:00 ¦ 0 𝄀 +p1 ¦ 2026-01-01 10:02:00 ¦ 1 𝄀 +p2 ¦ 2026-01-01 11:00:00 ¦ 1 𝄀 +p3 ¦ 2026-01-01 23:59:00 ¦ 1 𝄀 +p3 ¦ 2026-01-02 00:00:00 ¦ 0 𝄀 +p3 ¦ 2026-01-02 00:01:00 ¦ 1 +select pump, _wstart, sum(value) as value_sum +from readings +group by pump interval(ts, 1, minute) gapfill(partition) fill(value, 99) +order by pump, _wstart; +➤ pump[12,-1,0] ¦ _wstart[93,64,0] ¦ value_sum[3,38,0] 𝄀 +p1 ¦ 2026-01-01 10:00:00 ¦ 1 𝄀 +p1 ¦ 2026-01-01 10:01:00 ¦ 99 𝄀 +p1 ¦ 2026-01-01 10:02:00 ¦ 3 𝄀 +p2 ¦ 2026-01-01 11:00:00 ¦ 7 𝄀 +p3 ¦ 2026-01-01 23:59:00 ¦ 10 𝄀 +p3 ¦ 2026-01-02 00:00:00 ¦ 99 𝄀 +p3 ¦ 2026-01-02 00:01:00 ¦ 30 +select pump, _wstart, sum(value) as value_sum +from readings +group by pump interval(ts, 1, minute) gapfill(partition) fill(prev) +order by pump, _wstart; +➤ pump[12,-1,0] ¦ _wstart[93,64,0] ¦ value_sum[3,38,0] 𝄀 +p1 ¦ 2026-01-01 10:00:00 ¦ 1 𝄀 +p1 ¦ 2026-01-01 10:01:00 ¦ 1 𝄀 +p1 ¦ 2026-01-01 10:02:00 ¦ 3 𝄀 +p2 ¦ 2026-01-01 11:00:00 ¦ 7 𝄀 +p3 ¦ 2026-01-01 23:59:00 ¦ 10 𝄀 +p3 ¦ 2026-01-02 00:00:00 ¦ 10 𝄀 +p3 ¦ 2026-01-02 00:01:00 ¦ 30 +select pump, _wstart, sum(value) as value_sum +from readings +group by pump interval(ts, 1, minute) gapfill(partition) fill(next) +order by pump, _wstart; +➤ pump[12,-1,0] ¦ _wstart[93,64,0] ¦ value_sum[3,38,0] 𝄀 +p1 ¦ 2026-01-01 10:00:00 ¦ 1 𝄀 +p1 ¦ 2026-01-01 10:01:00 ¦ 3 𝄀 +p1 ¦ 2026-01-01 10:02:00 ¦ 3 𝄀 +p2 ¦ 2026-01-01 11:00:00 ¦ 7 𝄀 +p3 ¦ 2026-01-01 23:59:00 ¦ 10 𝄀 +p3 ¦ 2026-01-02 00:00:00 ¦ 30 𝄀 +p3 ¦ 2026-01-02 00:01:00 ¦ 30 +select pump, _wstart, sum(value) as value_sum +from readings +group by pump interval(ts, 1, minute) gapfill(partition) fill(linear) +order by pump, _wstart; +➤ pump[12,-1,0] ¦ _wstart[93,64,0] ¦ value_sum[3,38,0] 𝄀 +p1 ¦ 2026-01-01 10:00:00 ¦ 1 𝄀 +p1 ¦ 2026-01-01 10:01:00 ¦ 2 𝄀 +p1 ¦ 2026-01-01 10:02:00 ¦ 3 𝄀 +p2 ¦ 2026-01-01 11:00:00 ¦ 7 𝄀 +p3 ¦ 2026-01-01 23:59:00 ¦ 10 𝄀 +p3 ¦ 2026-01-02 00:00:00 ¦ 20 𝄀 +p3 ¦ 2026-01-02 00:01:00 ¦ 30 +select pump, _wstart, sum(value) as value_sum +from readings +group by pump interval(ts, 1, minute) fill(null) +order by pump, _wstart; +➤ pump[12,-1,0] ¦ _wstart[93,64,0] ¦ value_sum[-5,64,0] 𝄀 +p1 ¦ 2026-01-01 10:00:00 ¦ 1 𝄀 +p1 ¦ 2026-01-01 10:02:00 ¦ 3 𝄀 +p2 ¦ 2026-01-01 11:00:00 ¦ 7 𝄀 +p3 ¦ 2026-01-01 23:59:00 ¦ 10 𝄀 +p3 ¦ 2026-01-02 00:01:00 ¦ 30 +drop database time_window_gapfill_bvt; diff --git a/test/distributed/cases/window/time_window_gapfill.test b/test/distributed/cases/window/time_window_gapfill.test new file mode 100644 index 0000000000000..b70bf9f62ac79 --- /dev/null +++ b/test/distributed/cases/window/time_window_gapfill.test @@ -0,0 +1,49 @@ +drop database if exists time_window_gapfill_bvt; +create database time_window_gapfill_bvt; +use time_window_gapfill_bvt; + +create table readings(pump varchar(8), ts datetime, value int); +insert into readings values + ('p1', '2026-01-01 10:00:00', 1), + ('p1', '2026-01-01 10:02:00', 3), + ('p2', '2026-01-01 11:00:00', 7), + ('p3', '2026-01-01 23:59:00', 10), + ('p3', '2026-01-02 00:01:00', 30); + +select pump, _wstart, _wend, sum(value) as value_sum +from readings +group by pump interval(ts, 1, minute) gapfill(partition) +order by pump, _wstart; + +select pump, _wstart, coalesce(count(*), 0) as reading_count +from readings +group by pump interval(ts, 1, minute) gapfill(partition) fill(null) +order by pump, _wstart; + +select pump, _wstart, sum(value) as value_sum +from readings +group by pump interval(ts, 1, minute) gapfill(partition) fill(value, 99) +order by pump, _wstart; + +select pump, _wstart, sum(value) as value_sum +from readings +group by pump interval(ts, 1, minute) gapfill(partition) fill(prev) +order by pump, _wstart; + +select pump, _wstart, sum(value) as value_sum +from readings +group by pump interval(ts, 1, minute) gapfill(partition) fill(next) +order by pump, _wstart; + +select pump, _wstart, sum(value) as value_sum +from readings +group by pump interval(ts, 1, minute) gapfill(partition) fill(linear) +order by pump, _wstart; + +# Existing FILL(NULL) must not generate absent buckets. +select pump, _wstart, sum(value) as value_sum +from readings +group by pump interval(ts, 1, minute) fill(null) +order by pump, _wstart; + +drop database time_window_gapfill_bvt; diff --git a/test/distributed/cases/zz_accesscontrol/create_account.result b/test/distributed/cases/zz_accesscontrol/create_account.result index 19c17c224538a..60f69690ef86d 100644 --- a/test/distributed/cases/zz_accesscontrol/create_account.result +++ b/test/distributed/cases/zz_accesscontrol/create_account.result @@ -179,6 +179,8 @@ mo_iceberg_residency_policy mo_iceberg_tables mo_indexes mo_locks +mo_mongodb_connections +mo_mongodb_tables mo_mysql_compatibility_mode mo_partition_metadata mo_partition_tables diff --git a/test/iceberg/README.md b/test/iceberg/README.md index 64a01684c554b..6736f803e550a 100644 --- a/test/iceberg/README.md +++ b/test/iceberg/README.md @@ -6,7 +6,7 @@ remaining external Iceberg tests: - `ICE-TEST-124`: credential vending - `ICE-TEST-130`: public dataset read-only checks - `ICE-TEST-131..134`: Tier C sandbox catalog checks -- `ICE-TEST-135`: NESR demo checks +- `ICE-TEST-135`: reference-profile demo checks - `ICE-TEST-156..159`: real-file golden checks The templates are intentionally not marked complete in the test plan. A test is @@ -22,7 +22,7 @@ report artifact. | `tier_b_public_dataset_scenarios.example.json` | Public dataset count/filter/projection scenarios. | | `nyc_tlc_perf_queries.example.sql` | Optional NYC TLC performance query set for local benchmark runs. | | `tier_c_sandbox_scenarios.example.json` | Polaris/Open Catalog/Gravitino REST, remote signing, server planning and capability scenarios. | -| `tier_d_nesr_scenarios.example.json` | NESR publish/KPI/residency scenarios. | +| `tier_d_reference_scenarios.example.json` | Reference-profile publish/KPI/residency scenarios. | | `golden_real_scenarios.example.json` | Real-file timestamp, bucket/truncate, field-id and row ordinal golden scenarios. | ## Local structural gates @@ -166,7 +166,7 @@ pass only when the query fails and the output contains the expected error text. Current templates use it for: - expired credential fail-fast in `ICE-TEST-124` -- KSA residency denial in `ICE-TEST-135` +- regional residency denial in `ICE-TEST-135` ## Artifact requirements diff --git a/test/iceberg/external_profiles.env.example b/test/iceberg/external_profiles.env.example index 1580ed698f6f9..eed1590a84392 100644 --- a/test/iceberg/external_profiles.env.example +++ b/test/iceberg/external_profiles.env.example @@ -93,23 +93,23 @@ export MO_ICEBERG_TIER_C_SIGNER_URI='' export MO_ICEBERG_SERVER_PLANNING='' ############################################################################### -# ICE-TEST-135: Tier D NESR demo +# ICE-TEST-135: Tier D reference-profile demo ############################################################################### -export MO_ICEBERG_NESR='' -export MO_ICEBERG_NESR_CATALOG_URI='' -export MO_ICEBERG_NESR_SCENARIOS='test/iceberg/tier_d_nesr_scenarios.example.json' -export MO_ICEBERG_NESR_MO_SQL_CMD='' -export MO_ICEBERG_NESR_EXTERNAL_SQL_CMD='' -export MO_ICEBERG_NESR_EXPECTED_KPI='' -export MO_ICEBERG_NESR_NAMESPACE='' -export MO_ICEBERG_NESR_KPI_TABLE='' -export MO_ICEBERG_NESR_PUBLISH_SQL='' -export MO_ICEBERG_NESR_AUDIT_SQL='' -export MO_ICEBERG_NESR_MO_KPI_SQL='' -export MO_ICEBERG_NESR_EXTERNAL_KPI_SQL='' -export MO_ICEBERG_NESR_RESIDENCY_ASSERT_SQL='' -export MO_ICEBERG_NESR_RESIDENCY_ERROR='ICEBERG_RESIDENCY_DENIED' +export MO_ICEBERG_REFERENCE='' +export MO_ICEBERG_REFERENCE_CATALOG_URI='' +export MO_ICEBERG_REFERENCE_SCENARIOS='test/iceberg/tier_d_reference_scenarios.example.json' +export MO_ICEBERG_REFERENCE_MO_SQL_CMD='' +export MO_ICEBERG_REFERENCE_EXTERNAL_SQL_CMD='' +export MO_ICEBERG_REFERENCE_EXPECTED_KPI='' +export MO_ICEBERG_REFERENCE_NAMESPACE='' +export MO_ICEBERG_REFERENCE_KPI_TABLE='' +export MO_ICEBERG_REFERENCE_PUBLISH_SQL='' +export MO_ICEBERG_REFERENCE_AUDIT_SQL='' +export MO_ICEBERG_REFERENCE_MO_KPI_SQL='' +export MO_ICEBERG_REFERENCE_EXTERNAL_KPI_SQL='' +export MO_ICEBERG_REFERENCE_RESIDENCY_ASSERT_SQL='' +export MO_ICEBERG_REFERENCE_RESIDENCY_ERROR='ICEBERG_RESIDENCY_DENIED' ############################################################################### # ICE-TEST-156..159: real-file golden cross-engine checks diff --git a/test/iceberg/tier_d_nesr_scenarios.example.json b/test/iceberg/tier_d_nesr_scenarios.example.json deleted file mode 100644 index 009a5fef9ac1e..0000000000000 --- a/test/iceberg/tier_d_nesr_scenarios.example.json +++ /dev/null @@ -1,46 +0,0 @@ -[ - { - "id": "ICE-TEST-135", - "case_id": "ICE-TEST-135_nesr_gold_mart_kpi_publish", - "name": "nesr-gold-mart-kpi-publish", - "catalog": "${MO_ICEBERG_NESR_CATALOG_URI}", - "namespace": "${MO_ICEBERG_NESR_NAMESPACE}", - "table": "${MO_ICEBERG_NESR_KPI_TABLE}", - "ref": "main", - "comparison_mode": "ordered", - "engines": [ - { - "name": "mo", - "command_env": "MO_ICEBERG_NESR_MO_SQL_CMD", - "actions": [ - "${MO_ICEBERG_NESR_PUBLISH_SQL}", - "${MO_ICEBERG_NESR_AUDIT_SQL}" - ], - "sql": "${MO_ICEBERG_NESR_MO_KPI_SQL}" - }, - { - "name": "external", - "command_env": "MO_ICEBERG_NESR_EXTERNAL_SQL_CMD", - "sql": "${MO_ICEBERG_NESR_EXTERNAL_KPI_SQL}" - } - ] - }, - { - "id": "ICE-TEST-135", - "case_id": "ICE-TEST-135_nesr_ksa_residency_gate", - "name": "nesr-ksa-residency-gate", - "catalog": "${MO_ICEBERG_NESR_CATALOG_URI}", - "namespace": "${MO_ICEBERG_NESR_NAMESPACE}", - "table": "${MO_ICEBERG_NESR_KPI_TABLE}", - "ref": "main", - "comparison_mode": "ordered", - "engines": [ - { - "name": "mo", - "command_env": "MO_ICEBERG_NESR_MO_SQL_CMD", - "sql": "${MO_ICEBERG_NESR_RESIDENCY_ASSERT_SQL}", - "expect_error_contains": "${MO_ICEBERG_NESR_RESIDENCY_ERROR}" - } - ] - } -] diff --git a/test/iceberg/tier_d_reference_scenarios.example.json b/test/iceberg/tier_d_reference_scenarios.example.json new file mode 100644 index 0000000000000..34205d42e87bd --- /dev/null +++ b/test/iceberg/tier_d_reference_scenarios.example.json @@ -0,0 +1,46 @@ +[ + { + "id": "ICE-TEST-135", + "case_id": "ICE-TEST-135_reference_gold_mart_kpi_publish", + "name": "reference-gold-mart-kpi-publish", + "catalog": "${MO_ICEBERG_REFERENCE_CATALOG_URI}", + "namespace": "${MO_ICEBERG_REFERENCE_NAMESPACE}", + "table": "${MO_ICEBERG_REFERENCE_KPI_TABLE}", + "ref": "main", + "comparison_mode": "ordered", + "engines": [ + { + "name": "mo", + "command_env": "MO_ICEBERG_REFERENCE_MO_SQL_CMD", + "actions": [ + "${MO_ICEBERG_REFERENCE_PUBLISH_SQL}", + "${MO_ICEBERG_REFERENCE_AUDIT_SQL}" + ], + "sql": "${MO_ICEBERG_REFERENCE_MO_KPI_SQL}" + }, + { + "name": "external", + "command_env": "MO_ICEBERG_REFERENCE_EXTERNAL_SQL_CMD", + "sql": "${MO_ICEBERG_REFERENCE_EXTERNAL_KPI_SQL}" + } + ] + }, + { + "id": "ICE-TEST-135", + "case_id": "ICE-TEST-135_reference_regional_residency_gate", + "name": "reference-regional-residency-gate", + "catalog": "${MO_ICEBERG_REFERENCE_CATALOG_URI}", + "namespace": "${MO_ICEBERG_REFERENCE_NAMESPACE}", + "table": "${MO_ICEBERG_REFERENCE_KPI_TABLE}", + "ref": "main", + "comparison_mode": "ordered", + "engines": [ + { + "name": "mo", + "command_env": "MO_ICEBERG_REFERENCE_MO_SQL_CMD", + "sql": "${MO_ICEBERG_REFERENCE_RESIDENCY_ASSERT_SQL}", + "expect_error_contains": "${MO_ICEBERG_REFERENCE_RESIDENCY_ERROR}" + } + ] + } +] diff --git a/test/mongodb/README.md b/test/mongodb/README.md new file mode 100644 index 0000000000000..0f05a4244fbc5 --- /dev/null +++ b/test/mongodb/README.md @@ -0,0 +1,24 @@ +# MongoDB connector validation and operational examples + +Run package tests with `make test-mongodb-unit` and the complete local smoke with `make test-mongodb-e2e-local`. The E2E fixture is a single-node ReplicaSet using SCRAM-SHA-256, majority reads, a read-only source user, deterministic documents, a two-row cursor batch, and a random published port. Reports are written under `test/mongodb/reports/` and redacted before upload. + +## Frozen MVP contracts + +- MongoDB 8.0.12 and official Go driver v2.8.0 are the PR baseline. The product implementation accepts normal ReplicaSet seeds and SRV subject to endpoint policy; TLS/SRV and minimum supported production versions remain release gates. +- Numeric contract is `mongodb-aggregate-v1`: BSON double, `AVG(DOUBLE)`, one cursor, `max_parallelism=1`, then the existing target-compatible `FLOAT` cast. Every floating column uses the named numeric comparison contract and is excluded from `mongodb-aggregate-v1-exact`; that hash covers the exact key/count/source-batch subset with delimiter-safe hex encoding and an explicit NULL marker. This implementation enforces `max_parallelism=1` for every MongoDB external table. Local split remains a post-MVP gated task and stays disabled for this ingestion. +- Missing and BSON null both map to SQL NULL. There is no presence column in MVP. +- `try_null` is bounded per statement by `max-conversion-errors` and `max-conversion-error-rate` (the rate gate starts after 100 non-null try-conversion attempts); threshold violations fail the statement instead of silently degrading an unbounded scan. +- The indexed incremental timestamp must be declared `MONGODB_CONVERT 'try_null'`. Its BSON DateTime range is then pushed as an outward-rounded candidate and retained as an MO residual, so bounded ingestion does not pull the whole collection. A strict timestamp deliberately stays residual-only because pushdown could hide malformed source values outside the requested range. +- Incremental bounds are `[low, high)`. `low` includes the configured overlap and `high` includes a safety lag. A cursor failure restarts from the last committed watermark. +- MO does not yet expose an external-connection `USAGE` privilege object. Until it does, creating a MongoDB connection or a table mapping requires the account-admin role; ordinary users consume an existing mapping through normal table `SELECT` grants. Execution revalidates the tenant-scoped mapping ID/version, namespace, schema and connection generation before opening a cursor. + +## Backfill, cutover and rollback + +1. Run `sql/key_conflict_audit.js` against live data and every archive segment for the whole old-key period. Record gaps and the earliest recoverable timestamp; the old MO target cannot prove that no site was overwritten. +2. Create the `(device_id, site_id, window_start)` target. Install `sql/incremental_ingest.sql` for live ingestion and use `sql/bounded_backfill.sql` for bounded site/day history slices; each stored-procedure call commits its target rows and checkpoint together. Pause/retry only from a committed checkpoint. The SQL task body contains one `CALL`, because a multi-statement task body is not transactional while a top-level stored procedure is. +3. Export the same versioned columns from both shadows, sort by the row key, and run `compare_results.py`. Do not present the legacy Python `_row_hash` as the new `exact_row_hash`: omit it from both exports, or include its expected change as an exact per-row rule. Exact columns must match; all eight v1 floating columns use the explicit tolerance list (override it only with a reviewed contract change). Expected mismatches require a JSON rule containing the exact `key` array, `column`, `expected`, `actual`, and a named `rule`; unused or stale rules fail the comparison, so there is no broad ignore path. Duplicate result keys also fail instead of being silently overwritten. +4. Measure MongoDB CPU/lag/connections, scanned rows/bytes, CN memory/CPU and end-to-end p50/p95. Do not cut over until a 3-million-row bounded run completes inside the agreed five-minute budget without exceeding source limits. +5. Enable the account feature gate for shadow reads, then move only the scheduler. Old and new writers must use separate targets and watermarks. Stop the legacy ingestion workers only after the required connector gate, history repair, differential, failure recovery and owner sign-offs pass. +6. Roll back by pausing the new scheduler, waiting for its transaction to finish, restoring the old scheduler from its saved watermark, and validating that only one generation advances. Retain both targets through the rollback window. + +Production sign-offs, 30-run CI stability, source/archive backfill, performance evidence and a cutover rehearsal are external operational gates; repository code cannot mark them complete on behalf of their owners. diff --git a/test/mongodb/compare_results.py b/test/mongodb/compare_results.py new file mode 100644 index 0000000000000..797773b2661f2 --- /dev/null +++ b/test/mongodb/compare_results.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python3 +# Copyright 2026 Matrix Origin +# Licensed under the Apache License, Version 2.0. + +"""Versioned MongoDB aggregate differential oracle for sorted JSON-lines results.""" +import argparse +import hashlib +import json +import math +import sys + + +def canonical_value(value): + """Return a sortable, type-preserving identity for a JSON value.""" + if value is None: + return ("null", "") + if type(value) is bool: + return ("bool", "true" if value else "false") + if type(value) is int: + return ("integer", str(value)) + if type(value) is float: + if not math.isfinite(value): + raise ValueError("result keys must not contain non-finite numbers") + return ("float", value.hex()) + if type(value) is str: + return ("string", value) + return ("json", json.dumps(value, sort_keys=True, separators=(",", ":"), allow_nan=False)) + + +def canonical_values(values): + return tuple(canonical_value(value) for value in values) + + +def canonical(row, keys): + return canonical_values(row[key] for key in keys) + + +def digest(row): + encoded = json.dumps(row, sort_keys=True, separators=(",", ":"), allow_nan=False).encode() + return hashlib.sha256(b"mongodb-aggregate-v1\0" + encoded).hexdigest() + + +def exact_equal(left, right): + if type(left) is not type(right): + return False + if isinstance(left, dict): + return left.keys() == right.keys() and all(exact_equal(left[key], right[key]) for key in left) + if isinstance(left, list): + return len(left) == len(right) and all(exact_equal(x, y) for x, y in zip(left, right)) + if isinstance(left, float) and isinstance(right, float) and left == right == 0: + return math.copysign(1, left) == math.copysign(1, right) + return left == right + + +def load_rows(path, keys): + rows = {} + with open(path, encoding="utf-8") as source: + for line_number, line in enumerate(source, 1): + if not line.strip(): + continue + row = json.loads(line) + if not isinstance(row, dict): + raise ValueError("result row must be a JSON object at %s:%d" % (path, line_number)) + missing_keys = [key for key in keys if key not in row] + if missing_keys: + raise ValueError("result row is missing key columns %r at %s:%d" % + (missing_keys, path, line_number)) + key = canonical(row, keys) + if key in rows: + raise ValueError("duplicate row key %r at %s:%d" % (key, path, line_number)) + rows[key] = row + return rows + + +def load_rules(path): + if not path: + return {} + with open(path, encoding="utf-8") as source: + document = json.load(source) + if not isinstance(document, dict) or not isinstance(document.get("rules", []), list): + raise ValueError("expected-difference document requires a rules array") + rules = {} + for rule in document.get("rules", []): + if not isinstance(rule, dict): + raise ValueError("every expected-difference rule must be a JSON object") + key = canonical_values(rule.get("key", [])) + column = rule.get("column") + if not key or not column or not rule.get("rule") or "expected" not in rule or "actual" not in rule: + raise ValueError("every expected-difference rule requires key, column, expected, actual, and rule") + identity = (key, column) + if identity in rules: + raise ValueError("duplicate expected-difference rule for %r" % (identity,)) + rules[identity] = rule + return rules + + +def compare(expected, actual, tolerant, abs_tolerance, rules): + failures = [] + comparisons = [] + used_rules = set() + counts = {"exact-equal": 0, "tolerance-equal": 0, "expected-inconsistent": 0, "failed": 0} + for key in sorted(expected.keys() | actual.keys()): + left, right = expected.get(key), actual.get(key) + if left is None or right is None: + item = {"key": key, "class": "missing-row"} + failures.append(item) + comparisons.append(item) + counts["failed"] += 1 + continue + expected_difference_columns = set() + for column in sorted(left.keys() | right.keys()): + if column not in left or column not in right: + item = {"key": key, "column": column, "class": "missing-column", + "expected": left.get(column, ""), + "actual": right.get(column, "")} + failures.append(item) + comparisons.append(item) + counts["failed"] += 1 + continue + old, new = left[column], right[column] + if exact_equal(old, new): + counts["exact-equal"] += 1 + continue + if (column in tolerant and not isinstance(old, bool) and not isinstance(new, bool) + and isinstance(old, (int, float)) and isinstance(new, (int, float)) + and math.isclose(old, new, rel_tol=0, abs_tol=abs_tolerance)): + comparisons.append({"key": key, "column": column, "class": "tolerance-equal", + "expected": old, "actual": new}) + counts["tolerance-equal"] += 1 + continue + identity = (key, column) + rule = rules.get(identity) + if rule and exact_equal(rule["expected"], old) and exact_equal(rule["actual"], new): + comparisons.append({"key": key, "column": column, "class": "expected-inconsistent", + "rule": rule["rule"], "expected": old, "actual": new}) + used_rules.add(identity) + expected_difference_columns.add(column) + counts["expected-inconsistent"] += 1 + continue + item = {"key": key, "column": column, "class": "must-equal", + "expected": old, "actual": new} + failures.append(item) + comparisons.append(item) + counts["failed"] += 1 + + exact_left = {column: value for column, value in left.items() + if column not in tolerant and column not in expected_difference_columns} + exact_right = {column: value for column, value in right.items() + if column not in tolerant and column not in expected_difference_columns} + try: + expected_hash, actual_hash = digest(exact_left), digest(exact_right) + item = {"key": key, "class": "exact-hash", "expected": expected_hash, + "actual": actual_hash} + comparisons.append(item) + if expected_hash != actual_hash: + failure = dict(item) + failure["class"] = "exact-hash-mismatch" + failures.append(failure) + counts["failed"] += 1 + except ValueError: + # Non-finite values are already classified column-by-column and + # cannot participate in canonical JSON hashing. + comparisons.append({"key": key, "class": "exact-hash-unavailable"}) + + for identity, rule in rules.items(): + if identity not in used_rules: + item = {"key": identity[0], "column": identity[1], "class": "unused-expected-rule", + "rule": rule["rule"]} + failures.append(item) + comparisons.append(item) + counts["failed"] += 1 + return failures, comparisons, counts + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("expected") + parser.add_argument("actual") + parser.add_argument("--keys", default="device_id,site_id,window_start") + parser.add_argument( + "--tolerance-columns", + default=("temperature_celsius,humidity_percent,pressure_kpa,flow_rate_lpm," + "vibration_mm_s,voltage_volts,total_runtime_hours,active_runtime_hours"), + ) + parser.add_argument("--abs-tolerance", type=float, default=1e-9) + parser.add_argument("--expected-differences", help="versioned exact expected-difference rules JSON") + args = parser.parse_args() + keys = args.keys.split(",") + tolerant = set(filter(None, args.tolerance_columns.split(","))) + try: + expected = load_rows(args.expected, keys) + actual = load_rows(args.actual, keys) + rules = load_rules(args.expected_differences) + failures, comparisons, counts = compare(expected, actual, tolerant, args.abs_tolerance, rules) + except (OSError, ValueError, json.JSONDecodeError) as error: + json.dump({"contract": "mongodb-aggregate-v1", "failures": [{"class": "invalid-input", "error": str(error)}]}, sys.stdout, indent=2) + print() + return 2 + json.dump({"contract": "mongodb-aggregate-v1", "summary": counts, + "comparisons": comparisons, "failures": failures}, sys.stdout, indent=2) + print() + return 1 if failures else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/test/mongodb/dependency_report.md b/test/mongodb/dependency_report.md new file mode 100644 index 0000000000000..6e97d447c7f4f --- /dev/null +++ b/test/mongodb/dependency_report.md @@ -0,0 +1,12 @@ +# MongoDB dependency and build report + +Baseline: `2d0adac64ea6c72028c5443813428f84fbcd1575` (`up/main`, 2026-07-27). + +- Direct dependency: `go.mongodb.org/mongo-driver/v2 v2.8.0`. +- Newly recorded transitive modules: `github.com/xdg-go/pbkdf2 v1.0.0`, `github.com/xdg-go/scram v1.2.0`, `github.com/xdg-go/stringprep v1.0.4`, and `github.com/youmark/pkcs8` at `a2c0da244d78`. Existing graph versions of `klauspost/compress` and `golang/snappy` are reused. Driver v2.8.0 does not require `montanaflynn/stats`, so that review-time candidate is not added to the final module graph. +- The current main branch has no tracked `vendor/` directory. Consequently the readonly-module change has five net-new `go.mod` requirements and eleven `go.sum` lines; the two already-used modules `golang/snappy` and `klauspost/compress` are also promoted from indirect to direct by `go mod tidy`. No synthetic vendor tree is introduced. +- `license-eye -c .licenserc.yml dep check` and header check pass locally. +- A readonly `make build` succeeds. The local binary is 209,261,234 bytes versus 203,071,186 bytes in the adjacent pre-change workspace build (+6,190,048 bytes, about 3.05%). These binaries came from different branches/build timestamps, so this is an indicative upper bound, not a controlled release-size benchmark. +- The downloaded v2 driver module occupies 8,840 KiB in the local module cache; module-cache size is not shipped binary size. + +Release CI still owns the controlled clean-build time/size comparison, SBOM publication, musl TLS/SRV smoke and security-owner approval. diff --git a/test/mongodb/fixture_manifest.json b/test/mongodb/fixture_manifest.json new file mode 100644 index 0000000000000..3a3aa2dda6630 --- /dev/null +++ b/test/mongodb/fixture_manifest.json @@ -0,0 +1,10 @@ +{ + "contract": "mongodb-e2e-v1", + "rows": [ + ["64b000000000000000000001", "device-001", "site-east", "2026-07-27 10:00:05.000", "10", "batch-001"], + ["64b000000000000000000002", "device-001", "site-east", "2026-07-27 10:00:35.000", "14", "NULL"], + ["64b000000000000000000003", "device-001", "site-east", "2026-07-27 10:02:05.000", "20", "NULL"], + ["64b000000000000000000004", "device-001", "site-west", "2026-07-27 10:00:15.000", "30", "batch-002"], + ["64b000000000000000000005", "device-002", "site-east", "2026-07-27 10:01:00.000", "NULL", "NULL"] + ] +} diff --git a/test/mongodb/mongodb_e2e_local.go b/test/mongodb/mongodb_e2e_local.go new file mode 100644 index 0000000000000..9226538e35138 --- /dev/null +++ b/test/mongodb/mongodb_e2e_local.go @@ -0,0 +1,344 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. + +package main + +import ( + "context" + "database/sql" + "encoding/json" + "flag" + "fmt" + "os" + "path/filepath" + "reflect" + "strings" + "time" + + _ "github.com/go-sql-driver/mysql" +) + +type report struct { + Status string `json:"status"` + Cases []string `json:"cases"` + Error string `json:"error,omitempty"` +} + +type fixtureManifest struct { + Rows [][]string `json:"rows"` +} + +func main() { + var dsn, host, reportDir string + flag.StringVar(&dsn, "dsn", "root:111@tcp(127.0.0.1:6001)/?timeout=5s&readTimeout=30s&writeTimeout=30s", "MO DSN") + flag.StringVar(&host, "mongo-host", "127.0.0.1:27017", "MongoDB seed") + flag.StringVar(&reportDir, "report-dir", "test/mongodb/reports/local", "report directory") + flag.Parse() + + r := report{Status: "failed"} + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) + defer cancel() + db, err := sql.Open("mysql", dsn) + if err == nil { + defer db.Close() + err = waitForMO(ctx, db) + } + if err == nil { + err = run(ctx, db, host, &r) + } + if err == nil { + r.Status = "passed" + } else { + r.Error = err.Error() + } + if writeErr := writeReport(reportDir, r); writeErr != nil && err == nil { + err = writeErr + } + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func waitForMO(ctx context.Context, db *sql.DB) error { + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + for { + if err := db.PingContext(ctx); err == nil { + return nil + } + select { + case <-ctx.Done(): + return fmt.Errorf("wait for MatrixOne: %w", ctx.Err()) + case <-ticker.C: + } + } +} + +func run(ctx context.Context, db *sql.DB, host string, r *report) error { + manifest, err := loadFixtureManifest("test/mongodb/fixture_manifest.json") + if err != nil { + return err + } + statements := []string{ + "drop database if exists mongodb_ci", + "create database mongodb_ci", + "create mongodb connection if not exists mongodb_ci with ('hosts'='" + host + "','replica_set'='rs0','auth_source'='mongodb_source','auth_mechanism'='SCRAM-SHA-256','credential_secret_ref'='secret://env/MO_MONGODB_E2E_CREDENTIAL','tls_mode'='disabled','read_preference'='primary','read_concern'='majority','options_json'='{\"direct\":true}')", + "create external table mongodb_ci.events(mongo_id char(24) mongodb_path '_id', device_id varchar(20), site_id varchar(10), ts datetime(3) mongodb_convert 'try_null', measurement double mongodb_convert 'try_null', source_batch varchar(50)) engine=mongodb with ('connection'='mongodb_ci','database'='mongodb_source','collection'='events','schema_mode'='explicit','conversion_mode'='strict','max_parallelism'='1')", + } + for _, statement := range statements { + if _, err := db.ExecContext(ctx, statement); err != nil { + return fmt.Errorf("setup %s: %w", redact(statement), err) + } + } + r.Cases = append(r.Cases, "secret-backed-ddl") + if err := verifyShowCreate(ctx, db); err != nil { + return err + } + r.Cases = append(r.Cases, "show-create-redaction-roundtrip") + + if err := expectScalar(ctx, db, "select count(*) from mongodb_ci.events", "5"); err != nil { + return err + } + if err := expectRows(ctx, db, + "select mongo_id,device_id,site_id,cast(ts as char),coalesce(cast(measurement as char),'NULL'),coalesce(source_batch,'NULL') from mongodb_ci.events order by mongo_id", + manifest.Rows); err != nil { + return err + } + if err := expectScalar(ctx, db, "select count(*) from mongodb_ci.events where measurement >= 14", "3"); err != nil { + return err + } + if err := expectScalar(ctx, db, "select count(*) from mongodb_ci.events where source_batch is null", "3"); err != nil { + return err + } + r.Cases = append(r.Cases, "scan-projection-pushdown-null-conversion") + + cancelCtx, cancel := context.WithCancel(ctx) + cancel() + if err := db.QueryRowContext(cancelCtx, "select count(*) from mongodb_ci.events").Scan(new(string)); err == nil { + return fmt.Errorf("canceled MongoDB statement unexpectedly succeeded") + } + if err := expectScalar(ctx, db, "select count(*) from mongodb_ci.events", "5"); err != nil { + return fmt.Errorf("scan after cancellation: %w", err) + } + r.Cases = append(r.Cases, "multi-batch-cancel-recovery") + + windowSQL := "select count(*) from (select _wstart, device_id, site_id, avg(measurement) from mongodb_ci.events where device_id='device-001' group by device_id,site_id interval(ts,1,minute) gapfill(partition) fill(null)) x" + if err := expectScalar(ctx, db, windowSQL, "4"); err != nil { + return err + } + r.Cases = append(r.Cases, "mongoscan-timewin-gapfill") + + for _, statement := range []string{ + "create table mongodb_ci.minute_aggregate(device_id varchar(20), site_id varchar(10), window_start datetime, measurement double, primary key(device_id,site_id,window_start))", + "create table mongodb_ci.ingest_watermark(id int primary key, high datetime)", + "insert into mongodb_ci.ingest_watermark values(1,'2026-07-27 10:00:00')", + } { + if _, err := db.ExecContext(ctx, statement); err != nil { + return fmt.Errorf("create ingestion tables: %w", err) + } + } + tx, err := db.BeginTx(ctx, nil) + if err != nil { + return err + } + if _, err = tx.ExecContext(ctx, "replace into mongodb_ci.minute_aggregate select device_id,site_id,_wstart,avg(measurement) from mongodb_ci.events where ts >= '2026-07-27 10:00:00' and ts < '2026-07-27 10:03:00' group by device_id,site_id interval(ts,1,minute) gapfill(partition) fill(null)"); err == nil { + _, err = tx.ExecContext(ctx, "update mongodb_ci.ingest_watermark set high='2026-07-27 10:03:00' where id=1") + } + if err != nil { + _ = tx.Rollback() + return fmt.Errorf("bounded ingestion: %w", err) + } + if err = tx.Commit(); err != nil { + return err + } + if err := expectScalar(ctx, db, "select cast(high as char) from mongodb_ci.ingest_watermark where id=1", "2026-07-27 10:03:00"); err != nil { + return err + } + r.Cases = append(r.Cases, "atomic-aggregate-watermark") + + // The fixture contains one malformed numeric value. A strict mapping must + // abort the statement and leave both aggregate rows and watermark unchanged, + // even if earlier source rows were already converted. + if _, err := db.ExecContext(ctx, "create external table mongodb_ci.events_strict(mongo_id char(24) mongodb_path '_id', device_id varchar(20), site_id varchar(10), ts datetime(3), measurement double) engine=mongodb with ('connection'='mongodb_ci','database'='mongodb_source','collection'='events','schema_mode'='explicit','conversion_mode'='strict','max_parallelism'='1')"); err != nil { + return fmt.Errorf("create strict mapping: %w", err) + } + var targetBefore, watermarkBefore string + if err := db.QueryRowContext(ctx, "select count(*) from mongodb_ci.minute_aggregate").Scan(&targetBefore); err != nil { + return err + } + if err := db.QueryRowContext(ctx, "select cast(high as char) from mongodb_ci.ingest_watermark where id=1").Scan(&watermarkBefore); err != nil { + return err + } + failedTx, err := db.BeginTx(ctx, nil) + if err != nil { + return err + } + _, scanErr := failedTx.ExecContext(ctx, "replace into mongodb_ci.minute_aggregate select device_id,site_id,_wstart,avg(measurement) from mongodb_ci.events_strict where ts >= '2026-07-27 10:00:00' and ts < '2026-07-27 10:04:00' group by device_id,site_id interval(ts,1,minute) gapfill(partition) fill(null)") + if scanErr == nil { + _ = failedTx.Rollback() + return fmt.Errorf("strict MongoDB conversion unexpectedly succeeded") + } + _ = failedTx.Rollback() + if err := expectScalar(ctx, db, "select count(*) from mongodb_ci.minute_aggregate", targetBefore); err != nil { + return fmt.Errorf("target rollback: %w", err) + } + if err := expectScalar(ctx, db, "select cast(high as char) from mongodb_ci.ingest_watermark where id=1", watermarkBefore); err != nil { + return fmt.Errorf("watermark rollback: %w", err) + } + r.Cases = append(r.Cases, "conversion-error-atomic-rollback") + + // Repeating the committed bounded write is idempotent under the composite + // result key and does not create additional aggregate rows. + idempotentTx, err := db.BeginTx(ctx, nil) + if err != nil { + return err + } + if _, err = idempotentTx.ExecContext(ctx, "replace into mongodb_ci.minute_aggregate select device_id,site_id,_wstart,avg(measurement) from mongodb_ci.events where ts >= '2026-07-27 10:00:00' and ts < '2026-07-27 10:03:00' group by device_id,site_id interval(ts,1,minute) gapfill(partition) fill(null)"); err == nil { + _, err = idempotentTx.ExecContext(ctx, "update mongodb_ci.ingest_watermark set high='2026-07-27 10:03:00' where id=1") + } + if err != nil { + _ = idempotentTx.Rollback() + return fmt.Errorf("idempotent replay: %w", err) + } + if err = idempotentTx.Commit(); err != nil { + return err + } + if err := expectScalar(ctx, db, "select count(*) from mongodb_ci.minute_aggregate", targetBefore); err != nil { + return err + } + r.Cases = append(r.Cases, "bounded-idempotent-replay") + + // Rotating the secret reference increments the catalog generation. The next + // statement must authenticate with the new read-only identity; package tests + // assert that the old idle client is drained when this generation is leased. + if _, err := db.ExecContext(ctx, "alter mongodb connection mongodb_ci set ('credential_secret_ref'='secret://env/MO_MONGODB_E2E_CREDENTIAL_NEXT')"); err != nil { + return fmt.Errorf("rotate MongoDB connection: %w", err) + } + if err := expectScalar(ctx, db, "select count(*) from mongodb_ci.events", "5"); err != nil { + return fmt.Errorf("scan after credential rotation: %w", err) + } + r.Cases = append(r.Cases, "credential-generation-rotation") + + if _, err := db.ExecContext(ctx, "alter mongodb connection mongodb_ci disable"); err != nil { + return fmt.Errorf("disable MongoDB connection: %w", err) + } + if err := expectQueryFailure(ctx, db, "select count(*) from mongodb_ci.events", "disabled"); err != nil { + return err + } + if _, err := db.ExecContext(ctx, "alter mongodb connection mongodb_ci enable"); err != nil { + return fmt.Errorf("enable MongoDB connection: %w", err) + } + if err := expectScalar(ctx, db, "select count(*) from mongodb_ci.events", "5"); err != nil { + return fmt.Errorf("scan after connection re-enable: %w", err) + } + r.Cases = append(r.Cases, "connection-disable-enable") + return nil +} + +func loadFixtureManifest(path string) (fixtureManifest, error) { + data, err := os.ReadFile(path) + if err != nil { + return fixtureManifest{}, fmt.Errorf("read MongoDB fixture manifest: %w", err) + } + var manifest fixtureManifest + if err := json.Unmarshal(data, &manifest); err != nil { + return fixtureManifest{}, fmt.Errorf("decode MongoDB fixture manifest: %w", err) + } + if len(manifest.Rows) == 0 { + return fixtureManifest{}, fmt.Errorf("MongoDB fixture manifest has no rows") + } + return manifest, nil +} + +func expectRows(ctx context.Context, db *sql.DB, query string, expected [][]string) error { + rows, err := db.QueryContext(ctx, query) + if err != nil { + return fmt.Errorf("query %s: %w", redact(query), err) + } + defer rows.Close() + actual := make([][]string, 0, len(expected)) + for rows.Next() { + row := make([]string, 6) + dest := make([]any, len(row)) + for i := range row { + dest[i] = &row[i] + } + if err := rows.Scan(dest...); err != nil { + return err + } + actual = append(actual, row) + } + if err := rows.Err(); err != nil { + return err + } + if !reflect.DeepEqual(actual, expected) { + return fmt.Errorf("fixture result mismatch: expected %v, got %v", expected, actual) + } + return nil +} + +func verifyShowCreate(ctx context.Context, db *sql.DB) error { + var tableName, ddl string + if err := db.QueryRowContext(ctx, "show create table mongodb_ci.events").Scan(&tableName, &ddl); err != nil { + return fmt.Errorf("SHOW CREATE MongoDB table: %w", err) + } + lower := strings.ToLower(ddl) + if tableName != "events" || !strings.Contains(lower, "engine = mongodb") || + !strings.Contains(lower, "mongodb_path") || !strings.Contains(lower, "connection") { + return fmt.Errorf("SHOW CREATE MongoDB table omitted reconstructable mapping metadata") + } + for _, forbidden := range []string{"secret://", "127.0.0.1", "mo_reader", "password", "credential"} { + if strings.Contains(lower, forbidden) { + return fmt.Errorf("SHOW CREATE MongoDB table exposed forbidden source metadata") + } + } + return nil +} + +func expectScalar(ctx context.Context, db *sql.DB, query, expected string) error { + var actual string + if err := db.QueryRowContext(ctx, query).Scan(&actual); err != nil { + return fmt.Errorf("query %s: %w", redact(query), err) + } + if actual != expected { + return fmt.Errorf("query %s: expected %q, got %q", redact(query), expected, actual) + } + return nil +} + +func expectQueryFailure(ctx context.Context, db *sql.DB, query, contains string) error { + var value string + err := db.QueryRowContext(ctx, query).Scan(&value) + if err == nil { + return fmt.Errorf("query %s unexpectedly succeeded", redact(query)) + } + if contains != "" && !strings.Contains(strings.ToLower(err.Error()), strings.ToLower(contains)) { + return fmt.Errorf("query %s failed without %q: %w", redact(query), contains, err) + } + return nil +} + +func redact(value string) string { + if strings.Contains(strings.ToLower(value), "credential_secret_ref") { + return "" + } + return value +} + +func writeReport(dir string, value report) error { + if err := os.MkdirAll(dir, 0o755); err != nil { + return err + } + data, err := json.MarshalIndent(value, "", " ") + if err != nil { + return err + } + if err := os.WriteFile(filepath.Join(dir, "report.json"), data, 0o600); err != nil { + return err + } + summary := "## MongoDB connector E2E\n\nStatus: **" + value.Status + "**\n" + return os.WriteFile(filepath.Join(dir, "summary.md"), []byte(summary), 0o600) +} diff --git a/test/mongodb/mongodb_e2e_local_test.go b/test/mongodb/mongodb_e2e_local_test.go new file mode 100644 index 0000000000000..bbd000ee6c085 --- /dev/null +++ b/test/mongodb/mongodb_e2e_local_test.go @@ -0,0 +1,234 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "context" + "database/sql" + "errors" + "os" + "path/filepath" + "runtime" + "strings" + "testing" + "time" + + "github.com/DATA-DOG/go-sqlmock" + "github.com/stretchr/testify/require" +) + +func TestMongoDBLocalE2ERunContract(t *testing.T) { + repoRoot := mongoDBTestRepoRoot(t) + previous, err := os.Getwd() + require.NoError(t, err) + require.NoError(t, os.Chdir(repoRoot)) + t.Cleanup(func() { require.NoError(t, os.Chdir(previous)) }) + + manifest, err := loadFixtureManifest("test/mongodb/fixture_manifest.json") + require.NoError(t, err) + db, mock := newMongoDBE2ESQLMock(t) + + for range 4 { + mock.ExpectExec(".*").WillReturnResult(sqlmock.NewResult(0, 1)) + } + mock.ExpectQuery("show create table").WillReturnRows(sqlmock.NewRows([]string{"table", "ddl"}).AddRow( + "events", "CREATE EXTERNAL TABLE events (id CHAR(24) MONGODB_PATH '_id') ENGINE = MONGODB WITH ('connection'='mongodb_ci')")) + expectMongoDBE2EScalar(mock, "5") + fixtureRows := sqlmock.NewRows([]string{"id", "device_id", "site_id", "ts", "measurement", "source_batch"}) + for _, row := range manifest.Rows { + require.Len(t, row, 6) + fixtureRows.AddRow(row[0], row[1], row[2], row[3], row[4], row[5]) + } + mock.ExpectQuery("select mongo_id").WillReturnRows(fixtureRows) + expectMongoDBE2EScalar(mock, "3") + expectMongoDBE2EScalar(mock, "3") + // A pre-canceled context is rejected by database/sql before it reaches the + // driver, so no sqlmock expectation is consumed here. + expectMongoDBE2EScalar(mock, "5") + expectMongoDBE2EScalar(mock, "4") + for range 3 { + mock.ExpectExec(".*").WillReturnResult(sqlmock.NewResult(0, 1)) + } + mock.ExpectBegin() + mock.ExpectExec("replace into mongodb_ci.minute_aggregate").WillReturnResult(sqlmock.NewResult(0, 4)) + mock.ExpectExec("update mongodb_ci.ingest_watermark").WillReturnResult(sqlmock.NewResult(0, 1)) + mock.ExpectCommit() + expectMongoDBE2EScalar(mock, "2026-07-27 10:03:00") + mock.ExpectExec("create external table mongodb_ci.events_strict").WillReturnResult(sqlmock.NewResult(0, 0)) + expectMongoDBE2EScalar(mock, "4") + expectMongoDBE2EScalar(mock, "2026-07-27 10:03:00") + mock.ExpectBegin() + mock.ExpectExec("replace into mongodb_ci.minute_aggregate.*events_strict").WillReturnError(errors.New("strict conversion failed")) + mock.ExpectRollback() + expectMongoDBE2EScalar(mock, "4") + expectMongoDBE2EScalar(mock, "2026-07-27 10:03:00") + mock.ExpectBegin() + mock.ExpectExec("replace into mongodb_ci.minute_aggregate").WillReturnResult(sqlmock.NewResult(0, 4)) + mock.ExpectExec("update mongodb_ci.ingest_watermark").WillReturnResult(sqlmock.NewResult(0, 1)) + mock.ExpectCommit() + expectMongoDBE2EScalar(mock, "4") + mock.ExpectExec("alter mongodb connection mongodb_ci set").WillReturnResult(sqlmock.NewResult(0, 1)) + expectMongoDBE2EScalar(mock, "5") + mock.ExpectExec("alter mongodb connection mongodb_ci disable").WillReturnResult(sqlmock.NewResult(0, 1)) + mock.ExpectQuery("select count").WillReturnError(errors.New("MongoDB connection is disabled")) + mock.ExpectExec("alter mongodb connection mongodb_ci enable").WillReturnResult(sqlmock.NewResult(0, 1)) + expectMongoDBE2EScalar(mock, "5") + + result := report{} + require.NoError(t, run(t.Context(), db, "127.0.0.1:27017", &result)) + require.Equal(t, []string{ + "secret-backed-ddl", + "show-create-redaction-roundtrip", + "scan-projection-pushdown-null-conversion", + "multi-batch-cancel-recovery", + "mongoscan-timewin-gapfill", + "atomic-aggregate-watermark", + "conversion-error-atomic-rollback", + "bounded-idempotent-replay", + "credential-generation-rotation", + "connection-disable-enable", + }, result.Cases) + require.NoError(t, mock.ExpectationsWereMet()) +} + +func TestMongoDBLocalE2EHelpers(t *testing.T) { + t.Run("wait succeeds", func(t *testing.T) { + db, mock, err := sqlmock.New(sqlmock.MonitorPingsOption(true)) + require.NoError(t, err) + t.Cleanup(func() { _ = db.Close() }) + mock.ExpectPing() + require.NoError(t, waitForMO(t.Context(), db)) + require.NoError(t, mock.ExpectationsWereMet()) + }) + + t.Run("wait observes cancellation", func(t *testing.T) { + db, mock, err := sqlmock.New(sqlmock.MonitorPingsOption(true)) + require.NoError(t, err) + t.Cleanup(func() { _ = db.Close() }) + mock.ExpectPing().WillDelayFor(10 * time.Millisecond).WillReturnError(errors.New("not ready")) + ctx, cancel := context.WithTimeout(t.Context(), time.Millisecond) + defer cancel() + require.ErrorIs(t, waitForMO(ctx, db), context.DeadlineExceeded) + require.NoError(t, mock.ExpectationsWereMet()) + }) + + t.Run("fixture manifest failures", func(t *testing.T) { + _, err := loadFixtureManifest(filepath.Join(t.TempDir(), "missing.json")) + require.ErrorContains(t, err, "read MongoDB fixture manifest") + invalid := filepath.Join(t.TempDir(), "invalid.json") + require.NoError(t, os.WriteFile(invalid, []byte("{"), 0o600)) + _, err = loadFixtureManifest(invalid) + require.ErrorContains(t, err, "decode MongoDB fixture manifest") + empty := filepath.Join(t.TempDir(), "empty.json") + require.NoError(t, os.WriteFile(empty, []byte(`{"rows":[]}`), 0o600)) + _, err = loadFixtureManifest(empty) + require.ErrorContains(t, err, "has no rows") + }) + + t.Run("row comparison failures", func(t *testing.T) { + db, mock := newMongoDBE2ESQLMock(t) + mock.ExpectQuery("query-error").WillReturnError(errors.New("source offline")) + require.ErrorContains(t, expectRows(t.Context(), db, "query-error", nil), "source offline") + mock.ExpectQuery("scan-error").WillReturnRows(sqlmock.NewRows([]string{"only"}).AddRow("value")) + require.Error(t, expectRows(t.Context(), db, "scan-error", nil)) + mock.ExpectQuery("row-error").WillReturnRows( + sqlmock.NewRows([]string{"a", "b", "c", "d", "e", "f"}). + AddRow("1", "2", "3", "4", "5", "6"). + AddRow("1", "2", "3", "4", "5", "6"). + RowError(1, errors.New("getMore failed"))) + require.ErrorContains(t, expectRows(t.Context(), db, "row-error", nil), "getMore failed") + mock.ExpectQuery("mismatch").WillReturnRows(sqlmock.NewRows([]string{"a", "b", "c", "d", "e", "f"})) + require.ErrorContains(t, expectRows(t.Context(), db, "mismatch", [][]string{{"expected"}}), "fixture result mismatch") + require.NoError(t, mock.ExpectationsWereMet()) + }) + + t.Run("show create validation", func(t *testing.T) { + for _, tc := range []struct { + name string + row *sqlmock.Rows + err error + }{ + {name: "query error", err: errors.New("catalog offline")}, + {name: "incomplete", row: sqlmock.NewRows([]string{"table", "ddl"}).AddRow("raw", "CREATE TABLE raw(a int)")}, + {name: "secret leak", row: sqlmock.NewRows([]string{"table", "ddl"}).AddRow("raw", "ENGINE = MONGODB MONGODB_PATH connection secret://env/key")}, + } { + t.Run(tc.name, func(t *testing.T) { + db, mock := newMongoDBE2ESQLMock(t) + expectation := mock.ExpectQuery("show create table") + if tc.err != nil { + expectation.WillReturnError(tc.err) + } else { + expectation.WillReturnRows(tc.row) + } + require.Error(t, verifyShowCreate(t.Context(), db)) + require.NoError(t, mock.ExpectationsWereMet()) + }) + } + }) + + t.Run("scalar and expected failure", func(t *testing.T) { + db, mock := newMongoDBE2ESQLMock(t) + mock.ExpectQuery("scalar-error").WillReturnError(errors.New("query failed")) + require.ErrorContains(t, expectScalar(t.Context(), db, "scalar-error", "1"), "query failed") + mock.ExpectQuery("scalar-mismatch").WillReturnRows(sqlmock.NewRows([]string{"value"}).AddRow("2")) + require.ErrorContains(t, expectScalar(t.Context(), db, "scalar-mismatch", "1"), "expected") + mock.ExpectQuery("unexpected-success").WillReturnRows(sqlmock.NewRows([]string{"value"}).AddRow("1")) + require.ErrorContains(t, expectQueryFailure(t.Context(), db, "unexpected-success", ""), "unexpectedly succeeded") + mock.ExpectQuery("wrong-error").WillReturnError(errors.New("different")) + require.ErrorContains(t, expectQueryFailure(t.Context(), db, "wrong-error", "disabled"), "without") + mock.ExpectQuery("expected-error").WillReturnError(errors.New("connection disabled")) + require.NoError(t, expectQueryFailure(t.Context(), db, "expected-error", "DISABLED")) + require.NoError(t, mock.ExpectationsWereMet()) + }) + + t.Run("redaction and report", func(t *testing.T) { + require.Equal(t, "", redact("CREDENTIAL_SECRET_REF='secret'")) + require.Equal(t, "select 1", redact("select 1")) + dir := t.TempDir() + require.NoError(t, writeReport(dir, report{Status: "passed", Cases: []string{"scan"}})) + data, err := os.ReadFile(filepath.Join(dir, "report.json")) + require.NoError(t, err) + require.Contains(t, string(data), `"status": "passed"`) + summary, err := os.ReadFile(filepath.Join(dir, "summary.md")) + require.NoError(t, err) + require.Contains(t, string(summary), "Status: **passed**") + fileParent := filepath.Join(t.TempDir(), "not-a-directory") + require.NoError(t, os.WriteFile(fileParent, []byte("x"), 0o600)) + require.Error(t, writeReport(filepath.Join(fileParent, "child"), report{})) + }) +} + +func mongoDBTestRepoRoot(t *testing.T) string { + t.Helper() + _, source, _, ok := runtime.Caller(0) + require.True(t, ok) + return filepath.Clean(filepath.Join(filepath.Dir(source), "..", "..")) +} + +func newMongoDBE2ESQLMock(t *testing.T) (*sql.DB, sqlmock.Sqlmock) { + t.Helper() + db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherRegexp)) + require.NoError(t, err) + t.Cleanup(func() { _ = db.Close() }) + return db, mock +} + +func expectMongoDBE2EScalar(mock sqlmock.Sqlmock, value string) { + mock.ExpectQuery(".*").WillReturnRows(sqlmock.NewRows([]string{"value"}).AddRow(value)) +} + +func TestMongoDBLocalE2ERedactionIsCaseInsensitive(t *testing.T) { + require.True(t, strings.HasPrefix(redact("CrEdEnTiAl_SeCrEt_ReF=x"), "= archive_cutoff or archive_replay_ready) + ), + 'MongoDB live reset blocked: watermark has not passed archive cutoff and no verified replay source is ready' +); diff --git a/test/mongodb/sql/bounded_backfill.sql b/test/mongodb/sql/bounded_backfill.sql new file mode 100644 index 0000000000000..e7aaa827fd2ee --- /dev/null +++ b/test/mongodb/sql/bounded_backfill.sql @@ -0,0 +1,133 @@ +-- Copyright 2026 Matrix Origin +-- Licensed under the Apache License, Version 2.0. +-- +-- Bounded MongoDB history repair. Populate one non-overlapping site/day row +-- per recoverable source or archive slice, then call run_backfill_slice(id, fence). +-- The procedure commits the repaired target rows and checkpoint atomically. + +create table if not exists telemetry_backfill_control ( + backfill_id varchar(128) primary key, + source_name varchar(128) not null, + site_id varchar(10) not null, + slice_low datetime(3) not null, + slice_high datetime(3) not null, + state enum('PENDING', 'PAUSED', 'COMMITTED') not null default 'PENDING', + fence bigint unsigned not null default 1, + attempts bigint unsigned not null default 0, + committed_at datetime(3), + updated_at timestamp not null default utc_timestamp, + unique key slice_identity (source_name, site_id, slice_low, slice_high) +); + +-- Example queue row; generate equivalent rows for every site/day. An archive +-- external table can replace telemetry_events_external without changing the +-- transaction or target contract. +insert into telemetry_backfill_control( + backfill_id, source_name, site_id, slice_low, slice_high +) +select 'REPLACE_BACKFILL_ID', 'telemetry_events', 'REPLACE_SITE_ID', + cast('2026-01-01 00:00:00' as datetime), + cast('2026-01-02 00:00:00' as datetime) +where not exists ( + select 1 from telemetry_backfill_control where backfill_id = 'REPLACE_BACKFILL_ID' +); + +drop procedure if exists run_backfill_slice; +create procedure run_backfill_slice( + in p_backfill_id varchar(128), + in p_expected_fence bigint unsigned +)' +begin +select assert( + (select count(*) + from telemetry_backfill_control + where backfill_id = p_backfill_id + and fence = p_expected_fence + and state = ''PENDING'') = 1, + ''MongoDB backfill slice is absent, paused, committed, or has a stale fence'' +); + +-- This write obtains the per-slice row lock. A duplicate invocation either +-- waits and then observes the advanced fence/state, or fails before scanning. +update telemetry_backfill_control + set attempts = attempts + 1, + updated_at = utc_timestamp + where backfill_id = p_backfill_id + and fence = p_expected_fence + and state = ''PENDING''; +select assert( + row_count() = 1, + ''MongoDB backfill slice lost its fence before source scan'' +); + +replace into telemetry_minute_aggregate +select a.device_id, + a.site_id, + a.window_start, + a.temperature_celsius, + a.humidity_percent, + a.pressure_kpa, + a.flow_rate_lpm, + a.vibration_mm_s, + a.voltage_volts, + a.total_runtime_hours, + a.active_runtime_hours, + a.samples_in_window, + a.source_batch, + c.slice_high, + sha2(concat( + ''mongodb-aggregate-v1-exact|'', + ''D:'', hex(a.device_id), + ''|S:'', hex(a.site_id), + ''|T:'', date_format(a.window_start, ''%Y-%m-%dT%H:%i:%sZ''), + ''|N:'', cast(a.samples_in_window as char), + ''|B:'', case when a.source_batch is null then ''N'' + else concat(''V'', hex(a.source_batch)) end + ), 256), + ''mongodb-aggregate-v1'' + from ( + select r.device_id, + r.site_id, + _wstart as window_start, + round(avg(r.temperature_celsius), 2) as temperature_celsius, + round(avg(r.humidity_percent), 2) as humidity_percent, + round(avg(r.pressure_kpa), 2) as pressure_kpa, + round(avg(r.flow_rate_lpm), 2) as flow_rate_lpm, + round(avg(r.vibration_mm_s), 2) as vibration_mm_s, + round(avg(r.voltage_volts), 2) as voltage_volts, + max_by_non_null(r.total_runtime_hours, r.ts, r.mongo_id) as total_runtime_hours, + max_by_non_null(r.active_runtime_hours, r.ts, r.mongo_id) as active_runtime_hours, + coalesce(count(*), 0) as samples_in_window, + max_by(r.source_batch, r.ts, r.mongo_id) as source_batch + from telemetry_events_external r + join telemetry_backfill_control c + on c.backfill_id = p_backfill_id + and c.fence = p_expected_fence + and c.state = ''PENDING'' + and r.site_id = c.site_id + and r.ts >= c.slice_low + and r.ts < c.slice_high + group by r.device_id, r.site_id + interval(r.ts, 1, minute) gapfill(partition) fill(null) + ) a + join telemetry_backfill_control c + on c.backfill_id = p_backfill_id + and c.fence = p_expected_fence; + +update telemetry_backfill_control + set state = ''COMMITTED'', + committed_at = utc_timestamp(3), + fence = fence + 1, + updated_at = utc_timestamp + where backfill_id = p_backfill_id + and fence = p_expected_fence + and state = ''PENDING''; +end'; + +-- Operational controls: +-- pause: UPDATE ... SET state='PAUSED', fence=fence+1 WHERE backfill_id=?; +-- resume: UPDATE ... SET state='PENDING', fence=fence+1 WHERE backfill_id=?; +-- replay: set PENDING with a new fence, then call with that exact fence. +-- A failed/canceled call rolls back attempts, data, and state, so retry starts +-- from the last COMMITTED slice. Record unrecoverable intervals as PAUSED rows +-- and require a named business owner before cutover. diff --git a/test/mongodb/sql/incremental_ingest.sql b/test/mongodb/sql/incremental_ingest.sql new file mode 100644 index 0000000000000..4c95e445e9023 --- /dev/null +++ b/test/mongodb/sql/incremental_ingest.sql @@ -0,0 +1,147 @@ +-- Copyright 2026 Matrix Origin +-- Licensed under the Apache License, Version 2.0. +-- +-- Executable MongoDB aggregate-v1 ingestion template. Rename the source and +-- target once per deployment; keep the transaction body intact. Rows flow +-- directly from MongoDB through MongoScan and MO aggregation into MO storage. + +create table if not exists telemetry_ingest_control ( + source_name varchar(128) primary key, + committed_high datetime(3) not null, + requested_high datetime(3), + overlap_ms bigint not null default 300000, + safety_lag_ms bigint not null default 120000, + pending_low datetime(3), + pending_high datetime(3), + fence bigint unsigned not null default 0, + archive_cutoff datetime(3), + archive_replay_ready bool not null default false, + updated_at timestamp not null default utc_timestamp +); + +create table if not exists telemetry_minute_aggregate ( + device_id varchar(20) not null, + site_id varchar(10) not null, + window_start datetime not null, + temperature_celsius float, + humidity_percent float, + pressure_kpa float, + flow_rate_lpm float, + vibration_mm_s float, + voltage_volts float, + total_runtime_hours float, + active_runtime_hours float, + samples_in_window bigint not null, + source_batch varchar(128), + source_high datetime(3) not null, + exact_row_hash char(64) not null, + hash_version varchar(32) not null, + primary key (device_id, site_id, window_start) +); + +-- Bootstrap once with the agreed source lower bound. +insert into telemetry_ingest_control(source_name, committed_high) +select 'telemetry_events', cast('2026-01-01 00:00:00' as datetime) +where not exists (select 1 from telemetry_ingest_control where source_name = 'telemetry_events'); + +-- A top-level MO stored procedure executes in one transaction. A CALL issued +-- by SQL TASK reuses the task statement transaction, so a scan/getMore, +-- conversion, aggregate, write, timeout, or commit failure rolls target rows +-- and pending bounds back together. The UPDATE locks the singleton control row +-- and serializes task/manual invocations for this source. +drop procedure if exists run_incremental_ingest; +create procedure run_incremental_ingest() ' +begin +select assert( + (select count(*) from telemetry_ingest_control where source_name = ''telemetry_events'') = 1, + ''MongoDB ingestion control row is missing or duplicated'' +); +update telemetry_ingest_control + set pending_low = cast(date_format( + timestampadd(microsecond, -1000 * overlap_ms, committed_high), + ''%Y-%m-%d %H:%i:00.000'' + ) as datetime(3)), + pending_high = greatest(committed_high, cast(date_format( + least( + coalesce(requested_high, timestampadd(microsecond, -1000 * safety_lag_ms, utc_timestamp(3))), + timestampadd(microsecond, -1000 * safety_lag_ms, utc_timestamp(3)) + ), + ''%Y-%m-%d %H:%i:00.000'' + ) as datetime(3))), + updated_at = utc_timestamp + where source_name = ''telemetry_events''; + +replace into telemetry_minute_aggregate +select a.device_id, + a.site_id, + a.window_start, + a.temperature_celsius, + a.humidity_percent, + a.pressure_kpa, + a.flow_rate_lpm, + a.vibration_mm_s, + a.voltage_volts, + a.total_runtime_hours, + a.active_runtime_hours, + a.samples_in_window, + a.source_batch, + c.pending_high, + -- v1 exact hash intentionally excludes every FLOAT column. Hex makes + -- device_id/site_id/source_batch delimiter-safe, and the N/V marker + -- distinguishes a NULL source batch from an empty string. Floating + -- values use the separately versioned numeric contract after target + -- FLOAT cast. + sha2(concat( + ''mongodb-aggregate-v1-exact|'', + ''D:'', hex(a.device_id), + ''|S:'', hex(a.site_id), + ''|T:'', date_format(a.window_start, ''%Y-%m-%dT%H:%i:%sZ''), + ''|N:'', cast(a.samples_in_window as char), + ''|B:'', case when a.source_batch is null then ''N'' + else concat(''V'', hex(a.source_batch)) end + ), 256), + ''mongodb-aggregate-v1'' + from ( + select device_id, + site_id, + _wstart as window_start, + round(avg(temperature_celsius), 2) as temperature_celsius, + round(avg(humidity_percent), 2) as humidity_percent, + round(avg(pressure_kpa), 2) as pressure_kpa, + round(avg(flow_rate_lpm), 2) as flow_rate_lpm, + round(avg(vibration_mm_s), 2) as vibration_mm_s, + round(avg(voltage_volts), 2) as voltage_volts, + max_by_non_null(total_runtime_hours, ts, mongo_id) as total_runtime_hours, + max_by_non_null(active_runtime_hours, ts, mongo_id) as active_runtime_hours, + coalesce(count(*), 0) as samples_in_window, + max_by(source_batch, ts, mongo_id) as source_batch + from telemetry_events_external + where ts >= (select pending_low from telemetry_ingest_control where source_name = ''telemetry_events'') + and ts < (select pending_high from telemetry_ingest_control where source_name = ''telemetry_events'') + group by device_id, site_id + interval(ts, 1, minute) gapfill(partition) fill(null) + ) a + join telemetry_ingest_control c on c.source_name = ''telemetry_events''; + +update telemetry_ingest_control + set committed_high = pending_high, + pending_low = null, + pending_high = null, + requested_high = null, + fence = fence + 1, + updated_at = utc_timestamp + where source_name = ''telemetry_events'' + and pending_high is not null; +end'; + +-- The task body is deliberately one CALL statement. SQL TASK compound bodies +-- execute separate statements independently, whereas the procedure provides +-- the required all-or-nothing transaction. An external orchestrator may call +-- this procedure for scheduling and alerting, but it must not relay source rows. +drop task if exists mongodb_incremental_ingest; +create task mongodb_incremental_ingest +schedule '0 */5 * * * *' +timezone 'UTC' +retry 1 +timeout '4m' +as begin call run_incremental_ingest(); end; diff --git a/test/mongodb/sql/key_conflict_audit.js b/test/mongodb/sql/key_conflict_audit.js new file mode 100644 index 0000000000000..ac1790c797468 --- /dev/null +++ b/test/mongodb/sql/key_conflict_audit.js @@ -0,0 +1,9 @@ +// Copyright 2026 Matrix Origin +// Source-level evidence for the old (device_id, minute) key blocker. +db.events.aggregate([ + {$match: {ts: {$gte: ISODate("REPLACE_LOW"), $lt: ISODate("REPLACE_HIGH")}}}, + {$project: {device_id: 1, site_id: 1, minute: {$dateTrunc: {date: "$ts", unit: "minute", timezone: "UTC"}}}}, + {$group: {_id: {device_id: "$device_id", minute: "$minute"}, sites: {$addToSet: "$site_id"}}}, + {$match: {$expr: {$gt: [{$size: "$sites"}, 1]}}}, + {$sort: {"_id.minute": 1, "_id.device_id": 1}} +], {allowDiskUse: true}); diff --git a/test/mongodb/test_compare_results.py b/test/mongodb/test_compare_results.py new file mode 100644 index 0000000000000..25190c5472813 --- /dev/null +++ b/test/mongodb/test_compare_results.py @@ -0,0 +1,109 @@ +# Copyright 2026 Matrix Origin +# Licensed under the Apache License, Version 2.0. + +import importlib.util +import pathlib +import tempfile +import unittest + +ROOT = pathlib.Path(__file__).resolve().parents[2] +SPEC = importlib.util.spec_from_file_location("compare_results", ROOT / "test/mongodb/compare_results.py") +MODULE = importlib.util.module_from_spec(SPEC) +SPEC.loader.exec_module(MODULE) + + +class CompareResultsTest(unittest.TestCase): + def test_numeric_tolerance_and_exact_hash_contract(self): + key = MODULE.canonical_values(["device-001", "site-east", "2026-07-27 10:00:00"]) + expected = {key: {"device_id": "device-001", "site_id": "site-east", "window_start": key[2], "measurement_avg": 1.0}} + actual = {key: {"device_id": "device-001", "site_id": "site-east", "window_start": key[2], "measurement_avg": 1.0 + 1e-10}} + failures, comparisons, counts = MODULE.compare(expected, actual, {"measurement_avg"}, 1e-9, {}) + self.assertFalse(failures) + self.assertEqual(1, counts["tolerance-equal"]) + hashes = [item for item in comparisons if item["class"] == "exact-hash"] + self.assertEqual(hashes[0]["expected"], hashes[0]["actual"]) + + def test_expected_difference_is_exact_and_must_be_used(self): + key_values = ["device-001", "site-east", "t"] + key = MODULE.canonical_values(key_values) + expected = {key: {"device_id": "device-001", "site_id": "site-east", "window_start": "t", "source_batch": "old"}} + actual = {key: {"device_id": "device-001", "site_id": "site-east", "window_start": "t", "source_batch": None}} + rule = {"key": key_values, "column": "source_batch", "expected": "old", "actual": None, + "rule": "latest-document-missing-source-batch"} + failures, _, counts = MODULE.compare(expected, actual, set(), 0, {(key, "source_batch"): rule}) + self.assertFalse(failures) + self.assertEqual(1, counts["expected-inconsistent"]) + + failures, _, _ = MODULE.compare(expected, expected, set(), 0, {(key, "source_batch"): rule}) + self.assertEqual("unused-expected-rule", failures[0]["class"]) + + def test_duplicate_row_key_is_rejected(self): + with tempfile.NamedTemporaryFile("w", encoding="utf-8") as source: + source.write('{"device_id":"device-001","site_id":"site-east","window_start":"t","measurement":1}\n') + source.write('{"device_id":"device-001","site_id":"site-east","window_start":"t","measurement":2}\n') + source.flush() + with self.assertRaises(ValueError): + MODULE.load_rows(source.name, ["device_id", "site_id", "window_start"]) + + def test_row_key_identity_is_type_sensitive(self): + with tempfile.NamedTemporaryFile("w", encoding="utf-8") as source: + source.write('{"device_id":1,"site_id":"site-east","window_start":"t","measurement":1}\n') + source.write('{"device_id":"1","site_id":"site-east","window_start":"t","measurement":2}\n') + source.flush() + rows = MODULE.load_rows(source.name, ["device_id", "site_id", "window_start"]) + self.assertEqual(2, len(rows)) + + def test_expected_difference_key_identity_is_type_sensitive(self): + with tempfile.NamedTemporaryFile("w", encoding="utf-8") as source: + source.write('{"rules":[' + '{"key":[1,"site-east","t"],"column":"source_batch","expected":1,"actual":2,"rule":"integer"},' + '{"key":["1","site-east","t"],"column":"source_batch","expected":1,"actual":2,"rule":"string"}' + ']}') + source.flush() + rules = MODULE.load_rules(source.name) + self.assertEqual(2, len(rules)) + + def test_exact_contract_is_type_sensitive(self): + key = MODULE.canonical_values(["device-001", "site-east", "t"]) + expected = {key: {"device_id": "device-001", "site_id": "site-east", "window_start": "t", "count": 1}} + actual = {key: {"device_id": "device-001", "site_id": "site-east", "window_start": "t", "count": 1.0}} + failures, _, _ = MODULE.compare(expected, actual, set(), 0, {}) + self.assertEqual(["must-equal", "exact-hash-mismatch"], [item["class"] for item in failures]) + + def test_missing_column_is_not_explicit_null(self): + key = MODULE.canonical_values(["device-001", "site-east", "t"]) + expected = {key: {"device_id": "device-001", "site_id": "site-east", "window_start": "t", "source_batch": None}} + actual = {key: {"device_id": "device-001", "site_id": "site-east", "window_start": "t"}} + failures, _, _ = MODULE.compare(expected, actual, set(), 0, {}) + self.assertEqual("missing-column", failures[0]["class"]) + self.assertIn("exact-hash-mismatch", [item["class"] for item in failures]) + + def test_result_rows_require_every_key_column(self): + with tempfile.NamedTemporaryFile("w", encoding="utf-8") as source: + source.write('{"device_id":"device-001","window_start":"t","measurement":1}\n') + source.flush() + with self.assertRaisesRegex(ValueError, "missing key columns"): + MODULE.load_rows(source.name, ["device_id", "site_id", "window_start"]) + + def test_boolean_does_not_use_numeric_tolerance(self): + key = MODULE.canonical_values(["device-001", "site-east", "t"]) + expected = {key: {"device_id": "device-001", "site_id": "site-east", "window_start": "t", "measurement_avg": False}} + actual = {key: {"device_id": "device-001", "site_id": "site-east", "window_start": "t", "measurement_avg": 0}} + failures, _, counts = MODULE.compare(expected, actual, {"measurement_avg"}, 1, {}) + self.assertEqual("must-equal", failures[0]["class"]) + self.assertEqual(0, counts["tolerance-equal"]) + + def test_exact_comparison_is_recursively_type_sensitive(self): + self.assertFalse(MODULE.exact_equal({"nested": [1]}, {"nested": [1.0]})) + self.assertFalse(MODULE.exact_equal({"zero": -0.0}, {"zero": 0.0})) + + def test_expected_difference_document_shape_is_validated(self): + with tempfile.NamedTemporaryFile("w", encoding="utf-8") as source: + source.write('[]') + source.flush() + with self.assertRaisesRegex(ValueError, "rules array"): + MODULE.load_rules(source.name) + + +if __name__ == "__main__": + unittest.main()