diff --git a/.github/workflows/build-observer-firmwares-beta.yml b/.github/workflows/build-observer-firmwares-beta.yml index be54ee72..5b51f0c5 100644 --- a/.github/workflows/build-observer-firmwares-beta.yml +++ b/.github/workflows/build-observer-firmwares-beta.yml @@ -312,8 +312,16 @@ jobs: # Slim manifests come from the build output in out/ (the assets # actually uploaded to the release), not from config-beta.json -- see # gen-slim-manifests.py's --bin-dir mode (flasher repo PR #1). + # --prune deletes manifests for envs this build no longer produces. + # Without it the dir only ever grew: the retired + # LilyGo_TLora_V2_1_1_6_*_observer_mqtt_ manifests sat here for two + # months pointing at release assets that had since been pruned, so any + # node still on that build got a 404 from `ota update`. The generator + # caps the prune (--prune-limit, default 4) and fails the run instead + # of pruning when a build looks like it silently lost envs. python3 flasher/scripts/gen-slim-manifests.py \ --bin-dir out \ + --prune \ --static-path "$STATIC_PATH" \ --out-dir "flasher/$MANIFEST_DIR" \ --base-version "$FIRMWARE_VERSION" \ diff --git a/.github/workflows/build-observer-firmwares.yml b/.github/workflows/build-observer-firmwares.yml index 8d553875..f652f044 100644 --- a/.github/workflows/build-observer-firmwares.yml +++ b/.github/workflows/build-observer-firmwares.yml @@ -48,6 +48,12 @@ env: # repo). Baked into the slim OTA manifests' file URLs; must stay consistent # with config.json's staticPath. STATIC_PATH: https://observer-fw.gessaman.com + # Where the firmware fetches .json from — this URL *is* the release + # channel. Stated explicitly (it equals build.sh's default) rather than left + # unset, so "Verify production channel is baked in" below can assert against the + # same value the build was handed instead of a second hardcoded copy. Must match + # build.sh's OTA_MANIFEST_BASE_URL default and the Pages path serving flasher/v. + OTA_MANIFEST_BASE_URL: https://observer.gessaman.com/v jobs: @@ -137,6 +143,23 @@ jobs: FIRMWARE_BUILD_NUMBER: ${{ needs.enumerate.outputs.build_number }} run: /usr/bin/env bash build.sh build-firmware ${{ matrix.shard.envs }} + - name: Verify production channel is baked in + shell: bash + run: | + # Mirror of the beta workflow's guard, which production lacked. Fail fast + # rather than publish firmware that would OTA itself onto the wrong + # channel: the manifest base is a compile-time -D, so a build that lost + # it (or picked up beta's) is invisible until a node tries `ota check`. + BIN=$(find .pio/build -name firmware.elf | head -1) + if [ -z "$BIN" ]; then echo "no ELF found to verify" >&2; exit 1; fi + if ! strings "$BIN" | grep -qF "$OTA_MANIFEST_BASE_URL"; then + echo "ERROR: production manifest base missing from $BIN" >&2; exit 1 + fi + if strings "$BIN" | grep -qF 'https://observer.gessaman.com/beta/v'; then + echo "ERROR: beta manifest base present in a production build" >&2; exit 1 + fi + echo "OK: $BIN carries $OTA_MANIFEST_BASE_URL" + - name: Upload Shard Artifact uses: actions/upload-artifact@v4 with: @@ -253,8 +276,15 @@ jobs: # in out/ -- the assets actually uploaded to the release -- stamping this # build's number. Then persist the counter so the next run increments # from here. + # --prune deletes manifests for envs this build no longer produces, so + # a retired env cannot leave behind a manifest pointing at a release + # asset that later gets pruned (which is a 404 for `ota update` on any + # node still running it). The generator caps the prune (--prune-limit, + # default 4) and fails the run rather than pruning when a build looks + # like it silently lost envs. python3 flasher/scripts/gen-slim-manifests.py \ --bin-dir out \ + --prune \ --static-path "$STATIC_PATH" \ --out-dir flasher/v \ --base-version "$FIRMWARE_VERSION" \ diff --git a/.github/workflows/check-mqtt-preset-parity.yml b/.github/workflows/check-mqtt-preset-parity.yml index e1039a40..7b7d663d 100644 --- a/.github/workflows/check-mqtt-preset-parity.yml +++ b/.github/workflows/check-mqtt-preset-parity.yml @@ -1,7 +1,11 @@ name: Check MQTT Preset Name Parity -# Ensures observer-firmware and observer-firmware-dev share the same built-in -# MQTT preset *names* (config details may differ). See scripts/check_mqtt_preset_parity.py. +# Ensures observer-firmware and observer-firmware-dev ship an identical +# src/helpers/MQTTPresets.h. A slot's preset is stored in /mqtt.json by name, and +# firmware that does not know a name repairs it to "none" and writes the file +# back, so a node that rolls back between channels loses that slot for good. +# Behaviour that differs per channel belongs in MQTTPresetPolicy.h, which is not +# compared. See scripts/check_mqtt_preset_parity.py. permissions: contents: read @@ -81,9 +85,9 @@ jobs: - name: Self-test checker run: python3 scripts/check_mqtt_preset_parity.py --self-test - - name: Compare preset names + - name: Compare preset tables run: | - python3 scripts/check_mqtt_preset_parity.py \ + python3 scripts/check_mqtt_preset_parity.py --exact \ /tmp/preset-parity/prod.h \ /tmp/preset-parity/dev.h \ --label-a observer-firmware \ diff --git a/.gitignore b/.gitignore index 65d52ed7..ea6f96bb 100644 --- a/.gitignore +++ b/.gitignore @@ -67,3 +67,7 @@ __pycache__/ .build-wt-*/ .wt-*/ scripts/__pycache__/* + +# Reduced-TLS mbedTLS archives, ~6 MB per arch, fetched by scripts/fetch_mbedtls_4k.sh. +# Not committed because they must be rebuilt for every espressif32 platform bump. +.mbedtls-4k/ diff --git a/MQTT_IMPLEMENTATION.md b/MQTT_IMPLEMENTATION.md index c9eb2899..3990f5ee 100644 --- a/MQTT_IMPLEMENTATION.md +++ b/MQTT_IMPLEMENTATION.md @@ -283,6 +283,8 @@ pio run -e Station_G2_repeater_observer_mqtt # Station G3 (ESP32) pio run -e Station_G3_ESP32_repeater_observer_mqtt pio run -e Station_G3_ESP32_room_server_observer_mqtt +pio run -e Station_G3_ESP32_r2_repeater_observer_mqtt +pio run -e Station_G3_ESP32_r2_room_server_observer_mqtt # LilyGo T-LoRa V2.1-1.6 (TTGO LoRa32 V1.0) pio run -e LilyGo_TLora_V2_1_1_6_repeater_observer_mqtt_ @@ -323,6 +325,8 @@ the installed application slots and satisfies the updater's compatibility checks | `Station_G2_room_server_observer_mqtt` | `default_16MB.csv` | 16 MB | 6.25 MB | 16 MB flash board | | `Station_G3_ESP32_repeater_observer_mqtt` | `default_16MB.csv` | 16 MB | 6.25 MB | 16 MB flash board | | `Station_G3_ESP32_room_server_observer_mqtt` | `default_16MB.csv` | 16 MB | 6.25 MB | 16 MB flash board | +| `Station_G3_ESP32_r2_repeater_observer_mqtt` | `default_16MB.csv` | 16 MB | 6.25 MB | Second RF slot | +| `Station_G3_ESP32_r2_room_server_observer_mqtt` | `default_16MB.csv` | 16 MB | 6.25 MB | Second RF slot | | `LilyGo_TBeam_1W_repeater_observer_mqtt` | `default_16MB.csv` | 16 MB | 6.25 MB | Set in `boards/t_beam_1w.json`; required vs implicit `default.csv` | | `LilyGo_TBeam_1W_room_server_observer_mqtt` | `default_16MB.csv` | 16 MB | 6.25 MB | same | @@ -449,7 +453,7 @@ Each slot (1-6) supports the following commands: - `set mqttN.audience` - Clear JWT audience (reverts to username/password auth) - `set mqttN.filter ` - Select payload types uploaded to this slot -**Note:** Custom server/port settings only apply when the slot's preset is `custom`. Username/password also apply to built-in presets that use per-slot credentials (e.g. `inwmesh`); other userpass presets (`tennmesh`, `nashmesh`, `ctmesh`) ship fixed credentials in firmware. +**Note:** Custom server/port settings only apply when the slot's preset is `custom`. Username/password also apply to built-in presets that use per-slot credentials (e.g. `inwmesh`); other userpass presets (`tennmesh`, `nashmesh`, `ctmesh`, `marwoj`) ship fixed credentials in firmware. #### Per-broker packet filters diff --git a/docs/mbedtls-tls-footprint.md b/docs/mbedtls-tls-footprint.md index be528e9d..b9a426b3 100644 --- a/docs/mbedtls-tls-footprint.md +++ b/docs/mbedtls-tls-footprint.md @@ -136,6 +136,36 @@ fix was `rm -rf` the package and `pio pkg install` to re-download stock. A prepe search path keeps the change scoped to one env, because the linker takes each archive member from the first archive that satisfies an undefined symbol. +### How the archives are distributed + +They are not committed: ~6 MB per architecture, and they have to be rebuilt for every +`platformio/espressif32` bump, so committing them would grow history permanently and go +stale silently. Instead they are published as a release asset and fetched on demand: + +``` +scripts/fetch_mbedtls_4k.sh esp32s3 # download + verify against the manifest +MESHCORE_REDUCED_TLS=1 pio run -e Heltec_v3_repeater_observer_mqtt +``` + +- `scripts/mbedtls_4k_manifest.txt` — per-arch sha256 of each archive. **Update it on every + platform bump**, together with the published asset. +- `scripts/fetch_mbedtls_4k.sh` — downloads into `.mbedtls-4k//` (gitignored) and + verifies. `MBEDTLS_4K_LOCAL=` copies from a local build tree instead of downloading. +- `scripts/mbedtls_4k.py` — wired into `esp32_base.extra_scripts`, but a **no-op unless + `MESHCORE_REDUCED_TLS=1`**, so ordinary builds need no artifact and behave as before. + +The opt-in path is deliberately loud, because both ways this can go wrong produce a +firmware that looks correct and silently lacks the change: + +| failure | what happens without a guard | guard | +|---|---|---| +| directory missing or partial | linker ignores an unusable `-L` and resolves mbedTLS from the framework | pre-build: hard error | +| archives stale after a platform bump | links the wrong build | pre-build: sha256 vs manifest | +| `-L` present but outranked | framework archives win, flag is inert | post-link: `firmware.map` must resolve every `libmbed*.a` to `.mbedtls-4k/` | + +That last one is the reason the post-link check exists rather than trusting the flag: a +build flag reaching the compiler proves nothing about what got linked. + ## How to verify it worked 1. `strings`/`grep` the new `sdkconfig.h` for the four settings. diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index 9f44ae15..beddaf9d 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -2281,7 +2281,7 @@ void UITask::loop() { ? checkDisplayOn(KEY_ENTER) : handleMultiClick(KEY_SELECT, ev == BUTTON_EVENT_QUADRUPLE_CLICK); } - #endif + #endif #endif #if defined(UI_HAS_ROTARY_INPUT) RotaryInputEvent rotaryEv = rotary_input.poll(); diff --git a/scripts/check_mqtt_preset_parity.py b/scripts/check_mqtt_preset_parity.py index b65d3bc2..676d1ace 100755 --- a/scripts/check_mqtt_preset_parity.py +++ b/scripts/check_mqtt_preset_parity.py @@ -1,13 +1,25 @@ #!/usr/bin/env python3 -"""Compare MQTT built-in preset *names* between two MQTTPresets.h files. +"""Compare the MQTT broker preset table between two MQTTPresets.h files. -Only the first string field of each ``MQTT_PRESETS`` entry is compared (set -equality, case-sensitive). URL, auth, CA, keepalive, and credentials are -ignored so channel branches may diverge on config details without failing CI. +With ``--exact`` (what CI uses) the two files must be byte-identical. The table +is fleet state, not just a build detail: a slot's preset is stored in +/mqtt.json by NAME, and firmware that does not know a name does not merely +ignore it — MQTTPrefsSerializer repairs it to "none" and the repaired file is +written back to flash. A node that rolls back from one channel to the other +therefore loses that slot permanently. Byte equality also catches URL, CA and +credential drift, which a name-only check passes silently even though the two +channels are meant to dial the same brokers. + +Channel-specific behaviour belongs in MQTTPresetPolicy.h, which is not compared, +so this file can stay identical while the channels differ elsewhere. + +Without ``--exact`` only the first string field of each ``MQTT_PRESETS`` entry +is compared (set equality, case-sensitive). That is the older, weaker check, +kept for ad-hoc use. Usage:: - python3 scripts/check_mqtt_preset_parity.py FILE_A FILE_B \\ + python3 scripts/check_mqtt_preset_parity.py FILE_A FILE_B --exact \\ --label-a observer-firmware --label-b observer-firmware-dev python3 scripts/check_mqtt_preset_parity.py --self-test @@ -138,6 +150,49 @@ def compare( ] +def compare_exact( + path_a: Path, + path_b: Path, + *, + label_a: str, + label_b: str, +) -> list[str]: + """Return error lines if the two files differ byte for byte.""" + + data_a = path_a.read_bytes() + data_b = path_b.read_bytes() + if data_a == data_b: + return [] + + import difflib + + errors = [f"{label_a} and {label_b} do not match byte for byte."] + try: + diff = list( + difflib.unified_diff( + data_a.decode("utf-8").splitlines(), + data_b.decode("utf-8").splitlines(), + fromfile=label_a, + tofile=label_b, + lineterm="", + n=1, + ) + ) + except UnicodeDecodeError: + errors.append("(binary difference; cannot render a text diff)") + return errors + + # Enough to identify the drift without pasting the whole table into a log. + errors.extend(diff[:60]) + if len(diff) > 60: + errors.append(f"... {len(diff) - 60} more diff line(s)") + errors.append( + "Preset rows must be identical on both channels. Behaviour that differs " + "per channel belongs in MQTTPresetPolicy.h." + ) + return errors + + def load_names(path: Path) -> set[str]: text = path.read_text(encoding="utf-8") names, _ = parse_presets(text, source=str(path)) @@ -238,6 +293,26 @@ static const MQTTPresetDef MQTT_PRESETS[MQTT_PRESET_COUNT] = {{ print("self-test failed: URL scheme was treated as a comment.", file=sys.stderr) return 1 + # --exact: identical bytes pass, any drift fails — including a change + # that a name-only comparison waves through. + if compare_exact(equal_a, equal_a, label_a="a", label_b="a-copy"): + print("self-test failed: a file was not equal to itself.", file=sys.stderr) + return 1 + if compare(load_names(equal_a), load_names(equal_b), label_a="a", label_b="b"): + print("self-test failed: fixture assumption broken.", file=sys.stderr) + return 1 + exact_errs = compare_exact(equal_a, equal_b, label_a="a", label_b="b") + if not exact_errs or "byte for byte" not in exact_errs[0]: + print( + "self-test failed: --exact accepted files that differ only in " + f"config: {exact_errs!r}", + file=sys.stderr, + ) + return 1 + if not any("MQTTPresetPolicy.h" in line for line in exact_errs): + print("self-test failed: --exact failure omitted the remedy.", file=sys.stderr) + return 1 + # Silence unused path in fixture layout. dupes.write_text("// unused\n", encoding="utf-8") @@ -251,6 +326,11 @@ def main(argv: list[str] | None = None) -> int: parser.add_argument("file_b", type=Path, nargs="?", help="Second MQTTPresets.h (e.g. dev)") parser.add_argument("--label-a", default="file_a", help="Label for file_a in reports") parser.add_argument("--label-b", default="file_b", help="Label for file_b in reports") + parser.add_argument( + "--exact", + action="store_true", + help="Require the two files to be byte-identical (what CI enforces)", + ) parser.add_argument("--self-test", action="store_true") args = parser.parse_args(argv) @@ -260,6 +340,23 @@ def main(argv: list[str] | None = None) -> int: if args.file_a is None or args.file_b is None: parser.error("FILE_A and FILE_B are required unless --self-test is set") + if args.exact: + try: + errors = compare_exact( + args.file_a, args.file_b, label_a=args.label_a, label_b=args.label_b + ) + except OSError as error: + print(f"MQTT preset parity check could not run: {error}", file=sys.stderr) + return 2 + if errors: + print("MQTT preset parity check failed:", *errors, sep="\n ", file=sys.stderr) + return 1 + print( + f"MQTT preset parity check passed: {args.label_a} and {args.label_b} " + "have identical preset tables." + ) + return 0 + try: names_a = load_names(args.file_a) names_b = load_names(args.file_b) diff --git a/scripts/fetch_mbedtls_4k.sh b/scripts/fetch_mbedtls_4k.sh new file mode 100755 index 00000000..462773e6 --- /dev/null +++ b/scripts/fetch_mbedtls_4k.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +# Fetch the reduced-TLS mbedTLS archives into .mbedtls-4k//. +# +# These archives are built from the shipped sdkconfig plus three lines +# (CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y, IN_CONTENT_LEN 16384, +# OUT_CONTENT_LEN 4096) and save ~12 KiB of internal DRAM per TLS connection. +# See docs/mbedtls-tls-footprint.md for the rationale and the build recipe. +# +# They are not committed: ~6 MB per architecture, and they must be rebuilt for +# every platform bump, so they are published as a release asset keyed on the +# espressif32 platform version instead. +# +# scripts/fetch_mbedtls_4k.sh [arch] # default: esp32s3 +# +# Set MBEDTLS_4K_LOCAL to skip the download and copy from a local build tree: +# MBEDTLS_4K_LOCAL=~/mbedtls-4k-esp32s3/staged scripts/fetch_mbedtls_4k.sh +set -euo pipefail + +ARCH="${1:-esp32s3}" +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +DEST="$REPO_ROOT/.mbedtls-4k/$ARCH" +MANIFEST="$REPO_ROOT/scripts/mbedtls_4k_manifest.txt" +BASE_URL="${MBEDTLS_4K_BASE_URL:-https://github.com/agessaman/MeshCore/releases/download/mbedtls-4k}" + +if [ ! -f "$MANIFEST" ]; then + echo "error: missing $MANIFEST" >&2 + exit 1 +fi + +# Manifest lines: . Blank lines and # comments ignored. +# The "platform" and "stock:" lines bind the archives to a framework version; +# they are the build check's business, not ours, and are not architectures. +expected="$(awk -v a="$ARCH" '$1 == a && $0 !~ /^#/ {print $2" "$3}' "$MANIFEST")" +if [ -z "$expected" ]; then + echo "error: no manifest entries for arch '$ARCH'" >&2 + echo "known arches: $(awk '$0 !~ /^#/ && NF && $1 != "platform" && $1 !~ /^stock:/ {print $1}' \ + "$MANIFEST" | sort -u | tr '\n' ' ')" >&2 + exit 1 +fi + +mkdir -p "$DEST" + +if [ -n "${MBEDTLS_4K_LOCAL:-}" ]; then + echo "copying from $MBEDTLS_4K_LOCAL" + while read -r _sha name; do + cp "$MBEDTLS_4K_LOCAL/$name" "$DEST/$name" + done <<< "$expected" +else + TARBALL="mbedtls-4k-$ARCH.tar.gz" + echo "downloading $BASE_URL/$TARBALL" + tmp="$(mktemp -d)" + trap 'rm -rf "$tmp"' EXIT + curl -fsSL "$BASE_URL/$TARBALL" -o "$tmp/$TARBALL" + tar -xzf "$tmp/$TARBALL" -C "$tmp" + while read -r _sha name; do + # Accept the archive whether or not the tarball has a leading directory. + found="$(find "$tmp" -name "$name" -type f | head -1)" + if [ -z "$found" ]; then + echo "error: $name missing from $TARBALL" >&2 + exit 1 + fi + cp "$found" "$DEST/$name" + done <<< "$expected" +fi + +# Verify every archive against the manifest. A wrong or truncated archive would +# otherwise link silently and produce a firmware without the reduced buffers. +cd "$DEST" +if command -v shasum >/dev/null 2>&1; then + echo "$expected" | shasum -a 256 -c - +else + echo "$expected" | sha256sum -c - +fi + +echo "ok: $ARCH archives verified in $DEST" diff --git a/scripts/mbedtls_4k.py b/scripts/mbedtls_4k.py new file mode 100644 index 00000000..29cf0e3b --- /dev/null +++ b/scripts/mbedtls_4k.py @@ -0,0 +1,244 @@ +"""Link the reduced-TLS mbedTLS archives, and prove they were actually linked. + +Opt in per build with MESHCORE_REDUCED_TLS=1. Off by default, so an ordinary build +needs no 6 MB artifact and behaves exactly as before. + + MESHCORE_REDUCED_TLS=1 pio run -e Heltec_v3_repeater_observer_mqtt + +The archives lower the mbedTLS outbound record buffer from 16 KiB to 4 KiB, saving +~12 KiB of internal DRAM per TLS connection on non-PSRAM observers. The inbound +buffer stays at 16 KiB, so the contiguous allocation a handshake needs is unchanged +— this buys headroom, it does not move that floor. See docs/mbedtls-tls-footprint.md. + +Three failure modes this guards against, each of which produces a firmware that looks +fine and is silently wrong: + + - a -L pointing at a missing or partial directory. The linker ignores an + unusable search path and quietly resolves mbedTLS from the framework instead. + - archives that do not match the manifest, e.g. left over from an earlier + platform version. + - a manifest and archives that agree with each other but not with the installed + framework, which is what a platform bump without a rebuild leaves behind. That + one links cleanly and drifts on struct layout at runtime. + +So the opt-in path verifies every archive by sha256 before the build, checks the +framework's own mbedTLS archives still fingerprint as the ones these were built +against, and after the link re-reads firmware.map to confirm every libmbed*.a came +from our directory. +""" +Import("env") + +import hashlib +import os +import sys + +REQUIRED = ("libmbedcrypto.a", "libmbedtls_2.a", "libmbedtls.a", "libmbedx509.a") + + +def _fail(msg): + print("\n*** reduced-TLS build failed ***", file=sys.stderr) + print(msg, file=sys.stderr) + print( + "\nFetch the archives with: scripts/fetch_mbedtls_4k.sh " + "\nOr build without them by unsetting MESHCORE_REDUCED_TLS.", + file=sys.stderr, + ) + env.Exit(1) + + +def _sha256(path): + h = hashlib.sha256() + with open(path, "rb") as fh: + for chunk in iter(lambda: fh.read(1 << 20), b""): + h.update(chunk) + return h.hexdigest() + + +def _manifest(project_dir, arch): + path = os.path.join(project_dir, "scripts", "mbedtls_4k_manifest.txt") + if not os.path.isfile(path): + _fail("missing scripts/mbedtls_4k_manifest.txt") + wanted = {} + stock = {} + platform_id = "" + with open(path) as fh: + for line in fh: + line = line.strip() + if not line or line.startswith("#"): + continue + parts = line.split() + if len(parts) == 2 and parts[0] == "platform": + platform_id = parts[1] + elif len(parts) == 3 and parts[0] == "stock:" + arch: + stock[parts[2]] = parts[1] + elif len(parts) == 3 and parts[0] == arch: + wanted[parts[2]] = parts[1] + return wanted, stock, platform_id + + +# Where each espressif32 generation keeps the archives we displace. First directory +# holding all four wins, so this resolves without knowing which platform is in play. +FRAMEWORK_LIB_DIRS = ( + ("framework-arduinoespressif32", "tools/sdk/%s/lib"), + ("framework-arduinoespressif32-libs", "%s/lib"), + ("framework-arduinoespressif32", "tools/esp32-arduino-libs/%s/lib"), +) + + +def _framework_lib_dir(platform, arch): + for package, layout in FRAMEWORK_LIB_DIRS: + try: + base = platform.get_package_dir(package) + except Exception: + base = None + if not base: + continue + path = os.path.join(base, *(layout % arch).split("/")) + if all(os.path.isfile(os.path.join(path, name)) for name in REQUIRED): + return path + return None + + +if os.environ.get("MESHCORE_REDUCED_TLS", "") not in ("1", "true", "yes"): + Return() + +project_dir = env.subst("$PROJECT_DIR") +arch = env.BoardConfig().get("build.mcu", "") +if not arch: + _fail("could not determine board MCU, so cannot pick an archive set") + +staged = os.path.join(project_dir, ".mbedtls-4k", arch) +if not os.path.isdir(staged): + _fail("no archives for %s at %s" % (arch, staged)) + +wanted, stock, manifest_platform = _manifest(project_dir, arch) +if not wanted: + _fail("manifest has no entries for arch '%s'" % arch) + +for name in REQUIRED: + archive = os.path.join(staged, name) + if not os.path.isfile(archive): + _fail("missing %s" % archive) + if name not in wanted: + _fail("%s is not in the manifest for %s" % (name, arch)) + actual = _sha256(archive) + if actual != wanted[name]: + _fail( + "%s does not match the manifest\n expected %s\n actual %s\n" + "Rebuild it for this platform version, or re-run the fetch script." + % (archive, wanted[name], actual) + ) + +# Bind the staged archives to the framework they were built against. The hashes above +# only prove the staged files are the ones the manifest names; they say nothing about +# whether the manifest is still current. Bump the platform without rebuilding, and +# every check above still passes while the link takes mbedTLS built against a +# different IDF — a struct-layout drift that corrupts silently at runtime. So +# fingerprint the framework's own archives, the ones being displaced: if those moved, +# the staged pair is stale by construction. +platform = env.PioPlatform() +platform_id = "%s@%s" % (platform.name, platform.version) +stock_dir = _framework_lib_dir(platform, arch) +if stock_dir is None: + _fail("cannot locate the framework's own mbedTLS archives for %s, so the staged " + "ones cannot be tied to a framework version" % arch) +if not stock: + _fail("manifest has no stock:%s fingerprints — it predates the framework binding.\n" + "Add these lines for the framework now installed (%s):\n%s" + % (arch, platform_id, + "\n".join("stock:%s %s %s" % (arch, _sha256(os.path.join(stock_dir, n)), n) + for n in REQUIRED))) + +for name in REQUIRED: + actual = _sha256(os.path.join(stock_dir, name)) + if name not in stock: + _fail("manifest has no stock:%s entry for %s" % (arch, name)) + if actual != stock[name]: + _fail( + "the framework's mbedTLS archives are not the ones these were built against.\n" + " %s\n manifest %s\n installed %s\n" + "Manifest records %s; installed is %s.\n" + "Rebuild the reduced-TLS archives against this framework " + "(docs/mbedtls-tls-footprint.md), then update every hash in the manifest." + % (os.path.join(stock_dir, name), stock[name], actual, + manifest_platform or "no platform", platform_id) + ) + +if manifest_platform and manifest_platform != platform_id: + # Hashes are the check; the version string is orientation. Identical archives + # under a renamed platform are not a compatibility problem. + print("reduced-TLS: manifest says %s, installed is %s — archives match, so this is " + "only a stale label" % (manifest_platform, platform_id)) + +# Prepend so these satisfy mbedTLS symbols ahead of the framework's own copies: +# the linker takes each archive member from the first archive that resolves it. +env.Prepend(LIBPATH=[staged]) +print("reduced-TLS: linking mbedTLS from %s (verified)" % staged) + + +def _verify_map(source, target, env): + """Confirm every mbedTLS archive in the link came from our directory. + + Fails closed. Anything that stops this from *proving* the link — no map, an + unparsable map, a short archive list — is a failure, not a warning. A warning + here would leave exactly the hole the check exists to close: an opt-in build + that succeeds while silently linking the framework's 16 KiB buffers. + """ + # Derive the map name from PROGNAME rather than hardcoding firmware.map, so a + # renamed program cannot leave us inspecting a stale or absent file. + map_path = os.path.join(env.subst("$BUILD_DIR"), + env.subst("${PROGNAME}") + ".map") + if not os.path.isfile(map_path): + legacy = os.path.join(env.subst("$BUILD_DIR"), "firmware.map") + map_path = legacy if os.path.isfile(legacy) else map_path + if not os.path.isfile(map_path): + print("\n*** reduced-TLS: no linker map at %s ***" % map_path, + file=sys.stderr) + print("Cannot prove the reduced-TLS archives were linked. Ensure the env " + "emits a map (-Wl,-Map), or unset MESHCORE_REDUCED_TLS.", + file=sys.stderr) + env.Exit(1) + return + # The map records whatever the linker was given, which for a -L hit is a path + # relative to the linker's cwd (the project dir). Resolve before comparing, or + # every one of our own archives reads as stray. + staged_real = os.path.realpath(staged) + stray = set() + seen = set() + with open(map_path, errors="replace") as fh: + for line in fh: + for token in line.split(): + if "libmbed" not in token or ".a" not in token: + continue + path = token.split("(")[0] + base = os.path.basename(path) + if not base.startswith("libmbed") or not base.endswith(".a"): + continue + seen.add(base) + resolved = os.path.realpath(os.path.join(project_dir, path)) + if os.path.dirname(resolved) != staged_real: + stray.add(path) + if stray: + print("\n*** reduced-TLS: archives linked from the WRONG place ***", + file=sys.stderr) + for path in sorted(stray): + print(" " + path, file=sys.stderr) + env.Exit(1) + return + # Every required archive must appear. Seeing only some of them means the rest + # resolved somewhere this parse did not recognise, which is not proof of anything. + missing = [name for name in REQUIRED if name not in seen] + if missing: + print("\n*** reduced-TLS: %s names only %d of %d archives ***" + % (os.path.basename(map_path), len(seen), len(REQUIRED)), + file=sys.stderr) + print(" missing: " + ", ".join(missing), file=sys.stderr) + print("Either the map format changed or mbedTLS was resolved elsewhere; " + "the reduced buffers cannot be assumed.", file=sys.stderr) + env.Exit(1) + return + print("reduced-TLS: confirmed all %d archives linked from %s" + % (len(REQUIRED), staged)) + + +env.AddPostAction("$BUILD_DIR/${PROGNAME}.elf", _verify_map) diff --git a/scripts/mbedtls_4k_manifest.txt b/scripts/mbedtls_4k_manifest.txt new file mode 100644 index 00000000..5ac608a6 --- /dev/null +++ b/scripts/mbedtls_4k_manifest.txt @@ -0,0 +1,23 @@ +# Reduced-TLS mbedTLS archives (OUT_CONTENT_LEN 4096, IN_CONTENT_LEN 16384). +# Format: +# +# Rebuild these for every espressif32 platform bump — the archives must match the +# rest of the framework they link against. Built as of platformio/espressif32@6.11.0 +# from the recipe in docs/mbedtls-tls-footprint.md. +# +# Fetch with: scripts/fetch_mbedtls_4k.sh esp32s3 +esp32s3 01629f635b33ffa2c1fdfcd8ac52327cd3a92e8d4e7c9a32d92974e0cfdfe398 libmbedcrypto.a +esp32s3 07e7a09847589fefc35bc8d2f739d556535d535acd7185a9824b2af8edd5b05a libmbedtls_2.a +esp32s3 e12bcc8d76a368e819987f266e73c265178d6b6675f05d0e29014bb543c402af libmbedtls.a +esp32s3 c1e10324e19f6d7763737f72d9032cec832bdfce60c7a7d381a5fcfc7dcad573 libmbedx509.a + +# Framework binding, read by scripts/mbedtls_4k.py and ignored by the fetch script. +# "stock:" lines fingerprint the framework's own archives — the ones the entries above +# displace. They are what makes "rebuild on every platform bump" enforceable instead of +# advisory: if the framework's copies move, the entries above are stale by construction +# and the build stops. Regenerate both sets together, never one alone. +platform espressif32@6.11.0 +stock:esp32s3 abdaf759ee17aa697468427b55a86c6c0082ac4cdeb643a63d8b3ac2df324633 libmbedcrypto.a +stock:esp32s3 9a580d2ff7c885e1bf59479a14422e3d10a485ae9083acb5db943df714c0ac35 libmbedtls_2.a +stock:esp32s3 a0f331245feb5cf4fe8d9f99b03d34d64f10e38d8a8d680e35b34ec82aa3cf9e libmbedtls.a +stock:esp32s3 3d56277224b066118b6c48a973ae18fdf8078448bf54b482ac5557699e52f223 libmbedx509.a diff --git a/scripts/webconfig_cli_audit.py b/scripts/webconfig_cli_audit.py index 2a19b0cd..675face8 100644 --- a/scripts/webconfig_cli_audit.py +++ b/scripts/webconfig_cli_audit.py @@ -12,9 +12,17 @@ that come back an error, so the two stay honest about each other. python3 scripts/webconfig_mock_server.py --port 8137 & python3 scripts/webconfig_cli_audit.py +Board-specific commands (Board::handleCommand) are offered only when the node +says it answers them, so one run exercises one shape of board. The mock claims +none by default, like a Heltec V3; drive the other shapes with --board-cmds: + + python3 scripts/webconfig_mock_server.py --port 8137 \ + --board-cmds radio.fem.rxgain,radio.fem.txgain,fan & + Exits non-zero if anything fails that is not in EXPECTED_FAILURES. Stdlib only. """ +import glob import json import os import re @@ -30,12 +38,7 @@ INDEX_HTML = os.path.join(HERE, "..", "webui", "index.html") # Errors that are the correct answer, not a gap. EXPECTED_FAILURES = { - # Runtime-gated on the real device by Board::canControlLoRaFemLna(); the - # command exists in every build and the board answers for itself. The mock - # board is a Heltec V3, which has no front-end module. - "get radio.fem.rxgain": "unsupported", - "set radio.fem.rxgain on": "unsupported", - # Guarded by the firmware the same way when no alert PSK is configured. + # Guarded by the firmware when no alert PSK is configured. "alert test": "not configured", } @@ -45,8 +48,11 @@ SKIP = {"reboot", "clkreboot", "poweroff", "shutdown", "erase", "start ota", "log", "get acl"} # Listings use /api/terminal, not this bounded API audit. -def table(): - """The commands autocomplete offers, read straight out of the page.""" +def table(board_cmds=()): + """The commands autocomplete offers, read straight out of the page. + + `board_cmds` is what /api/status said this board answers; the CLI_BOARD_KEYS + entries gated on anything else are not offered and so not driven.""" html = open(INDEX_HTML, encoding="utf-8").read() def section(start, end): @@ -54,15 +60,25 @@ def table(): verbs = re.findall(r'\["([^"]+)","', section("var CLI_VERBS=", "var CLI_KEYS=")) keys = re.findall(r'\["([^"]+)","(?:[^"\\]|\\.)*",(\d)', - section("var CLI_KEYS=", "var CLI_SLOT=")) + section("var CLI_KEYS=", "var CLI_BOARD_KEYS=")) fields = re.findall(r'\["(\w+)","', section("var CLI_SLOT=", "var CLI_TYPES=")) gets = ["get " + k for k, mode in keys if mode != "2"] gets += ["get mqtt%d.%s" % (n, f) for n in (1, 3) for f in fields] # Verbs taking an argument need a value the node will accept; those are # covered by the round-trip probes below rather than guessed at here. + gets += ["get " + k for gate, k, mode in board_table() + if mode != "2" and gate in board_cmds] plain = [v for v in verbs if not v.endswith(" ") and v not in SKIP] - return gets + plain + return [command for command in gets if command not in SKIP] + plain + + +def board_table(): + """[(gate, key, mode)] from CLI_BOARD_KEYS — the keys the page offers only + when /api/status says this board answers for their gate.""" + html = open(INDEX_HTML, encoding="utf-8").read() + section = html[html.index("var CLI_BOARD_KEYS="):html.index("// Per-slot keys")] + return re.findall(r'\["([^"]+)","([^"]+)","(?:[^"\\]|\\.)*",(\d)', section) # Where top-level commands are implemented. MyMesh handles a few before @@ -74,15 +90,74 @@ COMMAND_SOURCES = [ "examples/simple_repeater/MyMesh.cpp", ] -# Firmware commands the table deliberately does not offer. Everything below -# except tls.bundletest is also rejected by /api/cli (wcCliUnavailable), so the -# portal never pretends to run something it cannot. +# Board::handleCommand() is dispatched BEFORE CommonCLI's own table, and the FEM +# commands now live there rather than in CommonCLI. A board file contributes +# whole commands ("get radio.fem.rxgain"), not the bare verbs the sources above +# yield, so the two are collected separately and merged. +BOARD_SOURCES = "variants/*/*Board.cpp" + +# Firmware commands the table deliberately does not offer. NOT_OFFERED = { "tls.bundletest", # TLS debugging, not an operator command "start ota", # binds port 80, which the portal is already using + "stop ota", # nothing to stop: `start ota` cannot run from here "clock sync", # takes its time from the caller; a web request has none + "get acl", # requires the streaming terminal endpoint } +# Of those, the ones /api/cli does NOT reject at POST (wcCliUnavailable). They +# are left out of the table rather than blocked, because running them is +# harmless — `stop ota` just reports that no OTA server is running, which is +# always true here. Everything else in NOT_OFFERED must come back a 400 with a +# reason, so the portal never pretends to run something it cannot. +NOT_REFUSED = {"tls.bundletest", "stop ota"} + +# The local firmware has additional management and diagnostics commands. They +# remain available for manual entry in the terminal; its compact autocomplete +# table intentionally omits them. Keep the board-command parity check focused +# on controls the page actually offers. +ADVANCED_UNLISTED = { + "clear recent.repeater", "clock.sync.mesh now", + "get battery.alert", "get battery.alert.critical", + "get battery.alert.low", "get battery.alert.region", "get clock.sync", + "get clock.sync.drift", "get clock.sync.internet", "get clock.sync.mesh", + "get clock.sync.mesh.edge", "get clock.sync.samples", "get flood.channel.data", + "get flood.channel.data.hops", "get host", "get outpath path", + "get recent.repeater", "get recent.repeaters", "get rx.watchdog", + "get tempradio", "powerlog", "send text.flood", "set battery.alert", + "set battery.alert.critical", "set battery.alert.low", "set clock.sync.drift", + "set clock.sync.internet", "set clock.sync.mesh", "set clock.sync.mesh.edge", + "set clock.sync.samples", "set outpath path", "set rx.watchdog", + "set tempradio", +} + + +def webconfig_variants(): + """Variant directories whose build serves the portal (ESP32 + MQTT bridge). + + Only these boards can put a command in front of this page; a board command + on an nRF52 variant is real but unreachable from here, so it is not a gap. + """ + out = set() + for ini in glob.glob(os.path.join(HERE, "..", "variants", "*", "platformio.ini")): + if "WITH_MQTT_BRIDGE" in open(ini, encoding="utf-8").read(): + out.add(os.path.basename(os.path.dirname(ini))) + return out + + +def board_commands(): + """Whole commands Board::handleCommand() answers, across portal variants.""" + variants = webconfig_variants() + found = set() + for path in glob.glob(os.path.join(HERE, "..", *BOARD_SOURCES.split("/"))): + if os.path.basename(os.path.dirname(path)) not in variants: + continue + src = open(path, encoding="utf-8").read() + body = src[src.find("::handleCommand"):] + for lit in re.findall(r'(?:mem|str)n?cmp\(\s*command\s*,\s*"([^"]+)"', body): + found.add(lit.strip()) + return found + def firmware_commands(): """Top-level command literals the firmware dispatches on.""" @@ -95,7 +170,7 @@ def firmware_commands(): continue for lit in re.findall(r'(?:mem|str)n?cmp\(\s*command\s*,\s*"([^"]+)"', src): found.add(lit.strip()) - return found - NOT_OFFERED + return (found | board_commands()) - NOT_OFFERED - ADVANCED_UNLISTED ROUND_TRIPS = [ ("set mqtt1.port 0", "get mqtt1.port", "0"), ("set usb.logging on", "get usb.logging", "on"), @@ -126,6 +201,29 @@ ROUND_TRIPS = [ ] +# Gated on /api/status's board_cmds, keyed by the gate the page probes for. +BOARD_ROUND_TRIPS = { + "radio.fem.rxgain": [("set radio.fem.rxgain off", "get radio.fem.rxgain", "off")], + "radio.fem.txgain": [("set radio.fem.txgain on", "get radio.fem.txgain", "on")], + "fan": [("set fan on", "get fan", "on 41.0C fan=on cd=0s")], +} + +# Board commands with no getter to read back, so a round-trip cannot reach them. +# Run in order, and drive the rejection path too: a set-only key that silently +# accepted anything would look identical to one that works. +# [(command, should_succeed, expected substring of the reply)] +BOARD_SET_PROBES = { + "fan": [ + ("set fan.lo 40", True, "OK"), + ("set fan.hi 70", True, "OK"), + ("set fan.lo 200", False, "0..100"), # out of range + ("set fan.lo 90", False, "< fan.hi"), # crosses the upper bound + ("set fan.hi 10", False, "> fan.lo"), # crosses the lower bound + ("set fan.hi 130", False, "<= 120"), # out of range + ], +} + + class Client: def __init__(self, base): self.base = base @@ -133,7 +231,19 @@ class Client: self.cookie = r.headers["Set-Cookie"].split(";")[0] # The node caps a sequence at MAX_BATCH and reports it; chunk to match # rather than hardcoding a number that drifts when the slot is resized. - self.max_cmds = json.load(self._open("/api/status")).get("max_cmds", 24) + status = json.load(self._open("/api/status")) + self.max_cmds = status.get("max_cmds", 24) + # Board::handleCommand() commands this node probed for at startup. The + # field is absent until the probe has run, which is NOT the same as an + # empty list, so wait for it rather than audit a board half-known. + for _ in range(20): + if "board_cmds" in status: + break + time.sleep(0.25) + status = json.load(self._open("/api/status")) + else: + sys.exit("node never reported board_cmds; it has not probed its board") + self.board_cmds = [c for c in status["board_cmds"].split(",") if c] def _open(self, path, data=None): headers = {"Content-Type": "application/json"} @@ -186,7 +296,7 @@ def main(): failures = [] - cmds = table() + cmds = table(cli.board_cmds) unexpected = [] for cmd, res in cli.run(cmds): if res["ok"]: @@ -196,6 +306,7 @@ def main(): continue unexpected.append((cmd, res["reply"])) print("commands offered by autocomplete : %d" % len(cmds)) + print("board commands this node answers : %s" % (", ".join(cli.board_cmds) or "none")) print("answered : %d" % (len(cmds) - len(unexpected))) print("sequence cap reported by the node: %d" % cli.max_cmds) for cmd, reply in unexpected: @@ -205,17 +316,39 @@ def main(): # The reverse direction: a command the firmware implements but the table # never offers is invisible to the check above, because the check only ever # drives what the table already knows about. - offered = " ".join(cmds) + " " + " ".join( - re.findall(r'\["([^"]+)","', open(INDEX_HTML, encoding="utf-8").read())) + # A board command is a whole `get`/`set` line, so the get-only list the audit + # drives cannot decide it is offered: `set fan.lo` has no `get` counterpart in + # the table at all, and a board key this mock does not claim is absent from + # `cmds` while still being offerable. Both are expanded from the page here. + html = open(INDEX_HTML, encoding="utf-8").read() + keys = re.findall(r'\["([^"]+)","(?:[^"\\]|\\.)*",(\d)', + html[html.index("var CLI_KEYS="):html.index("var CLI_BOARD_KEYS=")]) + offered = " ".join(cmds) + " " \ + + " ".join("set " + k for k, mode in keys if mode != "1") + " " \ + + " ".join("get %s set %s" % (k, k) for _, k, _ in board_table()) + " " \ + + " ".join(re.findall(r'\["([^"]+)","', html)) missing = sorted(c for c in firmware_commands() if c not in offered) print("\nfirmware commands not in the table: %d" % len(missing)) for c in missing: print(" MISSING %s" % c) failures += [(c, "not offered by autocomplete") for c in missing] - results = cli.run([c for probe in ROUND_TRIPS for c in probe[:2]]) - print("\nround-trips : %d" % len(ROUND_TRIPS)) - for i, (setc, getc, want) in enumerate(ROUND_TRIPS): + # The page asks the node for each gate by name (`get `), so a gate that + # no board getter answers would hide its keys on every board, silently. + fw = firmware_commands() + gates = sorted({gate for gate, _, _ in board_table()}) + bad_gates = [g for g in gates if "get " + g not in fw] + print("\nboard-command gates : %d" % len(gates)) + for g in bad_gates: + print(" FAIL %-30s no board answers `get %s`" % (g, g)) + failures += [(g, "gate has no getter") for g in bad_gates] + + probes = list(ROUND_TRIPS) + for gate in cli.board_cmds: + probes += BOARD_ROUND_TRIPS.get(gate, []) + results = cli.run([c for probe in probes for c in probe[:2]]) + print("\nround-trips : %d" % len(probes)) + for i, (setc, getc, want) in enumerate(probes): setr, getr = results[i * 2][1], results[i * 2 + 1][1] # `get` answers "> value"; compare the value, as the terminal displays it got = re.sub(r"^>\s?", "", getr["reply"]) @@ -225,10 +358,20 @@ def main(): % (getc, got, want, setr["reply"])) failures.append((getc, got)) + # Set-only board commands, which no round-trip can reach. + probes = [p for gate in cli.board_cmds for p in BOARD_SET_PROBES.get(gate, [])] + if probes: + print("\nset-only board commands : %d" % len(probes)) + for (cmd, want_ok, want), (_, res) in zip(probes, cli.run([p[0] for p in probes])): + if res["ok"] == want_ok and want in res["reply"]: + continue + print(" FAIL %-30s %s" % (cmd, res["reply"])) + failures.append((cmd, res["reply"])) + # Commands the portal refuses must be refused clearly, not run and fudged. print("\nrefused with a reason : ", end="") refused = [] - for cmd in sorted(NOT_OFFERED - {"tls.bundletest"}): + for cmd in sorted(NOT_OFFERED - NOT_REFUSED): try: cli._sequence([cmd]) refused.append((cmd, "was accepted, expected a 400")) @@ -236,7 +379,8 @@ def main(): body = json.load(e) if e.code == 400 else {} if e.code != 400 or not body.get("error"): refused.append((cmd, "HTTP %d, expected 400 with a reason" % e.code)) - print("%d/%d" % (len(NOT_OFFERED) - 1 - len(refused), len(NOT_OFFERED) - 1)) + checked = len(NOT_OFFERED) - len(NOT_REFUSED) + print("%d/%d" % (checked - len(refused), checked)) for cmd, why in refused: print(" FAIL %-30s %s" % (cmd, why)) failures += refused diff --git a/scripts/webconfig_mock_server.py b/scripts/webconfig_mock_server.py index 9b7905fe..d12856c4 100644 --- a/scripts/webconfig_mock_server.py +++ b/scripts/webconfig_mock_server.py @@ -103,6 +103,7 @@ def default_config(setup_mode): "radio": { "freq": 910.525, "bw": 62.5, "sf": 7, "cr": 5, "tx": 22, "af": 1.0, "rxdelay": 0.0, "txdelay": 0.5, "cad": False, "rxgain": True, + "fem_rxgain": False, "fem_txgain": False, "rxps_enabled": True, "rxps_level": 8, "rxps_preamble": 16, "rxps_rx_us": 18205, "rxps_sleep_us": 20423, "powersaving": True, @@ -157,6 +158,10 @@ class State: self.lock = threading.Lock() self.setup_mode = args.setup self.active_slots = args.active_slots + # Board::handleCommand() commands this "board" answers. Empty by default: + # the mock is a Heltec V3, which implements no such hook at all. + self.board_cmds = [c for c in args.board_cmds.split(",") if c] + self.probe_delay = args.probe_delay self.cfg = default_config(args.setup) # latched at AP start, like WebConfigServer::_initial_setup self.initial_setup = args.setup and self.cfg["wifi"]["ssid"] == "" @@ -188,7 +193,7 @@ class State: return c def status_json(self, authed): - return { + out = { "mode": "setup" if self.setup_mode else "lan", "auth": authed, "needs_setup": self.cfg["wifi"]["ssid"] == "", @@ -207,6 +212,12 @@ class State: "capabilities": 0x37FF, "max_cmds": CLI_MAX_CMDS, } + # ABSENT, not empty, until the board has been probed: the node's routes + # go live a tick before probeBoardCommands() runs, and the page has to + # retry rather than latch "this board has no board commands". + if time.time() - self.start >= self.probe_delay: + out["board_cmds"] = ",".join(self.board_cmds) + return out # --------------------------------------------------------------------------- @@ -282,7 +293,7 @@ def apply_set(cfg, key, val): ADMIN_PASSWORD = val return True, "OK" - if key == "radio.fem.rxgain": + if key == "radio.fem.rxgain" and key not in ST.board_cmds: return False, "Error: unsupported" # no FEM on the mock board, see GETTERS if key == "radio.rxps": @@ -406,13 +417,74 @@ def apply_set(cfg, key, val): sec, f = STR_KEYS[key] cfg[sec][f] = val return True, "OK" + gate = BOARD_CMD_GATE.get(key) + if gate: + if gate not in ST.board_cmds: + return False, "unknown config: %s" % key # no such command on this board + return apply_board_set(cfg, key, val) + # Strict fallthrough: this function is the single authority on what can be # set, for the batch and the CLI alike. Accepting unknown keys here once hid # the fact that the CLI could not reach `dutycycle` or `radio.fem.rxgain`. # Verbatim shape from CommonCLI::handleSetCmd's fallthrough. + # + # This is also where the board-specific commands land. `radio.fem.*` and + # `fan*` come from Board::handleCommand(), which is dispatched ahead of + # CommonCLI; the mock board is a Heltec V3 and implements no such hook, so + # they reach this fallthrough exactly as they do on the real thing. return False, "unknown config: %s" % key +# Commands that reach Board::handleCommand() rather than CommonCLI. Which ones a +# node answers is a property of the board, so the portal probes for them at +# startup and reports the answers in /api/status; --board-cmds picks which ones +# this mock claims. `fan.lo` / `fan.hi` have no getter and ride on `fan`. +BOARD_CMD_GATE = { + "radio.fem.rxgain": "radio.fem.rxgain", + "radio.fem.txgain": "radio.fem.txgain", + "fan": "fan", + "fan.lo": "fan", + "fan.hi": "fan", +} +BOARD_STATE = {"fan": "auto", "fan.lo": 45, "fan.hi": 60} +FEM_FIELD = {"radio.fem.rxgain": "fem_rxgain", "radio.fem.txgain": "fem_txgain"} + + +def apply_board_set(cfg, key, val): + if key in FEM_FIELD: + if val not in ("on", "off"): + return False, "Error: state must be on or off" + cfg["radio"][FEM_FIELD[key]] = val == "on" + return True, "OK - LoRa FEM %s gain %s" % ("RX" if "rx" in key else "TX", val) + if key == "fan": + if val not in ("on", "off", "auto"): + return False, "Error: fan must be on, off, or auto" + BOARD_STATE["fan"] = val + return True, "OK - fan %s" % val + try: + n = int(val) + except ValueError: + return False, "Error: expected a number" + if key == "fan.lo" and not (0 <= n <= 100 and n < BOARD_STATE["fan.hi"]): + return False, "Error: fan.lo must be 0..100 and < fan.hi" + if key == "fan.hi" and not (BOARD_STATE["fan.lo"] < n <= 120): + return False, "Error: fan.hi must be > fan.lo and <= 120" + BOARD_STATE[key] = n + return True, "OK - %s %d" % (key, n) + + +def board_get(cfg, key): + """Getter reply, or None when this board does not answer the command.""" + if BOARD_CMD_GATE.get(key) not in ST.board_cmds: + return None + if key == "fan": + return "%s 41.0C fan=%s cd=0s" % ( + BOARD_STATE["fan"], "on" if BOARD_STATE["fan"] == "on" else "off") + if key in FEM_FIELD: + return "on" if cfg["radio"][FEM_FIELD[key]] else "off" + return None # fan.lo / fan.hi are set-only on the board too + + # Payload-type names accepted alongside the decimal form. Mirrors # namedPacketTypes() in src/helpers/MQTTPacketFilter.h; 12-14 are reserved # upstream and stay reachable by number only. @@ -552,6 +624,12 @@ GETTERS = { "wifi.status": lambda c: ( "SSID: %s\nIP: 192.168.1.42\nRSSI: -58 dBm\nUptime: %dm" % (c["wifi"]["ssid"] or "(not set)", int(time.time() - ST.start) // 60)), + "link.status": lambda c: ( + "wifi: connected, IP: 192.168.1.42, RSSI: -58 dBm, Uptime: %dm" + % (int(time.time() - ST.start) // 60)), + "link.diag": lambda c: ( + "why:ethernet-not-enabled selected:wifi\n" + "wifi:state:connected ip:192.168.1.42"), "mqtt.status": lambda c: cli_mqtt_status(c), "mqtt.presets": lambda c: "\n".join( "%2d. %s%s" % (i + 1, n, "" if nd == "none" else " (needs %s)" % nd) @@ -599,6 +677,11 @@ def cli_get(cfg, key): def _cli_get_value(cfg, key): + if key in BOARD_CMD_GATE: + val = board_get(cfg, key) + # Not answered: the board has no hook for it, so CommonCLI's own getter + # fallthrough is what replies — exactly as on the real thing. + return (True, val) if val is not None else (False, "??: %s" % key) if key in GETTERS: val = GETTERS[key](cfg) return (True, val) if val is not None else (False, "Error: unsupported") @@ -633,6 +716,10 @@ def cli_read_key(cfg, key): "on" if r["rxps_enabled"] else "off", r["rxps_rx_us"], r["rxps_sleep_us"]), "bw": r["bw"], "sf": r["sf"], "cr": r["cr"], "mqtt.iata": cfg["mqtt"]["iata"], "mqtt.owner": cfg["mqtt"]["owner"], + "display.mode": "button", "display.timeout": "15", + "display.usb.mode": "button", "display.usb.timeout": "15", + "display.inbox": "off", "bluetooth.mac": "", + "bluetooth.stealth": "off", }.get(key) @@ -1110,6 +1197,12 @@ def main(): ap.add_argument("--port", type=int, default=8080) ap.add_argument("--setup", action="store_true", help="first-boot setup wizard mode") ap.add_argument("--active-slots", type=int, default=5, help="server slots to expose (2 or 5)") + ap.add_argument("--probe-delay", type=float, default=0.0, + help="seconds to withhold board_cmds from /api/status, simulating " + "the gap before the node has probed its board") + ap.add_argument("--board-cmds", default="", + help="comma list of Board::handleCommand() commands to answer, e.g. " + "radio.fem.rxgain,radio.fem.txgain,fan (default: none, like a Heltec V3)") ap.add_argument("--fw-version", default=FW_VERSION, help="version string to report, shaped like build.sh's embedded one") ap.add_argument("--minify", action="store_true", diff --git a/src/helpers/CommonRadioPrefs.h b/src/helpers/CommonRadioPrefs.h index d0083b8c..0aeff6b4 100644 --- a/src/helpers/CommonRadioPrefs.h +++ b/src/helpers/CommonRadioPrefs.h @@ -8,8 +8,8 @@ protected: CommonRadioPrefs() { } public: void markDirty() { _is_dirty = true; } - void clearDirty() { _is_dirty = false; } - bool isDirty() const { return _is_dirty; } + void clearDirty() override { _is_dirty = false; } + bool isDirty() const override { return _is_dirty; } virtual float getFreq() const = 0; virtual void setFreq(float f) = 0; diff --git a/src/helpers/ESP32WsTransportFix.cpp b/src/helpers/ESP32WsTransportFix.cpp index ab5ebdff..37c2e253 100644 --- a/src/helpers/ESP32WsTransportFix.cpp +++ b/src/helpers/ESP32WsTransportFix.cpp @@ -33,13 +33,24 @@ // Fix: [esp32_base] adds `-Wl,--wrap=esp_transport_ws_init`, so every // creation of a WS transport (esp-mqtt does one per wss slot) is routed // through __wrap_esp_transport_ws_init below, which replaces the freshly -// allocated 1024-byte buffer with a (WS_BUFFER_SIZE + 1)-byte one. The -// out-of-bounds index WS_BUFFER_SIZE then lands on our extra byte and the -// handshake fails cleanly ("Upgrade" header not found) instead of corrupting -// the heap. Upstream fixed this in ESP-IDF 5.x, so this file compiles to a +// allocated 1024-byte buffer with a (WS_BUFFER_SIZE + 1)-byte one, so the +// out-of-bounds index WS_BUFFER_SIZE lands on our extra byte instead of the +// heap canary. Upstream fixed this in ESP-IDF 5.x, so this file compiles to a // pass-through there and can be deleted (together with the --wrap flag) when // the fork moves to Arduino core 3.x. // +// Scope: this stops the heap corruption and NOTHING else. It does not make an +// oversized response fail the handshake — v4.4's read loop also exits on +// `header_len < WS_BUFFER_SIZE` going false, and then still accepts the +// connection if "Sec-WebSocket-Accept:" was inside those first bytes (it comes +// early, so it usually is). ws_connect() therefore returns success on a partial +// header block and the unread remainder arrives as the first "payload" read, +// where the deframer parses HTTP bytes as a frame header. Observed on hardware +// 2026-08-12: a large Cloudflare CSP header produced exactly that, surfacing as +// `Invalid MSG_TYPE response: 3`. Only IDF 5.2+ fixes it (it requires the +// "\r\n\r\n" delimiter, preserves the bytes after it, and fails cleanly when the +// buffer fills); it cannot be patched here because transport_ws.c is precompiled. +// // transport_ws_t below is copied verbatim from ESP-IDF release/v4.4 // transport_ws.c (the struct is file-private, so it is not in any shipped // header). Source fidelity was verified against the shipped binary: addr2line diff --git a/src/helpers/MQTTClientState.h b/src/helpers/MQTTClientState.h new file mode 100644 index 00000000..dd1fee44 --- /dev/null +++ b/src/helpers/MQTTClientState.h @@ -0,0 +1,82 @@ +#pragma once + +#include + +// What a slot's MQTT client is doing, as opposed to whether its network is up, +// and the two decisions that hang off it. +// +// Pure logic: no Arduino, esp-mqtt or bridge dependency, so the shutdown +// contract below is a host test rather than a hardware run. +// +// `client->connected()` answers "is the network up" and was being used for "is +// there anything to stop": a client resolving DNS, negotiating TLS or waiting +// after a failed CONNECT reports not-connected, so teardown skipped it and left +// its task running (F04). + +enum class MqttClientState : uint8_t { + Absent = 0, // no client object + Configured, // client allocated, never started + Starting, // start/reconnect requested, awaiting CONNECTED + Connected, // CONNECTED received + Disconnected, // started, no session (our reconnect ladder governs it) + Stopped, // stop completed; the SDK task is joined and gone + Quarantined, // stop failed: the SDK task was NOT joined. Never destroy, + // never reuse, never free anything it still points at. +}; + +static inline const char* mqttClientStateName(MqttClientState s) { + switch (s) { + case MqttClientState::Absent: return "absent"; + case MqttClientState::Configured: return "configured"; + case MqttClientState::Starting: return "starting"; + case MqttClientState::Connected: return "connected"; + case MqttClientState::Disconnected: return "disconnected"; + case MqttClientState::Stopped: return "stopped"; + case MqttClientState::Quarantined: return "quarantined"; + } + return "?"; +} + +// The client has been started and not proven stopped: it may still own a task, +// a socket and a TLS context. Quarantined is deliberately NOT live — it is +// worse: it may own them and we can never find out. +static inline bool mqttClientStateIsLive(MqttClientState s) { + return s == MqttClientState::Starting || s == MqttClientState::Connected || + s == MqttClientState::Disconnected; +} + +// A connection attempt is in flight, so an event for it can still arrive. +// Closing the transport is not enough here: PsychicMqttClient::softDisconnect() +// returns immediately when the client is not yet connected, which means an +// in-progress DNS/TLS/CONNECT is left to complete on its own. Cancelling one +// requires a real stop. +static inline bool mqttClientStateHasAttemptInFlight(MqttClientState s) { + return s == MqttClientState::Starting; +} + +// The SDK task is known to be gone (or never existed), so the object may be +// destroyed and anything it pointed at may be freed. +static inline bool mqttClientStateIsProvenStopped(MqttClientState s) { + return s == MqttClientState::Absent || s == MqttClientState::Configured || + s == MqttClientState::Stopped; +} + +// The bridge's cooperative stop may only be acknowledged when EVERY client is +// proven stopped. +// +// This is the invariant the whole shutdown contract rests on: the owner treats +// the acknowledgement as proof that the task destroyed its clients, and only +// then frees the queue and buffers and allows a restart. One client whose +// esp_mqtt_client_stop() never completed makes that false — its SDK task may +// still be running — so the acknowledgement must be withheld and the bridge +// left in its unproven state, however many other slots stopped cleanly. +static inline bool mqttStopMayBeAcknowledged(const MqttClientState* states, int count) { + // An empty set is trivially proven (no slots, nothing to stop); a null array + // with a nonzero count is a caller bug and must not read as proof. + if (count <= 0) return true; + if (states == nullptr) return false; + for (int i = 0; i < count; i++) { + if (!mqttClientStateIsProvenStopped(states[i])) return false; + } + return true; +} diff --git a/src/helpers/MQTTEffectiveConfig.h b/src/helpers/MQTTEffectiveConfig.h new file mode 100644 index 00000000..9408d524 --- /dev/null +++ b/src/helpers/MQTTEffectiveConfig.h @@ -0,0 +1,213 @@ +#pragma once + +#include +#include + +// The complete, owned description of what a slot's MQTT client should be +// configured with, plus the decision of whether the existing SDK client can be +// reconfigured in place or has to be recreated. +// +// Pure logic: no Arduino, esp-mqtt or PsychicMqttClient dependency, so every +// transition in the table below is exercised on the host +// (test/test_mqtt_effective_config). +// +// Why this exists (F02/F03). The bridge used to apply configuration field by +// field, skipping the cleanup of stale fields whenever +// `slot.initial_connect_done` was false — which `teardownSlot()` had just +// cleared, so normal live reconfiguration always skipped it. On hardware that +// sent the previous broker's JWT username in the CONNECT to a newly configured +// anonymous endpoint. Two rules fix it: +// +// 1. Every field is written on every apply. "Absent" is a value that gets +// written (the empty string), never an omission — IDF's +// `esp_mqtt_set_if_config()` treats NULL as "leave unchanged", so a +// cleared wrapper pointer cannot erase an SDK-held credential, while an +// empty string both overwrites it and leaves the CONNECT's username flag +// clear (verified on an ESP32-S3 against a local broker, IDF 4.4). +// 2. Where a field cannot be overwritten safely, the client is recreated. +// That is the exception, not the rule: esp-mqtt's stop/start cycle is the +// fork's documented internal-heap fragmentation driver, so recreation must +// never happen on the reconnect or token-renewal path. + +// Matches MQTTSlot::broker_uri so an effective config can hold its own copy. +#define MQTT_EFFECTIVE_URI_MAX 128 + +enum class MqttTransport : uint8_t { + Unknown = 0, + Tcp, // mqtt:// + Tls, // mqtts:// + Ws, // ws:// + Wss, // wss:// +}; + +enum class MqttTrust : uint8_t { + Plaintext = 0, // unencrypted transport: no server verification exists + Bundle, // shared CA bundle attach callback + PemCert, // one specific CA certificate +}; + +enum class MqttAuth : uint8_t { + None = 0, + UserPass, + Jwt, +}; + +struct MqttEffectiveConfig { + char uri[MQTT_EFFECTIVE_URI_MAX] = {0}; + MqttTransport transport = MqttTransport::Unknown; + MqttTrust trust = MqttTrust::Plaintext; + MqttAuth auth = MqttAuth::None; + // Borrowed pointers with a lifetime at least as long as the client's: preset + // certificates live in flash, credentials in the slot/bridge storage. + const char* pem = nullptr; + const char* username = nullptr; // nullptr == absent, written as "" + const char* password = nullptr; + uint16_t buffer_size = 0; + uint16_t keepalive = 0; + bool valid = false; // false until successfully built +}; + +// Client certificates are deliberately absent: `setClientCertificate()` has no +// caller in the firmware (no broker preset uses mutual TLS), so modelling it +// here would be untested configuration surface. Adding mutual TLS means adding +// it to this struct and to the recreate decision below. + +static inline MqttTransport mqttTransportFromUri(const char* uri) { + if (uri == nullptr) return MqttTransport::Unknown; + if (strncmp(uri, "mqtts://", 8) == 0) return MqttTransport::Tls; + if (strncmp(uri, "mqtt://", 7) == 0) return MqttTransport::Tcp; + if (strncmp(uri, "wss://", 6) == 0) return MqttTransport::Wss; + if (strncmp(uri, "ws://", 5) == 0) return MqttTransport::Ws; + return MqttTransport::Unknown; +} + +static inline bool mqttTransportIsEncrypted(MqttTransport t) { + return t == MqttTransport::Tls || t == MqttTransport::Wss; +} + +static inline const char* mqttTransportName(MqttTransport t) { + switch (t) { + case MqttTransport::Tcp: return "mqtt"; + case MqttTransport::Tls: return "mqtts"; + case MqttTransport::Ws: return "ws"; + case MqttTransport::Wss: return "wss"; + default: return "?"; + } +} + +// A credential the SDK must be told to forget is written as "" rather than +// left NULL. See rule 1 above. +static inline const char* mqttFieldOrEmpty(const char* v) { return v ? v : ""; } + +// Builds an effective config, deriving the transport from the URI and +// normalising the trust policy against it: an unencrypted transport verifies +// nothing, whatever certificate material was requested, so recording anything +// else would make a plaintext endpoint look like a trust change away from a +// verified one (and vice versa). Returns false for an empty or unrecognised +// URI, leaving *out invalid. +static inline bool mqttBuildEffectiveConfig(const char* uri, + MqttAuth auth, + const char* username, + const char* password, + MqttTrust requested_trust, + const char* pem, + uint16_t buffer_size, + uint16_t keepalive, + MqttEffectiveConfig* out) { + if (out == nullptr) return false; + *out = MqttEffectiveConfig(); + if (uri == nullptr || uri[0] == '\0') return false; + if (strlen(uri) >= MQTT_EFFECTIVE_URI_MAX) return false; + + const MqttTransport transport = mqttTransportFromUri(uri); + if (transport == MqttTransport::Unknown) return false; + + strncpy(out->uri, uri, MQTT_EFFECTIVE_URI_MAX - 1); + out->uri[MQTT_EFFECTIVE_URI_MAX - 1] = '\0'; + out->transport = transport; + out->auth = auth; + out->username = username; + out->password = password; + out->buffer_size = buffer_size; + out->keepalive = keepalive; + + if (!mqttTransportIsEncrypted(transport)) { + out->trust = MqttTrust::Plaintext; + out->pem = nullptr; + } else if (requested_trust == MqttTrust::PemCert && pem != nullptr) { + out->trust = MqttTrust::PemCert; + out->pem = pem; + } else if (requested_trust == MqttTrust::Bundle) { + out->trust = MqttTrust::Bundle; + } else { + // Encrypted transport with no usable trust material. Recorded as Plaintext + // trust so it is never confused with a verified policy; whether to connect + // at all is the caller's decision. + out->trust = MqttTrust::Plaintext; + } + + out->valid = true; + return true; +} + +struct MqttRecreateDecision { + bool recreate = false; + const char* reason = "reuse"; // static literal, for logs and tests +}; + +// Whether the SDK client that `applied` was written to can be reconfigured in +// place to reach `desired`. +// +// transport (scheme) change -> recreate. One `wss`->`mqtt` transition was +// observed working by reuse on hardware, but that proves one direction +// once, not that no websocket transport state survives the switch; the +// retained-`frame_state` bug class is real and unfixed upstream even in +// IDF 5.3, and this transition only happens when an operator changes the +// endpoint. +// trust change -> recreate. `cert_pem` cannot be cleared by +// writing "" (an empty PEM is a parse failure, not "no certificate"), and +// the bundle attach is a function pointer whose set_config semantics are +// not established on this build. Verification policy is the one field +// where a stale value silently weakens security. +// capacity growth -> recreate. IDF 4.4 allocates the MQTT buffers +// in `esp_mqtt_client_init()` and `esp_mqtt_set_config()` does not resize +// them; the wrapper's own reassembly buffer is likewise allocated once. +// everything else -> reuse, including every credential and +// auth-mode change, because those are rewritten unconditionally. +static inline MqttRecreateDecision mqttConfigRecreateDecision( + const MqttEffectiveConfig& applied, + const MqttEffectiveConfig& desired, + uint16_t allocated_buffer_size) { + MqttRecreateDecision d; + if (!desired.valid) { + d.recreate = false; + d.reason = "invalid-desired"; + return d; + } + if (!applied.valid) { + // Nothing applied yet: a fresh client needs configuring, not recreating. + d.reason = "first-apply"; + return d; + } + if (applied.transport != desired.transport) { + d.recreate = true; + d.reason = "transport-change"; + return d; + } + if (applied.trust != desired.trust) { + d.recreate = true; + d.reason = "trust-change"; + return d; + } + if (desired.trust == MqttTrust::PemCert && applied.pem != desired.pem) { + d.recreate = true; + d.reason = "ca-cert-change"; + return d; + } + if (desired.buffer_size > allocated_buffer_size) { + d.recreate = true; + d.reason = "buffer-growth"; + return d; + } + return d; +} diff --git a/src/helpers/MQTTPresetPolicy.h b/src/helpers/MQTTPresetPolicy.h new file mode 100644 index 00000000..a5a8ddce --- /dev/null +++ b/src/helpers/MQTTPresetPolicy.h @@ -0,0 +1,34 @@ +#pragma once + +#include "MQTTPresets.h" + +#include + +// Policy that keys off a preset rather than describing one. +// +// MQTTPresets.h is data: it is the broker table, and it is kept byte-identical +// between the observer-firmware and observer-firmware-dev channels so a node +// that rolls back cannot meet a preset name its firmware does not know. An +// unknown name is not merely ignored — MQTTPrefsSerializer repairs it to "none" +// and the repaired /mqtt.json is written back, so the operator's slot is gone +// for good. Channel-specific behaviour therefore lives here instead, where the +// two channels are free to differ. + +// True when the broker tears down a live session once its JWT passes exp, so the +// renewal must proactively bounce the connection to present a fresh token. +// +// Default true, because getting this wrong the safe way costs a re-handshake and +// getting it wrong the unsafe way costs an outage. waev is the exception: its +// operator confirmed (2026-08-11) that their servers do not disconnect on expiry, +// so a live session there needs only its credentials refreshed for the next +// reconnect. waev is also the only preset with a short token_lifetime, so it was +// the only one bouncing often — every ~47 min, and each bounce's re-handshake can +// cost ~10 KB of contiguous internal DRAM on a non-PSRAM board. +// +// Keyed by name rather than a struct field on purpose: adding a field would mean +// re-ordering a dozen positional initialisers in the table, where a mistake is +// silent. +static inline bool mqttPresetEnforcesTokenExp(const MQTTPresetDef* preset) { + if (!preset || !preset->name) return true; // custom/audience slots: assume enforced + return strcmp(preset->name, "waev") != 0; +} diff --git a/src/helpers/MQTTPresets.h b/src/helpers/MQTTPresets.h index 59bbac9f..bce84d1e 100644 --- a/src/helpers/MQTTPresets.h +++ b/src/helpers/MQTTPresets.h @@ -87,7 +87,7 @@ static inline bool mqttPresetNeedsSlotCredentials(const MQTTPresetDef* preset) { } // Number of built-in presets -static const int MQTT_PRESET_COUNT = 36; +static const int MQTT_PRESET_COUNT = 37; // Keep the certificate and preset tables in one translation unit. Defining // these as header-local constants created a complete flash copy in every MQTT @@ -199,6 +199,7 @@ extern const MQTTPresetDef MQTT_PRESETS[MQTT_PRESET_COUNT] = { { "idahomesh", "wss://mqtt.idahomesh.org:443/mqtt", "mqtt.idahomesh.org", ISRG_ROOT_X1, MQTT_AUTH_JWT, MQTT_TOPIC_MESHCORE, 0, true, 55, nullptr, nullptr }, { "ntxmesh", "wss://ntxmesh.dhovin.me:8883", "ntxmesh.dhovin.me", ISRG_ROOT_X1, MQTT_AUTH_JWT, MQTT_TOPIC_MESHCORE, 0, true, 55, nullptr, nullptr }, { "bsmesh", "wss://mqtt.bsmesh.de:8885", "mqtt.bsmesh.de", ISRG_ROOT_X1, MQTT_AUTH_JWT, MQTT_TOPIC_MESHCORE, 0, true, 55, nullptr, nullptr }, + { "marwoj", "mqtts://mqtt.marwoj.net:8883", nullptr, ISRG_ROOT_X1, MQTT_AUTH_USERPASS, MQTT_TOPIC_MESHCORE, 0, true, 55, "observer-agessaman", "ipRwCEclZkX47K" }, }; #else diff --git a/src/helpers/NetworkHostname.h b/src/helpers/NetworkHostname.h new file mode 100644 index 00000000..caf6396b --- /dev/null +++ b/src/helpers/NetworkHostname.h @@ -0,0 +1,107 @@ +#pragma once + +#include +#include + +namespace NetworkHostname { + +// ESP-IDF documents a 32-byte hostname limit. Keep one byte for the trailing +// NUL so the same buffer is safe through Arduino and lwIP APIs. +static constexpr size_t kMaxLength = 31; +static constexpr size_t kBufferSize = kMaxLength + 1; + +static inline bool isAsciiAlphaNumeric(uint8_t ch) { + return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9'); +} + +static inline char asciiLower(uint8_t ch) { + return ch >= 'A' && ch <= 'Z' ? static_cast(ch + ('a' - 'A')) + : static_cast(ch); +} + +/** + * Build a DHCP-safe hostname from the MeshCore node name. + * + * The result is lowercase, starts with "meshcore-", contains only letters, + * digits and hyphens, and never exceeds ESP-IDF's practical 31-character + * payload limit. Six hex digits from the stable node identity are retained + * whenever non-ASCII bytes are removed, a fallback is needed, or the readable + * name must be shortened. This keeps lossy sanitization from assigning the + * same DHCP identity to unrelated nodes. + */ +static inline bool build(char* dest, size_t dest_size, const char* node_name, + const uint8_t* stable_id, size_t stable_id_size) { + if (!dest || dest_size == 0) return false; + dest[0] = '\0'; + + static constexpr char kPrefix[] = "meshcore-"; + static constexpr char kFallback[] = "node"; + static constexpr char kHex[] = "0123456789abcdef"; + static constexpr size_t kPrefixLength = sizeof(kPrefix) - 1; + static constexpr size_t kSuffixLength = 7; // '-' plus six hex digits. + + // NodePrefs::node_name currently holds at most 31 bytes. A larger scratch + // buffer keeps this helper safe and independently testable with other input. + char slug[64]; + size_t slug_length = 0; + bool separator_pending = false; + bool removed_non_ascii = false; + if (node_name) { + for (size_t i = 0; node_name[i] != '\0' && slug_length < sizeof(slug) - 1; + ++i) { + const uint8_t ch = static_cast(node_name[i]); + if (isAsciiAlphaNumeric(ch)) { + if (separator_pending && slug_length > 0 && + slug_length < sizeof(slug) - 1) { + slug[slug_length++] = '-'; + } + if (slug_length < sizeof(slug) - 1) { + slug[slug_length++] = asciiLower(ch); + } + separator_pending = false; + } else { + if (ch >= 0x80) removed_non_ascii = true; + if (slug_length > 0) separator_pending = true; + } + } + } + + const bool used_fallback = slug_length == 0; + if (slug_length == 0) { + for (size_t i = 0; i < sizeof(kFallback) - 1; ++i) { + slug[slug_length++] = kFallback[i]; + } + } + slug[slug_length] = '\0'; + + size_t max_length = dest_size - 1; + if (max_length > kMaxLength) max_length = kMaxLength; + if (max_length == 0) return false; + + const bool needs_truncation = kPrefixLength + slug_length > max_length; + const bool needs_identity = needs_truncation || removed_non_ascii || used_fallback; + const bool can_add_identity = needs_identity && stable_id && + stable_id_size >= 3 && max_length > kPrefixLength + kSuffixLength; + const size_t suffix_length = can_add_identity ? kSuffixLength : 0; + const size_t prefix_length = kPrefixLength < max_length + ? kPrefixLength : max_length; + size_t slug_budget = max_length - prefix_length - suffix_length; + if (slug_budget > slug_length) slug_budget = slug_length; + while (slug_budget > 0 && slug[slug_budget - 1] == '-') --slug_budget; + + size_t out = 0; + for (size_t i = 0; i < prefix_length; ++i) dest[out++] = kPrefix[i]; + for (size_t i = 0; i < slug_budget; ++i) dest[out++] = slug[i]; + if (can_add_identity) { + dest[out++] = '-'; + for (size_t i = 0; i < 3; ++i) { + dest[out++] = kHex[(stable_id[i] >> 4) & 0x0f]; + dest[out++] = kHex[stable_id[i] & 0x0f]; + } + } + dest[out] = '\0'; + return true; +} + +} // namespace NetworkHostname diff --git a/src/helpers/NetworkLink.cpp b/src/helpers/NetworkLink.cpp new file mode 100644 index 00000000..ba87b35a --- /dev/null +++ b/src/helpers/NetworkLink.cpp @@ -0,0 +1,979 @@ +#include "NetworkLink.h" + +#if defined(ESP_PLATFORM) + +#include "MQTTConnectionPolicy.h" +#include "WifiPowerSavePolicy.h" + +#include +#include +#include + +#include +#include +#include +#include + +#if defined(NETWORK_PREFER_ETHERNET) +#include "ethernet/ch390/CH390Config.h" + +// Arduino-ESP32's built-in ETH implementation calls this before bringing up +// Ethernet. It creates the shared Arduino network event group/task used by +// WiFiGenericClass::hostByName(), even when no Wi-Fi interface is started. +// ESP32-CH390 initializes esp_netif directly and omits this Arduino layer. +extern void tcpipInit(); +#endif + +// Same "MQTT: " prefix as MQTT_DEBUG_PRINTLN so existing log greps keep matching. +#if defined(MQTT_DEBUG) + #define NETWORK_DEBUG_PRINTLN(F, ...) do { if (Serial.availableForWrite() > 0) { Serial.printf("MQTT: " F "\n", ##__VA_ARGS__); } } while (0) +#else + #define NETWORK_DEBUG_PRINTLN(...) do {} while (0) +#endif + +namespace { + +class NetworkLinkBase : public NetworkLink { + protected: + std::atomic _outage_bits{AlertFaultPolicy::packOutageSnapshot({false, 0, 0})}; + std::atomic _connected_at{0}; + std::atomic _last_disconnect_time{0}; + std::atomic _last_disconnect_reason{0}; + bool _status_initialized = false; + bool _last_connected = false; + unsigned long _last_status_check = 0; + static constexpr int kDnsServers = 2; + // Only ever touched on the lwIP thread (see snapshotDns()), so no atomics. + ip_addr_t _dns_snapshot[kDnsServers] = {}; + bool _dns_captured = false; + + AlertFaultPolicy::OutageSnapshot outage() const { + return AlertFaultPolicy::unpackOutageSnapshot( + _outage_bits.load(std::memory_order_acquire)); + } + + void setOutage(AlertFaultPolicy::OutageSnapshot snapshot) { + _outage_bits.store(AlertFaultPolicy::packOutageSnapshot(snapshot), + std::memory_order_release); + } + + void noteConnected(unsigned long now_ms) { + if (_connected_at.load(std::memory_order_relaxed) == 0) { + _connected_at.store(now_ms, std::memory_order_relaxed); + } + setOutage(AlertFaultPolicy::applyWifiGotIp(outage())); + } + + void noteDisconnected(unsigned long now_ms, uint8_t reason) { + _last_disconnect_reason.store(reason, std::memory_order_relaxed); + _last_disconnect_time.store(now_ms, std::memory_order_relaxed); + setOutage(AlertFaultPolicy::applyWifiDisconnectEvent( + (uint32_t)now_ms, reason, outage())); + } + + + public: + unsigned long connectedAtMillis() const override { + return _connected_at.load(std::memory_order_relaxed); + } + + uint8_t lastDisconnectReason() const override { + return _last_disconnect_reason.load(std::memory_order_relaxed); + } + + unsigned long lastDisconnectTime() const override { + return _last_disconnect_time.load(std::memory_order_relaxed); + } + + AlertFaultPolicy::OutageSnapshot outageSnapshot() const override { + return outage(); + } + + private: + // Remember the resolver this link's DHCP lease installed, so switching back + // to it can put that resolver back. + // + // lwIP keeps ONE global server list, not one per interface: a DHCP lease on + // any medium calls dns_setserver() and overwrites whatever the other medium + // had. IDF 4.4 has no per-interface retention either — esp_netif_get_dns_info() + // reads the same globals — so the medium that leased last owns DNS for every + // socket. Without this, an Ethernet node that falls back to Wi-Fi and then + // fails back keeps asking the Wi-Fi network's DNS server. When the two are on + // different subnets that server is unreachable from Ethernet, and the node + // reads as connected while every broker and NTP hostname fails to resolve, + // until Ethernet's own DHCP renewal happens to fix it hours later. + // + // Both halves run through esp_netif_tcpip_exec() because lwIP's DNS functions + // belong to the TCP/IP thread, and these are called from the Arduino event + // task (Ethernet GOT_IP) and the MQTT task (Wi-Fi edge, and select()). That + // also serializes the snapshot itself, so it needs no atomics. Neither caller + // is the TCP/IP thread, so the call cannot deadlock on itself. + // + // The whole ip_addr_t is kept, not an IPv4 word: these builds compile lwIP + // with IPv6 on, and reinterpreting a v6 server as v4 would install four + // meaningless bytes as a resolver. (RDNSS is disabled here, so a v6 server + // should never appear — storing the tagged value means it stays correct if + // that ever changes.) + static esp_err_t snapshotDnsOnTcpipThread(void* ctx) { + NetworkLinkBase* self = static_cast(ctx); + bool any = false; + for (int i = 0; i < kDnsServers; i++) { + const ip_addr_t* server = dns_getserver(i); + self->_dns_snapshot[i] = (server != nullptr) ? *server : *IP_ADDR_ANY; + if (!ip_addr_isany_val(self->_dns_snapshot[i])) any = true; + } + // A lease that carried no resolver at all (static configuration, or a + // server that offered none) must not be remembered as "this medium's DNS is + // nothing" — restoring that would wipe a working resolver for no gain. + if (any) self->_dns_captured = true; + return ESP_OK; + } + + static esp_err_t restoreDnsOnTcpipThread(void* ctx) { + NetworkLinkBase* self = static_cast(ctx); + if (!self->_dns_captured) return ESP_OK; + // Every slot is written, empty ones included: returning to a network with + // one server must not leave the other medium's second server behind as a + // fallback that only fails slowly. + for (int i = 0; i < kDnsServers; i++) { + dns_setserver(i, &self->_dns_snapshot[i]); + } + return ESP_OK; + } + + public: + void snapshotDns() { esp_netif_tcpip_exec(snapshotDnsOnTcpipThread, this); } + + // A medium that has never held a lease with a resolver leaves the current one + // alone rather than blanking it. + void restoreDns() { esp_netif_tcpip_exec(restoreDnsOnTcpipThread, this); } + +}; + +class WiFiNetworkLink final : public NetworkLinkBase { + bool _event_registered = false; + char _hostname[32] = {}; + char _ssid[33] = {}; + char _password[65] = {}; + unsigned long _last_reconnect_attempt = 0; + uint8_t _reconnect_backoff_attempt = 0; + + // One mapping for startup, reconnect and CLI (see WifiPowerSavePolicy). The + // stored default is `none`; `min` means MIN_MODEM here exactly as the CLI + // says it does. Mapping the stored value locally is what let a node set to + // `min` silently run with power save off after its first reconnect. + void applyPowerPrefs(uint8_t wifi_power_save) { + static_assert((int)WifiPowerSavePolicy::kModeNone == (int)WIFI_PS_NONE, "wifi_ps_type_t drift"); + static_assert((int)WifiPowerSavePolicy::kModeMinModem == (int)WIFI_PS_MIN_MODEM, "wifi_ps_type_t drift"); + static_assert((int)WifiPowerSavePolicy::kModeMaxModem == (int)WIFI_PS_MAX_MODEM, "wifi_ps_type_t drift"); + esp_wifi_set_ps((wifi_ps_type_t)WifiPowerSavePolicy::modeFor(wifi_power_save)); + // Read back rather than logging what we asked for: this is the only place + // the mode is observable on a running node, and the setting used to change + // meaning between the CLI and this path. + wifi_ps_type_t applied = WIFI_PS_NONE; + esp_wifi_get_ps(&applied); + NETWORK_DEBUG_PRINTLN("WiFi power save: %s (mode=%d)", + WifiPowerSavePolicy::nameFor(wifi_power_save), (int)applied); +#ifdef MQTT_WIFI_TX_POWER + WiFi.setTxPower(MQTT_WIFI_TX_POWER); +#else + WiFi.setTxPower(WIFI_POWER_11dBm); +#endif + } + + public: + const char* mediumName() const override { return "wifi"; } + NetworkMedium medium() const override { return NetworkMedium::WiFi; } + const char* statusName() const override { + switch (WiFi.status()) { + case WL_CONNECTED: return "connected"; + case WL_NO_SSID_AVAIL: return "no_ssid"; + case WL_CONNECT_FAILED: return "connect_failed"; + case WL_CONNECTION_LOST: return "connection_lost"; + case WL_DISCONNECTED: return "disconnected"; + case 255: return "not_started"; + default: return "unknown"; + } + } + int statusCode() const override { return (int)WiFi.status(); } + + bool configValid(const char* wifi_ssid) const override { + return wifi_ssid && wifi_ssid[0] != '\0'; + } + + void setHostname(const char* hostname) override { + strncpy(_hostname, hostname ? hostname : "", sizeof(_hostname) - 1); + _hostname[sizeof(_hostname) - 1] = '\0'; + } + + void updateWifiCredentials(const char* wifi_ssid, const char* wifi_password) override { + strncpy(_ssid, wifi_ssid ? wifi_ssid : "", sizeof(_ssid) - 1); + _ssid[sizeof(_ssid) - 1] = '\0'; + strncpy(_password, wifi_password ? wifi_password : "", sizeof(_password) - 1); + _password[sizeof(_password) - 1] = '\0'; + } + + bool begin(const char* wifi_ssid, const char* wifi_password) override { + if (!configValid(wifi_ssid)) return false; + updateWifiCredentials(wifi_ssid, wifi_password); + + // Arduino-ESP32 applies this stored value when it creates the STA netif. + // It must be set before WiFi.mode()/begin() for the first DHCP exchange. + if (_hostname[0] != '\0') WiFi.setHostname(_hostname); + WiFi.mode(WIFI_STA); + WiFi.setAutoReconnect(true); + + if (!_event_registered) { + WiFi.onEvent([this](WiFiEvent_t event, WiFiEventInfo_t info) { + switch (event) { + case ARDUINO_EVENT_WIFI_STA_GOT_IP: + NETWORK_DEBUG_PRINTLN("WiFi connected: %s", + IPAddress(info.got_ip.ip_info.ip.addr).toString().c_str()); + noteConnected(millis()); + _reconnect_backoff_attempt = 0; + break; + case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: + noteDisconnected(millis(), info.wifi_sta_disconnected.reason); + NETWORK_DEBUG_PRINTLN("WiFi disconnected: reason %d", + info.wifi_sta_disconnected.reason); + break; + default: + break; + } + }); + _event_registered = true; + } + + // Preserve the existing restart behavior: MQTT stop leaves the station up, + // and begin() must not force a disconnect that races the first DNS lookup. + if (!isConnected()) { + WiFi.begin(_ssid, _password); + } else { + noteConnected(millis()); + } + return true; + } + + NetworkTransition maintain(uint32_t now_ms, uint8_t wifi_power_save) override { + const bool connected = isConnected(); + if (connected && connectedAtMillis() == 0) noteConnected(now_ms); + + if (!_status_initialized) { + _last_connected = connected; + _status_initialized = true; + setOutage(AlertFaultPolicy::applyWifiStatus( + now_ms, connected, outage(), false)); + // Already associated when the link started (end()/begin() leaves STA up): + // there is no connect transition below to carry the setting, so apply it + // here or the node keeps running whatever mode was set before. + if (connected) { + applyPowerPrefs(wifi_power_save); + snapshotDns(); + } + } + + if ((uint32_t)(now_ms - _last_status_check) <= 10000) { + if (connected && outage().down) noteConnected(now_ms); + return NetworkTransition::None; + } + _last_status_check = now_ms; + + if (connected) { + const bool transitioned = !_last_connected; + if (transitioned) { + setOutage(AlertFaultPolicy::applyWifiStatus( + now_ms, true, outage(), true)); + _connected_at.store(now_ms, std::memory_order_relaxed); + _reconnect_backoff_attempt = 0; + applyPowerPrefs(wifi_power_save); + snapshotDns(); + } + _last_connected = true; + return transitioned ? NetworkTransition::Up : NetworkTransition::None; + } + + AlertFaultPolicy::OutageSnapshot snapshot = AlertFaultPolicy::applyWifiStatus( + now_ms, false, outage(), true); + setOutage(snapshot); + const bool transitioned = _last_connected; + if (transitioned) { + _connected_at.store(0, std::memory_order_relaxed); + } else if (snapshot.down && _ssid[0] != '\0' && MQTTConnectionPolicy::wifiReconnectDue( + now_ms, snapshot.started_ms, (uint32_t)_last_reconnect_attempt, + _reconnect_backoff_attempt)) { + _last_reconnect_attempt = now_ms; + _reconnect_backoff_attempt = + MQTTConnectionPolicy::nextWifiBackoffAttempt(_reconnect_backoff_attempt); + WiFi.disconnect(); + WiFi.begin(_ssid, _password); + } + _last_connected = false; + return transitioned ? NetworkTransition::Down : NetworkTransition::None; + } + + bool isConnected() const override { return WiFi.status() == WL_CONNECTED; } + IPAddress localIP() const override { return WiFi.localIP(); } + int rssi() const override { return isConnected() ? WiFi.RSSI() : INT_MIN; } + bool resolveHost(const char* hostname, IPAddress& address) const override { + return WiFi.hostByName(hostname, address); + } + void formatDiagnostics(char* reply, size_t reply_size) const override { + snprintf(reply, reply_size, + "> why:ethernet-not-enabled selected:wifi\n" + "wifi:state:%s ip:%s", + statusName(), + localIP().toString().c_str()); + } +}; + +#if defined(NETWORK_PREFER_ETHERNET) +class EthernetNetworkLink final : public NetworkLinkBase { + public: + enum class EventState : uint8_t { + None, + Started, + LinkDown, + LinkUp, + GotIp, + Stopped, + }; + + private: + std::atomic _started{false}; + bool _event_registered = false; + char _hostname[32] = {}; + std::atomic _event_state{static_cast(EventState::None)}; + + public: + const char* mediumName() const override { return "ethernet"; } + NetworkMedium medium() const override { return NetworkMedium::Ethernet; } + const char* statusName() const override { + return isConnected() ? "connected" : "disconnected"; + } + int statusCode() const override { return isConnected() ? 1 : 0; } + bool configValid(const char*) const override { return true; } + + void setHostname(const char* hostname) override { + strncpy(_hostname, hostname ? hostname : "", sizeof(_hostname) - 1); + _hostname[sizeof(_hostname) - 1] = '\0'; + } + + bool begin(const char*, const char*) override { + if (_started.load(std::memory_order_acquire)) return true; + // DNS and WiFiClientSecure are transport-neutral sockets in this Arduino + // core, but their hostname path still uses WiFiGeneric's event group. + // Initialize that shared runtime without enabling or associating Wi-Fi. + tcpipInit(); + if (!_event_registered) { + WiFi.onEvent([this](WiFiEvent_t event, WiFiEventInfo_t) { + switch (event) { + case ARDUINO_EVENT_ETH_START: + _event_state.store(static_cast(EventState::Started), + std::memory_order_relaxed); + break; + case ARDUINO_EVENT_ETH_CONNECTED: + _event_state.store(static_cast(EventState::LinkUp), + std::memory_order_relaxed); + break; + case ARDUINO_EVENT_ETH_GOT_IP: + _event_state.store(static_cast(EventState::GotIp), + std::memory_order_relaxed); + noteConnected(millis()); + // Taken here rather than at the maintain() edge: this is the moment + // the lease installed the resolver, before a Wi-Fi fallback lease + // can overwrite it. + snapshotDns(); + break; + case ARDUINO_EVENT_ETH_DISCONNECTED: + _event_state.store(static_cast(EventState::LinkDown), + std::memory_order_relaxed); + // Ethernet has no 802.11 reason code; zero means unavailable. + noteDisconnected(millis(), 0); + _connected_at.store(0, std::memory_order_relaxed); + break; + case ARDUINO_EVENT_ETH_STOP: + _event_state.store(static_cast(EventState::Stopped), + std::memory_order_relaxed); + break; + default: + break; + } + }); + _event_registered = true; + } + _event_state.store(static_cast(EventState::None), + std::memory_order_relaxed); + const bool started = beginConfiguredCH390(_hostname); + _started.store(started, std::memory_order_release); + if (started && isConnected()) noteConnected(millis()); + return started; + } + + bool restart() { + CH390.end(); + _started.store(false, std::memory_order_release); + // Preserve status/outage history across attempts. maintain() observes the + // resulting edge in this same task iteration, so a retry cannot reset a + // prolonged-down alert timer or hide a previously connected transition. + return begin(nullptr, nullptr); + } + + NetworkTransition maintain(uint32_t now_ms, uint8_t) override { + const bool connected = isConnected(); + if (!_status_initialized) { + _last_connected = connected; + _status_initialized = true; + setOutage(AlertFaultPolicy::applyWifiStatus( + now_ms, connected, outage(), false)); + if (connected) { + noteConnected(now_ms); + snapshotDns(); + } + return NetworkTransition::None; + } + + if (connected == _last_connected) { + if (connected && outage().down) noteConnected(now_ms); + return NetworkTransition::None; + } + + _last_connected = connected; + if (connected) { + _connected_at.store(now_ms, std::memory_order_relaxed); + setOutage(AlertFaultPolicy::applyWifiStatus( + now_ms, true, outage(), true)); + snapshotDns(); + return NetworkTransition::Up; + } + + const bool outage_was_down = outage().down; + _connected_at.store(0, std::memory_order_relaxed); + AlertFaultPolicy::OutageSnapshot snapshot = AlertFaultPolicy::applyWifiStatus( + now_ms, false, outage(), true); + setOutage(snapshot); + if (!outage_was_down) { + _last_disconnect_time.store(now_ms, std::memory_order_relaxed); + } + return NetworkTransition::Down; + } + + bool isConnected() const override { + return _started.load(std::memory_order_acquire) && CH390.isConnected(); + } + IPAddress localIP() const override { return CH390.localIP(); } + int rssi() const override { return INT_MIN; } + bool resolveHost(const char* hostname, IPAddress& address) const override { + // Arduino's hostByName is a thin wrapper over the process-wide lwIP resolver; + // DNS follows the selected esp_netif even though this entry point is named WiFi. + return WiFi.hostByName(hostname, address); + } + void formatDiagnostics(char* reply, size_t reply_size) const override { + snprintf(reply, reply_size, "> ethernet:%s ip=%s", + statusName(), localIP().toString().c_str()); + } + + EventState eventState() const { + return static_cast( + _event_state.load(std::memory_order_relaxed)); + } + bool started() const { return _started.load(std::memory_order_acquire); } + bool sampleLink(bool& known) const { + known = false; + if (!_started.load(std::memory_order_acquire)) return false; + + // IEEE 802.3 BMSR link status is latch-low. Read it twice so the second + // value is the current carrier state rather than a remembered link flap. + (void)CH390.readPHY(0x01); + const uint32_t bmsr = CH390.readPHY(0x01) & 0xffffu; + if (bmsr != 0 && bmsr != 0xffffu) { + known = true; + return (bmsr & (1u << 2)) != 0; + } + + // A failed/unsupported direct PHY read can still use the driver's events. + const EventState state = eventState(); + known = state == EventState::LinkDown || state == EventState::LinkUp || + state == EventState::GotIp || state == EventState::Stopped; + return state == EventState::LinkUp || state == EventState::GotIp; + } + bool linkUp() const { + bool known = false; + return sampleLink(known); + } + const char* eventName() const { + switch (eventState()) { + case EventState::None: return "none"; + case EventState::Started: return "started"; + case EventState::LinkDown: return "link-down"; + case EventState::LinkUp: return "link-up"; + case EventState::GotIp: return "got-ip"; + case EventState::Stopped: return "stopped"; + } + return "unknown"; + } +}; + +class AutomaticNetworkLink final : public NetworkLink { + EthernetNetworkLink _ethernet; + WiFiNetworkLink _wifi; + std::atomic _selected{NetworkMedium::None}; + std::atomic _ethernet_started{false}; + std::atomic _wifi_started{false}; + char _wifi_ssid[33] = {}; + char _wifi_password[65] = {}; + std::atomic _ethernet_stable_since{0}; + std::atomic _selected_down_since{0}; + std::atomic _last_ethernet_init_attempt{0}; + std::atomic _ethernet_retry_attempt{0}; + std::atomic _ethernet_no_ip_since{0}; + std::atomic _switch_locks{0}; + std::atomic _switch_in_progress{false}; + std::atomic _ethernet_seen{false}; // held a lease at least once this boot + + // Ethernet is the primary for alerts once it has carried traffic, or when it + // is the only configured medium; a Wi-Fi-only install keeps Wi-Fi alerts. + bool ethernetIsAlertPrimary() const { + return _ethernet_seen.load(std::memory_order_acquire) || !wifiConfigured(); + } + + NetworkLink& selectedInterface(NetworkMedium selected) { + return selected == NetworkMedium::Ethernet + ? static_cast(_ethernet) + : static_cast(_wifi); + } + const NetworkLink& selectedInterface(NetworkMedium selected) const { + return selected == NetworkMedium::Ethernet + ? static_cast(_ethernet) + : static_cast(_wifi); + } + + bool wifiConfigured() const { return _wifi_ssid[0] != '\0'; } + + void rememberWifi(const char* ssid, const char* password) { + strncpy(_wifi_ssid, ssid ? ssid : "", sizeof(_wifi_ssid) - 1); + _wifi_ssid[sizeof(_wifi_ssid) - 1] = '\0'; + strncpy(_wifi_password, password ? password : "", sizeof(_wifi_password) - 1); + _wifi_password[sizeof(_wifi_password) - 1] = '\0'; + } + + void startWifiFallback() { + if (_wifi_started.load(std::memory_order_acquire) || !wifiConfigured()) return; + _wifi_started.store(_wifi.begin(_wifi_ssid, _wifi_password), + std::memory_order_release); + } + + // Lock and mutation each publish one flag then read the other; seq_cst keeps + // both sides from missing each other. + bool beginUnlockedMutation() { + bool expected = false; + if (!_switch_in_progress.compare_exchange_strong(expected, true)) { + return false; + } + if (_switch_locks.load() != 0) { + _switch_in_progress.store(false, std::memory_order_release); + return false; + } + return true; + } + + void endUnlockedMutation() { + _switch_in_progress.store(false, std::memory_order_release); + } + + bool selectIfUnlocked(NetworkMedium medium) { + if (!beginUnlockedMutation()) return false; + select(medium); + endUnlockedMutation(); + return true; + } + + void startWifiFallbackIfUnlocked() { + if (!beginUnlockedMutation()) return; + startWifiFallback(); + endUnlockedMutation(); + } + + void select(NetworkMedium medium) { + if (medium == NetworkMedium::Ethernet) { + // ESP-IDF gives Wi-Fi a higher default-route priority than Ethernet. + // Keep only the selected STA associated so sockets cannot silently stay + // on Wi-Fi after the manager has declared Ethernet active. + WiFi.setAutoReconnect(false); + WiFi.disconnect(false, false); + _wifi_started.store(false, std::memory_order_release); + } + _selected_down_since.store(0, std::memory_order_relaxed); + _selected.store(medium, std::memory_order_release); + // Put back the resolver this medium leased. lwIP's server list is global, + // so whichever medium leased last still owns it here (see snapshotDns()). + if (medium == NetworkMedium::Ethernet) { + _ethernet.restoreDns(); + } else if (medium == NetworkMedium::WiFi) { + _wifi.restoreDns(); + } + } + + bool startOrRetryEthernet(uint32_t now_ms, bool restart) { + const bool started = restart ? _ethernet.restart() + : _ethernet.begin(nullptr, nullptr); + _last_ethernet_init_attempt.store(now_ms, std::memory_order_relaxed); + _ethernet_started.store(started, std::memory_order_release); + if (started) { + _ethernet_retry_attempt.store(0, std::memory_order_relaxed); + } else { + uint8_t attempt = _ethernet_retry_attempt.load(std::memory_order_relaxed); + if (attempt != UINT8_MAX) ++attempt; + _ethernet_retry_attempt.store(attempt, std::memory_order_relaxed); + } + return started; + } + + public: + const char* mediumName() const override { + const NetworkMedium selected = _selected.load(std::memory_order_acquire); + if (selected == NetworkMedium::Ethernet) return "ethernet"; + if (selected == NetworkMedium::WiFi) return "wifi"; + return "none"; + } + NetworkMedium medium() const override { + return _selected.load(std::memory_order_acquire); + } + const char* statusName() const override { + const NetworkMedium selected = _selected.load(std::memory_order_acquire); + return selected == NetworkMedium::None ? "not_selected" + : selectedInterface(selected).statusName(); + } + int statusCode() const override { + const NetworkMedium selected = _selected.load(std::memory_order_acquire); + return selected == NetworkMedium::None ? 0 + : selectedInterface(selected).statusCode(); + } + bool configValid(const char* wifi_ssid) const override { + // Hardware availability and stored credentials are configuration. Current + // link/DHCP state is runtime state and must not permanently suppress the + // MQTT task that monitors for a late cable or lease. + (void)wifi_ssid; + return true; + } + bool isAutomatic() const override { return true; } + + void updateWifiCredentials(const char* wifi_ssid, const char* wifi_password) override { + rememberWifi(wifi_ssid, wifi_password); + _wifi.updateWifiCredentials(_wifi_ssid, _wifi_password); + } + + void setHostname(const char* hostname) override { + // Whichever medium wins now or during a later failover presents the same + // stable DHCP identity to the LAN. + _ethernet.setHostname(hostname); + _wifi.setHostname(hostname); + } + + bool begin(const char* wifi_ssid, const char* wifi_password) override { + rememberWifi(wifi_ssid, wifi_password); + if (!_ethernet_started.load(std::memory_order_acquire)) { + const uint32_t now_ms = millis(); + const uint8_t attempt = + _ethernet_retry_attempt.load(std::memory_order_relaxed); + if (NetworkPolicy::ethernetInitRetryDue( + attempt, now_ms, + _last_ethernet_init_attempt.load(std::memory_order_relaxed)) && + beginUnlockedMutation()) { + startOrRetryEthernet(now_ms, attempt != 0); + endUnlockedMutation(); + } + } + // bootstrap() owns the initial choice. MQTT begin() is intentionally + // idempotent and cannot demote a boot-selected Ethernet link because of a + // momentary status sample between tasks. + const NetworkMedium selected = _selected.load(std::memory_order_acquire); + if (selected == NetworkMedium::None) { + if (_ethernet.isConnected()) { + select(NetworkMedium::Ethernet); + } else if (wifiConfigured()) { + startWifiFallback(); + _selected.store(NetworkMedium::WiFi, std::memory_order_release); + } + } else if (selected == NetworkMedium::WiFi) { + startWifiFallback(); + } + return _ethernet_started.load(std::memory_order_acquire) || + _wifi_started.load(std::memory_order_acquire); + } + + bool bootstrap(const char* wifi_ssid, const char* wifi_password, + uint32_t wait_ms) override { + rememberWifi(wifi_ssid, wifi_password); + if (!_ethernet_started.load(std::memory_order_acquire)) { + startOrRetryEthernet(millis(), false); + } + + const uint32_t started_at = millis(); + for (;;) { + bool link_known = false; + const bool link_up = _ethernet.sampleLink(link_known); + if (!NetworkPolicy::ethernetBootProbePending( + _ethernet_started.load(std::memory_order_acquire), + _ethernet.isConnected(), link_known, link_up, + (uint32_t)(millis() - started_at), wait_ms)) { + break; + } + delay(25); + } + + if (_ethernet.isConnected()) _ethernet_seen.store(true, std::memory_order_release); + const NetworkMedium initial = NetworkPolicy::bootSelection( + _ethernet.isConnected(), wifiConfigured()); + if (initial == NetworkMedium::Ethernet) { + select(initial); + } else { + startWifiFallback(); + _selected.store(initial, std::memory_order_release); + } + return initial != NetworkMedium::None; + } + + NetworkTransition maintain(uint32_t now_ms, uint8_t wifi_power_save) override { + bool ethernet_started = _ethernet_started.load(std::memory_order_acquire); + const bool switching_locked = + _switch_locks.load(std::memory_order_acquire) != 0; + const bool ethernet_stopped = + ethernet_started && + _ethernet.eventState() == EthernetNetworkLink::EventState::Stopped; + if (ethernet_stopped) { + _ethernet_started.store(false, std::memory_order_release); + ethernet_started = false; + if (_ethernet_retry_attempt.load(std::memory_order_relaxed) == 0) { + _ethernet_retry_attempt.store(1, std::memory_order_relaxed); + _last_ethernet_init_attempt.store(now_ms, std::memory_order_relaxed); + } + } + const EthernetNetworkLink::EventState ethernet_event = + _ethernet.eventState(); + const bool ethernet_link_up = + ethernet_event == EthernetNetworkLink::EventState::LinkUp || + ethernet_event == EthernetNetworkLink::EventState::GotIp; + if (ethernet_started && ethernet_link_up && !_ethernet.isConnected()) { + if (_ethernet_no_ip_since.load(std::memory_order_relaxed) == 0) { + uint32_t started_at = now_ms; + if (started_at == 0) started_at = 1; + _ethernet_no_ip_since.store(started_at, std::memory_order_relaxed); + } + } else { + _ethernet_no_ip_since.store(0, std::memory_order_relaxed); + } + // Restarts rebuild the CH390 netif, so they take the same mutation gate as + // a route switch: an OTA/WebConfig lock taken after the sample above wins. + if (!switching_locked && NetworkPolicy::ethernetNoIpRecoveryDue( + ethernet_started, ethernet_link_up, _ethernet.isConnected(), + now_ms, _ethernet_no_ip_since.load(std::memory_order_relaxed)) && + beginUnlockedMutation()) { + ethernet_started = startOrRetryEthernet(now_ms, true); + _ethernet_no_ip_since.store(0, std::memory_order_relaxed); + endUnlockedMutation(); + } + if (!ethernet_started && !switching_locked) { + const uint8_t attempt = + _ethernet_retry_attempt.load(std::memory_order_relaxed); + if (NetworkPolicy::ethernetInitRetryDue( + attempt, now_ms, + _last_ethernet_init_attempt.load(std::memory_order_relaxed)) && + beginUnlockedMutation()) { + ethernet_started = startOrRetryEthernet(now_ms, true); + endUnlockedMutation(); + } + } + + const NetworkTransition ethernet_transition = + _ethernet.maintain(now_ms, wifi_power_save); + if (_ethernet.isConnected()) _ethernet_seen.store(true, std::memory_order_release); + const bool wifi_started = _wifi_started.load(std::memory_order_acquire); + const NetworkTransition wifi_transition = wifi_started + ? _wifi.maintain(now_ms, wifi_power_save) + : NetworkTransition::None; + + // Ethernet may recover while a Wi-Fi fallback is still associating. In + // that sequence the selected enum never changes, but Wi-Fi would win + // ESP-IDF's default-route priority once it came up. Tear the unused STA + // down even without a selection edge, and force MQTT to reconnect if it + // had already become reachable. + NetworkMedium selected = _selected.load(std::memory_order_acquire); + if (selected == NetworkMedium::Ethernet && _ethernet.isConnected() && + wifi_started) { + const bool wifi_had_route = _wifi.isConnected(); + if (selectIfUnlocked(NetworkMedium::Ethernet) && wifi_had_route) { + return NetworkTransition::Switched; + } + } + + if (_ethernet.isConnected()) { + if (_ethernet_stable_since.load(std::memory_order_relaxed) == 0) { + _ethernet_stable_since.store(now_ms, std::memory_order_relaxed); + } + } else { + _ethernet_stable_since.store(0, std::memory_order_relaxed); + } + + const bool selected_connected = isConnected(); + if (!selected_connected) { + if (_selected_down_since.load(std::memory_order_relaxed) == 0) { + _selected_down_since.store(now_ms, std::memory_order_relaxed); + } + } else { + _selected_down_since.store(0, std::memory_order_relaxed); + } + + const uint32_t selected_down_since = + _selected_down_since.load(std::memory_order_relaxed); + const uint32_t selected_down_ms = selected_down_since == 0 + ? 0 : (uint32_t)(now_ms - selected_down_since); + selected = _selected.load(std::memory_order_acquire); + if (selected == NetworkMedium::Ethernet && !_ethernet.isConnected() && + selected_down_ms >= NetworkPolicy::kEthernetDownGraceMs) { + startWifiFallbackIfUnlocked(); + } + + const uint32_t ethernet_stable_since = + _ethernet_stable_since.load(std::memory_order_relaxed); + const uint32_t ethernet_stable_ms = ethernet_stable_since == 0 + ? 0 : (uint32_t)(now_ms - ethernet_stable_since); + const bool selection_locked = + _switch_locks.load(std::memory_order_acquire) != 0; + const NetworkPolicy::AutomaticSelectionInput input = { + selected, _ethernet.isConnected(), + _wifi_started.load(std::memory_order_acquire) && _wifi.isConnected(), + wifiConfigured(), selection_locked, + ethernet_stable_ms, selected_down_ms}; + const NetworkMedium next = NetworkPolicy::automaticSelection(input); + + if (next != selected) { + if (selectIfUnlocked(next)) { + return selected == NetworkMedium::None ? NetworkTransition::Up + : NetworkTransition::Switched; + } + } + + if (selected == NetworkMedium::Ethernet) return ethernet_transition; + if (selected == NetworkMedium::WiFi) return wifi_transition; + return NetworkTransition::None; + } + + void lockSwitching() override { + uint8_t value = _switch_locks.load(std::memory_order_relaxed); + while (value != UINT8_MAX && !_switch_locks.compare_exchange_weak( + value, static_cast(value + 1))) {} + while (_switch_in_progress.load()) delay(1); + } + void unlockSwitching() override { + uint8_t value = _switch_locks.load(std::memory_order_relaxed); + while (value != 0 && !_switch_locks.compare_exchange_weak( + value, static_cast(value - 1), + std::memory_order_relaxed, std::memory_order_relaxed)) {} + } + + bool isConnected() const override { + const NetworkMedium selected = _selected.load(std::memory_order_acquire); + return selected != NetworkMedium::None && + selectedInterface(selected).isConnected(); + } + IPAddress localIP() const override { + const NetworkMedium selected = _selected.load(std::memory_order_acquire); + return selected == NetworkMedium::None ? IPAddress() + : selectedInterface(selected).localIP(); + } + int rssi() const override { + const NetworkMedium selected = _selected.load(std::memory_order_acquire); + return selected == NetworkMedium::None ? INT_MIN + : selectedInterface(selected).rssi(); + } + bool resolveHost(const char* hostname, IPAddress& address) const override { + const NetworkMedium selected = _selected.load(std::memory_order_acquire); + return selected != NetworkMedium::None && + selectedInterface(selected).resolveHost(hostname, address); + } + void formatDiagnostics(char* reply, size_t reply_size) const override { + const NetworkMedium selected = _selected.load(std::memory_order_acquire); + const bool ethernet_started = + _ethernet_started.load(std::memory_order_acquire); + const bool wifi_started = _wifi_started.load(std::memory_order_acquire); + const bool ethernet_connected = _ethernet.isConnected(); + bool ethernet_link_known = false; + bool ethernet_link_up = _ethernet.sampleLink(ethernet_link_known); + ethernet_link_known = ethernet_link_known || ethernet_connected; + ethernet_link_up = ethernet_link_up || ethernet_connected; + const bool switching_locked = + _switch_locks.load(std::memory_order_acquire) != 0; + const uint32_t now_ms = millis(); + const uint32_t ethernet_stable_since = + _ethernet_stable_since.load(std::memory_order_relaxed); + const uint32_t ethernet_stable_ms = ethernet_stable_since == 0 + ? 0 : (uint32_t)(now_ms - ethernet_stable_since); + const uint8_t retry_attempt = + _ethernet_retry_attempt.load(std::memory_order_relaxed); + const uint32_t retry_delay = + NetworkPolicy::ethernetInitRetryDelayMs(retry_attempt); + const uint32_t since_attempt = (uint32_t)( + now_ms - _last_ethernet_init_attempt.load(std::memory_order_relaxed)); + const uint32_t retry_in = !ethernet_started && retry_delay > since_attempt + ? retry_delay - since_attempt : 0; + const NetworkDiagnosticReason reason = + NetworkPolicy::automaticDiagnosticReason( + ethernet_started, ethernet_link_known, ethernet_link_up, + ethernet_connected, selected, switching_locked, + ethernet_stable_ms); + snprintf(reply, reply_size, + "> why:%s selected:%s lock:%s\n" + "eth:init:%s retry:%u/%lums evt:%s link:%s ip:%s\n" + "wifi:cfg:%s started:%s link:%s", + NetworkPolicy::diagnosticReasonName(reason), + NetworkPolicy::mediumName(selected), + switching_locked ? "yes" : "no", + ethernet_started ? "ok" : "failed", retry_attempt, + (unsigned long)retry_in, _ethernet.eventName(), + ethernet_link_known ? (ethernet_link_up ? "up" : "down") + : "unknown", + _ethernet.localIP().toString().c_str(), + wifiConfigured() ? "yes" : "no", wifi_started ? "yes" : "no", + (wifi_started && _wifi.isConnected()) ? "up" : "down"); + } + unsigned long connectedAtMillis() const override { + const NetworkMedium selected = _selected.load(std::memory_order_acquire); + return selected == NetworkMedium::None + ? 0 : selectedInterface(selected).connectedAtMillis(); + } + uint8_t lastDisconnectReason() const override { + const NetworkMedium selected = _selected.load(std::memory_order_acquire); + return selected == NetworkMedium::None + ? 0 : selectedInterface(selected).lastDisconnectReason(); + } + unsigned long lastDisconnectTime() const override { + const NetworkMedium selected = _selected.load(std::memory_order_acquire); + return selected == NetworkMedium::None + ? 0 : selectedInterface(selected).lastDisconnectTime(); + } + AlertFaultPolicy::OutageSnapshot outageSnapshot() const override { + const NetworkMedium selected = _selected.load(std::memory_order_acquire); + return selected == NetworkMedium::None + ? AlertFaultPolicy::OutageSnapshot{false, 0, 0} + : selectedInterface(selected).outageSnapshot(); + } + NetworkMedium alertMedium() const override { + return ethernetIsAlertPrimary() ? NetworkMedium::Ethernet : NetworkMedium::WiFi; + } + AlertFaultPolicy::OutageSnapshot alertOutageSnapshot() const override { + return ethernetIsAlertPrimary() ? _ethernet.outageSnapshot() : _wifi.outageSnapshot(); + } +}; +#endif + +} // namespace + +NetworkLink& activeNetworkLink() { +#if defined(NETWORK_PREFER_ETHERNET) + static AutomaticNetworkLink network; +#else + static WiFiNetworkLink network; +#endif + return network; +} +#endif diff --git a/src/helpers/NetworkLink.h b/src/helpers/NetworkLink.h new file mode 100644 index 00000000..afc125a9 --- /dev/null +++ b/src/helpers/NetworkLink.h @@ -0,0 +1,81 @@ +#pragma once + +#include "NetworkPolicy.h" + +#if defined(ESP_PLATFORM) + +#include +#include +#include "AlertFaultPolicy.h" + +#ifndef NETWORK_ETHERNET_BOOT_WAIT_MS +#define NETWORK_ETHERNET_BOOT_WAIT_MS 8000UL +#endif + +/** + * Physical network selected for IP-based services. + * + * The interface owns link bring-up and medium-specific maintenance. MQTT, NTP, + * OTA, and other socket users only consume connectivity and addressing. Normal + * MQTT shutdown deliberately does not stop this interface because an OTA + * download runs after the broker clients have been released. + */ +class NetworkLink { + public: + virtual ~NetworkLink() = default; + + virtual const char* mediumName() const = 0; + virtual NetworkMedium medium() const = 0; + virtual const char* statusName() const = 0; + virtual int statusCode() const = 0; + virtual bool configValid(const char* wifi_ssid) const = 0; + // Configure the DHCP hostname before begin()/bootstrap(). Implementations + // retain it for any later fallback interface start. + virtual void setHostname(const char* hostname) = 0; + virtual bool begin(const char* wifi_ssid, const char* wifi_password) = 0; + // Latest stored credentials; the next reconnect attempt uses them without a reboot. + virtual void updateWifiCredentials(const char* wifi_ssid, const char* wifi_password) { + (void)wifi_ssid; + (void)wifi_password; + } + virtual NetworkTransition maintain(uint32_t now_ms, uint8_t wifi_power_save) = 0; + + // Automatic selectors are boot-owned so first-run services can use the + // chosen link before MQTT starts. Compatibility Wi-Fi builds keep the + // original MQTT-task-owned begin() path. + virtual bool isAutomatic() const { return false; } + virtual bool bootstrap(const char* wifi_ssid, const char* wifi_password, + uint32_t wait_ms) { + (void)wait_ms; + return begin(wifi_ssid, wifi_password); + } + + // WebConfig and OTA pin the current route for the lifetime of their session. + virtual void lockSwitching() {} + virtual void unlockSwitching() {} + + virtual bool isConnected() const = 0; + virtual IPAddress localIP() const = 0; + virtual int rssi() const = 0; // INT_MIN when the selected medium has no RSSI. + virtual bool resolveHost(const char* hostname, IPAddress& address) const = 0; + virtual void formatDiagnostics(char* reply, size_t reply_size) const = 0; + + virtual unsigned long connectedAtMillis() const = 0; + virtual uint8_t lastDisconnectReason() const = 0; + virtual unsigned long lastDisconnectTime() const = 0; + virtual AlertFaultPolicy::OutageSnapshot outageSnapshot() const = 0; + + // Fault reporting normally follows the selected interface. Automatic + // Ethernet-preferred builds instead keep reporting the primary Ethernet + // outage while healthy Wi-Fi carries traffic, so prolonged degradation is + // not hidden by a successful fallback. + virtual NetworkMedium alertMedium() const { return medium(); } + virtual AlertFaultPolicy::OutageSnapshot alertOutageSnapshot() const { + return outageSnapshot(); + } +}; + +/** Build-selected singleton. Wi-Fi is the compatibility default. */ +NetworkLink& activeNetworkLink(); + +#endif diff --git a/src/helpers/NetworkPolicy.h b/src/helpers/NetworkPolicy.h new file mode 100644 index 00000000..a4e7953a --- /dev/null +++ b/src/helpers/NetworkPolicy.h @@ -0,0 +1,225 @@ +#pragma once + +#include + +enum class NetworkTransition : uint8_t { + None, + Up, + Down, + Switched, +}; + +enum class NetworkMedium : uint8_t { + None, + Ethernet, + WiFi, +}; + +enum class NetworkDiagnosticReason : uint8_t { + EthernetActive, + EthernetInitFailed, + EthernetLinkUnknown, + EthernetLinkDown, + EthernetAwaitingIp, + EthernetStabilizing, + SwitchingLocked, + EthernetReady, +}; + +namespace NetworkPolicy { + +struct MQTTTransitionActions { + bool disconnect_started_slots; + bool retry_disconnected_slots_now; + bool reset_reconnect_backoff; +}; + +static constexpr MQTTTransitionActions mqttActions(NetworkTransition transition) { + return { + transition == NetworkTransition::Down || transition == NetworkTransition::Switched, + transition == NetworkTransition::Up || transition == NetworkTransition::Switched, + transition == NetworkTransition::Switched, + }; +} + +static constexpr const char* mediumName(NetworkMedium medium) { + return medium == NetworkMedium::Ethernet ? "ethernet" + : medium == NetworkMedium::WiFi ? "wifi" + : "none"; +} + +struct AutomaticSelectionInput { + NetworkMedium selected; + bool ethernet_connected; + bool wifi_connected; + bool wifi_configured; + bool switching_locked; + uint32_t ethernet_stable_ms; + uint32_t selected_down_ms; +}; + +// Keep short link flaps from bouncing the default route. Ethernet is allowed +// to recover before Wi-Fi is started, and must then remain usable before it can +// preempt a working Wi-Fi fallback. +static constexpr uint32_t kEthernetDownGraceMs = 3000; +static constexpr uint32_t kEthernetFailbackStableMs = 10000; +static constexpr uint32_t kEthernetNoLinkBootGraceMs = 750; +static constexpr uint32_t kEthernetNoIpRecoveryMs = 120000; +static constexpr uint32_t kEthernetInitRetryMinMs = 5000; +static constexpr uint32_t kEthernetInitRetryMaxMs = 300000; +static constexpr uint32_t kNtpRetryMs = 30000; +static constexpr uint32_t kManualOtaSessionTimeoutMs = + 15UL * 60UL * 1000UL; + +static inline uint32_t ethernetInitRetryDelayMs(uint8_t attempt) { + if (attempt == 0) return 0; + uint32_t delay_ms = kEthernetInitRetryMinMs; + for (uint8_t i = 1; i < attempt && delay_ms < kEthernetInitRetryMaxMs; ++i) { + delay_ms = delay_ms > kEthernetInitRetryMaxMs / 2 + ? kEthernetInitRetryMaxMs : delay_ms * 2; + } + return delay_ms; +} + +static inline bool ethernetInitRetryDue(uint8_t attempt, + uint32_t now_ms, + uint32_t last_attempt_ms) { + return attempt == 0 || + (uint32_t)(now_ms - last_attempt_ms) >= + ethernetInitRetryDelayMs(attempt); +} + +static constexpr bool ethernetNoIpRecoveryDue(bool initialized, + bool link_up, + bool connected, + uint32_t now_ms, + uint32_t no_ip_since_ms) { + return initialized && link_up && !connected && no_ip_since_ms != 0 && + (uint32_t)(now_ms - no_ip_since_ms) >= kEthernetNoIpRecoveryMs; +} + +static inline NetworkDiagnosticReason automaticDiagnosticReason( + bool ethernet_initialized, bool ethernet_link_known, + bool ethernet_link_up, bool ethernet_connected, NetworkMedium selected, + bool switching_locked, uint32_t ethernet_stable_ms) { + if (!ethernet_initialized) { + return NetworkDiagnosticReason::EthernetInitFailed; + } + if (!ethernet_link_known) { + return NetworkDiagnosticReason::EthernetLinkUnknown; + } + if (!ethernet_link_up) { + return NetworkDiagnosticReason::EthernetLinkDown; + } + if (!ethernet_connected) { + return NetworkDiagnosticReason::EthernetAwaitingIp; + } + if (selected == NetworkMedium::Ethernet) { + return NetworkDiagnosticReason::EthernetActive; + } + if (switching_locked) { + return NetworkDiagnosticReason::SwitchingLocked; + } + if (selected == NetworkMedium::WiFi && + ethernet_stable_ms < kEthernetFailbackStableMs) { + return NetworkDiagnosticReason::EthernetStabilizing; + } + return NetworkDiagnosticReason::EthernetReady; +} + +static inline const char* diagnosticReasonName( + NetworkDiagnosticReason reason) { + switch (reason) { + case NetworkDiagnosticReason::EthernetActive: + return "ethernet-active"; + case NetworkDiagnosticReason::EthernetInitFailed: + return "ethernet-init-failed"; + case NetworkDiagnosticReason::EthernetLinkUnknown: + return "ethernet-link-unknown"; + case NetworkDiagnosticReason::EthernetLinkDown: + return "ethernet-link-down"; + case NetworkDiagnosticReason::EthernetAwaitingIp: + return "ethernet-awaiting-ip"; + case NetworkDiagnosticReason::EthernetStabilizing: + return "ethernet-stabilizing"; + case NetworkDiagnosticReason::SwitchingLocked: + return "switching-locked"; + case NetworkDiagnosticReason::EthernetReady: + return "ethernet-ready"; + } + return "unknown"; +} + +static constexpr bool ntpPendingAfterConnectivitySample( + bool synced, bool pending, bool was_connected, bool connected) { + return pending || (!synced && connected && !was_connected); +} + +static constexpr bool ntpRetryDue(bool synced, bool connected, + uint32_t now_ms, uint32_t last_attempt_ms) { + return !synced && connected && + (uint32_t)(now_ms - last_attempt_ms) >= kNtpRetryMs; +} + +static constexpr NetworkMedium bootSelection(bool ethernet_connected, + bool wifi_configured) { + return ethernet_connected ? NetworkMedium::Ethernet + : wifi_configured ? NetworkMedium::WiFi + : NetworkMedium::None; +} + +// Give the PHY a short window to report carrier. Once a definitive link-down +// sample arrives, do not stall mesh startup for the full DHCP deadline. A +// present link (or an unknown PHY state) still receives the entire probe. +static constexpr bool ethernetBootProbePending(bool ethernet_initialized, + bool ethernet_connected, + bool link_known, + bool link_up, + uint32_t elapsed_ms, + uint32_t wait_ms) { + return ethernet_initialized && !ethernet_connected && elapsed_ms < wait_ms && + (!link_known || link_up || elapsed_ms < kEthernetNoLinkBootGraceMs); +} + +static inline NetworkMedium automaticSelection( + const AutomaticSelectionInput& input) { + if (input.switching_locked) return input.selected; + + if (input.selected == NetworkMedium::Ethernet) { + if (input.ethernet_connected) return NetworkMedium::Ethernet; + if (input.wifi_configured && input.wifi_connected && + input.selected_down_ms >= kEthernetDownGraceMs) { + return NetworkMedium::WiFi; + } + return NetworkMedium::Ethernet; + } + + if (input.selected == NetworkMedium::WiFi) { + if (input.ethernet_connected && + (!input.wifi_connected || + input.ethernet_stable_ms >= kEthernetFailbackStableMs)) { + return NetworkMedium::Ethernet; + } + return NetworkMedium::WiFi; + } + + if (input.ethernet_connected) return NetworkMedium::Ethernet; + if (input.wifi_configured && input.wifi_connected) return NetworkMedium::WiFi; + return NetworkMedium::None; +} + +// `start ota` uses the selected LAN only when reachable and not explicitly +// forced to SoftAP. Manifest OTA has no fallback and checks connectivity itself. +static constexpr bool startOtaUsesSelectedNetwork(bool force_ap, + bool network_connected) { + return !force_ap && network_connected; +} + +static constexpr bool manualOtaTimeoutDue(uint32_t now_ms, + uint32_t started_ms, + bool upload_in_progress) { + return !upload_in_progress && + (uint32_t)(now_ms - started_ms) >= kManualOtaSessionTimeoutMs; +} + +} // namespace NetworkPolicy diff --git a/src/helpers/NtpValidation.h b/src/helpers/NtpValidation.h new file mode 100644 index 00000000..e81510b7 --- /dev/null +++ b/src/helpers/NtpValidation.h @@ -0,0 +1,141 @@ +#pragma once + +#include +#include + +// Client-side NTPv4 request building and response validation. +// +// Pure logic: no Arduino, WiFi or UDP headers, so every rejection case is +// host-testable. The caller owns the socket and supplies the datagram plus +// whether it arrived from the server it asked (see MQTTBridge::probeNtpServer). +// +// This exists because the NTPClient library accepted *any* non-empty datagram +// on its fixed local port as time: it ignored the read length, the mode, the +// stratum, the leap indicator and the request/response correlation, so a +// one-byte packet from anywhere set the clock — which then feeds JWT issuance, +// certificate validity and the RTC. Everything below is the validation that +// path never had. +namespace NtpValidation { + +static const size_t kPacketSize = 48; + +// Seconds between the NTP epoch (1900-01-01) and the Unix epoch (1970-01-01). +static const uint32_t kUnixEpochOffset = 2208988800UL; +// Wrap distance for NTP era 1, which starts 2036-02-07: era-1 seconds count +// from there, so a small NTP seconds field is a *future* time, not a past one. +static const uint32_t kEra1UnixOffset = 2085978496UL; + +enum Reject : uint8_t { + kAccepted = 0, + kShortPacket, // fewer than 48 bytes: not an NTP response at all + kWrongSource, // not from the address/port we queried + kBadVersion, // NTP version outside 3..4 + kBadMode, // not mode 4 (server) + kLeapAlarm, // LI=3: the server itself is unsynchronised + kBadStratum, // 0 (kiss-of-death) or >= 16 (unsynchronised) + kOriginMismatch, // did not echo the transmit timestamp we sent + kZeroTransmit, // no transmit timestamp + kEpochTooEarly, // before the caller's floor + kEpochTooLate, // implausibly far in the future +}; + +// The transmit timestamp we send and the server must echo back in its originate +// field. Random, so an off-path sender cannot answer a query it never saw. +struct Nonce { + uint32_t seconds; + uint32_t fraction; +}; + +struct Result { + Reject reject; + uint32_t epoch; // Unix seconds; only meaningful when reject == kAccepted +}; + +static inline uint32_t readU32(const uint8_t* p) { + return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | + ((uint32_t)p[2] << 8) | (uint32_t)p[3]; +} + +static inline void writeU32(uint8_t* p, uint32_t v) { + p[0] = (uint8_t)(v >> 24); + p[1] = (uint8_t)(v >> 16); + p[2] = (uint8_t)(v >> 8); + p[3] = (uint8_t)v; +} + +// LI=0 (no warning), VN=4, Mode=3 (client). The NTPClient request claimed LI=3, +// advertising an alarm condition it had no business asserting. +static inline void buildRequest(uint8_t out[kPacketSize], Nonce nonce) { + memset(out, 0, kPacketSize); + out[0] = 0x23; + out[1] = 0; // stratum: unspecified + out[2] = 6; // poll interval + out[3] = 0xEC; // precision + writeU32(out + 40, nonce.seconds); // transmit timestamp = our nonce + writeU32(out + 44, nonce.fraction); +} + +// Unix time for an NTP seconds field, handling the 2036 era rollover instead of +// wrapping into 1900 the way an unchecked subtraction does. +static inline uint32_t unixFromNtpSeconds(uint32_t ntp_seconds) { + return ntp_seconds >= kUnixEpochOffset ? (ntp_seconds - kUnixEpochOffset) + : (ntp_seconds + kEra1UnixOffset); +} + +// `source_matches` is the caller's check that the datagram came from the +// address and port it queried; it is a parameter rather than a lookup so this +// stays free of socket types. +static inline Result validate(const uint8_t* data, size_t len, bool source_matches, + Nonce nonce, uint32_t min_epoch, uint32_t max_epoch) { + Result r; + r.epoch = 0; + + if (data == nullptr || len < kPacketSize) { r.reject = kShortPacket; return r; } + if (!source_matches) { r.reject = kWrongSource; return r; } + + const uint8_t li = (uint8_t)((data[0] >> 6) & 0x03); + const uint8_t version = (uint8_t)((data[0] >> 3) & 0x07); + const uint8_t mode = (uint8_t)(data[0] & 0x07); + const uint8_t stratum = data[1]; + + if (version < 3 || version > 4) { r.reject = kBadVersion; return r; } + if (mode != 4) { r.reject = kBadMode; return r; } + if (li == 3) { r.reject = kLeapAlarm; return r; } + // Stratum 0 carries a kiss-of-death code (RATE/DENY/RSTR) rather than time; + // 16 and above means the server has no time to give. + if (stratum == 0 || stratum >= 16) { r.reject = kBadStratum; return r; } + + if (readU32(data + 24) != nonce.seconds || + readU32(data + 28) != nonce.fraction) { r.reject = kOriginMismatch; return r; } + + const uint32_t transmit_seconds = readU32(data + 40); + if (transmit_seconds == 0) { r.reject = kZeroTransmit; return r; } + + const uint32_t epoch = unixFromNtpSeconds(transmit_seconds); + if (epoch < min_epoch) { r.reject = kEpochTooEarly; return r; } + if (epoch > max_epoch) { r.reject = kEpochTooLate; return r; } + + r.reject = kAccepted; + r.epoch = epoch; + return r; +} + +// Short enough for a LoRa-bounded diagnostic reply. +static inline const char* rejectReason(Reject reject) { + switch (reject) { + case kAccepted: return "ok"; + case kShortPacket: return "short packet"; + case kWrongSource: return "wrong source"; + case kBadVersion: return "bad version"; + case kBadMode: return "not a server reply"; + case kLeapAlarm: return "server unsynced"; + case kBadStratum: return "bad stratum"; + case kOriginMismatch: return "unsolicited reply"; + case kZeroTransmit: return "no timestamp"; + case kEpochTooEarly: return "time too old"; + case kEpochTooLate: return "time too far ahead"; + default: return "invalid"; + } +} + +} // namespace NtpValidation diff --git a/src/helpers/RadioWatchdog.h b/src/helpers/RadioWatchdog.h new file mode 100644 index 00000000..1642c60b --- /dev/null +++ b/src/helpers/RadioWatchdog.h @@ -0,0 +1,116 @@ +#pragma once + +#include + +// Decides when the observer radio watchdog should kick a radio that is parked in +// RX but hearing nothing (see Dispatcher::loop()). +// +// Pure logic: no Arduino, radio or mesh headers. The caller feeds the raw 32-bit +// activity timestamps it can see (last receive, last radio interrupt, last +// successful transmit) plus its millis() counter. +// +// Why this is not a max() of those three timestamps: millis() wraps every ~49.7 +// days, and a pre-wrap timestamp is numerically larger than every fresh +// post-wrap one. Picking the largest therefore latches onto an old transmit and +// reports the radio silent while it is receiving continuously, resetting a +// healthy radio once per watchdog interval until that timestamp stops winning. +// +// Instead the caller's timestamps are only ever compared with their own previous +// values: any change is fresh activity, stamped against a monotonic 64-bit clock +// extended from millis(). Nothing downstream has a rollover case, and evidence +// older than one 32-bit cycle stays old instead of aliasing back to "recent". +// +// How far a timestamp may run behind the previous one and still count as an +// out-of-order reading rather than a very long forward gap (same rule as +// RadioActivityWindow). +#define RADIO_WATCHDOG_BACKSTEP_TOLERANCE_MS 5000UL + +struct RadioWatchdogDecision { + bool recover; // trip now: idle + restart receive + bool measurable; // false until some activity has been observed + uint64_t silent_ms; // age of the most recent activity (0 when !measurable) +}; + +class RadioWatchdog { +public: + RadioWatchdog() { reset(0); } + + void reset(uint32_t now_ms) { + _now_ms = now_ms; + _last_input_ms = now_ms; + _seeded = false; + _has_activity = false; + _last_recv = _last_irq = _last_tx = 0; + _last_activity_ms = now_ms; + _recovered = false; + _last_recovery_ms = 0; + } + + // Call once per loop with the current activity timestamps. `in_recv_mode` and + // `watchdog_ms` (0 disables) gate the decision; the silence measurement is + // updated either way so a disabled or transmitting radio does not accumulate + // phantom silence. + RadioWatchdogDecision update(uint32_t now_ms, bool in_recv_mode, uint32_t watchdog_ms, + uint32_t last_recv, uint32_t last_irq, uint32_t last_tx) { + tick(now_ms); + + if (!_seeded) { + // First observation: the timestamps carry activity from before this + // tracker existed, so date it to now rather than trusting a raw value we + // cannot place on our own clock. Worst case that delays the first + // possible trip by one watchdog interval. + _seeded = true; + _has_activity = (last_recv != 0 || last_irq != 0 || last_tx != 0); + _last_activity_ms = _now_ms; + } else if (last_recv != _last_recv || last_irq != _last_irq || last_tx != _last_tx) { + _has_activity = true; + _last_activity_ms = _now_ms; + } + _last_recv = last_recv; + _last_irq = last_irq; + _last_tx = last_tx; + + RadioWatchdogDecision d; + d.recover = false; + d.measurable = _has_activity; + d.silent_ms = _has_activity ? (_now_ms - _last_activity_ms) : 0; + + if (!_has_activity || !in_recv_mode || watchdog_ms == 0) return d; + if (d.silent_ms <= watchdog_ms) return d; + // One recovery per watchdog interval: a radio that stays silent through a + // reset must not be reset every loop. + if (_recovered && (_now_ms - _last_recovery_ms) <= watchdog_ms) return d; + + d.recover = true; + return d; + } + + // Call after acting on a decision with recover set. + void noteRecovery() { + _recovered = true; + _last_recovery_ms = _now_ms; + } + + uint64_t nowMs() const { return _now_ms; } + +private: + // Extends the caller's 32-bit millis() to a monotonic 64-bit clock. + void tick(uint32_t now_ms) { + uint32_t delta = now_ms - _last_input_ms; + if (delta > 0x80000000u && + (uint32_t)(_last_input_ms - now_ms) <= RADIO_WATCHDOG_BACKSTEP_TOLERANCE_MS) { + return; // out-of-order reading: no time has passed + } + _now_ms += delta; + _last_input_ms = now_ms; + } + + uint64_t _now_ms; + uint32_t _last_input_ms; + bool _seeded; + bool _has_activity; + uint32_t _last_recv, _last_irq, _last_tx; + uint64_t _last_activity_ms; + bool _recovered; + uint64_t _last_recovery_ms; +}; diff --git a/src/helpers/WebConfigKeys.h b/src/helpers/WebConfigKeys.h index 0f7a9289..117a0470 100644 --- a/src/helpers/WebConfigKeys.h +++ b/src/helpers/WebConfigKeys.h @@ -20,7 +20,7 @@ static const char* const WC_ALLOWED_SET_KEYS[] = { // NodePrefs (radio / node) "name", "bluetooth.name", "bluetooth.mac", "bluetooth.stealth", "lat", "lon", "radio", "tx", "af", "rxdelay", "txdelay", - "cad", "radio.rxgain", "radio.fem.rxgain", "radio.rxps", "powersaving", + "cad", "radio.rxgain", "radio.fem.rxgain", "radio.fem.txgain", "radio.rxps", "powersaving", "repeat", "display.mode", "display.timeout", "display.usb.mode", "display.usb.timeout", "display.inbox", diff --git a/src/helpers/WifiPowerSavePolicy.h b/src/helpers/WifiPowerSavePolicy.h new file mode 100644 index 00000000..bb8a3571 --- /dev/null +++ b/src/helpers/WifiPowerSavePolicy.h @@ -0,0 +1,76 @@ +#pragma once + +#include +#include + +// The single mapping between the stored `wifi.powersave` preference, its CLI +// name, and the IDF power-save mode. +// +// Pure lookup so host tests can hold startup, reconnect, CLI and web config to +// one table: they used to map the same stored value differently, so a node set +// to `min` silently ran with power save off after its first reconnect while +// `get wifi.powersave` still said min. +// +// Stored values are fleet state — never renumber them. 0 was the shipped +// default from 2026-01-02 to 2026-03-28, and every association path ran it with +// power save off, so it keeps meaning `none`; an explicit `min` is stored as 3. +// Older firmware repairs 3 to `none` when it loads /mqtt.json. +namespace WifiPowerSavePolicy { + +enum StoredValue : uint8_t { + kLegacyDefault = 0, // WIFI_PS_NONE: the old default, never an operator choice + kNone = 1, // WIFI_PS_NONE (default) + kMax = 2, // WIFI_PS_MAX_MODEM + kMin = 3, // WIFI_PS_MIN_MODEM + kMaxStoredValue = kMin, +}; + +// Mirrors wifi_ps_type_t. MQTTBridge.cpp static_asserts these against the SDK. +enum Mode : uint8_t { + kModeNone = 0, + kModeMinModem = 1, + kModeMaxModem = 2, +}; + +// Anything outside the known range reads as the default rather than as the +// lowest-numbered mode, so a corrupt byte cannot silently enable modem sleep. +static inline Mode modeFor(uint8_t stored) { + switch (stored) { + case kMin: return kModeMinModem; + case kMax: return kModeMaxModem; + case kNone: return kModeNone; + default: return kModeNone; + } +} + +static inline const char* nameFor(uint8_t stored) { + switch (stored) { + case kMin: return "min"; + case kMax: return "max"; + case kNone: return "none"; + default: return "none"; + } +} + +// Parses a CLI argument, which may be followed by trailing text (the observer +// setters take the rest of the command line). Returns false and leaves *out +// untouched for anything else. +static inline bool parseName(const char* value, uint8_t* out) { + if (value == nullptr || out == nullptr) return false; + static const struct { const char* name; uint8_t stored; } kNames[] = { + { "min", kMin }, + { "none", kNone }, + { "max", kMax }, + }; + for (unsigned i = 0; i < sizeof(kNames) / sizeof(kNames[0]); i++) { + const size_t len = strlen(kNames[i].name); + if (strncmp(value, kNames[i].name, len) == 0 && + (value[len] == '\0' || value[len] == ' ')) { + *out = kNames[i].stored; + return true; + } + } + return false; +} + +} // namespace WifiPowerSavePolicy diff --git a/src/helpers/bridges/MQTTErrorLabels.h b/src/helpers/bridges/MQTTErrorLabels.h new file mode 100644 index 00000000..cee1b688 --- /dev/null +++ b/src/helpers/bridges/MQTTErrorLabels.h @@ -0,0 +1,125 @@ +#pragma once + +#include + +// Operator-facing labels for the SDK error codes the observer reports through +// `get wifi.status`, `get mqttN.diag` and the web config panel. +// +// Pure lookup: no Arduino or ESP headers, so the table is host-testable. The +// numeric values below are the installed SDK's; MQTTBridge.cpp static_asserts +// every one of them against the real enum/#define, so a framework bump either +// keeps these labels honest or fails the build. Codes with no entry return +// nullptr and the caller prints the raw number — an unknown code must never be +// given a neighbouring code's name. +namespace MQTTErrorLabels { + +// esp_wifi_types.h wifi_err_reason_t. Values below 200 are 802.11 reason codes +// forwarded from the AP; 200+ are Espressif's own local failures. +enum WifiReason : uint16_t { + kWifiAuthExpire = 2, + kWifiAssocExpire = 4, + kWifiAssocLeave = 8, + kWifi4WayHandshakeTimeout = 15, + kWifiGroupCipherInvalid = 18, + kWifiCipherSuiteRejected = 24, + kWifiMissingAcks = 34, + kWifiTimeout = 39, + kWifiInvalidPmkid = 49, + kWifiBssTransitionDisassoc = 12, + kWifiBeaconTimeout = 200, + kWifiNoApFound = 201, + kWifiAuthFail = 202, + kWifiAssocFail = 203, + kWifiHandshakeTimeout = 204, + kWifiConnectionFail = 205, + kWifiApTsfReset = 206, + kWifiRoaming = 207, + kWifiSaQueryTimeout = 209, +}; + +// esp_tls_errors.h, ESP_ERR_ESP_TLS_BASE (0x8000) + offset. +enum TlsError : int32_t { + kTlsCannotResolveHostname = 0x8001, + kTlsCannotCreateSocket = 0x8002, + kTlsUnsupportedProtoFamily= 0x8003, + kTlsFailedConnectToHost = 0x8004, + kTlsSocketSetoptFailed = 0x8005, + kTlsConnectionTimeout = 0x8006, + kTlsTcpClosedFin = 0x8008, + kTlsMbedtlsCertPartlyOk = 0x8010, + kTlsMbedtlsSetHostname = 0x8012, + kTlsMbedtlsX509ParseFailed= 0x8015, + kTlsMbedtlsSslSetupFailed = 0x8017, + kTlsMbedtlsSslWriteFailed = 0x8018, + kTlsMbedtlsHandshakeFailed= 0x801A, +}; + +// MQTT 3.1.1 CONNACK return codes (esp_mqtt_error_codes.connect_return_code). +enum ConnackCode : uint8_t { + kConnackAccepted = 0, + kConnackBadProtocol = 1, + kConnackIdRejected = 2, + kConnackServerUnavail = 3, + kConnackBadCredentials = 4, + kConnackNotAuthorized = 5, +}; + +// Short enough to sit inside a LoRa-bounded diagnostic reply next to the raw code. +static inline const char* wifiReason(uint8_t reason) { + switch (reason) { + case kWifiAuthExpire: return "auth expired"; + case kWifiAssocExpire: return "assoc expired"; + case kWifiAssocLeave: return "AP disconnected"; + case kWifiBssTransitionDisassoc: return "AP steered us away"; + case kWifi4WayHandshakeTimeout: return "4-way handshake timeout"; + case kWifiGroupCipherInvalid: return "group cipher mismatch"; + case kWifiCipherSuiteRejected: return "cipher suite rejected"; + case kWifiMissingAcks: return "AP saw no acks"; + case kWifiTimeout: return "802.11 timeout"; + case kWifiInvalidPmkid: return "invalid PMKID"; + case kWifiBeaconTimeout: return "beacon lost"; + case kWifiNoApFound: return "SSID not found"; + case kWifiAuthFail: return "auth failed (check password)"; + case kWifiAssocFail: return "association failed"; + case kWifiHandshakeTimeout: return "handshake timeout"; + case kWifiConnectionFail: return "connect failed"; + case kWifiApTsfReset: return "AP restarted"; + case kWifiRoaming: return "roaming"; + case kWifiSaQueryTimeout: return "SA query timeout (PMF)"; + default: return nullptr; + } +} + +static inline const char* tlsError(int32_t err) { + switch (err) { + case kTlsCannotResolveHostname: return "DNS failed"; + case kTlsCannotCreateSocket: return "socket error"; + case kTlsUnsupportedProtoFamily: return "unsupported protocol family"; + case kTlsFailedConnectToHost: return "connect failed"; + case kTlsSocketSetoptFailed: return "socket setopt failed"; + case kTlsConnectionTimeout: return "connection timeout"; + case kTlsTcpClosedFin: return "server closed connection"; + case kTlsMbedtlsCertPartlyOk: return "cert chain partly parsed"; + case kTlsMbedtlsSetHostname: return "SNI hostname rejected"; + case kTlsMbedtlsX509ParseFailed: return "cert parse failed"; + case kTlsMbedtlsSslSetupFailed: return "TLS setup failed"; + case kTlsMbedtlsSslWriteFailed: return "TLS write failed"; + case kTlsMbedtlsHandshakeFailed: return "TLS handshake failed"; + default: return nullptr; + } +} + +// The broker answered and refused: this is what an operator needs instead of a +// transport error, which is why the bridge keeps the CONNACK code separately. +static inline const char* connackReason(uint8_t code) { + switch (code) { + case kConnackBadProtocol: return "protocol rejected"; + case kConnackIdRejected: return "client id rejected"; + case kConnackServerUnavail: return "server unavailable"; + case kConnackBadCredentials: return "bad user/password"; + case kConnackNotAuthorized: return "not authorized"; + default: return nullptr; + } +} + +} // namespace MQTTErrorLabels diff --git a/src/helpers/esp32/HttpPort80Lease.h b/src/helpers/esp32/HttpPort80Lease.h new file mode 100644 index 00000000..464cf39a --- /dev/null +++ b/src/helpers/esp32/HttpPort80Lease.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include + +// Ownership guard for the two AsyncWebServer users. It prevents `start ota` +// from claiming port 80 while WebConfig is listening (and vice versa), even +// when the requests arrive from different tasks. +namespace HttpPort80Lease { + +enum class Owner : uint8_t { None = 0, WebConfig, Ota }; + +inline std::atomic& current() { + static std::atomic owner{Owner::None}; + return owner; +} + +inline bool acquire(Owner requested) { + if (requested == Owner::None) return false; + Owner expected = Owner::None; + return current().compare_exchange_strong( + expected, requested, std::memory_order_acq_rel, + std::memory_order_relaxed); +} + +inline void release(Owner expected) { + current().compare_exchange_strong( + expected, Owner::None, std::memory_order_acq_rel, + std::memory_order_relaxed); +} + +inline const char* ownerName() { + switch (current().load(std::memory_order_acquire)) { + case Owner::WebConfig: return "webconfig"; + case Owner::Ota: return "ota"; + default: return "none"; + } +} + +} // namespace HttpPort80Lease diff --git a/src/helpers/esp32/WebConfigHtml.h b/src/helpers/esp32/WebConfigHtml.h index b0d92304..f9a59278 100644 --- a/src/helpers/esp32/WebConfigHtml.h +++ b/src/helpers/esp32/WebConfigHtml.h @@ -1,15 +1,15 @@ // Auto-generated by scripts/generate_webconfig_html.py from webui/index.html // DO NOT EDIT - edit webui/index.html instead. // Compressed with Google Brotli 1.2.0 (quality 11, lgwin 24). -// shipped-page-sha256: 89f2d0614c39dd8fa2f3a9ad8b4f20c8377d34ba2204cb10befb4969d99a73cb +// shipped-page-sha256: 77545bdea9618803bb6f48f4cc77d17898f06f1ee0fdbdd5f477a24482037e5b #pragma once #include #include -const uint32_t WEBCONFIG_HTML_RAW_LEN = 116713; -const uint32_t WEBCONFIG_HTML_BR_LEN = 30176; -const char WEBCONFIG_HTML_ETAG[] = "\"ce803de963276f23\""; -const char WEBCONFIG_HTML_VERSION[] = "2eff0d1520d69ada"; +const uint32_t WEBCONFIG_HTML_RAW_LEN = 117962; +const uint32_t WEBCONFIG_HTML_BR_LEN = 30537; +const char WEBCONFIG_HTML_ETAG[] = "\"6e21340cc3d92fd8\""; +const char WEBCONFIG_HTML_VERSION[] = "fb0569c5bd27273d"; const uint16_t WEBCONFIG_HTML_LOADER_LEN = 762; const uint8_t WEBCONFIG_HTML_LOADER[] PROGMEM = { 0x3c,0x21,0x64,0x6f,0x63,0x74,0x79,0x70,0x65,0x20,0x68,0x74,0x6d,0x6c,0x3e,0x3c, @@ -33,8 +33,8 @@ const uint8_t WEBCONFIG_HTML_LOADER[] PROGMEM = { 0x6d,0x65,0x6f,0x75,0x74,0x28,0x28,0x29,0x3d,0x3e,0x63,0x2e,0x61,0x62,0x6f,0x72, 0x74,0x28,0x29,0x2c,0x39,0x30,0x30,0x30,0x30,0x29,0x3b,0x74,0x72,0x79,0x7b,0x63, 0x6f,0x6e,0x73,0x74,0x20,0x72,0x3d,0x61,0x77,0x61,0x69,0x74,0x20,0x66,0x65,0x74, - 0x63,0x68,0x28,0x22,0x2f,0x75,0x69,0x3f,0x76,0x3d,0x32,0x65,0x66,0x66,0x30,0x64, - 0x31,0x35,0x32,0x30,0x64,0x36,0x39,0x61,0x64,0x61,0x22,0x2c,0x63,0x3f,0x7b,0x73, + 0x63,0x68,0x28,0x22,0x2f,0x75,0x69,0x3f,0x76,0x3d,0x66,0x62,0x30,0x35,0x36,0x39, + 0x63,0x35,0x62,0x64,0x32,0x37,0x32,0x37,0x33,0x64,0x22,0x2c,0x63,0x3f,0x7b,0x73, 0x69,0x67,0x6e,0x61,0x6c,0x3a,0x63,0x2e,0x73,0x69,0x67,0x6e,0x61,0x6c,0x7d,0x3a, 0x7b,0x7d,0x29,0x3b,0x69,0x66,0x28,0x72,0x2e,0x6f,0x6b,0x29,0x70,0x3d,0x61,0x77, 0x61,0x69,0x74,0x20,0x72,0x2e,0x74,0x65,0x78,0x74,0x28,0x29,0x3b,0x65,0x6c,0x73, @@ -63,1890 +63,1913 @@ const uint8_t WEBCONFIG_HTML_LOADER[] PROGMEM = { }; const uint8_t WEBCONFIG_HTML_BR[] PROGMEM = { - 0x5f,0xe8,0xc7,0x31,0x0a,0xc9,0x3a,0x99,0x13,0x14,0xc8,0x4d,0x97,0x05,0xba,0x03, - 0x09,0x2e,0xef,0x4d,0x1d,0x40,0x3d,0x16,0x77,0x88,0xf1,0xc2,0xc6,0xfc,0x03,0x29, - 0x22,0x90,0x60,0x1d,0xe7,0x46,0x29,0xd0,0x04,0x13,0x87,0xa0,0x6d,0xd9,0x81,0x88, - 0x1b,0x4f,0x1d,0x32,0xa4,0xb7,0x36,0x93,0xc1,0xbc,0xd0,0xf3,0x68,0x1a,0xfd,0x13, - 0xfd,0x8f,0x99,0x29,0xd6,0x3d,0x66,0xc6,0x14,0x71,0xe4,0xb6,0x7b,0xff,0xa7,0x23, - 0x99,0x81,0x90,0x9e,0x62,0x39,0x69,0x26,0x4c,0xf4,0x3e,0x74,0x61,0xed,0x62,0x4b, - 0x90,0xb0,0x14,0x45,0xad,0x02,0xca,0xb1,0x39,0x35,0x92,0x95,0x93,0x37,0xfa,0xfa, - 0xbd,0x3f,0xf7,0xff,0x5f,0xbf,0x7b,0xf1,0x8a,0xe4,0x5c,0x26,0x7a,0xca,0x6d,0xe1, - 0xea,0x2b,0xed,0xab,0xb7,0x20,0x03,0xce,0x13,0x48,0x16,0x13,0x3d,0xba,0x82,0x16, - 0xea,0xb2,0xaa,0x9f,0x62,0x24,0x87,0xec,0xb5,0x9d,0xf0,0x74,0x69,0x01,0xe0,0x00, - 0x75,0xa0,0xe0,0xff,0x5a,0x3a,0x0b,0x79,0x09,0x8a,0x0c,0x22,0x6d,0xbb,0xf6,0xcd, - 0xbe,0x71,0xec,0x4a,0x06,0xe8,0x00,0x34,0x2b,0xa0,0xfd,0x73,0xd7,0x4c,0xad,0x57, - 0x53,0x9d,0x53,0x27,0x33,0x9b,0x01,0x9f,0x3f,0xd7,0x9f,0x8b,0x6a,0x39,0x16,0x4b, - 0xce,0x61,0x5f,0xf5,0xd3,0xdd,0xcb,0xc4,0xa7,0x34,0x37,0xfd,0x94,0xd1,0x09,0xd3, - 0xfa,0x74,0x19,0x3b,0x44,0x82,0x12,0xf3,0x49,0x00,0x07,0x80,0x47,0xc9,0xcf,0x60, - 0xda,0xf9,0x84,0xa6,0x4b,0xaa,0x4f,0x9f,0x94,0x6c,0x42,0x37,0xeb,0x35,0x7f,0xf6, - 0x6a,0x2a,0x71,0xc4,0xf9,0x1a,0x52,0xda,0x41,0x4f,0xd8,0xae,0x5d,0x51,0xf2,0xcf, - 0x89,0x50,0x39,0xe5,0xb9,0xf5,0xff,0x6d,0xbf,0x6a,0x9f,0xcd,0x2a,0xdc,0xf6,0x68, - 0x18,0x9b,0x22,0x51,0xab,0xfa,0xcb,0xcc,0x7f,0xf7,0xf9,0xaf,0xb0,0x3c,0x13,0x02, - 0x48,0x0a,0x48,0xa8,0xbc,0x34,0xda,0x07,0x4d,0x05,0xa9,0xb3,0x2d,0x37,0x77,0x96, - 0x29,0x78,0x45,0x1c,0x0d,0xfa,0xc7,0xa7,0x2e,0x93,0x6f,0x3d,0x6d,0xa5,0xff,0x7c, - 0x5e,0x11,0xbd,0xa6,0x07,0x02,0x43,0xae,0xcb,0x7b,0x1d,0x2c,0xc1,0xac,0x96,0xaa, - 0xaf,0x01,0x4c,0xd6,0x0a,0xcb,0x20,0xdb,0x34,0xaa,0xdc,0x6b,0xfa,0xfb,0xaa,0xd6, - 0xe7,0x7d,0x57,0x10,0x7b,0xcd,0xea,0xcc,0x35,0x2d,0x47,0xb1,0x98,0x45,0x33,0x41, - 0x96,0x21,0x24,0xf0,0x7e,0xf7,0xbe,0x2d,0xeb,0x9f,0x9f,0x2f,0x51,0xc9,0x18,0x55, - 0x24,0x9b,0x1c,0xa7,0x4c,0xd9,0xb9,0xc8,0x75,0xd1,0x3d,0xc7,0x9a,0x7e,0x5e,0x40, - 0x0a,0xf1,0x6b,0x61,0x7b,0x54,0x02,0x9a,0x8d,0x59,0xbf,0xff,0xde,0xd2,0x52,0xcb, - 0x2c,0xb0,0x41,0x4a,0x9e,0x2d,0x63,0xed,0x62,0x43,0x03,0x39,0xe7,0x76,0xcc,0x88, - 0x1b,0x2f,0xa6,0xbe,0xc9,0x1c,0xa4,0xa9,0x22,0xcb,0xa0,0x34,0x05,0x53,0x67,0x60, - 0x38,0x6a,0x18,0x8e,0x21,0x9b,0x7c,0x11,0xef,0xfd,0xac,0x34,0x05,0x76,0x56,0x16, - 0xd8,0x83,0x2a,0xa0,0xd9,0x00,0xd8,0x9c,0x43,0xa2,0x1d,0x38,0xd6,0xb0,0x65,0x8c, - 0xd9,0x6b,0xb3,0xd6,0x68,0x35,0x6e,0x35,0xd2,0x72,0x01,0xca,0x2f,0xb5,0x34,0x56, - 0x6d,0x0c,0x3b,0xa1,0x54,0x01,0x99,0x93,0xb4,0xc9,0xfe,0x1f,0x43,0xd7,0xb1,0xfe, - 0xba,0x88,0x88,0xa0,0x7b,0x4e,0x6a,0xcb,0xd0,0x7d,0x7f,0x43,0x6f,0x2d,0x5b,0x08, - 0x01,0xb2,0x89,0xd6,0x3e,0xff,0xdf,0xa4,0xa6,0x0d,0x2d,0xd0,0x34,0x84,0xe4,0x0e, - 0xbc,0x7e,0x3f,0xc9,0xb2,0xbd,0x7d,0xc8,0xb2,0xfe,0xf7,0x68,0xe7,0x38,0xdf,0xdf, - 0x5a,0x8d,0x91,0x10,0x02,0x98,0x02,0xd1,0xf9,0x8f,0x31,0x6b,0xaf,0x14,0x33,0x73, - 0x20,0xf8,0x05,0x78,0x9f,0xf1,0x1e,0xfd,0x80,0x59,0x9c,0xc0,0x64,0xb4,0x8e,0x2e, - 0x83,0x95,0xb8,0x88,0x0f,0x64,0x32,0xd3,0xe6,0x50,0x52,0x0a,0xcd,0x9e,0xda,0xda, - 0x5a,0xf1,0x11,0x30,0x10,0xbb,0x40,0x45,0xd2,0xd6,0xd2,0x9a,0x4a,0x67,0xfb,0x35, - 0xdf,0x1d,0xe6,0xeb,0xc0,0x5e,0x93,0x4a,0x52,0xfe,0xa2,0x73,0xe1,0x94,0xfc,0x0f, - 0x90,0x19,0x51,0xeb,0xdd,0xde,0x78,0x1a,0x36,0xca,0x3c,0x11,0x69,0xa7,0x3d,0x7a, - 0x5d,0x77,0x7e,0x76,0xeb,0x8e,0x76,0x19,0x3a,0x31,0xc3,0xe5,0xf1,0x8b,0x53,0xfa, - 0x99,0xcc,0x32,0x17,0x27,0x79,0x3d,0x53,0x7f,0xbe,0xd8,0x45,0x8e,0xa8,0x57,0xcf, - 0xba,0xd9,0x1f,0xbf,0x08,0xb5,0xdc,0xe3,0xed,0x3c,0x81,0x88,0x10,0x2c,0xae,0xdc, - 0xe9,0x5e,0xbb,0x42,0x9e,0x8d,0x30,0x1f,0x3f,0x53,0x7f,0x25,0x2a,0xfa,0xc3,0x9f, - 0xfc,0x3c,0xfd,0x4c,0xcb,0x9b,0x92,0xd1,0xff,0xc2,0x72,0x90,0x58,0xaf,0x8a,0xa6, - 0x7b,0x18,0x99,0x1b,0xe6,0x55,0x79,0x63,0x06,0x28,0xd0,0x76,0xa7,0x1e,0x60,0xe8, - 0xfd,0x5f,0xca,0xc1,0x24,0xd7,0xcf,0x78,0xbc,0x7e,0xc6,0xdc,0x37,0xbe,0x54,0xb6, - 0xa6,0xb2,0x16,0x5d,0x27,0x28,0x28,0x23,0x4c,0xca,0x8f,0xe5,0x79,0xb7,0x7c,0xfc, - 0xf8,0x4a,0xa5,0x44,0x45,0x2f,0x9b,0x0d,0x11,0xe6,0x7e,0xe3,0xc1,0xf9,0xb9,0x10, - 0x50,0x71,0xe1,0x01,0xd9,0x42,0x6a,0xbf,0x7f,0x9e,0x78,0x8a,0xd6,0x3d,0xfc,0x31, - 0x4a,0xab,0xc5,0xdb,0xcf,0x43,0xce,0x22,0xf4,0x33,0x89,0x57,0x19,0x80,0x2e,0xfe, - 0x31,0x89,0xa9,0xb3,0xbf,0x23,0x0a,0x3a,0xd1,0xd7,0x3f,0x85,0xec,0x62,0x6a,0x3d, - 0xb9,0xfe,0xb3,0x97,0xa4,0x87,0x97,0x67,0xb9,0xcb,0x2d,0x5c,0x44,0xd9,0x3d,0x64, - 0xea,0xdd,0x93,0x18,0x58,0xb9,0xd4,0x52,0xa9,0xf7,0x81,0x72,0xeb,0x2c,0x72,0x0a, - 0x22,0x74,0xaa,0xb1,0xcd,0x04,0xf5,0x09,0xef,0x10,0xe3,0xf5,0xb2,0xb0,0x40,0x91, - 0x4f,0x07,0x88,0x24,0xdf,0xc5,0xf5,0xa7,0x49,0xf4,0x8e,0x30,0x17,0x68,0xd8,0xea, - 0x90,0xa7,0x6b,0x7a,0x5e,0x78,0xdf,0xf6,0xff,0x7c,0x12,0x18,0x3f,0x23,0x28,0xb4, - 0x90,0x42,0xc5,0x7f,0x5e,0x46,0xf6,0xf6,0xa3,0x9f,0xcb,0x61,0xed,0x1b,0x0d,0x3b, - 0xb6,0xd1,0x40,0x2e,0x32,0x62,0xb8,0xa2,0x8a,0xca,0x20,0x02,0x37,0xe8,0x74,0xbc, - 0x7f,0xd7,0xad,0x1c,0xee,0xe5,0x05,0x09,0x53,0x23,0xb7,0x7b,0xa6,0x1d,0x9c,0x78, - 0x28,0xf6,0x34,0x52,0xce,0xbd,0xd6,0x93,0x01,0x62,0xa1,0x43,0x32,0xa1,0xaa,0x85, - 0x45,0x4d,0x2f,0xcb,0xd0,0x5b,0x13,0x68,0x5c,0xa0,0xcb,0x93,0xdc,0x31,0x63,0xc9, - 0xf7,0x38,0xeb,0x61,0xb3,0x16,0x4b,0x0d,0x97,0x47,0x02,0xa2,0x24,0x11,0x37,0x9e, - 0xef,0x50,0x44,0x43,0x3e,0xe7,0x33,0x1c,0xa6,0x84,0x0d,0x93,0x45,0x03,0x4c,0xcd, - 0x49,0x20,0x17,0xc6,0xc0,0x97,0x5a,0x69,0x94,0x74,0x4a,0x43,0x62,0x79,0x9e,0x3e, - 0xf1,0xd1,0x09,0xe5,0x20,0xab,0xc9,0x44,0x2c,0xee,0x45,0xb6,0x37,0xb6,0x20,0xd0, - 0x05,0x46,0x52,0x2b,0xbe,0xdf,0x12,0xca,0xfd,0xf0,0x73,0x99,0x58,0xf5,0x74,0x71, - 0xa7,0x6d,0xfa,0xd7,0x1a,0xd7,0xce,0x2c,0xf6,0x56,0x10,0x50,0x3c,0x0f,0x3d,0xf7, - 0x19,0xbd,0xf8,0x84,0x3a,0xff,0xb2,0xb7,0x62,0x8f,0x91,0x93,0xcf,0xa3,0x4c,0x7a, - 0xba,0x03,0xdb,0xef,0x42,0x2b,0xe7,0xa1,0x6f,0x51,0x62,0xf0,0x58,0x8e,0xf2,0x08, - 0x0f,0xd8,0x69,0x0a,0x57,0xf8,0x62,0x7a,0x74,0xc7,0xb7,0x2f,0x86,0x41,0xa2,0x8a, - 0xde,0x8a,0xdd,0x7c,0xdb,0x73,0x16,0xd0,0xac,0x91,0x14,0x41,0xa3,0x09,0x66,0xe0, - 0xbc,0xeb,0x18,0x12,0xdf,0x90,0xc1,0x20,0x43,0xf5,0x75,0x51,0xdf,0xca,0x49,0x5d, - 0xad,0x83,0x0a,0x26,0x9d,0x6e,0xba,0x12,0x10,0xe2,0xe7,0x0a,0x32,0x99,0x75,0xc6, - 0xf3,0x8f,0x51,0x3a,0xdb,0x0c,0x17,0x8a,0xeb,0x02,0xa3,0x44,0x9a,0x6b,0x2c,0xa3, - 0x6b,0x7a,0x42,0xda,0xdf,0xe0,0xf7,0xd8,0x1b,0x7f,0xfe,0x86,0x5b,0xf7,0xd5,0xc1, - 0x9f,0x8e,0x28,0xe0,0xe2,0x0f,0x81,0x92,0xf8,0x3e,0x4d,0x6a,0xcc,0x68,0xb5,0x0b, - 0x98,0x78,0x5e,0x71,0xfd,0x15,0x19,0x60,0x12,0xe2,0xfc,0x17,0xf3,0xf4,0x53,0xa8, - 0x87,0x29,0x4c,0xdd,0xdf,0xb5,0xfa,0xc9,0x97,0x43,0xa8,0x7e,0x84,0x4b,0x0d,0x83, - 0xd7,0x6a,0x67,0xe8,0x29,0x0c,0x31,0x97,0xe6,0x15,0x6d,0x77,0x5f,0x73,0x79,0x9c, - 0x37,0xe4,0x3f,0x17,0x3b,0x0d,0x94,0xbf,0x7d,0xc8,0x26,0xba,0x7c,0x64,0x19,0xbd, - 0x4c,0x79,0xf4,0x17,0x3a,0x2d,0xcc,0xf8,0x51,0x01,0xc8,0x79,0x0c,0xca,0x51,0x85, - 0x31,0x30,0x3d,0x19,0x91,0x3d,0xe7,0x9f,0xfe,0x84,0xa4,0xbf,0xd0,0xb0,0x59,0xf0, - 0x6d,0x4e,0xe7,0x22,0xb6,0x51,0x15,0x1b,0x82,0x1c,0x51,0x4e,0x2d,0x05,0x15,0xb2, - 0xea,0xac,0x54,0x60,0x11,0xb0,0x47,0x21,0x4f,0x69,0x0f,0xc5,0x1c,0x74,0x5a,0x90, - 0xd9,0x10,0xee,0x2f,0x09,0xb2,0xec,0x60,0x37,0xc7,0xa1,0x29,0x10,0xab,0x4f,0x41, - 0x4c,0x21,0x7a,0xac,0x56,0xc3,0x75,0x47,0x72,0xd2,0xcf,0x4f,0x80,0xa5,0xec,0xa3, - 0x49,0x7b,0x3c,0x8a,0x74,0x30,0xbc,0x1d,0xcb,0x6e,0x5e,0x7c,0x0d,0x92,0x35,0xd6, - 0xc4,0xaf,0x8b,0x4a,0x1e,0x8a,0x47,0xb8,0x2c,0xe9,0x21,0x93,0xd9,0xe4,0x36,0xdd, - 0x7a,0x7a,0x72,0xe0,0xd5,0x72,0x79,0x9b,0x3d,0x64,0x4a,0x22,0xf0,0x96,0x98,0xf4, - 0x73,0xac,0x1a,0x18,0x13,0xb6,0x3a,0xcb,0x3f,0xdd,0x27,0x3a,0xdc,0xd4,0x38,0x37, - 0x06,0xa3,0xd5,0xee,0x80,0x4d,0x6a,0x3f,0xf1,0x51,0xb6,0x2a,0xda,0xd4,0xf3,0x99, - 0xb9,0x35,0x61,0x0a,0x96,0x0a,0xd3,0x44,0xc6,0x0c,0x82,0x5a,0xfd,0x61,0xcd,0x92, - 0x2a,0xaf,0x22,0x09,0xb5,0x54,0xc4,0x1f,0x80,0x22,0xb9,0xbc,0xa2,0xbc,0x9b,0x76, - 0xbd,0xe1,0xc2,0x65,0x0b,0x9d,0x57,0xc8,0xb7,0x3c,0x63,0xe9,0x34,0xb1,0x23,0xaf, - 0xbc,0x28,0x2d,0x71,0xb2,0xe7,0x2b,0x7a,0x02,0x2e,0x72,0xc2,0x90,0xfd,0x33,0xe7, - 0x8e,0x9d,0x31,0xf5,0x6e,0x3d,0x84,0xa5,0xab,0x85,0x31,0x90,0x0d,0x7b,0xc8,0x12, - 0xc7,0x92,0x4a,0x0f,0xa6,0x3f,0x49,0xa1,0x42,0xea,0xfc,0x6b,0x75,0xb9,0x94,0xd6, - 0x41,0xe7,0xbe,0xa9,0x6a,0xbd,0xb5,0x3e,0xe8,0x01,0xad,0xff,0xda,0xcc,0xdb,0x35, - 0x36,0xcb,0x9c,0xae,0x0d,0x63,0x43,0xe2,0x3d,0x8c,0x5a,0xa2,0xc3,0x2d,0x39,0xf6, - 0xc4,0x46,0x0e,0x5f,0x51,0xff,0xa3,0x43,0x0e,0x46,0x4d,0x2f,0x76,0x13,0x5e,0xcf, - 0x54,0x92,0x52,0x05,0xbd,0x19,0xf7,0xfe,0x91,0x2f,0x64,0x1a,0xfd,0xa5,0x54,0x44, - 0xd7,0xcf,0x15,0x8e,0x5b,0x03,0xed,0xa3,0x23,0x5d,0x31,0xea,0xe9,0x30,0x74,0x91, - 0x35,0xcb,0x44,0xd5,0xe8,0x56,0x09,0xe4,0xf3,0xfb,0xd6,0xdc,0x88,0x21,0x1a,0xcb, - 0xe7,0xae,0xc7,0x64,0xdb,0xc1,0xbc,0x32,0x31,0x82,0xf7,0x3f,0xdd,0x04,0x05,0x37, - 0xcd,0xe9,0x5a,0x12,0xa3,0x60,0x7f,0x17,0x95,0x70,0x5b,0xc1,0xa9,0xda,0x45,0x45, - 0xf2,0x72,0x5f,0x85,0x6c,0x75,0xa4,0xec,0x15,0x86,0xf3,0xea,0x78,0xab,0xcd,0x30, - 0xbc,0xf6,0x59,0x25,0x04,0x0b,0x8f,0x7b,0xb6,0xe9,0x98,0xc5,0xae,0x89,0x00,0x68, - 0x10,0x25,0xcd,0xbd,0x69,0x59,0x03,0x5a,0x9f,0x46,0xd3,0xa7,0x1d,0xda,0xc1,0x20, - 0x63,0x73,0xff,0x4e,0x4f,0x63,0x16,0x57,0xae,0xb5,0xd5,0x66,0xdf,0x42,0xc3,0xb3, - 0x86,0x62,0x13,0x98,0x76,0x9f,0xda,0x1d,0x0c,0x9d,0xe2,0xd8,0x88,0x2b,0xf2,0x5c, - 0x39,0x3d,0x74,0x97,0xdf,0xa5,0x99,0xd3,0xfe,0x70,0x25,0xca,0x0c,0x95,0x30,0xcb, - 0xb9,0x50,0x97,0xb1,0x25,0xd7,0x3c,0xb6,0x48,0xfb,0x46,0x30,0x5e,0x9b,0x3d,0x4f, - 0x94,0x44,0xbd,0xe2,0xa3,0x8b,0x95,0x6e,0xae,0x6b,0x0a,0x56,0x24,0x0c,0xef,0xa2, - 0x5a,0xfb,0x0c,0x9d,0x16,0x4a,0xf6,0xd8,0xa8,0x8e,0xa7,0x63,0x53,0xbd,0x12,0x55, - 0xc1,0x67,0x1a,0x87,0x40,0x43,0xf6,0xa4,0xaa,0xd9,0xf9,0x06,0xde,0x0f,0x39,0x08, - 0x81,0xbe,0xb7,0x44,0x99,0x80,0x03,0x58,0x4a,0xfb,0xa8,0x2c,0xe3,0x99,0x88,0x60, - 0x54,0x57,0xaf,0x48,0xd5,0x38,0x04,0x62,0x04,0x18,0x6e,0x2b,0x37,0x39,0x44,0x25, - 0xa0,0x67,0x9d,0xc0,0xde,0x67,0xeb,0x94,0x93,0x39,0x91,0x2d,0x98,0x60,0x7d,0x47, - 0xa7,0x5c,0x77,0x29,0xa1,0xde,0xcd,0x4d,0x55,0x14,0x77,0x31,0xbd,0x19,0x9c,0x5c, - 0x9c,0xa8,0x93,0x67,0xef,0x16,0xbb,0xbb,0x33,0x22,0xa2,0x64,0x8b,0x9a,0x82,0xf9, - 0x86,0x74,0x71,0xbc,0x08,0x0b,0x2b,0x05,0x11,0xf1,0xf0,0xd0,0x3b,0x52,0xe1,0xe0, - 0x62,0xc6,0xb4,0x76,0xa1,0xda,0xf9,0x17,0x83,0x91,0x63,0x4e,0x4c,0x97,0xd7,0x3e, - 0x30,0x7a,0x3d,0x42,0xa2,0x15,0x93,0xe7,0x8d,0xb7,0x34,0xe5,0x34,0x83,0x51,0x90, - 0xb0,0x2b,0x6f,0xd1,0x95,0x84,0xe8,0xc8,0x77,0x8c,0x27,0x56,0x04,0x2f,0x06,0xac, - 0x9d,0x2c,0x5f,0x1a,0xcf,0xae,0xbb,0xee,0x4a,0x24,0xb6,0x28,0x4c,0x47,0x3f,0x49, - 0x6b,0xbc,0xcf,0xfe,0x96,0x5f,0xb7,0xe3,0x02,0x75,0x9d,0x4c,0xba,0x2b,0x49,0xb1, - 0x92,0xf0,0x9c,0xd3,0xd4,0xe2,0x31,0x2b,0x9e,0xd0,0xcf,0x96,0x89,0xf3,0x5e,0xd8, - 0xc6,0x67,0xe7,0xf0,0xf6,0x28,0xbc,0x4a,0x68,0xe4,0xf4,0x7b,0x2b,0x48,0x69,0x54, - 0xbd,0x48,0x62,0x17,0x91,0xd8,0x6f,0x59,0x1b,0x64,0x99,0x25,0xf7,0xbb,0xea,0x4d, - 0xbd,0xbf,0xc8,0xb8,0x69,0xa1,0x00,0xf5,0x23,0xc6,0x30,0x5f,0xdb,0xd4,0xec,0xef, - 0x28,0x45,0xdf,0x29,0x4a,0x7b,0x53,0xe3,0x67,0xb6,0xe7,0x98,0x2b,0xd8,0xac,0x0f, - 0xf3,0xa3,0xa4,0xd0,0xbf,0x61,0x1c,0xc7,0x01,0x85,0xd7,0x42,0x10,0xac,0x78,0xe6, - 0x3a,0x91,0xa8,0x54,0x39,0x44,0xb8,0x5e,0x81,0xbd,0x1f,0xf6,0xe5,0xa6,0xbf,0xe9, - 0x0b,0xf0,0x74,0x2e,0xc9,0x77,0x4c,0x10,0xd8,0x93,0xec,0x11,0xdb,0xfc,0x90,0x81, - 0x02,0xe5,0x79,0x9a,0xba,0x45,0x51,0xe7,0x8e,0xb0,0x76,0x50,0x55,0xf1,0xfe,0xa3, - 0xd0,0x64,0x31,0x6f,0xbe,0x6f,0x5a,0x8b,0xba,0x8a,0x76,0x7c,0x09,0x0d,0x21,0x65, - 0xbf,0xd1,0x0f,0xf0,0xf8,0x9e,0x5b,0x0b,0x04,0xf4,0x9b,0x87,0xb5,0x64,0x82,0x5c, - 0x57,0x81,0x94,0xd1,0xa7,0xbb,0x44,0x86,0x61,0xdf,0x74,0x50,0x67,0xad,0xec,0x90, - 0xfe,0xee,0x05,0x53,0x46,0x15,0x8b,0x6b,0x89,0x20,0xf9,0xf0,0x70,0x0b,0xa0,0xd2, - 0xdb,0x81,0x12,0x37,0x69,0xdd,0xea,0xa1,0xe1,0x1c,0x40,0xfe,0xdd,0x9d,0x5e,0x12, - 0x4c,0xeb,0xfc,0xef,0x6a,0x7d,0x7f,0xfa,0x5c,0x06,0x56,0xbf,0xe2,0x97,0x13,0x00, - 0x95,0x00,0x76,0x86,0x80,0xce,0x27,0x5e,0x70,0x69,0x97,0xc0,0xa4,0x4d,0x9d,0x80, - 0x71,0x63,0x09,0xbb,0xbb,0x04,0x03,0x54,0x2c,0xad,0xcf,0x28,0x4d,0x85,0xb2,0x07, - 0x6a,0x5e,0xe2,0x69,0x6c,0x9c,0x7d,0x59,0xf6,0x7e,0x3a,0x7b,0xcd,0x36,0x54,0xa1, - 0x42,0xdf,0x76,0xfb,0x2b,0xd1,0xad,0x58,0xe2,0xe4,0x44,0xc4,0x70,0x9b,0x47,0x69, - 0x7e,0x03,0x5b,0x77,0xf4,0xa4,0x68,0xdb,0x1a,0x47,0x88,0x5d,0x4d,0xef,0xa6,0x46, - 0xa0,0x27,0x5b,0xee,0xdc,0x07,0xbc,0x1d,0xb8,0x15,0x14,0x3a,0x0b,0x6b,0x2a,0x19, - 0xfd,0x40,0xca,0x2e,0xb9,0x61,0x00,0xcf,0x6b,0x72,0x33,0xf2,0x7c,0x9c,0xb4,0x76, - 0xf2,0x72,0xe6,0x48,0xa5,0x70,0xa6,0x9e,0xca,0x8f,0xe1,0x0d,0xdd,0xe1,0x3a,0x40, - 0x8b,0x0d,0x0a,0xa4,0x16,0xf4,0x34,0x29,0x46,0xef,0x22,0x3f,0x64,0xab,0x16,0x3e, - 0xab,0x2e,0xc2,0x13,0xd2,0xc5,0x7b,0x37,0x0b,0x5a,0x3e,0xe5,0xe8,0xa9,0xd0,0xf1, - 0x1d,0xa2,0x8f,0x9b,0x19,0xb3,0x1f,0xd6,0x60,0xea,0x64,0x05,0x50,0xb7,0x4a,0x1c, - 0x83,0x97,0x33,0x4c,0x15,0xc5,0x75,0x56,0x20,0x24,0x12,0x1a,0xf4,0x15,0xca,0x54, - 0xba,0xe8,0x34,0x46,0x80,0x6e,0xd3,0xb2,0x33,0xc1,0xef,0x15,0xbc,0x26,0xa3,0x85, - 0xfd,0x83,0xa1,0xc9,0x55,0xed,0x7c,0x8c,0x6d,0xf4,0x40,0x70,0xcf,0xfd,0x06,0x94, - 0xed,0xc2,0x92,0x79,0x6a,0x01,0xcb,0x99,0xe1,0x46,0x84,0xac,0x59,0x60,0xb4,0xa9, - 0xa9,0xad,0xae,0x99,0x75,0x41,0xf6,0x40,0xce,0xd1,0x58,0x1d,0xed,0x3e,0x57,0xe1, - 0xf1,0xa9,0xeb,0x30,0x69,0x04,0x1a,0x5b,0x27,0xb2,0xa2,0xee,0x8e,0x89,0x38,0x6d, - 0xda,0xdd,0x27,0xa9,0xf6,0x2e,0x69,0x55,0x35,0xf7,0x4b,0x12,0x2b,0xe7,0x6a,0x44, - 0x80,0x0e,0x05,0xb5,0x0c,0x13,0x6c,0x33,0xca,0x24,0x5e,0x27,0xc8,0xcf,0x1d,0x23, - 0x47,0x67,0xcf,0xcc,0xe5,0x47,0x7b,0x88,0x81,0xc0,0x94,0xa3,0x17,0x0e,0x73,0xcf, - 0x97,0xb3,0xb7,0xb8,0xbf,0x7b,0xac,0xd1,0xaf,0xab,0x4c,0x9d,0x4c,0x92,0xb8,0x76, - 0x10,0xae,0xb8,0x95,0x8f,0x8f,0x7c,0x4d,0x71,0x78,0x90,0x62,0xce,0x31,0x64,0x4a, - 0x7a,0xee,0x36,0xa4,0xeb,0xbb,0x67,0xb9,0x37,0xe8,0xd1,0x9b,0xcc,0x62,0x31,0xcc, - 0xe4,0x7c,0x49,0xd9,0x4a,0xb0,0xd1,0x03,0x1b,0x37,0x82,0x21,0xd7,0xbe,0xd4,0x67, - 0xe5,0xf7,0x47,0xdf,0xcf,0x99,0xca,0xcc,0xc0,0x35,0x8e,0x6e,0x3c,0x91,0x8e,0x59, - 0x63,0xcd,0xc0,0xed,0xe7,0x4a,0x7e,0x2e,0x93,0x54,0xfd,0xbe,0x44,0x42,0xe9,0x56, - 0xe3,0x31,0x87,0x49,0x17,0xa1,0x1d,0x23,0x5a,0x1f,0x6c,0x73,0xf6,0x71,0xa6,0xd1, - 0xf8,0x61,0x27,0x49,0x6b,0x1c,0x1d,0x12,0x7b,0x83,0x09,0x39,0xd9,0xd8,0xf0,0xe1, - 0x89,0xb1,0x4c,0xbc,0x84,0xe9,0x35,0x86,0xbf,0x0f,0xe7,0x79,0xcc,0xd9,0xe1,0x7d, - 0xe7,0xf6,0xfa,0xeb,0x80,0xf0,0x3a,0xf0,0x6c,0x2b,0xe3,0xf9,0x33,0x59,0xcf,0x4b, - 0x19,0x9c,0x13,0x70,0x41,0x8b,0xdb,0x78,0xff,0xfe,0x7e,0x9e,0x7e,0x62,0x5e,0xc8, - 0x82,0x13,0x24,0x2e,0x1b,0xdd,0xeb,0x96,0xe9,0x3d,0xde,0xff,0x74,0xb1,0x6f,0x2c, - 0x68,0xa2,0x17,0xef,0x08,0x0d,0x02,0xa9,0x57,0x07,0xdd,0x77,0x8b,0x57,0xc5,0x7b, - 0xa9,0x5e,0x07,0x32,0x2d,0x5c,0x4d,0xac,0xd2,0x5b,0xec,0xa2,0xdf,0x73,0xff,0xbf, - 0xfc,0x89,0x6b,0x3a,0x48,0x97,0xbb,0x06,0x38,0xb6,0x9b,0xc8,0x48,0x65,0x57,0x0b, - 0xd6,0x16,0xb8,0x4a,0xdf,0xde,0x72,0xe3,0x14,0x25,0x5d,0xfa,0xc7,0x18,0x25,0x76, - 0xc1,0x82,0xf5,0xa9,0xa0,0x5e,0x81,0xb8,0x2b,0x97,0xc7,0x0d,0x83,0xf4,0x49,0x3e, - 0x62,0x3d,0xb1,0x2e,0x05,0xe5,0x4b,0xdd,0x12,0xfc,0xac,0x6c,0x3c,0x1f,0xce,0x9a, - 0x47,0x75,0x4b,0x72,0xa0,0x35,0xa7,0x1d,0x4a,0x83,0x3c,0xee,0xab,0x21,0x69,0xaa, - 0xf9,0xfa,0xd0,0xd1,0x7a,0x5d,0x1a,0x78,0xf3,0x23,0x0d,0xce,0x94,0x7d,0x39,0x21, - 0xa2,0x61,0xe7,0x3b,0x9d,0xa9,0x08,0xe7,0xc3,0xa9,0x90,0x62,0x07,0x31,0x8d,0x19, - 0x34,0x8d,0x17,0xaa,0x3b,0x74,0x9d,0x4f,0x51,0xcb,0x08,0x37,0xdb,0xe6,0xef,0xed, - 0xcc,0x1c,0x0a,0xa3,0x4e,0xb8,0x18,0x78,0xc6,0xa6,0x5e,0xe0,0x18,0xfa,0x21,0x43, - 0x8b,0x58,0x7a,0xa5,0x78,0xd1,0x7d,0x77,0x79,0xe1,0x1e,0x77,0x71,0xf5,0xfa,0x63, - 0x1c,0x10,0xd6,0xd4,0x90,0xea,0x32,0x4b,0xfc,0x54,0x11,0x6b,0xf3,0x74,0xea,0x5c, - 0x17,0x2d,0xaa,0x27,0x2b,0xcd,0xc9,0x6a,0x71,0x2b,0xc5,0x2e,0x93,0xc1,0x98,0x9e, - 0xdb,0xd7,0x33,0xd3,0xe7,0xa2,0x5e,0x8d,0x2b,0xe9,0xfc,0x93,0xf9,0x5f,0x05,0x6d, - 0x8c,0x6b,0x5f,0x84,0x4d,0x63,0xdb,0x29,0x0e,0x27,0xba,0xbb,0xfd,0xd0,0xe5,0xa1, - 0xcf,0xb5,0x98,0x56,0x96,0x00,0x93,0xa6,0xe6,0x29,0xe5,0x08,0xf4,0x1d,0x73,0xc4, - 0xeb,0x92,0xbf,0x2e,0xc2,0x30,0x86,0xed,0xa0,0x03,0xe3,0x71,0xbb,0x6a,0x92,0x70, - 0xb4,0xd4,0xd9,0xdd,0xc7,0x7c,0x96,0x20,0xe7,0x54,0xe3,0xa2,0x00,0x52,0xff,0x52, - 0x21,0x67,0x54,0x30,0x8b,0x2b,0x51,0xac,0x27,0x00,0xb8,0x85,0x9d,0xfa,0xd0,0x70, - 0x5e,0xa8,0x28,0x32,0x38,0x81,0x29,0x81,0x68,0xc7,0xbf,0xd4,0x95,0xc8,0xe3,0xc6, - 0xcc,0xb6,0x23,0xfa,0xde,0x1a,0xc8,0xe8,0xea,0x3e,0xc5,0x48,0x76,0xd1,0xaf,0xac, - 0x26,0xf0,0xa2,0x07,0xc9,0x9c,0xea,0xab,0x9a,0x94,0xb3,0xfb,0xf5,0x0d,0x87,0xeb, - 0x29,0x89,0x70,0x7e,0x10,0x2e,0x7f,0x54,0x7d,0xa2,0xbf,0xd3,0x7a,0x34,0xfc,0x67, - 0x14,0xde,0x92,0xca,0xe4,0x7e,0xe9,0x96,0x8e,0x1f,0xc7,0xa8,0xc9,0x4e,0x40,0x2c, - 0xc0,0x69,0x0e,0xd9,0x82,0x71,0x43,0x32,0x49,0xdf,0x15,0x30,0x26,0x24,0x57,0x67, - 0xfa,0xac,0x9b,0xad,0x90,0x79,0x5a,0xf9,0x62,0x13,0x67,0x6d,0xc5,0x7a,0xf3,0x5c, - 0x85,0xdf,0xdb,0x82,0x1a,0xfb,0xbc,0xb0,0xfd,0xc9,0xa9,0x6c,0xb4,0x20,0x1b,0x77, - 0x35,0xc0,0x98,0x47,0xc3,0x57,0xba,0xe3,0xb8,0x50,0xba,0xdd,0x6a,0x73,0x56,0xa4, - 0xd9,0xd9,0x2d,0x89,0x7d,0xbc,0x8c,0x96,0xd2,0x02,0x0e,0x73,0xa2,0x93,0x9e,0xe4, - 0xef,0x47,0xde,0x3b,0xa8,0xba,0x85,0xad,0xc8,0xb5,0x52,0x77,0xdf,0x91,0xc4,0x79, - 0xee,0x3f,0x3f,0x8d,0x0a,0x23,0x90,0x75,0xc9,0x1d,0x25,0x3f,0x51,0x3f,0x73,0x22, - 0x8c,0x74,0xd9,0x5c,0x9b,0xd6,0x29,0x22,0x20,0x71,0xe1,0xf1,0xa3,0xbc,0xd8,0x30, - 0x0b,0x0f,0x90,0xaa,0xd9,0x72,0x41,0x0d,0xd4,0x67,0x8a,0x9f,0x5b,0xec,0x21,0x4f, - 0xc0,0x71,0x1a,0x89,0x62,0x3a,0x66,0xfe,0xa8,0xe4,0x2b,0x2a,0xf7,0x83,0xa2,0xe4, - 0x6b,0x24,0x8c,0x53,0xe6,0x4f,0x54,0x4d,0xad,0x49,0x3c,0xb5,0xa0,0xc2,0x9b,0x4a, - 0xdd,0x98,0x3b,0xc7,0x52,0xd2,0xf3,0x68,0x60,0xf9,0xf9,0x86,0xa8,0x6f,0x55,0xdc, - 0x9f,0xb0,0xe0,0x20,0x66,0x31,0x4e,0x61,0xe7,0xc7,0xe8,0x6c,0xc2,0x1e,0x1d,0xb6, - 0x0d,0x59,0x53,0x96,0xa4,0x9b,0xad,0xb6,0xd2,0xa6,0x69,0xff,0xca,0xe4,0x1f,0x5a, - 0x5e,0x6c,0x56,0x95,0x1a,0x8a,0x42,0x3f,0xd1,0xf0,0xc5,0xcb,0x8a,0x97,0x4d,0x64, - 0x8f,0xb5,0xc8,0xfa,0x94,0x5c,0x80,0xff,0x6d,0x19,0x4e,0x5f,0x51,0x6c,0x1a,0x50, - 0xc9,0x8a,0xd7,0xa5,0x69,0x4e,0xeb,0xce,0x9a,0xbd,0xce,0x5c,0xa5,0xbf,0x3b,0xd5, - 0xb8,0x00,0x71,0x8b,0x2d,0x4d,0x41,0x0e,0x95,0x25,0xdc,0xff,0xc2,0xfd,0xc3,0x73, - 0xe2,0x0c,0x1c,0x31,0xc9,0x46,0x45,0xe3,0x76,0x9a,0xef,0xdf,0x48,0x19,0xec,0xfc, - 0xd9,0x2c,0xb1,0x4a,0x22,0x3d,0xe9,0xef,0x16,0xa3,0x23,0xec,0x1e,0xa4,0xf4,0xfd, - 0x3a,0x37,0x2a,0xb4,0xff,0xf9,0x68,0x58,0x13,0x4d,0x6c,0xfc,0x38,0x23,0x36,0xae, - 0xe0,0x92,0x1c,0x31,0x43,0xaf,0x5f,0x51,0x69,0x10,0x72,0x89,0xe9,0xa2,0x66,0x2c, - 0x29,0x2a,0xe2,0x0f,0xff,0x62,0xa4,0x6b,0xd4,0xc2,0xdb,0x71,0x6c,0xda,0x3c,0x3a, - 0x79,0x2e,0x0e,0x7c,0x1a,0xdd,0x96,0xe5,0x09,0x4e,0x71,0x7d,0xa2,0x54,0x10,0x4f, - 0x53,0x86,0x01,0x11,0x1c,0xb4,0xe1,0x02,0x61,0xd6,0xae,0xa7,0xe8,0xdc,0xe3,0xb2, - 0x8a,0xa1,0x13,0xe8,0x3d,0x75,0xe3,0xbf,0xf0,0x29,0x3d,0x6f,0xd1,0x2f,0x69,0x59, - 0x5e,0xc5,0xee,0x32,0xae,0xd3,0xe0,0xed,0x5f,0x5d,0xd5,0x34,0x87,0x23,0x6f,0x51, - 0x93,0x11,0xd8,0x3b,0x24,0xab,0x7e,0x53,0xf4,0x7f,0x61,0xef,0xe3,0x16,0x26,0x21, - 0x70,0x00,0xa1,0x71,0xe9,0x03,0xb0,0xbf,0x6c,0x81,0xdc,0xc1,0xfe,0xfa,0x7a,0x79, - 0x56,0x0e,0x13,0x29,0x96,0x92,0x5e,0x34,0xb0,0x7d,0xf8,0xb9,0xbc,0x03,0xa7,0xfa, - 0x42,0xed,0x16,0x3f,0x5f,0xa7,0x3c,0xbd,0x9f,0x75,0x9b,0xfc,0x38,0xbe,0xc6,0x9e, - 0xec,0x27,0x5a,0xe2,0x83,0xc7,0xe5,0x73,0x24,0xd5,0xa9,0x9c,0x74,0x0c,0x43,0x08, - 0xf3,0xf8,0x5a,0x49,0xa2,0x9f,0x58,0x13,0xde,0x8f,0x0b,0x2b,0xfc,0xf6,0xfc,0xee, - 0xdc,0x57,0xcd,0x0e,0xac,0x85,0x7b,0x1b,0x33,0xa0,0x45,0xf1,0x29,0x32,0xab,0xc1, - 0x71,0x05,0xe5,0x09,0x90,0x0e,0x00,0x82,0x61,0x51,0xe0,0xf2,0x16,0x1b,0x5b,0x21, - 0x84,0x51,0x80,0xa4,0xb1,0x40,0x33,0x0e,0x80,0x0c,0x77,0x37,0x25,0x5c,0x53,0xf5, - 0x22,0x0f,0xb3,0xc6,0xf4,0xf4,0x75,0x04,0xc8,0x22,0x11,0xc3,0x1d,0x5f,0xed,0x45, - 0xe6,0xee,0xe2,0x80,0xed,0x2b,0x80,0x0a,0x67,0x45,0xe4,0x04,0x1f,0xdd,0x2c,0xa4, - 0x33,0x88,0x19,0x61,0x5d,0x0b,0x3e,0x41,0x0c,0x33,0x26,0xf2,0x17,0xf6,0x60,0x89, - 0x03,0x42,0xd9,0x62,0xee,0x2d,0x63,0xb5,0xa6,0x9a,0x84,0xa8,0x42,0xa6,0x0d,0x47, - 0xf0,0x38,0x63,0xff,0xc2,0x40,0x29,0x21,0x36,0xdb,0xc3,0x09,0xea,0x55,0x80,0x67, - 0x58,0xdb,0xc3,0xbf,0x2b,0x48,0x99,0x18,0x8b,0x0d,0xe4,0x58,0x3e,0x55,0x88,0xf3, - 0x67,0xff,0x33,0x31,0x8b,0xb0,0x28,0xa6,0x4d,0xe6,0xa0,0xa1,0x07,0xa6,0x99,0x69, - 0xf5,0x2c,0x6e,0x32,0x43,0xd4,0x8e,0x30,0xb6,0x60,0x02,0xdb,0xa5,0xa9,0x54,0x30, - 0xea,0xc2,0x00,0xb4,0xd7,0x05,0x08,0xb0,0xbb,0x88,0x38,0xd0,0x35,0x04,0xe0,0xe8, - 0x8d,0xf1,0x06,0x05,0xf5,0x4c,0x81,0xfc,0x9b,0x08,0xd8,0x87,0xf5,0x59,0x10,0x93, - 0x67,0xa2,0x43,0xcd,0x22,0x64,0x0f,0xf8,0x3e,0x2f,0xb3,0x2d,0x44,0x14,0xac,0xb0, - 0x4b,0x69,0xbc,0x15,0x41,0x57,0x70,0x6d,0x15,0x9a,0x46,0xf0,0x21,0x10,0x46,0x35, - 0x09,0x11,0x3e,0x9c,0xd3,0x8a,0x68,0x68,0x14,0x8f,0x14,0x13,0xd1,0xe0,0x21,0x00, - 0x34,0xaa,0x10,0x87,0x42,0x4c,0x26,0xab,0x8a,0x9c,0xd5,0x9a,0x49,0x6a,0x18,0x8d, - 0x48,0xfa,0x54,0x98,0xbb,0x00,0x51,0xa7,0x4c,0xe2,0x03,0x7c,0xbf,0xb0,0x36,0xeb, - 0x5b,0xc7,0xce,0x7d,0x6c,0x76,0xec,0x9e,0xfd,0x74,0x45,0x7e,0x65,0xa9,0x05,0x0e, - 0xbc,0xe2,0xa0,0x7e,0xac,0xc1,0xe4,0xb9,0x4b,0xc2,0xe0,0x76,0xfa,0xa3,0xb0,0xb4, - 0xb8,0xd3,0xce,0x18,0x54,0x01,0xb4,0x63,0x20,0x4b,0x06,0x01,0xbc,0x95,0xda,0x67, - 0xf8,0xd5,0x34,0x90,0x7c,0xed,0x7a,0x96,0x6f,0x87,0x97,0x45,0x17,0x1f,0x99,0x02, - 0x1d,0x26,0xca,0x1b,0xfd,0xc2,0x00,0x30,0x50,0xa4,0x8a,0xc0,0x70,0xd1,0x38,0xd4, - 0x04,0x5d,0x86,0x83,0x01,0xe0,0x2b,0x85,0xe1,0x85,0x09,0x72,0xe9,0xf7,0x94,0xf9, - 0x76,0x8c,0xc7,0x7b,0x9b,0xe8,0x11,0x59,0xe6,0xb8,0x3a,0x3e,0xf5,0x81,0xf1,0x29, - 0x1f,0x8f,0x3f,0x45,0x8a,0xf1,0xd1,0xdb,0xfc,0x78,0x7b,0x1f,0xb8,0x08,0x17,0xcf, - 0x67,0x60,0xc7,0x7a,0xac,0xb9,0x0d,0x5e,0xdb,0xe9,0xee,0x87,0x32,0x51,0xfe,0x32, - 0x9a,0xb5,0xc8,0x4a,0x9c,0x8b,0xa0,0xdb,0xd5,0x90,0x47,0xb6,0x45,0x16,0xc5,0x2a, - 0x0b,0x0a,0x9c,0x2d,0xc3,0x81,0x58,0x47,0xc6,0x04,0x76,0x76,0xfb,0x4a,0x34,0x4e, - 0x1b,0x42,0x9d,0xef,0x47,0x2e,0xd8,0x2b,0xbf,0x64,0x11,0xd6,0x21,0xa1,0x3e,0xbc, - 0xbe,0x5b,0x8d,0x32,0x84,0x6b,0x64,0x4a,0x1f,0xc1,0x0f,0x33,0x8c,0x22,0x3c,0x1e, - 0x63,0x6f,0x50,0xcf,0x24,0xf0,0xbb,0x57,0x69,0xdc,0x02,0x7b,0x2c,0xcd,0x40,0xa4, - 0x9c,0xba,0xfd,0xf8,0x58,0xaf,0xec,0x32,0x8c,0x98,0x2c,0x64,0xc8,0x4d,0x4d,0x03, - 0xb2,0x46,0xa0,0x02,0xba,0x76,0x2a,0x58,0xfe,0xd7,0xee,0x30,0xcc,0x8f,0xac,0x13, - 0x59,0x7f,0xd9,0xf0,0x8c,0x34,0xa5,0xe6,0x66,0x4b,0xe9,0x3a,0xc4,0x3f,0x0d,0x19, - 0xf8,0x8f,0x36,0x18,0x87,0xbd,0x98,0x00,0xa1,0x0a,0x34,0xa0,0xe3,0xa1,0xfc,0x72, - 0x12,0x64,0xef,0xd6,0xd1,0x0e,0xfb,0xa0,0x7c,0xab,0x3c,0x2c,0xc2,0x9a,0x1e,0xc4, - 0x8b,0x8a,0xb8,0x64,0xf7,0x17,0x6e,0x66,0x92,0x71,0x43,0x82,0x93,0xe5,0xd0,0x97, - 0x79,0xa5,0x39,0x55,0xb2,0xb3,0x50,0x17,0x13,0x42,0x4a,0x1a,0x80,0x2a,0xa3,0xc1, - 0x32,0xae,0xd0,0xe8,0xb3,0x20,0x7e,0xd3,0xc8,0x40,0x49,0x5f,0xae,0x11,0x5f,0xbd, - 0x83,0xc2,0x64,0x78,0xed,0x17,0x80,0x10,0x38,0x49,0xc7,0x79,0x56,0xd4,0x96,0xe6, - 0x19,0xf2,0x24,0xc7,0x4b,0xde,0x35,0x01,0x27,0xc9,0x8e,0xb3,0x75,0x8f,0x30,0xac, - 0x7a,0x3b,0x30,0x50,0x14,0x18,0x51,0xeb,0x79,0xf5,0x5b,0x8e,0xa0,0xd2,0x1d,0x10, - 0x10,0x4c,0xf9,0x10,0xe5,0x50,0x40,0x9e,0x59,0x22,0xca,0x3b,0x60,0x30,0xc9,0xdf, - 0x4f,0x3e,0x82,0x74,0x13,0x5b,0x4e,0x19,0xc3,0x9a,0x94,0x32,0x57,0x6e,0xe7,0x94, - 0xc3,0x80,0xfd,0x5c,0xe1,0x0c,0x6c,0x1f,0x2f,0x18,0x2a,0x37,0xae,0xb9,0xd0,0xa1, - 0xe3,0x45,0x0c,0x45,0x10,0xa1,0xd7,0xfc,0x98,0x3c,0x95,0xc1,0x8c,0xdb,0xab,0x91, - 0x9e,0x18,0x35,0x7e,0x96,0xb8,0x36,0xdb,0x1d,0xfc,0xc4,0xc6,0x72,0xe5,0x2e,0xae, - 0x7b,0x2b,0x12,0x20,0x6b,0xe5,0xfc,0x63,0x02,0x39,0x33,0xc6,0x90,0xae,0x07,0x5f, - 0x39,0x00,0x77,0x96,0x0d,0x9f,0x81,0xe9,0xe8,0x5a,0x9b,0xb6,0x5a,0xc1,0x20,0x20, - 0xd6,0xe7,0xdb,0xb7,0xd5,0x87,0xda,0x1a,0x80,0x75,0x29,0x64,0x07,0x93,0x33,0x48, - 0x32,0x59,0xdd,0x6f,0xe8,0x18,0xa6,0x07,0xaf,0x4c,0xdf,0x85,0x4a,0xa9,0xd0,0xae, - 0x19,0x47,0x5d,0xd8,0x43,0x32,0xcb,0x21,0x87,0xea,0x2c,0xa2,0x11,0x9a,0x87,0x82, - 0x16,0x67,0x50,0x8b,0xe5,0x96,0x28,0x52,0x33,0x0d,0x53,0x6c,0xee,0xca,0x8c,0x7b, - 0x3e,0x5b,0x03,0x83,0x3f,0xc0,0xeb,0x59,0xbc,0xe3,0x65,0x76,0xec,0xec,0x11,0x4f, - 0x3f,0xb8,0x42,0x21,0x21,0x3f,0x1e,0xa2,0x26,0xe7,0xcb,0x84,0x34,0xd6,0x5f,0x2d, - 0xfe,0x26,0x4e,0x28,0x54,0x98,0x5c,0x0c,0x70,0xc9,0x98,0xa2,0x44,0x20,0x55,0x55, - 0x4e,0x00,0x95,0x62,0x25,0x39,0x11,0x3c,0x0c,0x24,0x42,0x85,0x6b,0xa5,0xc5,0x29, - 0x4c,0xbb,0xdc,0x8b,0x8a,0x3e,0x55,0xda,0x82,0x7d,0xb5,0xf7,0x3d,0x2b,0xe7,0x78, - 0xa0,0xcb,0x2a,0x59,0xb4,0xcf,0xb8,0xb8,0x8f,0xf4,0x24,0x09,0x76,0x32,0xf2,0xc6, - 0x26,0x19,0xbd,0x8d,0xe6,0x07,0x83,0x53,0x59,0x94,0xad,0xc5,0x96,0xb0,0x0d,0x14, - 0x0b,0x3b,0xd5,0x08,0x19,0x29,0x3d,0x4b,0x17,0xa0,0xeb,0x58,0x6a,0xb8,0xca,0xf9, - 0xd6,0xed,0xed,0x4d,0x60,0x15,0x1d,0x9c,0xae,0x26,0x72,0xe4,0x88,0xde,0x75,0xf9, - 0x9f,0x0d,0xb8,0xb3,0x3b,0x58,0xd0,0x3c,0xb4,0x0f,0x67,0x2a,0x18,0x86,0x5c,0xa5, - 0x9c,0xdb,0x46,0x8f,0x57,0xc7,0x7c,0x3b,0xb0,0xcc,0x65,0x93,0x4d,0x1d,0xd7,0x29, - 0xf3,0x8b,0x40,0x3f,0x9f,0xe2,0xd1,0xbc,0xb6,0xb6,0x1d,0x14,0x0b,0x38,0xb5,0x82, - 0xd2,0x22,0xd5,0x0a,0x60,0xb6,0x51,0xd7,0x27,0x7a,0xa2,0x06,0x84,0xa1,0xd9,0x57, - 0xd4,0xbe,0xc2,0xd2,0x5c,0x78,0xf0,0xbc,0x93,0xf7,0x5c,0x1e,0x52,0xea,0x1c,0xad, - 0xf0,0x33,0x7e,0xc5,0xcf,0x6b,0x82,0xa7,0x48,0x9e,0xc9,0x85,0xba,0x9d,0xae,0x69, - 0x92,0xbd,0xeb,0x7f,0xe0,0xfe,0x85,0x49,0x79,0x2c,0x42,0xe2,0xbb,0xff,0xce,0xc0, - 0x47,0x15,0x22,0x43,0x4d,0xd1,0x70,0x9d,0xd5,0xc4,0x02,0x9b,0xed,0x09,0x31,0xbb, - 0x93,0x69,0xc4,0x38,0xf6,0xdb,0xd2,0xd9,0x18,0x20,0x10,0x60,0xbb,0x35,0x18,0x33, - 0x2a,0xc9,0x42,0x87,0xcd,0x7f,0xa4,0xa0,0x05,0x1f,0xcc,0x20,0x48,0xe9,0xdd,0xac, - 0x52,0x84,0x2a,0x4b,0x13,0x79,0xdb,0x4f,0xfd,0x81,0x8d,0x92,0xa9,0xa5,0x80,0x4c, - 0x04,0xb8,0xa8,0x42,0x69,0x30,0xe5,0x8d,0xf0,0xb0,0x4f,0x85,0x19,0xa2,0x4f,0x01, - 0xd4,0xdf,0x76,0x43,0x06,0x86,0xf6,0xac,0xfa,0x43,0xff,0xf6,0xfa,0x61,0x8c,0x51, - 0xe5,0x61,0x57,0x80,0x4d,0x29,0x21,0x0f,0xfd,0xbf,0xc0,0x5f,0x0c,0xca,0xcb,0x30, - 0xe2,0x95,0x5f,0xc7,0xec,0xed,0x50,0x9b,0x5b,0x02,0xa4,0x8f,0xd6,0xa3,0xa1,0xa9, - 0xcf,0x12,0x92,0x59,0xc6,0x10,0x68,0xf5,0x55,0xa8,0x4c,0xab,0x73,0x10,0x59,0x7d, - 0x74,0xb8,0xc5,0x88,0x2f,0x22,0x63,0x90,0x22,0x45,0xe9,0x72,0xc4,0x1c,0x21,0x34, - 0x57,0x76,0xd1,0xdd,0xb6,0x82,0x26,0xbf,0x84,0x57,0x1f,0xc4,0x41,0xd5,0x28,0x5f, - 0xa8,0x50,0xa9,0xfb,0xc8,0x4f,0x24,0x7e,0x76,0xb5,0x69,0x01,0x6b,0x13,0x14,0xba, - 0x92,0xad,0x6c,0x7e,0x75,0x50,0xc9,0x74,0x2a,0x89,0xc5,0x7a,0xef,0x43,0xf0,0x2d, - 0x51,0xe7,0xd4,0x76,0x82,0x36,0xf4,0x8f,0x0e,0x25,0x56,0x46,0xfc,0x42,0x71,0x2e, - 0x90,0x75,0x1b,0x76,0x72,0xd5,0x2e,0x2b,0x98,0x0d,0x01,0x33,0x6f,0x89,0x9f,0x2a, - 0x16,0xd2,0x7c,0x2b,0x1d,0xca,0xae,0x2a,0x5b,0x91,0x9c,0xeb,0x97,0xb7,0x46,0x1c, - 0x8a,0x4e,0xb5,0x64,0x72,0x21,0x0b,0x86,0x64,0xab,0xc3,0x29,0x2c,0xe7,0xa3,0xe7, - 0x3c,0x8b,0x56,0xbb,0x31,0x41,0x17,0x97,0x24,0x23,0xcb,0x3c,0xe9,0x34,0x77,0xe3, - 0x33,0x13,0x77,0x84,0xa1,0x4b,0xf3,0x5c,0x2e,0xe9,0x5e,0x32,0x72,0x36,0xa4,0x34, - 0x3b,0x67,0x59,0xd1,0x3a,0x59,0xb6,0x59,0x29,0x0e,0x53,0xca,0x62,0xd5,0x24,0xd9, - 0x55,0x90,0x27,0x2a,0xa6,0x5f,0xdb,0xcf,0x0b,0xe9,0x69,0x02,0x48,0x6a,0xf6,0xea, - 0x1a,0xac,0xe5,0xb7,0x27,0x3c,0xd3,0xe6,0xcf,0xc6,0x17,0x69,0x80,0xb8,0x55,0xf3, - 0xde,0x92,0xcd,0xd0,0x2f,0xb1,0xc7,0xc7,0x62,0xac,0x02,0x6f,0x69,0x3c,0x90,0xc8, - 0x7c,0x6a,0x95,0x77,0x60,0x74,0xe6,0xba,0x4d,0x0b,0x7f,0xf1,0xf4,0x98,0x92,0x5d, - 0x26,0x2d,0xc4,0xa4,0xf1,0x75,0xc3,0xa5,0x29,0x56,0x77,0x68,0xdd,0xbe,0x0f,0x10, - 0xb8,0x97,0x5f,0x55,0x64,0x89,0x0e,0xed,0x7d,0xb1,0x36,0x9c,0x33,0xc7,0xde,0xec, - 0x9b,0xf3,0xf0,0x42,0x6d,0xa3,0x52,0xe0,0xad,0x8e,0x5d,0x0f,0x06,0x53,0xba,0x3d, - 0xd2,0x6c,0x96,0x87,0x96,0x92,0xc7,0x06,0x71,0x73,0xaa,0xd9,0xe6,0x77,0xa7,0xe3, - 0x70,0x1a,0xd7,0xa0,0xb3,0xc8,0xf3,0x31,0xf1,0x27,0xeb,0xf7,0xa3,0x81,0xdb,0x72, - 0x0d,0x38,0xac,0x51,0x02,0x86,0x51,0x65,0x56,0x24,0xcb,0xeb,0xe4,0xda,0xb8,0x09, - 0x23,0xef,0x67,0x9b,0x6c,0xc9,0x5e,0x36,0xf9,0xeb,0xdf,0x96,0xb7,0xfd,0xd6,0xac, - 0x6c,0x98,0xd3,0x44,0xba,0x0e,0xce,0xe4,0x18,0x72,0xe4,0x21,0xa0,0x39,0x31,0x61, - 0x03,0xcc,0x30,0x08,0x44,0xe2,0xc1,0x88,0x50,0x88,0x16,0xf6,0x05,0xb2,0xe6,0x12, - 0xb1,0xa5,0x37,0xb9,0x58,0x17,0x0c,0x42,0x0b,0x8a,0x04,0x59,0x86,0x44,0x97,0x38, - 0xdb,0x43,0x90,0x0a,0x4e,0x43,0x9c,0x1e,0x32,0xb1,0xeb,0xc1,0x20,0x73,0x5f,0x11, - 0x1a,0x9d,0xc7,0xea,0x40,0x3f,0xae,0x3a,0xc4,0x3f,0x2f,0x16,0x10,0x45,0x23,0x54, - 0xb5,0xec,0x16,0xdb,0x92,0x54,0x45,0xd2,0x88,0x00,0xca,0x8f,0x5b,0xcf,0x80,0x25, - 0xdf,0xed,0xbd,0x63,0x7a,0x1a,0x7a,0xcd,0x01,0x63,0x7d,0x70,0xe9,0xe6,0x72,0x4d, - 0xf2,0x1d,0x41,0xa8,0x4a,0xac,0x47,0x64,0x7a,0x32,0x80,0xc2,0x6e,0x1e,0xc8,0x11, - 0xd4,0x60,0x11,0x05,0x52,0xdd,0xc4,0xff,0x17,0x2d,0xb8,0xb6,0x09,0xbf,0x24,0x6a, - 0x8f,0x58,0xfb,0xb4,0x7f,0xe7,0xeb,0xc7,0x94,0x2e,0x86,0x30,0x37,0x7e,0xf3,0xc8, - 0x7c,0x48,0x0f,0x66,0xc1,0x9a,0x52,0xf8,0x5f,0x02,0x4f,0xda,0xc0,0x70,0xda,0xc1, - 0x8c,0x1a,0x93,0xfd,0x27,0x5c,0x60,0xcd,0x62,0x34,0x8c,0xd4,0x64,0x7e,0x29,0x48, - 0x22,0xd9,0xef,0xe0,0x4d,0xd7,0x38,0x3e,0x95,0xbc,0x6a,0x1f,0xd5,0x3a,0x1a,0xcb, - 0x94,0xfd,0xd7,0xf0,0x47,0x20,0x3b,0x27,0xb6,0x3a,0x9c,0xba,0x42,0xb1,0x1d,0x26, - 0xcc,0x28,0x64,0x4d,0xf2,0xb7,0x24,0xd6,0x1c,0x75,0x20,0x21,0xb1,0xb9,0x79,0x36, - 0x7a,0xa7,0x2a,0x46,0x71,0x97,0x6f,0x74,0x86,0x57,0xe2,0x76,0xaa,0x81,0x88,0x70, - 0x8d,0x14,0x87,0x3c,0x40,0xd2,0x2e,0x4d,0x17,0xaf,0x8e,0x37,0x23,0x6f,0xfc,0x09, - 0xe8,0x26,0x4d,0xd6,0xdf,0x92,0xff,0x46,0x42,0x0a,0xfa,0x37,0x0a,0x47,0x60,0xe2, - 0xe3,0x47,0x7a,0xcf,0x85,0xa4,0x6f,0xbe,0x74,0x19,0xe5,0xa4,0x13,0x5d,0xc9,0x8d, - 0x15,0xc0,0x22,0x1b,0x87,0xd1,0xf1,0xff,0x49,0x0e,0x9d,0x12,0x4a,0x89,0x05,0x60, - 0x8e,0xf3,0x76,0x9c,0xdc,0x36,0x48,0x7c,0xf9,0x91,0x16,0x36,0x95,0x5b,0x0a,0x70, - 0x50,0xb9,0x96,0x33,0x3f,0x65,0xf7,0x38,0x58,0xa9,0xdd,0x5d,0x08,0x64,0xf1,0xe0, - 0xc2,0x8a,0xac,0xf3,0xfd,0xf0,0x8f,0x5a,0x84,0x50,0x39,0xf3,0x37,0x47,0x42,0xc9, - 0x0e,0x51,0x33,0x9f,0xbf,0x1e,0xab,0x26,0x8b,0xc6,0x06,0xb5,0x08,0x95,0x65,0x09, - 0xf3,0xea,0x36,0x4b,0xf8,0xd9,0x9c,0xda,0x78,0xa4,0x75,0x19,0xe5,0xa5,0x99,0xae, - 0xed,0xa7,0xb1,0xb4,0xee,0x64,0x3b,0xf1,0x53,0xe3,0x81,0xfd,0xa0,0xe9,0xe9,0x94, - 0x4b,0xcd,0xb4,0x59,0x70,0xec,0x0a,0x92,0x5a,0x2b,0xec,0x8e,0xfe,0xbc,0xf5,0xc3, - 0xd6,0x6b,0xae,0x8b,0xf6,0xc9,0xe6,0x37,0x57,0xc1,0xe8,0xb0,0x66,0x13,0x5e,0x0e, - 0x68,0xd0,0x32,0x46,0x0f,0x3a,0x67,0xd9,0xda,0x76,0x53,0xd6,0xce,0x42,0xe5,0x0f, - 0x76,0x15,0x61,0x29,0x44,0x6d,0x84,0xdf,0x87,0x3b,0xa4,0xcb,0xaf,0x24,0x72,0x15, - 0x61,0x65,0x2d,0x69,0x60,0xd0,0xbc,0xff,0x08,0xe3,0x68,0x88,0x0c,0xd5,0x61,0x36, - 0xdc,0x47,0x04,0x47,0x8a,0x10,0xfe,0x5d,0x92,0xc6,0xb1,0x22,0xd5,0xdf,0x0a,0xe9, - 0x3d,0xac,0xf2,0xeb,0x90,0x79,0x5b,0x76,0xec,0x20,0xa6,0x31,0x1d,0x21,0x5a,0x7e, - 0xe0,0x53,0xd5,0x8c,0xa4,0xd9,0x77,0x74,0x99,0x33,0xb4,0x74,0x70,0x4a,0x35,0x0a, - 0xa0,0x7e,0x99,0x98,0x09,0x2e,0xbd,0x4a,0x7a,0xae,0x6e,0x29,0x05,0x4a,0x99,0x7b, - 0x51,0xa1,0xb9,0x79,0x70,0x39,0x5b,0x71,0xd3,0x19,0xb6,0x74,0xe7,0x59,0x26,0xeb, - 0x74,0x97,0x6c,0x6d,0xd4,0xb8,0xbe,0x48,0x69,0x7b,0x05,0x22,0x72,0x92,0xce,0xd5, - 0xe1,0x45,0x30,0xe6,0xc9,0x16,0xc1,0x61,0x13,0x95,0x8c,0x90,0xb6,0xb9,0xd2,0xec, - 0xc1,0xd8,0x38,0x0d,0x8f,0x83,0x0e,0xca,0xd4,0x2b,0x7a,0x44,0xb5,0x81,0x77,0xab, - 0xe0,0x87,0xc4,0x50,0xc6,0x5f,0xa8,0x91,0x85,0x49,0xd3,0xaa,0xed,0x30,0x60,0xe4, - 0xc0,0xa0,0xa1,0xed,0x50,0xe0,0x27,0xdb,0x3f,0xfb,0xb9,0xa7,0x42,0x57,0x1e,0x10, - 0xa0,0x8b,0x9f,0x64,0x97,0x7c,0x1d,0xda,0xa9,0x16,0x5c,0x55,0x7e,0x3b,0x48,0x57, - 0xc2,0xa2,0xa9,0xbf,0x5e,0x44,0xfd,0xf5,0x57,0xca,0xb4,0xfb,0x9a,0xa6,0x24,0x5f, - 0xc3,0xee,0xa0,0x55,0x1f,0x74,0x08,0xa9,0x95,0x0e,0x2b,0x0e,0x28,0x87,0x75,0x43, - 0xc1,0x6a,0xbe,0xd5,0x06,0xf9,0x04,0x47,0xd9,0x17,0xd1,0xcd,0xc5,0xba,0xa8,0x5c, - 0x0d,0xcd,0x7b,0x5b,0xa1,0xf4,0xef,0x41,0x0d,0x51,0x5c,0xca,0x67,0x3f,0xd1,0x03, - 0xa8,0xb9,0x6d,0xbf,0x24,0xea,0x86,0x76,0x27,0xa4,0xce,0xdf,0x3c,0x27,0x3f,0x20, - 0x7c,0xb5,0x70,0x3f,0x07,0x7b,0xce,0x93,0x1d,0x55,0x59,0x48,0xa2,0x07,0xdd,0x6f, - 0xb9,0x74,0xb1,0x34,0xdb,0x17,0x33,0x7c,0xd9,0x19,0x67,0x30,0xee,0xfd,0x81,0xd4, - 0x48,0x58,0x21,0x5e,0x7c,0x54,0xa8,0x62,0x57,0x82,0x20,0x45,0xb2,0x7f,0x46,0x05, - 0x28,0xf1,0xa2,0xb4,0x85,0x55,0x69,0xc8,0xc6,0xc9,0x19,0xd3,0xb0,0x13,0x3d,0x97, - 0xb7,0x4d,0x17,0x99,0xba,0x0a,0xfa,0x24,0x61,0xbb,0xf8,0x9b,0xea,0x77,0x52,0xf7, - 0x9f,0x38,0xa5,0xfc,0xf8,0xf9,0x7c,0xd8,0x00,0xb2,0x83,0x6c,0x18,0x78,0x7e,0x33, - 0x51,0x00,0xc8,0xd2,0x99,0x00,0xea,0xf5,0x01,0xbc,0xaf,0x7d,0xae,0x9c,0x4f,0x7a, - 0xa9,0xaf,0x9f,0xcc,0x65,0x94,0xa0,0x18,0xf2,0xde,0x7e,0xb1,0xb4,0x6a,0x7e,0xf3, - 0xa2,0xb9,0x28,0xcc,0x82,0xd2,0x34,0x74,0xea,0x8d,0x84,0x4e,0x7d,0xea,0xc6,0x53, - 0x37,0x9f,0xba,0xf5,0xd4,0xed,0x03,0xca,0xb8,0x3e,0x8d,0x4c,0xd7,0x56,0xaa,0x51, - 0x05,0xe5,0xed,0x24,0xf3,0xd0,0x99,0x4f,0xbf,0xf6,0x2b,0x4d,0x67,0x6d,0xd4,0x7b, - 0x69,0x1e,0x8e,0x4b,0x23,0x82,0x11,0x53,0x02,0xe9,0x19,0xdb,0xa1,0x7d,0x25,0x42, - 0x4b,0xc4,0xc6,0xb9,0x52,0x81,0xe6,0xe8,0x35,0x8c,0xbb,0xb8,0x8c,0x74,0xab,0x2c, - 0xcb,0xa2,0x6b,0xa4,0x71,0xbc,0xed,0x22,0xb7,0xe2,0xcf,0x11,0x2c,0xbb,0xc3,0xdc, - 0x78,0xd6,0x9c,0xc2,0x3b,0x50,0x57,0x3d,0xbe,0xc1,0xfc,0x47,0x83,0x64,0x3b,0xb4, - 0x9c,0x24,0xbf,0x89,0x9f,0x98,0x9a,0xb5,0xac,0x46,0x5d,0xac,0x01,0x18,0x8c,0x12, - 0x85,0xc5,0xf7,0x54,0x0d,0x76,0xde,0x9b,0xe3,0x89,0x82,0xb8,0xf2,0x14,0xbc,0x9d, - 0xf9,0x3b,0x71,0x02,0xcf,0x23,0x27,0x21,0x28,0x67,0xea,0xc7,0x04,0x0c,0x6e,0x54, - 0xd2,0xff,0x5b,0x63,0x58,0x53,0xda,0x04,0xe6,0xdd,0x2c,0x71,0xf0,0xf7,0x8a,0xac, - 0xa2,0xb6,0x62,0x2b,0xf6,0xe8,0x41,0xac,0x3b,0x16,0x62,0x6f,0x0e,0xdb,0x28,0x11, - 0x22,0xd0,0x6a,0xb5,0x51,0xc6,0x45,0x7e,0x18,0x99,0xf9,0xab,0xf5,0x84,0x38,0x51, - 0xab,0x8f,0x4a,0x45,0xa2,0x97,0x7c,0x8b,0xcb,0x3c,0x52,0x0b,0x7f,0x35,0x1f,0x70, - 0xe7,0xa0,0xdc,0x22,0xd9,0x19,0xd4,0xe8,0xca,0x12,0xc7,0xf5,0x06,0x07,0xd7,0xdb, - 0x98,0x2d,0x52,0x95,0x4c,0x63,0x7a,0x66,0x05,0xb3,0x48,0x26,0x5b,0x1b,0x2b,0x05, - 0xb4,0xb4,0x9a,0xcd,0x0b,0x69,0x0e,0x4b,0x13,0x1e,0x2e,0x7b,0x0b,0x3b,0x78,0x7c, - 0x65,0xc0,0x42,0x39,0x15,0x0a,0x8c,0x91,0x3e,0xa2,0x9f,0x14,0x7e,0xa3,0xe8,0x81, - 0x85,0xcd,0xb3,0xd6,0xd7,0xe7,0x42,0xc9,0xfc,0x09,0x4b,0x13,0x3d,0x35,0xca,0xcb, - 0x4d,0x97,0xa2,0x34,0x4b,0x3e,0x47,0x06,0xa6,0xeb,0xb3,0x9f,0x8d,0xda,0x38,0x9b, - 0xbf,0x7d,0x66,0x5e,0xa9,0x73,0x14,0x18,0xd9,0xab,0xcb,0x2f,0x0d,0x3e,0x01,0xe1, - 0xe8,0x4a,0x3a,0x86,0xc6,0x21,0xea,0x57,0x66,0x7c,0x0b,0x43,0xf5,0xa5,0xc7,0x8c, - 0xe0,0xcb,0x49,0xb1,0x0f,0x1d,0x71,0x39,0x39,0xa7,0xab,0xff,0x3d,0xec,0x3e,0x14, - 0x1b,0x19,0xb9,0x7e,0x08,0xcf,0xbd,0x0a,0x98,0xf7,0xe5,0xa1,0xd7,0x43,0x42,0x0d, - 0x73,0x3f,0xc7,0xf2,0x4a,0xa5,0xfc,0x5c,0xc5,0x5c,0x8a,0xec,0x44,0x5b,0x72,0x7c, - 0x0d,0x2f,0xca,0x9a,0x7f,0x62,0x6b,0xaa,0xb4,0xeb,0xcb,0xee,0x65,0x96,0xa3,0x59, - 0xee,0xe9,0xb9,0xa2,0xd1,0xe6,0xfa,0x50,0x04,0x07,0xf9,0x39,0x7b,0xba,0x85,0xbc, - 0x4b,0xa6,0x83,0x07,0x4c,0xf6,0xa0,0x71,0x91,0x90,0x5a,0x72,0x93,0xf5,0xd1,0xde, - 0x24,0xe3,0xf7,0x8f,0x4a,0xc1,0xbe,0x01,0xbf,0xed,0x8d,0xdc,0x8a,0xc0,0x20,0x40, - 0x82,0x4a,0xa3,0xe1,0x97,0xed,0xf8,0x9c,0x44,0xe6,0x53,0x16,0x91,0x43,0x5f,0x3b, - 0x4f,0x39,0xd8,0x3c,0x2c,0xb1,0x7b,0x9b,0xc2,0xa9,0x60,0x95,0xb9,0x5b,0x61,0x08, - 0xc1,0x26,0xee,0x94,0xe5,0xce,0x9c,0x51,0xa9,0x23,0xbb,0xb7,0xa9,0x16,0x97,0x92, - 0x9b,0x45,0x61,0x9f,0x94,0xe4,0x5b,0x19,0x02,0xa4,0x20,0x56,0xab,0xee,0x97,0x4e, - 0x76,0x8f,0x82,0x5a,0x90,0x59,0x76,0x69,0x83,0x29,0xcb,0xc3,0x2d,0x3c,0xaa,0xa4, - 0xdf,0x7c,0x42,0x1d,0x6f,0xab,0x0c,0xb4,0x3e,0xaf,0x47,0xd6,0x7a,0xc1,0xb8,0xdb, - 0x75,0xf7,0xc5,0xe4,0x80,0x67,0xf2,0x78,0x50,0x6e,0x29,0x0f,0x95,0x0f,0xe1,0xbc, - 0x65,0x0f,0x2f,0xb8,0x3c,0x6e,0x1e,0xf6,0x54,0xb9,0xbf,0x15,0x9f,0x50,0xb5,0x75, - 0x71,0x42,0xb5,0xd6,0xe5,0x66,0xfd,0x10,0xde,0x67,0xf6,0x96,0x57,0xdf,0xba,0x3a, - 0xa1,0x46,0xeb,0xfa,0x84,0x9a,0xad,0x9b,0x13,0x6a,0xb5,0x6e,0xf7,0xd4,0xfe,0x7d, - 0x0b,0x86,0x22,0xa7,0xe9,0x27,0x8e,0x04,0x08,0x22,0x02,0x29,0xed,0x8e,0xd0,0x19, - 0xca,0xf0,0x66,0xf8,0x84,0xf2,0x29,0xd0,0x0d,0x45,0xd5,0xc8,0x2b,0x12,0x90,0x04, - 0x7b,0xa1,0x37,0x03,0xaf,0x81,0x35,0x6b,0x87,0x68,0xb9,0x2b,0xbb,0xe4,0xc3,0xe2, - 0xfe,0x77,0x15,0xb2,0x40,0xe4,0xc7,0x6f,0x9a,0x91,0x91,0xf3,0x60,0xb3,0x94,0x75, - 0x46,0x51,0x96,0x87,0x10,0xcb,0xda,0xa6,0xeb,0x9c,0xfa,0x37,0x9f,0x11,0x17,0x51, - 0x4d,0xb7,0x1f,0x00,0xcf,0xc4,0x7f,0x54,0x4f,0x71,0x80,0xda,0x87,0xaf,0xce,0xab, - 0xae,0xfb,0x73,0xae,0x12,0x40,0xea,0x68,0x31,0x93,0x3c,0x83,0xe9,0x33,0xfe,0x93, - 0x62,0x27,0xd3,0x19,0x61,0xcf,0xdc,0xbb,0xf3,0x54,0x98,0x24,0x1a,0x7c,0x37,0x67, - 0x6a,0x63,0xc8,0xf1,0x24,0x5d,0xa4,0x51,0x93,0x30,0x11,0x3f,0x21,0x38,0x64,0x21, - 0x98,0x12,0xef,0x31,0x34,0x5a,0x72,0x20,0x89,0x2f,0xee,0x9a,0x0e,0x8f,0x41,0xb4, - 0x95,0xa4,0xcc,0x2e,0xc1,0x87,0x9c,0xf4,0xe1,0xd9,0x6f,0x08,0xd6,0xe1,0xa3,0x68, - 0xa6,0xd0,0xe2,0x71,0xa6,0x46,0x41,0x39,0x53,0x4e,0xa8,0x68,0x47,0xa7,0xd9,0x97, - 0xb3,0x37,0x47,0x28,0x76,0x69,0xad,0xc3,0xd7,0xf8,0x14,0x00,0x4e,0x95,0x64,0x13, - 0x2c,0x14,0x86,0x19,0xeb,0x32,0x75,0xb3,0x9d,0x0d,0xde,0xb6,0x74,0x14,0x2d,0x4e, - 0xd3,0xfe,0x1f,0x9f,0x67,0xb7,0x81,0x73,0xd6,0x7e,0x0b,0x1c,0x55,0x8b,0x66,0xd1, - 0xeb,0xb0,0x19,0xfc,0x4d,0x66,0xd9,0x29,0x2c,0xc1,0xf5,0xf8,0xbc,0xd4,0x61,0xb6, - 0x15,0xc8,0x6c,0x73,0x8d,0xbc,0xd1,0xba,0x52,0x7e,0x8c,0x66,0x1e,0xdb,0x45,0x44, - 0x07,0xfb,0xbe,0xdb,0x91,0x1b,0x12,0x55,0xbf,0x9e,0x71,0x49,0x70,0x68,0xd4,0x38, - 0xbd,0x80,0x90,0xb1,0x0a,0x55,0x7c,0x93,0xf5,0xd5,0x0e,0x7e,0x12,0x14,0x49,0x02, - 0x0a,0x7d,0x87,0x8e,0xab,0x5d,0x31,0x2c,0x93,0xbf,0x8c,0xd6,0xb0,0xcc,0xa1,0xe5, - 0xa9,0x8b,0xb5,0x8e,0xcf,0x18,0xe7,0xc5,0x2b,0x1d,0x47,0x73,0xdf,0x74,0xc7,0xca, - 0x0d,0x69,0xff,0x43,0x3d,0x32,0x25,0xef,0xe5,0x71,0x63,0x47,0x53,0x84,0x87,0x3b, - 0x9c,0xc5,0xa6,0x38,0xec,0xbf,0x49,0x39,0x6d,0xbe,0xf2,0x16,0x26,0x40,0x1b,0xe7, - 0xa3,0x98,0xe6,0x4f,0x3e,0x46,0xfd,0x2e,0xdf,0xbb,0x94,0xcf,0x29,0x37,0x97,0x64, - 0x6e,0x3d,0x40,0xdb,0xcc,0xf7,0x07,0x72,0xa2,0xf7,0xa1,0xc9,0x10,0xee,0xd8,0x54, - 0xfc,0xcd,0x18,0x5d,0x6f,0x70,0x09,0x24,0x69,0xc3,0x72,0xe8,0x99,0x48,0xf1,0xb3, - 0xac,0x74,0xfc,0xc5,0x83,0x7d,0x55,0x38,0x64,0x97,0x4f,0x53,0x52,0x76,0x73,0x14, - 0x49,0xbb,0xe6,0x58,0x04,0xb8,0xbc,0x7d,0xa7,0x34,0xc6,0x03,0xcc,0x3a,0x5a,0x5d, - 0xa4,0x1c,0xc5,0x1b,0x09,0xe7,0x3d,0xef,0xfd,0x03,0x39,0xb3,0x7a,0xe7,0x26,0xb7, - 0xb2,0xde,0xb7,0x8d,0xcf,0x92,0x99,0x92,0xff,0xbb,0xf9,0xfe,0x58,0x8a,0x8f,0xaa, - 0xd6,0xd2,0x16,0x48,0x63,0x37,0xaa,0x78,0x3e,0x66,0x5f,0x92,0xf6,0x71,0xd1,0x34, - 0x78,0x5c,0xac,0xe7,0x72,0x56,0x3c,0x42,0x83,0xf4,0x01,0xed,0x0a,0x15,0x59,0xd9, - 0x32,0xda,0xc9,0x72,0xf2,0xa0,0x56,0x37,0x97,0x29,0xcc,0x4c,0xf6,0xe2,0xe0,0x7e, - 0x25,0xcd,0x7b,0x6a,0x71,0xe7,0x93,0x38,0xa6,0x93,0xec,0xde,0x1d,0xf9,0xad,0xa2, - 0x74,0xf0,0x53,0x89,0x02,0xc3,0x38,0xa5,0x95,0x48,0xf9,0x27,0x01,0x48,0x91,0x64, - 0x61,0x37,0xd3,0x38,0xab,0xb1,0x2e,0x02,0xdb,0x80,0xc1,0x28,0x75,0x54,0xdd,0x25, - 0x2e,0x20,0xd9,0xd1,0x76,0xd0,0x93,0xa7,0x80,0x92,0xb7,0xb9,0x21,0xca,0xac,0x5d, - 0xea,0x66,0xfc,0x9e,0xbe,0xa8,0x0a,0xf0,0xe8,0x1a,0xaa,0x5f,0x71,0x69,0x03,0x19, - 0xfe,0xaf,0xe0,0xb1,0x7b,0xf0,0x7b,0xfb,0x32,0xfa,0x9e,0xbc,0x0f,0xeb,0x25,0x5d, - 0x8a,0x79,0x9d,0x74,0xf9,0x38,0xcf,0x2c,0x5a,0xa5,0xaf,0xee,0x4a,0x00,0xc7,0xaf, - 0x1f,0x0a,0xd3,0xcf,0x76,0x14,0x97,0x11,0x54,0x8d,0xc8,0xeb,0x6b,0x16,0xb7,0xd3, - 0x21,0xea,0xc5,0xb8,0xc6,0x0f,0x14,0xa4,0x1e,0x8e,0x70,0xc8,0x5a,0x68,0xec,0xe8, - 0x4c,0x4d,0x86,0x19,0x4e,0x03,0x4f,0x8d,0x15,0x99,0x94,0xd4,0xeb,0x8a,0xfe,0x57, - 0x50,0x73,0xcf,0x4a,0x65,0x69,0x00,0x85,0x4c,0x95,0x09,0x77,0x39,0x93,0xde,0xf5, - 0x22,0x01,0x20,0x4a,0xfc,0x81,0xa4,0x88,0x30,0xcb,0xb5,0x0f,0x70,0xa4,0x2b,0x73, - 0xa3,0x63,0xf8,0xae,0xf1,0xf8,0x80,0x25,0x52,0x6c,0xca,0xe8,0xdb,0x6c,0x0b,0x54, - 0x43,0x83,0x20,0x59,0x47,0xd8,0x59,0x38,0x2a,0x7d,0x44,0xe8,0x30,0x9f,0xf2,0x8e, - 0xec,0xe1,0x76,0x97,0xf3,0x8e,0x94,0x47,0xfb,0x7e,0xe5,0xb8,0x6e,0xa1,0x61,0x86, - 0xfa,0x13,0xfe,0x50,0x2c,0x1e,0x14,0x02,0x0c,0x39,0xd7,0x25,0x8c,0xc7,0x7c,0x02, - 0x79,0x5e,0xf0,0x61,0xf8,0x7a,0x5d,0x15,0xe6,0x4b,0x88,0x3d,0xce,0xbb,0xc2,0xed, - 0xb0,0xdc,0xc1,0x21,0x53,0x69,0xff,0x98,0x8f,0x36,0x56,0xcd,0xf0,0x87,0xe4,0xc4, - 0x8f,0x78,0x80,0x58,0x2e,0x62,0xeb,0x9d,0x25,0x62,0x16,0x64,0x3e,0xed,0x25,0x06, - 0x48,0x45,0x32,0xde,0xee,0x73,0x81,0xae,0xf9,0x43,0x6c,0xb6,0x42,0xf3,0xb2,0x8b, - 0xd2,0x6c,0x16,0x01,0x8b,0xe3,0x4f,0xd1,0x12,0x4a,0x33,0x83,0x92,0xa7,0x0f,0xbf, - 0x9f,0x3b,0xa4,0xe5,0x38,0xa9,0xdd,0x50,0x5e,0xcc,0x25,0x12,0x01,0x91,0x53,0x91, - 0x2b,0x00,0xc3,0xc6,0x2c,0x9e,0x8b,0x4a,0xca,0xca,0x71,0xbd,0x68,0xfe,0xb0,0x13, - 0x84,0x9b,0x16,0x04,0xde,0xe6,0x72,0xbc,0x82,0xc5,0xff,0x38,0xce,0xc6,0xaf,0x76, - 0x11,0xed,0x7e,0x79,0xd5,0x11,0x3a,0x98,0xdc,0xb2,0xd3,0xed,0x51,0x3d,0x2b,0x4a, - 0xf9,0x39,0xaf,0xf5,0x7a,0x7b,0xb1,0x25,0x3f,0xc4,0x81,0xff,0x4b,0x04,0x9d,0x5e, - 0xa5,0xb8,0x16,0x98,0x56,0xb6,0x1c,0xc1,0xe3,0x97,0x58,0xe4,0x94,0xe9,0x00,0xb2, - 0x1f,0xf4,0xb1,0x85,0x12,0xaf,0x4d,0x53,0xe2,0xbd,0xc6,0xa2,0x2f,0xf8,0xd8,0x45, - 0x12,0xb2,0xae,0xd1,0xc3,0x9c,0x19,0x5b,0x19,0x09,0xbf,0x72,0x6b,0xf2,0xc8,0x9e, - 0x78,0xfd,0x72,0xc9,0xdf,0x3d,0xcd,0x4f,0x5e,0xf8,0xd3,0xd0,0xdd,0xb0,0xba,0xd4, - 0x68,0x9f,0x7b,0x32,0xf1,0x0b,0x8f,0x97,0x26,0xbf,0x77,0x66,0x76,0xa7,0x08,0x0a, - 0xe6,0xe0,0x2b,0x18,0xd2,0x9d,0xc0,0x82,0x43,0xae,0xed,0x62,0x8d,0xb7,0xe9,0xdf, - 0x2d,0x5b,0x41,0xcd,0xb7,0x49,0xb9,0x77,0xdc,0xa8,0x01,0xbf,0x99,0x34,0x6c,0x7d, - 0xbb,0x92,0x02,0xf1,0x92,0x68,0x7e,0x37,0xa6,0xb9,0x11,0x31,0x6e,0x63,0x3c,0xd6, - 0xbc,0x56,0xb7,0xe5,0x04,0x7f,0xbb,0xfe,0x75,0x95,0x79,0x5e,0x1a,0x11,0x7b,0xc2, - 0x09,0x0e,0xda,0x4b,0x9b,0x24,0xde,0x99,0x1f,0x82,0xd2,0xda,0x3d,0xfa,0xfd,0x66, - 0x0d,0x8d,0x91,0x6a,0x6b,0xc1,0x21,0x4b,0xea,0xf8,0xbe,0x59,0x00,0xf5,0x05,0x55, - 0xba,0x56,0x50,0x86,0xe3,0x35,0x2b,0x8c,0xfe,0x9e,0x98,0xb5,0x08,0xd0,0x65,0xe8, - 0x25,0x2b,0x3f,0x1a,0x68,0x19,0x62,0x31,0x03,0x8d,0x44,0x8f,0xaa,0x04,0x0a,0xe0, - 0x8e,0x08,0x7b,0xad,0x87,0x7d,0x62,0x21,0x44,0xc9,0x68,0x0c,0x41,0x2d,0x9b,0x82, - 0x4d,0xd7,0x18,0x30,0xa8,0xb0,0x54,0xc4,0xaf,0x2b,0xd7,0x23,0xfd,0x65,0x9a,0xaf, - 0x45,0x5f,0x4a,0xc1,0x9b,0xd1,0x27,0x15,0x88,0x9e,0x90,0x01,0x69,0xdb,0x7b,0x1d, - 0x67,0x0f,0xa2,0xb3,0x87,0xf1,0x01,0x05,0xde,0xe3,0x0f,0xd6,0xc8,0x7b,0xfe,0xa1, - 0xf6,0xf2,0x9e,0x7e,0xe0,0xf7,0x7f,0xf0,0x3c,0xfe,0xbd,0x8f,0x9a,0x47,0x7b,0xbb, - 0x9c,0x66,0x15,0x8d,0x22,0x3a,0xa1,0x7d,0x4d,0x17,0x98,0x2c,0x1f,0x4d,0x4f,0xdc, - 0xd1,0xbb,0xb2,0xf4,0x60,0x33,0x5a,0xb1,0xb5,0x60,0x92,0x1a,0x9d,0xec,0x50,0x82, - 0xc4,0xe7,0x94,0x72,0x35,0xff,0xeb,0x5b,0xa3,0x82,0xdb,0xb0,0x96,0x4c,0x13,0x97, - 0xd2,0x60,0x15,0x7a,0x36,0xe4,0x34,0xff,0x6a,0xa8,0x21,0xbe,0x74,0x9d,0xb5,0x54, - 0xe9,0x4a,0x75,0xee,0xaf,0xd2,0xa9,0xd3,0xfc,0xd7,0xca,0x28,0x0f,0x22,0x44,0xa5, - 0xac,0xb5,0xe0,0x1d,0xca,0x67,0x1b,0x61,0x70,0x8f,0x08,0xfb,0x44,0x0d,0x7d,0x63, - 0x67,0x98,0x02,0x40,0xf3,0x6c,0x5f,0x4c,0x96,0x6a,0x46,0x57,0xb6,0x11,0x03,0xf6, - 0xae,0xd5,0xfc,0x60,0xf1,0xfc,0x85,0x77,0xec,0xb6,0xa3,0x85,0x14,0x16,0x9c,0x91, - 0xeb,0x61,0x78,0xdc,0x6c,0x14,0x29,0x7e,0x3f,0x44,0x17,0xe0,0x9f,0x6c,0xe3,0xe8, - 0xd1,0x28,0x21,0x07,0x74,0x61,0xf3,0x87,0xf4,0xdb,0x89,0x48,0xff,0x63,0x09,0x76, - 0x08,0x76,0xd6,0xb1,0xa1,0xee,0xdb,0xc7,0xa5,0xef,0xd5,0x10,0x92,0x7b,0xbb,0xe3, - 0x62,0x71,0x6e,0x30,0x07,0x2e,0x82,0x87,0xd2,0x83,0x5d,0xe0,0xed,0x08,0x9c,0x95, - 0x28,0x03,0x7b,0xf1,0x11,0x41,0x00,0xeb,0x51,0xfa,0x6f,0x35,0x1b,0x0c,0x0e,0xc6, - 0x20,0x42,0x46,0x0a,0xe2,0x13,0xa1,0xfa,0xe5,0xa6,0x8e,0x2a,0xe0,0x18,0x40,0x23, - 0xfb,0xd5,0xa6,0x87,0x24,0xdd,0xc9,0xd3,0x72,0x15,0xc4,0x37,0xe3,0x91,0xdf,0x6e, - 0x89,0x82,0x41,0x45,0x76,0xea,0x56,0xe2,0xcf,0xa6,0x12,0x0d,0xf1,0x97,0xc7,0x68, - 0x50,0xd8,0x50,0xf0,0xe2,0x20,0xfb,0x49,0x85,0x7f,0xe8,0xd6,0x7b,0x7c,0x44,0xa9, - 0xc9,0x5d,0x95,0x37,0x23,0x63,0xba,0x90,0xb5,0x3f,0x08,0x75,0xc4,0xbb,0x04,0x87, - 0x7b,0xd1,0x91,0x8b,0x9c,0xf2,0x01,0x46,0x30,0xf9,0xda,0x34,0xd3,0xea,0x4d,0x15, - 0x28,0x69,0x4e,0x60,0xcd,0x33,0x1e,0x8f,0x9d,0x51,0x92,0x5c,0xfe,0x0a,0x21,0x4d, - 0xc1,0xe8,0x4a,0xad,0x05,0x9d,0x6b,0xc8,0xa6,0x41,0x29,0xad,0x91,0x91,0x66,0x70, - 0xda,0x5b,0x22,0x59,0x97,0x14,0xda,0x7a,0x60,0x53,0x60,0x84,0xa6,0x8c,0x9a,0x52, - 0x46,0x6a,0x54,0x22,0x4d,0xa6,0x0d,0xbf,0x2d,0xb7,0x6d,0xd8,0xd5,0x9c,0x9b,0x3c, - 0x0c,0x2a,0x1f,0xbe,0xc9,0xf9,0x96,0xd5,0xa6,0xa5,0x27,0xa6,0x87,0xcb,0xfc,0x0c, - 0xef,0x49,0x0f,0x2e,0xa1,0xe6,0x67,0x4d,0xc2,0xd0,0x27,0x30,0xbb,0xb2,0xec,0x49, - 0xee,0x58,0xff,0x34,0xff,0xe0,0x8e,0x8d,0x1d,0x96,0xa8,0xcc,0xb9,0x9d,0x80,0x75, - 0x80,0x0a,0xd7,0x57,0xca,0xc8,0x11,0xc0,0xd9,0x0c,0xef,0x99,0xce,0xb4,0xab,0x5a, - 0x8b,0x2b,0x65,0x0e,0xd3,0xd9,0xf3,0x74,0x2e,0xbe,0xae,0x85,0x91,0xe6,0xd2,0xa1, - 0x66,0x08,0x19,0x44,0xfe,0xdf,0xd4,0x91,0xaf,0x83,0x50,0xda,0xe2,0x8d,0x4b,0xd7, - 0x34,0xd1,0x7b,0x81,0x15,0xf4,0x13,0x2b,0x68,0x8c,0x44,0x8e,0xd8,0x29,0x9f,0x74, - 0x06,0x92,0x7a,0xe8,0x76,0xf4,0x77,0xd0,0x3d,0x65,0xad,0x82,0xec,0x3d,0x7c,0xbd, - 0xdb,0xae,0xf7,0xbe,0xb5,0x3b,0xc2,0xed,0x5d,0xf9,0x46,0x21,0xaa,0xc5,0x5e,0x63, - 0x7e,0x3d,0x6d,0x08,0x8d,0xf8,0x01,0xe3,0x13,0x6a,0xa1,0x03,0x1f,0x42,0xad,0xfc, - 0x3f,0xc4,0x32,0x7b,0xa1,0x6b,0xc9,0x5e,0x81,0xa6,0x5b,0xe9,0xe4,0xe1,0x69,0x26, - 0x11,0x66,0x87,0x0e,0x92,0xf1,0x29,0xc2,0xac,0xd1,0xd2,0x98,0x99,0xab,0x00,0x53, - 0xb7,0x31,0xb4,0x8c,0x37,0x0c,0xff,0x20,0x0c,0xec,0x26,0xca,0x58,0xae,0xb8,0x8a, - 0x5b,0x65,0x76,0xbc,0x97,0x2e,0x41,0xc4,0xc1,0x8a,0x5c,0xea,0x82,0xa6,0x4f,0xda, - 0x90,0xbb,0x60,0x86,0x06,0x19,0x8b,0xb1,0xae,0x2b,0x9b,0x8d,0xe0,0xc2,0x85,0x45, - 0x0e,0x21,0x99,0xc7,0xfc,0x70,0xaa,0x63,0x52,0x6a,0x20,0xb3,0x45,0x42,0xa1,0x73, - 0x08,0x2b,0xf5,0x14,0x6d,0x29,0x2b,0xa1,0x01,0xda,0xdf,0x5c,0x51,0x18,0xdf,0x86, - 0x16,0x4d,0x9f,0x95,0x55,0x53,0x46,0xea,0x1c,0x14,0x4a,0xa1,0xa2,0x61,0x8f,0x36, - 0xc3,0xd4,0xdc,0x2e,0x77,0x2d,0x46,0xe3,0xba,0x09,0x2e,0xab,0x92,0x66,0xd9,0x09, - 0xc6,0xac,0x9c,0xfa,0x90,0xaa,0xcd,0x48,0xba,0xe9,0x42,0xae,0xc5,0xa4,0x4e,0xab, - 0xb2,0x6e,0x12,0xae,0xe3,0x84,0x8a,0xed,0xd2,0x56,0x49,0x85,0x89,0xd3,0xd6,0xcc, - 0x4c,0x89,0x41,0xb0,0x6e,0xbe,0xe6,0xe1,0xf0,0xd0,0x14,0x7e,0xa9,0xbb,0x3e,0x77, - 0x55,0xe8,0x4f,0xa3,0x36,0x7b,0x1e,0xf1,0x12,0xde,0x05,0x6f,0x93,0xd1,0xb0,0x0c, - 0x34,0x09,0xae,0x7d,0x79,0x8e,0x08,0x26,0xfe,0x21,0x51,0x06,0x3b,0xf6,0xe4,0x0e, - 0x7d,0x8b,0xa1,0x07,0x54,0x80,0x8f,0xb6,0x2f,0x41,0x31,0x67,0xa0,0x80,0xdb,0xc7, - 0x4f,0x8e,0xb1,0x0a,0x0e,0xa2,0x96,0xd1,0x9a,0x1e,0xa3,0xe5,0xed,0xaf,0x73,0x08, - 0x95,0xa9,0x0f,0x63,0x66,0xac,0x35,0xbb,0xd1,0xe0,0x65,0x6d,0xfd,0x92,0x50,0x6a, - 0x6e,0x1f,0x35,0xd7,0x80,0x94,0xad,0x30,0x8a,0x1f,0x45,0x7b,0x9e,0x49,0x83,0xa2, - 0x53,0x71,0x90,0x4a,0xf6,0x32,0x0d,0x86,0xcd,0x2f,0x4a,0x8d,0xf8,0x92,0x39,0xc0, - 0xf4,0xbd,0x8f,0xcd,0x9a,0xbf,0x74,0x2a,0x3c,0x8e,0x8c,0xcf,0x21,0x90,0x01,0xee, - 0xd3,0xd1,0xcc,0x7a,0x2a,0x82,0x3b,0x11,0xff,0xa8,0xc0,0x47,0x74,0x2c,0x2a,0xa6, - 0xf7,0xdb,0x6a,0x18,0x20,0x75,0x7f,0xa9,0xc0,0xe2,0x55,0x02,0xe9,0xa2,0x5e,0x08, - 0x1d,0x8b,0x58,0xff,0xb3,0x48,0x48,0xcf,0xa1,0x08,0xf7,0xa0,0x87,0x52,0xe7,0xad, - 0x2b,0x76,0xf8,0x4b,0x43,0x87,0x42,0x8a,0xca,0xde,0x8d,0xdd,0xda,0x30,0x7b,0x93, - 0x86,0x1a,0x11,0x19,0x6f,0x11,0x50,0xab,0x48,0x4c,0xb6,0x8d,0xf4,0xee,0xfd,0xe6, - 0x18,0x88,0x74,0x12,0xeb,0xb2,0xf7,0x51,0xcc,0xcc,0x19,0x3f,0x8e,0x9c,0xd8,0x1e, - 0xb4,0x0e,0x64,0xe2,0x37,0x5e,0x7a,0x99,0xce,0xc9,0xe6,0xb4,0x3a,0xda,0x33,0xc9, - 0xdf,0xc6,0x75,0x93,0x3c,0x35,0x3d,0xad,0xc5,0x14,0xe7,0x94,0x35,0x4b,0x88,0x67, - 0xbe,0x2c,0x93,0xd5,0xa8,0x6c,0x13,0x73,0xd7,0xd1,0xf2,0x8c,0x37,0x47,0x89,0x5c, - 0xe7,0xc4,0x90,0x45,0x90,0x99,0x84,0xb0,0xf5,0xd5,0x14,0x6c,0x91,0x28,0x32,0x97, - 0xb3,0x6a,0xac,0x08,0x4b,0xa9,0x34,0x02,0x6c,0x3c,0xe4,0xb0,0x84,0xc1,0x48,0xb1, - 0xf0,0x88,0xee,0x1b,0x05,0x70,0xd4,0x48,0xc8,0x13,0x5f,0x6e,0xf4,0xe2,0x12,0xfa, - 0xb6,0xfa,0xe8,0xa3,0xcb,0xf2,0x7b,0x8d,0x7d,0x12,0x81,0x9e,0xb1,0x0d,0x95,0x18, - 0xfe,0xd8,0xaa,0x08,0x7c,0x55,0x28,0x8e,0xdb,0xc1,0x46,0x10,0xd8,0x27,0x7a,0xfe, - 0x5b,0xdd,0x7a,0x4d,0xa4,0xd0,0x81,0xda,0x88,0xa8,0x2e,0x8c,0x3f,0xb5,0xcf,0xbc, - 0xab,0x8c,0x37,0x58,0xc5,0x83,0xce,0x88,0x50,0x56,0x15,0x2e,0x98,0x2f,0xe8,0xa1, - 0x2c,0x3c,0x59,0x4a,0x75,0xe7,0x84,0xa3,0x90,0x76,0xdc,0x61,0xa9,0x49,0x7b,0x1d, - 0xd4,0x62,0x8e,0x36,0xc6,0x6b,0x69,0x9e,0x2e,0x8d,0x56,0x84,0x6e,0xbc,0x94,0x73, - 0x87,0x79,0x0e,0x17,0x7b,0x44,0xfc,0xd2,0xe5,0xae,0xfc,0x34,0x93,0xd1,0xea,0x46, - 0x5e,0x8b,0x89,0xb5,0xe9,0x1c,0xc2,0x9d,0xff,0xc8,0xc1,0x6d,0x72,0x5a,0x16,0x1c, - 0x79,0x1d,0xa0,0x91,0x60,0xd4,0x96,0xd6,0xb2,0xb5,0x8e,0x18,0x87,0x59,0xc4,0xb2, - 0xf9,0xaa,0xd5,0x2b,0x55,0x37,0x5d,0xfa,0x66,0xf7,0xc7,0xfe,0x13,0xaa,0x70,0x95, - 0x7c,0x79,0x39,0xc6,0x44,0x90,0x85,0x9a,0x51,0x61,0xe7,0x1e,0xc2,0x01,0xa1,0x8f, - 0xfc,0xea,0x10,0xce,0xcd,0x98,0x2d,0x56,0xff,0x33,0x19,0xea,0xd9,0x48,0x36,0x61, - 0x6b,0xa8,0x43,0x7b,0x77,0x5f,0x9a,0xad,0x59,0xee,0xac,0xa7,0x10,0x4f,0x6f,0x80, - 0x99,0xf8,0x0a,0x36,0xe5,0x33,0x5d,0xb9,0xbc,0xad,0xe0,0x02,0x3d,0x35,0xa9,0x2d, - 0x87,0x00,0xe5,0x58,0xaf,0x30,0x4b,0xc7,0xab,0x9e,0x1f,0x55,0x15,0xb4,0x41,0x2f, - 0x99,0x54,0x63,0x1a,0x83,0x64,0x05,0xcc,0x02,0x51,0xfc,0xf5,0x13,0xe6,0xc2,0x9b, - 0x5f,0x18,0xc0,0x20,0xfc,0x16,0x6c,0x5e,0x6d,0x0e,0xc5,0xbf,0x6a,0x5e,0x70,0x24, - 0x82,0xeb,0x65,0xc2,0x86,0xac,0x5f,0x58,0x97,0xd8,0x02,0x41,0x60,0x70,0x51,0x2c, - 0x08,0x9c,0x3b,0x8b,0x52,0xb4,0x53,0x2b,0x41,0x94,0xe6,0x69,0xac,0xc1,0xa4,0xa6, - 0xa1,0xea,0xf1,0x64,0x17,0x48,0xe3,0x29,0xc6,0xdc,0x78,0x73,0x59,0x75,0xbe,0xa6, - 0x3c,0x4f,0x58,0x5a,0xd9,0xfd,0x0c,0xf9,0x9e,0x7b,0xd1,0x5a,0x37,0x37,0xce,0x15, - 0x0c,0xe4,0x48,0xb8,0x5a,0x2f,0x46,0x62,0xda,0x98,0xf9,0x83,0x01,0x8a,0xc6,0xf9, - 0x26,0x92,0x8c,0x76,0x27,0x8d,0x97,0x18,0x67,0x9d,0x87,0xd1,0x4a,0x7c,0xb4,0xc0, - 0xac,0xe9,0xff,0x65,0xd1,0xfc,0xdb,0x81,0x5e,0xcd,0x46,0x82,0xd0,0x0e,0x70,0x8c, - 0xf9,0x44,0xb2,0x77,0x48,0xee,0x12,0xd0,0xe0,0xcd,0x8d,0x6d,0x4c,0x2c,0xf4,0xfc, - 0xcd,0x11,0x90,0xbb,0xf6,0xca,0x72,0xfd,0xf9,0xdb,0xe9,0xea,0xf0,0xac,0x15,0xe9, - 0x18,0x21,0x57,0xfc,0x46,0x02,0x83,0x49,0x6d,0xae,0x69,0xcc,0xde,0xf7,0x86,0x7a, - 0x3d,0x56,0x1c,0x3b,0x3f,0xbe,0x81,0x09,0x56,0xad,0xec,0x6d,0xe7,0x7b,0xe3,0x52, - 0xfd,0x54,0x1d,0xff,0x85,0xaa,0xb6,0xe8,0x10,0xc4,0xa5,0xd0,0x3d,0x50,0x2c,0xcf, - 0x7c,0xcd,0x66,0x3a,0x4d,0xa2,0x59,0xe1,0x3c,0x00,0x62,0x75,0x03,0x2c,0x53,0x85, - 0x5a,0x46,0xc8,0x24,0xcb,0x28,0xe9,0x10,0xaf,0x18,0xcf,0x78,0xd1,0x4e,0x32,0x2f, - 0xf6,0x24,0xce,0x55,0x59,0x00,0x9e,0x08,0x6e,0xa4,0xbc,0x71,0x39,0xf0,0xa5,0xa9, - 0x01,0xb4,0x80,0x1a,0x27,0x84,0xdf,0x0c,0xd3,0xa2,0x2c,0x7e,0x5c,0x45,0x71,0xbc, - 0x4a,0xd2,0x52,0x14,0x9e,0x8d,0xa7,0x96,0x30,0x6e,0x01,0x14,0x8a,0x6d,0xa0,0xa1, - 0xc4,0xa1,0x5a,0xac,0x61,0x0c,0x9d,0x6e,0x74,0x64,0xe7,0x4c,0x69,0xf4,0xd9,0x3f, - 0x51,0xa5,0x35,0xff,0x93,0xb7,0x93,0xa8,0x66,0xa5,0x0d,0x0e,0xd0,0x23,0xe6,0x27, - 0x31,0xdf,0x1e,0x6b,0xf5,0xf8,0xf0,0x62,0x3d,0x7e,0xf7,0xf1,0xef,0x5f,0xbe,0x18, - 0xe9,0xe1,0x03,0x77,0xb7,0x91,0x6d,0x43,0xab,0x7c,0x71,0x1c,0x6f,0x53,0xab,0x76, - 0x08,0x39,0x84,0x60,0x49,0x59,0xc9,0x34,0x38,0xc1,0x17,0xce,0xb3,0x9a,0x0f,0x32, - 0xbb,0xad,0xc6,0x8f,0x4c,0xcc,0xf1,0x3c,0x7e,0x28,0xe1,0xd8,0xcd,0x20,0xfe,0x9f, - 0x6b,0xf3,0x9c,0xef,0xf2,0x17,0xf5,0x5e,0xe8,0x7f,0xd1,0xfa,0x92,0xbf,0xa5,0x8a, - 0xe3,0x8a,0x73,0x39,0x82,0x9d,0x60,0x29,0x89,0x39,0xf9,0xe0,0x83,0xf4,0x80,0x6c, - 0x7d,0x0c,0xe2,0xb9,0xef,0x9f,0xac,0xae,0x46,0x5f,0x95,0x96,0x88,0x7a,0xe4,0xdd, - 0xfb,0xe4,0xeb,0xb9,0xf3,0xb2,0x32,0x2b,0x08,0x80,0x62,0x7b,0x47,0x05,0x9c,0x0c, - 0xd9,0xdd,0xb6,0x96,0x46,0x6e,0xe6,0xe6,0xe5,0x3e,0x47,0x46,0xb3,0x97,0x05,0xdd, - 0x65,0xf1,0x68,0xe1,0xd7,0x88,0x85,0xd7,0x9b,0xa7,0x8b,0x1f,0x5c,0xf5,0x5f,0xa6, - 0xd3,0x45,0x2d,0xa4,0x35,0x22,0x33,0x89,0x0f,0x96,0x4c,0x6f,0x77,0x91,0x12,0x19, - 0x79,0xf5,0x8b,0xf4,0xbd,0x78,0x3b,0xbd,0x98,0xdf,0x57,0x20,0x14,0x90,0xe4,0xe6, - 0xab,0x80,0xe8,0x0f,0x13,0xe6,0x92,0x2f,0x7d,0x53,0x72,0x88,0xb4,0xed,0x6d,0x7a, - 0x17,0x1c,0x74,0xdb,0xb8,0xa7,0x46,0x5f,0x8f,0xc7,0xba,0x4c,0x25,0x11,0x48,0xf9, - 0x5b,0x26,0xa6,0xbc,0xbd,0x81,0x9c,0x45,0x20,0xc4,0xab,0x00,0x79,0xee,0x92,0x69, - 0x52,0x0f,0xec,0x9f,0x42,0xce,0x89,0x28,0xe6,0x89,0xed,0x85,0xb6,0xda,0x4a,0x65, - 0x5a,0x0b,0xe0,0x67,0x1d,0x7a,0x23,0x7e,0x11,0x2a,0xd4,0x42,0xc8,0x9e,0x98,0x77, - 0xed,0xe0,0xc7,0xa7,0x8a,0xcf,0xc0,0xad,0xd4,0xbc,0xe9,0xad,0x05,0x52,0xc9,0x55, - 0x80,0x2a,0x45,0xd8,0x3f,0xad,0x32,0xdd,0xc0,0x2c,0x95,0x3e,0x5c,0x8f,0xe6,0x19, - 0xa5,0xe9,0xed,0x53,0xef,0x75,0xee,0x73,0xc3,0xcb,0xb2,0x26,0x2d,0xe7,0x1c,0xca, - 0x44,0x01,0x72,0xb9,0xa9,0x77,0x8d,0xbf,0xef,0xa5,0x48,0xe4,0x5f,0x49,0xa8,0xff, - 0xd6,0x78,0xb3,0x86,0xda,0xf3,0x5c,0x13,0x55,0x2c,0x5f,0x16,0xeb,0xe7,0xf4,0xe0, - 0x02,0x4e,0xb9,0x02,0x4a,0xd8,0x39,0x84,0x1a,0xd3,0x07,0xf6,0xb6,0x5f,0xad,0xfc, - 0x6f,0x63,0xe9,0xe5,0x75,0xfb,0x7e,0xf6,0xce,0x27,0xa7,0x57,0x62,0x1f,0xe3,0x8d, - 0x1d,0x17,0x2f,0x7a,0x94,0xff,0xab,0x5f,0x24,0x9a,0xc1,0x71,0xa3,0xa1,0xfd,0x34, - 0xe2,0x56,0x2f,0x5a,0x2d,0xa7,0x1b,0x4e,0x89,0xdd,0x1e,0xc5,0x98,0x6b,0x67,0xd9, - 0x2c,0x88,0xae,0xca,0x74,0x61,0xbc,0x27,0x40,0x58,0x20,0xd9,0x74,0x1f,0x52,0xd2, - 0xc2,0xcc,0xe1,0x18,0x74,0x17,0x9e,0x6e,0x7e,0x9e,0xa4,0x42,0x36,0xd2,0x7e,0xe1, - 0x78,0xff,0x81,0x8f,0xef,0x73,0x1c,0x52,0x6a,0x2b,0xb9,0xf0,0x9f,0xa2,0xf8,0x34, - 0xa9,0x1c,0xc8,0xf7,0x41,0x5f,0xfc,0xea,0x4b,0x52,0x39,0xf5,0xb1,0x4b,0xf8,0x9a, - 0xa2,0x6c,0x4c,0xba,0x14,0x53,0x23,0xdd,0x03,0x1e,0x3a,0x23,0x35,0x28,0xd0,0x07, - 0xd2,0x0a,0xbf,0xed,0x36,0xca,0x69,0x87,0xf7,0xd3,0xaa,0xd5,0xf4,0xbd,0xb5,0xae, - 0x93,0x57,0x68,0xc9,0x22,0xdc,0x59,0xed,0x22,0xdd,0xd9,0x4f,0xbc,0x37,0x3a,0xf5, - 0xf7,0x31,0x9d,0x9a,0xb5,0x2a,0x11,0xf2,0x77,0x92,0xd5,0xa0,0x72,0xe1,0x6e,0x09, - 0x00,0xb6,0x6a,0x73,0xbd,0xfa,0x2a,0xdd,0x82,0x76,0x74,0x6b,0x3f,0xc0,0x51,0x80, - 0xef,0x2a,0x4c,0xcd,0x82,0x6c,0xe6,0xf9,0xd5,0x4a,0x6c,0xaa,0xc6,0xc6,0xaf,0xe9, - 0x6a,0x17,0x0f,0x3a,0x09,0x73,0xf0,0xc3,0x27,0x9b,0x78,0xce,0x37,0x2d,0x95,0x46, - 0x4a,0x58,0xc9,0xac,0xf5,0x73,0x4c,0x44,0x98,0xb2,0x66,0x55,0x72,0xd2,0xaa,0xb5, - 0xf9,0x24,0x69,0x9f,0xdd,0xa1,0x21,0xc2,0x6b,0x0c,0x67,0x00,0xe0,0xa2,0x49,0x6c, - 0x70,0xbe,0xc2,0x07,0x10,0x83,0x83,0x28,0xc7,0x2e,0xbe,0x6b,0xaa,0x81,0xf3,0x51, - 0x69,0x7f,0xec,0xb4,0xfd,0x37,0xc9,0x64,0x0b,0x90,0xa1,0x84,0xcb,0x31,0x5d,0xf6, - 0xb5,0x6d,0x7e,0x8e,0xb6,0x40,0xe3,0xa8,0xc5,0xd9,0x1e,0x0a,0x79,0x36,0xd8,0xb6, - 0x8d,0x4e,0x37,0x53,0x66,0xa5,0x34,0x4c,0xb3,0xcd,0xcb,0xab,0xaf,0x3e,0x99,0xac, - 0x89,0x96,0xfd,0x6c,0x47,0xb1,0xc9,0xba,0x91,0xf9,0xff,0xa7,0x2f,0x83,0x7b,0x3d, - 0x02,0x5e,0x97,0x65,0xf4,0xf1,0x6b,0x90,0x2d,0x4e,0x4e,0x8e,0xec,0x60,0xd6,0xdf, - 0x3b,0x6c,0xdb,0x96,0x07,0xe0,0x19,0xe8,0x10,0xca,0x1b,0x21,0xd5,0xb8,0xac,0x35, - 0x17,0xb0,0x11,0x5d,0x95,0x31,0xd5,0x6b,0xe3,0x15,0xe2,0x55,0x72,0x88,0x65,0xc9, - 0xc1,0xbb,0xc2,0x97,0x21,0x5b,0x29,0x3a,0x43,0x93,0xda,0x34,0x64,0x5e,0xa1,0x1d, - 0xf2,0xaf,0xa4,0x3c,0x5d,0x51,0xee,0xb1,0xd9,0x31,0x6a,0x1e,0xcc,0xd6,0x05,0xf1, - 0x09,0x0f,0xe1,0x5f,0xe3,0x6b,0x5f,0x23,0xfc,0x2b,0xef,0x01,0x2b,0xbc,0x8e,0x07, - 0x9c,0x3e,0x12,0xaa,0xfd,0xcd,0x6d,0xcf,0xcc,0x17,0x60,0x47,0xbc,0x9b,0x84,0x1f, - 0x7b,0xd5,0x30,0xfe,0x9d,0xa5,0xfb,0x99,0x3b,0x87,0x99,0x45,0xaf,0x65,0xf1,0x17, - 0x7f,0xe5,0x5f,0xb2,0x5d,0x0d,0x98,0x01,0x7f,0xdc,0x0b,0x86,0xff,0x19,0x44,0x1e, - 0xe0,0x86,0xb5,0x30,0xc1,0xa3,0x01,0xa9,0x3c,0x66,0x9c,0x05,0xf7,0x01,0x34,0xd8, - 0xca,0xdb,0x22,0xcd,0x6e,0x2f,0xdd,0xbe,0x41,0x46,0xa0,0x7d,0xa2,0x7b,0x95,0xc8, - 0x22,0x8d,0x5e,0xc1,0xc1,0x2d,0x4e,0xff,0x05,0x27,0xf9,0x64,0xc6,0xc4,0xe8,0x88, - 0xd0,0x33,0x4b,0x0b,0xaf,0xc1,0x54,0xe7,0x66,0x0a,0x04,0xe1,0xa6,0xf2,0x4b,0xd4, - 0x27,0xc7,0x2a,0xd5,0x27,0x7a,0xb9,0x9c,0x87,0x50,0x3c,0xef,0x13,0xbd,0x19,0xcb, - 0xbd,0xeb,0x79,0x4a,0x12,0x32,0xae,0xde,0xcd,0x03,0x0f,0x33,0xb7,0xef,0x22,0x97, - 0x0a,0x44,0x80,0x86,0x89,0xd2,0xf0,0xe1,0xda,0x19,0xaa,0xfa,0x41,0x82,0x03,0xf3, - 0x9d,0x9f,0xe1,0x24,0x4e,0x67,0xa7,0x74,0x53,0xb7,0x6a,0x5d,0x1c,0xfc,0xd1,0xc5, - 0x1a,0xdc,0xc6,0xd0,0xfc,0x70,0x6e,0x34,0x81,0x87,0x89,0xba,0x58,0x4f,0xc4,0xd2, - 0xab,0xe7,0x37,0xe6,0xe0,0x47,0xc1,0xc4,0x51,0x8f,0xac,0xd4,0xf9,0x46,0x7a,0x37, - 0x95,0x0c,0xcc,0x17,0xac,0x9d,0x5a,0x04,0x4b,0x6a,0x63,0x1a,0xe2,0x08,0xd6,0x61, - 0x3d,0xbb,0xd1,0x2f,0x88,0xe5,0x39,0xed,0xc4,0x52,0x15,0x99,0xad,0xce,0x53,0x9c, - 0x7d,0x44,0xeb,0x2b,0xb5,0x3e,0xb8,0x14,0x8c,0x4a,0x87,0x31,0x72,0x95,0xb2,0x4c, - 0xf2,0x2f,0xf6,0xa9,0x95,0xb4,0x57,0x52,0x45,0xcd,0xad,0x2d,0x7a,0x05,0x19,0x5d, - 0xdb,0xd8,0xec,0x18,0x17,0x4b,0xfe,0xe3,0x8a,0x3b,0x2d,0x29,0x64,0xe4,0xd8,0x27, - 0xe3,0x22,0xdf,0x86,0x97,0xe5,0xe2,0x88,0x5e,0x6d,0xde,0xd7,0x47,0xfc,0x6f,0x3a, - 0xc0,0xfa,0xa1,0xe2,0x92,0x5c,0x3b,0x79,0x69,0x61,0x40,0xf4,0xfa,0xf9,0xba,0x43, - 0xd1,0x1d,0xe5,0x16,0xa2,0x92,0x5e,0xaa,0x80,0xf7,0xcb,0x2a,0xe0,0x41,0x07,0xe0, - 0xe0,0x18,0x3c,0xd8,0x0b,0x5b,0x27,0xc9,0x54,0x12,0x1d,0xf0,0x38,0xab,0x80,0xa3, - 0xf2,0xba,0xbe,0x42,0xa5,0x07,0x29,0x88,0x1f,0xdc,0x53,0xe5,0x3b,0x61,0x14,0x35, - 0x11,0xdb,0xf6,0xab,0xf8,0x14,0x13,0x7c,0x09,0x1f,0x0d,0x55,0x5a,0x02,0xa5,0x5f, - 0x02,0x95,0xbe,0x58,0xf1,0x18,0x7d,0x0f,0x8e,0x80,0x2b,0x0a,0xc0,0x3f,0xa2,0x08, - 0x9a,0x94,0xd2,0x40,0x59,0x04,0xe1,0xc7,0x7a,0xcb,0x5d,0xfa,0xc4,0xbf,0x40,0x6e, - 0x90,0xf4,0x3b,0xcd,0x24,0xa2,0x1e,0x77,0xa5,0x9c,0x5d,0x8c,0x10,0x51,0x95,0x17, - 0x45,0xd5,0x74,0x10,0x18,0x54,0x59,0x11,0xa9,0xb2,0xee,0xcc,0x44,0x4c,0x4a,0x0a, - 0x03,0xd5,0x44,0x2a,0x64,0xc6,0x15,0x9a,0x6e,0xf1,0x00,0xea,0x00,0xa2,0xe9,0xf5, - 0x6a,0xba,0x5b,0x74,0x53,0x68,0xed,0x26,0x24,0xc6,0x0a,0x40,0x98,0xa9,0xf3,0xdb, - 0x34,0x3c,0x4d,0x9c,0x7e,0xcf,0x7f,0xd5,0x88,0x24,0x75,0x73,0xea,0xaf,0x36,0xc7, - 0x92,0x9c,0xb4,0x27,0x23,0xc5,0x38,0xfa,0x13,0x23,0x5e,0xeb,0x9d,0x8c,0x6b,0x3c, - 0x8e,0x11,0xf3,0x20,0x99,0x8f,0x2d,0x58,0x53,0x2c,0xbe,0xbc,0x7a,0x57,0x51,0xf0, - 0xb2,0xa3,0x9c,0xc1,0x25,0x6e,0x39,0x66,0x2e,0x78,0x13,0x0a,0x3a,0xbc,0x93,0xc9, - 0xf9,0x19,0x33,0x3b,0x75,0xd2,0x8e,0xff,0x1f,0xfd,0x2b,0x5d,0xb2,0xc4,0xef,0x7d, - 0xac,0x2b,0x31,0x03,0xfa,0x39,0xc1,0xd0,0x26,0xe6,0x95,0x60,0x49,0xda,0x0f,0x64, - 0xfd,0x43,0x1a,0xd3,0x23,0xbe,0x2d,0x83,0xf3,0x6b,0x73,0x38,0xd6,0x6b,0x0d,0xac, - 0x96,0xdc,0x33,0xc7,0x47,0x27,0xa7,0xef,0xc4,0xa1,0x59,0x40,0x44,0xb5,0xb4,0x57, - 0xb8,0x78,0xd9,0x7b,0xc3,0x40,0x40,0x4b,0x0a,0xa5,0x36,0x26,0x21,0x51,0x01,0x81, - 0x63,0xaf,0xce,0xd3,0x31,0x90,0x94,0xe0,0x3f,0x79,0x8c,0x65,0xb9,0xbc,0xb5,0xc5, - 0xcd,0xd3,0x1e,0x50,0xa9,0x9c,0x7d,0x6f,0x9f,0xd5,0xd5,0x32,0x7d,0xae,0xd4,0xf6, - 0x70,0x70,0x15,0xa4,0x27,0x1a,0xcb,0xe7,0x6a,0x57,0xaf,0xe0,0x89,0xa4,0x40,0x24, - 0x47,0x85,0x40,0x86,0x77,0x4d,0x1e,0x9c,0xc9,0xae,0x9d,0xe5,0xf8,0xd5,0x47,0x19, - 0x7a,0xff,0xbc,0x59,0xee,0xb2,0xf8,0x71,0xce,0x48,0x14,0x4d,0x80,0x2b,0xd0,0xfb, - 0x52,0xb7,0xd4,0xd1,0x15,0x3a,0x7f,0x7c,0x5c,0xfd,0x72,0x7e,0xf9,0x4e,0xb1,0x75, - 0x9d,0x64,0xd0,0x61,0xd5,0x19,0xd7,0xc9,0xed,0xab,0x31,0x14,0xd5,0x5b,0xd0,0x4a, - 0x07,0xe0,0xa5,0xf3,0x4b,0x60,0x0b,0xf5,0x4f,0x6b,0x6c,0x36,0x98,0x57,0xaf,0x46, - 0xe0,0x2f,0x31,0x9f,0xd4,0x30,0xe6,0xcf,0x13,0x74,0x27,0x95,0xd3,0xdc,0x35,0xd8, - 0x9a,0xcb,0x6b,0xea,0x80,0xf8,0xaf,0x4f,0x51,0x6f,0xc8,0xd2,0x7a,0x00,0x29,0x6d, - 0x9e,0xde,0x9e,0x3e,0x15,0x53,0x58,0x68,0x26,0x62,0xdc,0x4e,0x66,0xdb,0x4a,0xfa, - 0x3f,0x9f,0x29,0xdb,0x3f,0xa1,0xc9,0x9e,0xea,0xd9,0x67,0x3a,0x41,0x2f,0x74,0xf8, - 0x9f,0x38,0xfe,0x57,0xa8,0xa9,0x23,0x5f,0x2a,0xa6,0xb8,0x19,0xaa,0x38,0x57,0x73, - 0x30,0x82,0x74,0xd1,0xb3,0x14,0xb6,0x62,0x46,0x15,0x27,0x5c,0xa5,0x47,0x1d,0xd0, - 0x70,0x08,0xa7,0xf5,0x2b,0x1a,0xde,0x6a,0x7d,0xf0,0xa5,0x39,0xe6,0x7d,0x06,0xeb, - 0x17,0x34,0x2c,0x0b,0x17,0xea,0x59,0x31,0x62,0x1f,0x8b,0x73,0x2f,0x3f,0xcd,0xfe, - 0x8f,0x20,0x4b,0x55,0x77,0x37,0xd6,0x0f,0xe5,0xf1,0xa2,0x8a,0xad,0x3c,0x85,0x46, - 0xfd,0x3c,0x45,0xf1,0x6a,0x12,0x62,0x02,0xbd,0x86,0xfb,0xad,0x5a,0x72,0x7d,0x5f, - 0x6d,0xe5,0x1c,0xcd,0xf4,0xf2,0x39,0x92,0x1d,0xed,0x6e,0xcf,0xfb,0xfc,0xd6,0xe6, - 0x58,0xec,0x41,0x38,0x5b,0x02,0x8c,0x94,0x7f,0x66,0x86,0x2c,0x0f,0x71,0xa5,0xcd, - 0x2e,0xd8,0xb8,0xec,0xb9,0x75,0xee,0x06,0x06,0x53,0xd3,0x06,0x95,0xb9,0xa7,0xf9, - 0x39,0x06,0x8b,0xa6,0xbb,0x63,0x35,0x86,0xf4,0x5e,0xa8,0x5b,0x77,0xda,0xb8,0x76, - 0x2e,0x7d,0x15,0xa3,0xfc,0xe9,0x70,0xe2,0x7f,0x45,0x89,0x2e,0x41,0x2c,0x5d,0x25, - 0x24,0xb6,0x3e,0x52,0x0c,0x24,0x89,0xbc,0x3a,0x98,0x46,0x11,0x85,0xf2,0x2b,0x93, - 0x76,0x53,0x5a,0xdc,0x1f,0xf0,0xb3,0x6f,0x87,0xde,0xef,0x07,0xbc,0x0f,0x6e,0x08, - 0xc1,0xa9,0x75,0x48,0x1f,0x4d,0x3c,0x85,0xd0,0x9e,0x7e,0xa2,0xca,0x2e,0x90,0xbc, - 0xf9,0x81,0x6c,0xea,0xdb,0x11,0x93,0x5e,0x76,0xd6,0xec,0xa0,0xa2,0x0b,0x30,0x21, - 0x1d,0x35,0xf6,0xe7,0x07,0x23,0x8f,0x3d,0xd7,0x41,0x61,0x5e,0x4c,0x03,0x11,0xa0, - 0x7c,0x55,0x50,0xce,0xee,0x9d,0x0c,0x4c,0x1b,0x2b,0x7c,0x31,0xf9,0xd8,0xc7,0xbf, - 0x59,0x8b,0xc6,0xda,0x55,0xa2,0xd8,0xd4,0x19,0x02,0x65,0xe7,0x02,0x58,0x94,0xb1, - 0x30,0x91,0xec,0x92,0x90,0x99,0xb4,0xae,0x58,0xd3,0xc4,0x04,0xff,0xec,0xe0,0x2a, - 0x98,0x37,0xe6,0x60,0x1b,0x72,0x43,0x98,0x7b,0xae,0x39,0x22,0xa4,0xc6,0x5c,0x59, - 0xa2,0x29,0xce,0x60,0x59,0x24,0x96,0x26,0x80,0xbe,0x20,0xd5,0x02,0x4d,0x2a,0xf7, - 0xb2,0xf7,0x52,0x2d,0x84,0x7d,0x73,0x3b,0xb9,0xc1,0xaa,0x1a,0xcb,0x0f,0xad,0x76, - 0x6e,0xb2,0xbb,0x80,0x27,0x5d,0x6c,0x31,0xc6,0xa4,0x8a,0x7c,0xde,0x57,0x03,0xd7, - 0xb7,0x80,0xe5,0xef,0x81,0xf4,0x68,0xed,0x70,0xd8,0x8c,0x02,0x9e,0x39,0x74,0xc2, - 0x40,0x3e,0xec,0xb4,0xaf,0xa4,0xcd,0xb4,0x94,0x68,0x79,0x01,0x8d,0xe5,0x18,0xf3, - 0xd2,0x1c,0x41,0xe4,0x6a,0x1b,0x4f,0xc4,0x58,0x0a,0x97,0x68,0x6c,0x63,0x15,0x9f, - 0xf9,0xc1,0xc5,0xe0,0x1c,0xaf,0x37,0x07,0x57,0x8c,0x5b,0x0b,0x2e,0x1a,0xb4,0xf3, - 0x0a,0xf5,0x33,0x8c,0x35,0x7a,0xa2,0x41,0x04,0x08,0xbe,0xd5,0x54,0x48,0x84,0xc3, - 0x20,0x43,0x44,0xe6,0x31,0xe8,0x56,0x80,0x7e,0x5f,0xca,0x5a,0x36,0xd0,0x10,0x01, - 0x9a,0xe6,0x10,0xe6,0x04,0xf4,0x41,0x90,0x0c,0xd2,0xf3,0xde,0x31,0xe7,0xbd,0xfb, - 0x3e,0x49,0x0f,0xd6,0x1e,0x55,0x66,0x4e,0x79,0x46,0xe6,0x65,0x0e,0xb7,0xd5,0xbd, - 0xd2,0x57,0x78,0x4e,0xe2,0x15,0x25,0x37,0x3e,0xc5,0xf3,0xb3,0xa4,0x36,0x28,0xd6, - 0x38,0x09,0xa2,0x08,0x6a,0x19,0x45,0x3b,0xc0,0x94,0x87,0x60,0x52,0x44,0x71,0xb0, - 0x07,0x11,0x6d,0x36,0x1b,0xdf,0x03,0x18,0x4f,0xb7,0x5d,0xad,0xcf,0x7d,0xd8,0x55, - 0x35,0x52,0x60,0xfd,0xd0,0x8f,0xb4,0x63,0x9b,0x40,0xae,0x84,0xbc,0x86,0xaa,0x5e, - 0x88,0x6e,0xed,0x29,0x75,0x42,0x52,0x1c,0x4d,0xbd,0x7d,0xd1,0xc6,0xd1,0x86,0x4d, - 0x9c,0x4a,0xec,0xc6,0xca,0x6c,0x6d,0x75,0x5b,0x83,0x6c,0x3b,0xcf,0x70,0xaf,0x38, - 0x28,0x06,0x46,0x8a,0x6d,0x04,0x3f,0x92,0x30,0xce,0x6f,0x54,0xcf,0xa7,0x88,0xf6, - 0x73,0x24,0xe6,0x34,0xed,0xa5,0xee,0x46,0x29,0xef,0xa7,0xf9,0x24,0xbf,0x87,0xd4, - 0x7d,0xb5,0x40,0x07,0xad,0x2c,0xe0,0x90,0xe5,0x7f,0x70,0x97,0xfa,0x37,0x81,0xd8, - 0x39,0xc5,0x17,0xfd,0x6c,0x99,0xfe,0x4f,0x7b,0x5c,0xa5,0xf3,0x82,0x83,0xf8,0xeb, - 0xa4,0xf5,0xe8,0xe3,0x31,0x47,0x42,0x46,0x35,0x8f,0x90,0x02,0x2f,0xf3,0xac,0xfb, - 0x62,0xf7,0x40,0x59,0xaf,0x31,0x9e,0x58,0x5d,0x9c,0x37,0x0a,0xe5,0x7e,0x84,0xf5, - 0x6a,0x0b,0xaf,0x27,0x89,0x61,0x20,0xcd,0x29,0x09,0xf5,0x39,0x37,0x77,0x69,0x39, - 0x21,0x1e,0xc7,0x34,0x14,0x2c,0x2e,0xa9,0x3a,0xa0,0xa4,0x97,0x70,0x91,0x49,0x1b, - 0x99,0xb3,0xde,0x08,0xbd,0x2c,0x4e,0x39,0x89,0x56,0xf6,0x86,0x80,0x2a,0x01,0xb9, - 0x7f,0x25,0xb0,0x0b,0xab,0x96,0xe4,0xb9,0xd7,0xef,0xdc,0xcc,0x38,0xb2,0xae,0x6c, - 0x64,0x19,0x42,0xdf,0x3d,0x59,0xea,0xa3,0xa1,0x44,0x65,0x3a,0xb2,0xbc,0x67,0x5e, - 0x8f,0xbd,0x13,0x18,0x63,0x06,0x51,0x13,0x15,0xb5,0x4f,0xc9,0xb5,0xf4,0x47,0xfa, - 0x3d,0x39,0x26,0x2a,0xa2,0x78,0xe2,0x03,0x93,0x2c,0x5e,0xd2,0x06,0xbd,0x5b,0x1e, - 0x6b,0x8e,0x66,0x96,0xda,0x09,0x5b,0x71,0x96,0x59,0xb5,0xb5,0xcf,0x96,0x2a,0xc4, - 0x07,0xdf,0xb1,0xd0,0x18,0x5c,0xc8,0x67,0xab,0xce,0x8e,0x23,0xad,0x20,0x6e,0xcc, - 0x23,0x22,0x62,0x00,0xb5,0xa9,0xfc,0xe5,0x8a,0xaa,0x77,0xfd,0xfb,0x22,0x3a,0xac, - 0x65,0x47,0xec,0x8b,0x29,0xd8,0xa4,0x10,0xe4,0x2f,0xfa,0xa7,0x4f,0x4e,0x15,0xea, - 0xaf,0x5a,0xd8,0x39,0x29,0x6b,0xb3,0xb9,0xd3,0x5e,0x8f,0x17,0x1f,0xc9,0x71,0x25, - 0x91,0x12,0x41,0xc0,0xd4,0xe8,0x62,0x34,0xa3,0xea,0x9f,0xab,0xa8,0xcd,0xa6,0x11, - 0xaf,0xf8,0x21,0x98,0x4b,0x13,0xd5,0xab,0x50,0x57,0x45,0x4c,0xaa,0x90,0x2d,0xd1, - 0x9b,0xab,0xde,0x55,0xdf,0x4a,0x1f,0xb1,0xb4,0xcb,0xe7,0x95,0xb4,0x7b,0xd1,0x2b, - 0xee,0xeb,0x4e,0xa6,0x04,0x94,0xaf,0x15,0xdf,0x4b,0x0c,0xfc,0xf0,0xfc,0xf1,0x79, - 0x90,0x5a,0xe7,0x05,0x61,0x56,0xf2,0x83,0xb0,0x94,0x77,0xcb,0x55,0x77,0x1c,0x6d, - 0x8d,0x4f,0x40,0xad,0xda,0x11,0xe5,0x24,0xb1,0x93,0xce,0x05,0x40,0x76,0x7a,0x54, - 0x3c,0x11,0x95,0x96,0x39,0xbc,0x47,0x71,0x25,0xf4,0xa6,0x1d,0xa1,0x46,0xd7,0x7e, - 0xc0,0xd5,0x45,0x58,0xfe,0x91,0xe0,0xa6,0x0d,0xd4,0xd9,0xa1,0x93,0x9d,0xa4,0xd3, - 0x25,0x41,0x68,0x5f,0xd7,0x23,0x93,0x32,0x50,0xc2,0x8d,0x38,0x83,0x99,0xf0,0x9a, - 0xea,0xe9,0x25,0x00,0xc3,0x0b,0xac,0x80,0x08,0xd6,0xa2,0x3d,0xa4,0xe0,0x45,0x4f, - 0x16,0x35,0x87,0xba,0x50,0x74,0x3b,0xf9,0xad,0x35,0xeb,0x20,0x3a,0x06,0xae,0x0b, - 0xa8,0xfb,0x96,0x8a,0x82,0xec,0x03,0x0b,0x59,0x3e,0x0e,0x7a,0x41,0xa3,0x34,0x20, - 0xf6,0x6d,0x59,0xf8,0x5a,0x9a,0x65,0x16,0xec,0xc8,0x4b,0xe0,0xe6,0xbb,0xc1,0xb2, - 0xd7,0x5f,0xcb,0xe0,0x4f,0x91,0x1a,0xd4,0x20,0x3c,0x85,0xc3,0xa6,0x94,0xf1,0x5c, - 0xc6,0x70,0x66,0x13,0x93,0x11,0x35,0x96,0x68,0x58,0xfe,0x48,0x24,0xe5,0xea,0x4a, - 0xbc,0xa8,0x2b,0x99,0x14,0x17,0x89,0x3d,0xe8,0x8e,0x4a,0x6a,0x09,0xb3,0x3e,0x78, - 0x72,0xd4,0x31,0x01,0xf1,0xd3,0xd1,0x8e,0x69,0x89,0x86,0xa0,0x95,0x3d,0x39,0x8d, - 0x94,0xf3,0x9b,0xf4,0x21,0x4a,0x27,0xf1,0xc2,0x49,0xbb,0x5e,0xc9,0x3e,0xe5,0x20, - 0x4c,0x91,0x2f,0x12,0xe3,0x32,0x88,0x93,0x9e,0x42,0xc5,0x11,0x96,0xa7,0x9a,0x84, - 0xcf,0x51,0x8d,0x2e,0x77,0xb4,0x91,0x14,0xd7,0xe2,0xd0,0x63,0x49,0xab,0xcb,0x0f, - 0xcc,0x77,0xfb,0xcc,0x57,0xa5,0x2d,0x10,0xb2,0x52,0x22,0xc6,0x19,0x14,0x5a,0x31, - 0x89,0xd1,0x28,0x39,0x28,0x28,0x5b,0xd9,0xca,0x29,0x94,0x06,0xb9,0x57,0x14,0xa8, - 0x5b,0x98,0x83,0x8f,0x0a,0x50,0x33,0x7d,0xa0,0x7e,0xcc,0x98,0x37,0xcf,0xad,0x35, - 0x05,0x56,0x07,0xc3,0xf9,0xe6,0xe0,0x73,0xc3,0x8b,0x63,0xd6,0x8d,0x8d,0x2f,0xce, - 0xba,0xe2,0x58,0x5a,0xe4,0x8b,0x00,0xb7,0x3b,0x2a,0xb9,0x9a,0xb9,0xd4,0x35,0xd0, - 0xe6,0x51,0x23,0x03,0xfd,0x01,0x75,0xad,0xf1,0x6d,0xe3,0x6e,0x29,0xf7,0xe5,0x9d, - 0x5b,0x69,0x78,0xa6,0x71,0x59,0x63,0xf9,0x5c,0xf4,0x80,0x25,0xd9,0x27,0x56,0x0f, - 0xc6,0x3b,0x28,0x13,0xf4,0x13,0x7a,0x99,0x11,0x22,0x43,0xc7,0x0c,0x80,0x08,0x3a, - 0xfa,0x6e,0xbc,0x1e,0xfa,0x20,0xe7,0xd1,0x07,0x1e,0x02,0x4d,0xc8,0x18,0x4b,0xb2, - 0x53,0x69,0xc6,0x8d,0x32,0x53,0x2b,0xf4,0x74,0x08,0x11,0x0a,0x75,0xe1,0x79,0x83, - 0xaf,0x4d,0x31,0x63,0x54,0x08,0xde,0x75,0xf3,0xdd,0xf7,0xa7,0xfe,0x39,0xea,0x8a, - 0x95,0x37,0x2d,0x23,0x11,0x36,0x3f,0xcd,0xf8,0xe9,0xcf,0xb2,0xd0,0xba,0xc4,0xb1, - 0xf1,0x3c,0x7d,0x65,0x55,0xae,0xf6,0x3b,0x4b,0x2a,0x0a,0x3a,0xff,0xf0,0xa4,0xbe, - 0xaa,0x38,0xe2,0x7b,0xdb,0xe7,0x02,0x2e,0x5c,0x96,0x1d,0x09,0x5c,0x06,0x46,0xd4, - 0xa1,0x12,0xd1,0xba,0xc5,0x0b,0x40,0xe3,0xdc,0x3e,0x9e,0xa1,0x31,0x24,0xc0,0xb9, - 0xe7,0xa7,0xb8,0xdc,0x95,0xc0,0xa5,0x06,0xc2,0x89,0x4c,0xf3,0x93,0xb5,0xaa,0xda, - 0xdc,0x4e,0x97,0x99,0x63,0x67,0x25,0xd2,0x9b,0x6e,0xc7,0x33,0xfc,0x60,0x05,0x0d, - 0x35,0x99,0xad,0xdd,0xf8,0x7e,0x16,0x16,0xa7,0xa2,0x27,0xe0,0xef,0xcd,0xc9,0x21, - 0x7b,0x3f,0x88,0x14,0x4a,0xfa,0x7f,0x20,0x6d,0xb7,0x54,0xb3,0x7b,0x01,0x30,0x09, - 0x98,0x0a,0xf1,0xed,0x63,0x19,0x97,0x2c,0x09,0x80,0x62,0x16,0xad,0x04,0x03,0x9a, - 0x9f,0xf8,0x51,0x19,0xa5,0xce,0x35,0x99,0x92,0x4d,0xb3,0x93,0x78,0x12,0xd6,0x08, - 0x51,0x6e,0x92,0xb9,0xd0,0x3b,0x8d,0x61,0xb0,0x6c,0xe4,0xb6,0xde,0xa9,0xe2,0x11, - 0xc2,0x66,0xfc,0xee,0x12,0xa4,0x26,0x3e,0x87,0x97,0x16,0x55,0x3a,0x93,0x80,0xce, - 0xea,0xf7,0x0e,0x96,0xb8,0xf5,0x80,0x6e,0xfb,0xa1,0x9d,0x7a,0x68,0x7f,0x5a,0x8c, - 0xd4,0x89,0xdd,0xd3,0xf8,0x82,0xd1,0xde,0xd7,0x47,0x27,0x60,0x4b,0xcf,0xb8,0xc0, - 0x33,0x14,0xeb,0x28,0xcc,0xf9,0xb4,0x67,0xa0,0xeb,0xaf,0xfa,0x5e,0xe4,0xe0,0xda, - 0x00,0x6b,0xe0,0xf2,0xdf,0xa0,0xe5,0x73,0xc8,0xba,0x2c,0x5d,0x9e,0x33,0x07,0xf5, - 0xfb,0x25,0x1c,0x68,0x7d,0x37,0x8b,0x12,0xcf,0x0a,0xbb,0x82,0x9c,0xb2,0x73,0x4f, - 0x7c,0x78,0x42,0x87,0xa5,0x86,0x6e,0xa9,0xfd,0x9f,0x99,0x64,0xa8,0xeb,0x78,0x4e, - 0xc5,0xd7,0xb8,0x7c,0x5c,0x44,0x3f,0xca,0x5a,0x94,0x47,0xf6,0x0d,0xba,0x1e,0xf2, - 0xf0,0xdc,0x23,0x1e,0x66,0xff,0x1e,0x1a,0x53,0x43,0xcc,0x74,0x1f,0x00,0x4e,0x44, - 0x7e,0x5a,0x75,0x78,0xc1,0x1b,0x9c,0x59,0x3a,0xfd,0x2b,0x5b,0xf0,0x8a,0x1e,0x58, - 0x4d,0x04,0x46,0xab,0x09,0x6f,0xd6,0x19,0x14,0xee,0xbf,0x2e,0x5b,0x6a,0x4d,0xea, - 0xf8,0x4f,0xa6,0xab,0xdd,0xbc,0x96,0x04,0x02,0x4e,0xc9,0x50,0x33,0x50,0x06,0x34, - 0x22,0x29,0x6c,0xb3,0x6e,0xcd,0xe5,0xd2,0xe1,0x5d,0xa5,0x58,0x37,0x4a,0xec,0x5d, - 0x52,0xdd,0x22,0xd3,0x87,0x33,0x7c,0x6b,0x5b,0x20,0x44,0xf5,0xf8,0xff,0xae,0x67, - 0xca,0x8a,0x2b,0xde,0x90,0x16,0x54,0x50,0x39,0x04,0xdf,0xca,0x44,0xbd,0xfc,0x16, - 0x6a,0xc5,0x1b,0x50,0x85,0x7f,0x64,0x84,0xa1,0xac,0xd8,0x99,0xaa,0xfc,0x00,0x15, - 0x36,0xe2,0xdd,0x3b,0x26,0x53,0x7a,0x84,0x4e,0x99,0x95,0x0b,0x22,0xfb,0x80,0x4b, - 0x23,0xc9,0xbc,0x09,0x9c,0xcf,0x8e,0x70,0x2c,0xad,0xad,0x58,0x95,0x3d,0x98,0xa8, - 0x32,0x6b,0x2a,0x64,0xfb,0xad,0xf5,0x93,0x2e,0xaa,0xab,0x2f,0xf4,0x5b,0x67,0xb5, - 0x12,0x29,0x2b,0x30,0x5c,0x56,0x97,0xdb,0x96,0xb1,0x74,0x51,0x0a,0x4c,0xa4,0x9e, - 0x47,0x0a,0xf9,0x5c,0xaf,0x67,0x1d,0x5c,0xd8,0x37,0x63,0x50,0xe2,0x00,0x38,0x14, - 0x80,0x4c,0x20,0x1b,0x35,0xa8,0xbe,0xc3,0x12,0x7b,0x46,0x8b,0x80,0xce,0xad,0x40, - 0x41,0xc1,0x2e,0x28,0x7a,0x24,0x77,0x56,0x01,0x40,0x4c,0xba,0xc7,0x2e,0xa3,0xed, - 0x5f,0x6e,0x3f,0x74,0x51,0x6b,0x36,0xe6,0xca,0x9f,0x6f,0xdb,0x73,0x69,0x4e,0xb3, - 0xff,0x89,0xd0,0x70,0xa4,0x3d,0x16,0x63,0x53,0x92,0x40,0xe5,0xba,0x2e,0x74,0x7a, - 0x46,0x0f,0x78,0xd3,0x78,0x15,0xe5,0xfc,0x30,0xea,0x3a,0x73,0x14,0x26,0xb5,0x96, - 0xca,0x3f,0xba,0x5d,0xde,0x54,0x6a,0xa2,0x93,0x3a,0xe0,0xce,0x5a,0x87,0xa2,0x57, - 0x0b,0xff,0xe7,0x9e,0xca,0x6e,0xe7,0xd7,0x45,0x8d,0x0e,0x65,0xb3,0xfc,0x62,0xbd, - 0x9b,0x32,0xc2,0xa1,0x02,0x35,0xfc,0x71,0xba,0x65,0xfc,0x46,0xcd,0xa9,0x22,0x42, - 0xac,0xf9,0x33,0x89,0xbc,0x14,0xbe,0x57,0x90,0xfb,0x4d,0xdc,0xeb,0x41,0xb3,0xbd, - 0xd8,0xa0,0xb3,0xf2,0x88,0x51,0x14,0x58,0xbb,0xb0,0xb3,0x4e,0x9a,0xed,0x89,0x86, - 0x91,0x4a,0x33,0x77,0xdb,0xba,0x7e,0x54,0x79,0x69,0xe0,0x88,0x24,0x16,0x0f,0x15, - 0xf4,0xd4,0xab,0x0d,0x78,0xaa,0xb9,0x55,0x47,0x1d,0xf2,0x9e,0x0a,0x70,0x12,0x58, - 0xf0,0x9d,0x7c,0x8d,0xea,0xd9,0x1a,0x36,0xca,0x04,0xd6,0x31,0x25,0x6e,0x40,0x05, - 0x61,0x5a,0xfa,0xa8,0xd3,0x8e,0x7f,0x93,0xc2,0x0d,0xe3,0x1e,0x2f,0x62,0x18,0xe5, - 0x12,0xdb,0x64,0x54,0xb0,0x8d,0x14,0x2f,0x3f,0x82,0xe5,0xc6,0xbe,0x14,0x37,0x2d, - 0xd5,0xfc,0x67,0xf5,0x85,0xcc,0x8c,0xf5,0x96,0x6e,0x75,0x45,0x1f,0xf1,0x46,0x2b, - 0xa7,0xf3,0xf5,0xa9,0x36,0xb9,0x47,0xcf,0xba,0x1a,0xa4,0x0c,0x6a,0x40,0x47,0xc7, - 0x18,0xf3,0x6d,0xae,0xde,0x89,0x2c,0x24,0xfe,0xae,0x67,0xc0,0x5d,0xa4,0xf4,0x30, - 0xef,0x48,0x37,0x93,0x67,0xc5,0x14,0x4e,0xa1,0xed,0x8a,0x8e,0x5b,0xc7,0xd1,0x80, - 0xda,0xfc,0x4d,0x7a,0xc5,0x4c,0xe5,0x74,0xc0,0x82,0x14,0x3d,0x1d,0x33,0x35,0x5f, - 0x59,0x83,0x7e,0x7d,0xfa,0x72,0x2a,0xcc,0x5a,0x88,0xdd,0xbe,0xb6,0x83,0x17,0x02, - 0x6c,0x68,0x0b,0x63,0xf1,0xe2,0x09,0x38,0x03,0x3e,0xa1,0xd5,0x7f,0x32,0xac,0x5b, - 0xe3,0xb5,0x07,0x0c,0x5a,0x63,0x47,0xf4,0xc7,0x0a,0xab,0xde,0x40,0x1f,0x86,0x10, - 0x15,0x11,0x68,0x32,0xc1,0x75,0x1a,0x21,0xff,0xee,0xac,0x26,0x30,0x39,0x97,0xd0, - 0xac,0x32,0xb7,0xa3,0x60,0xd9,0x1b,0x48,0x17,0x31,0xb4,0x9b,0x08,0x88,0x9b,0x12, - 0xcf,0x2c,0x25,0xc5,0x06,0x6c,0x1e,0x81,0xca,0xe3,0xe9,0x3d,0x25,0x82,0x80,0x50, - 0x96,0x86,0x78,0x59,0x01,0x03,0x90,0x43,0xf3,0x7e,0x90,0xd6,0xf9,0x41,0x48,0x07, - 0x45,0x97,0xa6,0x61,0x67,0xbd,0x48,0x08,0xce,0x6e,0x21,0x7b,0x5d,0x3b,0x94,0x32, - 0xf8,0xec,0xb8,0x28,0xae,0xbe,0x74,0xb1,0x6d,0x61,0xb3,0xd9,0xa0,0x2d,0x69,0xd8, - 0xd1,0x03,0xe2,0x35,0x35,0xe5,0x9e,0xd8,0xe5,0x29,0xa0,0xda,0x81,0x2c,0x13,0x25, - 0x55,0x02,0x13,0x42,0x17,0x7d,0x33,0x94,0xfe,0x8d,0xc3,0xf3,0xd9,0x94,0xb8,0xe4, - 0x64,0x5a,0x63,0x34,0xf8,0x31,0x4d,0xbb,0xcb,0x83,0x71,0x00,0xd6,0x9e,0x64,0xb6, - 0x15,0x20,0xc2,0x0f,0xa0,0xbb,0x1e,0x9d,0x54,0x22,0x16,0xbb,0x28,0x4d,0x65,0xec, - 0x6d,0xa7,0xa2,0xab,0xf7,0x1a,0x2e,0x20,0xd6,0x59,0x81,0x78,0x37,0x8d,0x21,0xa5, - 0x62,0x9c,0x3e,0xe3,0x2e,0x1a,0xba,0x85,0x35,0x29,0x4e,0x53,0xf0,0xd4,0xf7,0x00, - 0x9f,0xae,0x80,0x08,0xa8,0xe7,0x6c,0x5e,0x1c,0xe1,0x8a,0xf6,0x40,0x82,0xfa,0x6a, - 0x5f,0x10,0x08,0xac,0xa4,0xbf,0xec,0x2d,0xd2,0xdf,0xed,0xe9,0xe2,0x9f,0xc6,0x3a, - 0xf9,0xce,0x6f,0x1e,0x85,0xfb,0x2c,0x6e,0xbc,0x32,0x46,0x36,0x47,0xef,0x78,0x23, - 0x91,0x4e,0xbd,0x0d,0x9e,0x72,0x17,0x41,0x0d,0xc1,0x6a,0x4f,0xa7,0x6b,0xda,0x6f, - 0xfb,0xc3,0xdf,0xb1,0x5f,0xfe,0x09,0xb9,0x64,0xd3,0x57,0x69,0x73,0x25,0xe3,0xb2, - 0x93,0x0f,0xc4,0xd4,0x8a,0x2e,0xcf,0x0b,0xda,0xff,0x14,0xce,0xb5,0x15,0xaf,0xf1, - 0xb1,0xff,0x6e,0xe9,0xe2,0x73,0x27,0x33,0x2b,0xa3,0xfe,0x85,0x99,0xbd,0xe4,0x32, - 0xcf,0xd8,0x9e,0x4d,0xc7,0xab,0x2b,0x16,0xda,0xc1,0x07,0xba,0xb5,0xae,0x2f,0xf1, - 0x24,0x4e,0xf6,0x8a,0xb4,0x6e,0x68,0xa3,0x20,0xe8,0x6d,0xeb,0xb6,0xc8,0x37,0x1d, - 0x82,0xe5,0x39,0xcd,0xc0,0x65,0xc3,0x24,0x68,0x2f,0x21,0x58,0x37,0xed,0x26,0xa7, - 0x0d,0x0e,0x33,0xb5,0x34,0xcc,0x0c,0x8c,0x6f,0x4f,0x65,0x4f,0x70,0x48,0xda,0x8a, - 0x33,0x19,0x3f,0xec,0xff,0x29,0x42,0xce,0xed,0xd6,0xe8,0xbc,0x03,0x12,0xe2,0xfb, - 0x70,0x42,0xc2,0xaf,0xa5,0xd1,0xbc,0xae,0xda,0x4c,0x2a,0x2e,0xe5,0xfb,0xda,0xfc, - 0x4f,0x6b,0x3a,0x8d,0xd4,0xeb,0x8e,0xac,0xc5,0xfa,0xb8,0x9d,0xdf,0xd8,0x3b,0x17, - 0xdb,0xbe,0xfc,0x59,0xed,0xb0,0x80,0x19,0x8e,0x9d,0xff,0x3a,0xea,0xc1,0xae,0xa5, - 0x27,0x93,0x47,0x1d,0x4b,0x6c,0xcc,0x1e,0xf5,0xdb,0x63,0x5e,0xb4,0x0f,0xd0,0x88, - 0xd2,0xca,0x18,0xe7,0xf4,0x87,0xdb,0xeb,0xad,0x55,0xf4,0xcd,0xdf,0x43,0xf9,0x67, - 0x13,0x5c,0x94,0x1f,0xb0,0x70,0x2a,0x87,0x50,0x0b,0x79,0x2d,0x5f,0x93,0x64,0x3f, - 0xb7,0xdd,0x75,0xe2,0xe9,0xa8,0x90,0x4c,0x03,0xb7,0x26,0x0a,0x3a,0x6c,0xcb,0x88, - 0x49,0x74,0x73,0x91,0x0e,0x33,0x05,0xf5,0xfc,0x41,0xa7,0x52,0xd6,0xdd,0xdd,0x56, - 0xd7,0x36,0x79,0x07,0xf1,0x19,0x97,0x8e,0x91,0xd9,0x76,0xb4,0x02,0xc5,0x6e,0xf4, - 0x70,0x6c,0x89,0x12,0x16,0xb5,0xc5,0xb6,0x3c,0xb2,0x51,0x9f,0x3b,0x9a,0x54,0xff, - 0xf2,0x6e,0x90,0x8f,0xbb,0xeb,0x71,0x90,0xfd,0x9c,0xed,0x82,0x51,0x7b,0xe7,0x62, - 0xc8,0x6b,0x07,0x45,0xf5,0x7d,0x70,0x79,0x7b,0xb1,0x84,0x35,0x7f,0x2f,0x8f,0x77, - 0x8c,0x4d,0x4d,0xbd,0xbb,0x09,0x9d,0x79,0x12,0xc4,0x0d,0x31,0x21,0xdb,0xd6,0xa0, - 0x90,0x10,0xb1,0x49,0xb6,0xf2,0x09,0xf1,0x90,0x83,0xb0,0x6f,0x69,0xc1,0x5f,0x1b, - 0x91,0xba,0xce,0x3b,0x10,0x9d,0x7d,0x95,0x37,0x11,0x5e,0x24,0x9a,0x7c,0xce,0x02, - 0xf8,0x98,0xe1,0xdb,0x98,0xd5,0x2c,0xb1,0x03,0xfe,0x72,0x9a,0xbe,0x75,0xa8,0x10, - 0x48,0x27,0x3e,0xc5,0xb6,0xd5,0xad,0xee,0x1c,0x50,0xea,0x33,0x6e,0x81,0x6a,0x05, - 0x15,0xc0,0x73,0x72,0x82,0x0d,0xf6,0x95,0x3b,0x2a,0x69,0x50,0xad,0x0a,0x68,0x60, - 0xfb,0xbb,0xea,0x71,0xb0,0x0a,0x48,0xc6,0x7b,0x13,0xf5,0xba,0x2d,0xb1,0xb8,0xee, - 0x9f,0x9d,0x34,0x3b,0xab,0x4c,0xae,0xdd,0x22,0xa9,0x69,0x6d,0x57,0x09,0xed,0x4e, - 0x96,0xda,0x24,0x56,0x3a,0x4c,0x57,0xd2,0x58,0xbb,0x3c,0x13,0xd9,0x31,0x9b,0x09, - 0x5e,0x1d,0xd0,0xe0,0xb8,0xac,0x0b,0xfb,0x80,0x4f,0xe5,0xc9,0x63,0x8f,0x51,0x28, - 0x3e,0x74,0x41,0x7d,0x08,0x56,0x2b,0x82,0x55,0x84,0xe7,0x6b,0xe8,0x67,0x5c,0xee, - 0xa7,0xe7,0x81,0x60,0x03,0xba,0x38,0xd9,0x85,0x0a,0xd8,0x64,0xa9,0x55,0x45,0x47, - 0x17,0x18,0x0b,0xf1,0x66,0x49,0x29,0x82,0x25,0xb1,0x74,0x07,0xac,0x36,0xcf,0xa9, - 0xe0,0x1d,0xf5,0x81,0x42,0x3d,0xeb,0xac,0xcb,0xd2,0xdd,0xe6,0x68,0xbb,0x19,0x1e, - 0xd6,0x3a,0x98,0xc8,0xc8,0xc2,0x8c,0x72,0x6b,0xfd,0xbc,0xb5,0x71,0xb6,0x31,0x7d, - 0xf8,0xfc,0x5a,0xab,0x7c,0x94,0x96,0x5b,0x3e,0x5d,0x5b,0xd2,0x26,0xbb,0xf8,0xf7, - 0xb4,0xd1,0xd1,0x8f,0xf5,0xa1,0x38,0xcd,0x58,0xf6,0x51,0x4b,0x16,0x61,0x11,0xb6, - 0x4f,0x8b,0x5c,0x88,0xa7,0xd2,0xe3,0x20,0x2e,0x03,0x47,0xdf,0x83,0xf1,0x64,0x76, - 0xd7,0x26,0x38,0x25,0xca,0xac,0x17,0xd4,0x69,0x63,0x84,0xa4,0x18,0x93,0x14,0x46, - 0x43,0x9a,0xcb,0xc2,0xb8,0x7c,0x34,0x73,0x4d,0x78,0x3c,0xd4,0x77,0x0f,0xe1,0x28, - 0x76,0x83,0x73,0xbe,0x48,0x5d,0xda,0xbf,0x8b,0x65,0xe7,0xb9,0x37,0xc2,0x1d,0x78, - 0xbc,0x7f,0xde,0x74,0x23,0x46,0x0f,0x4d,0xfe,0x35,0x48,0x84,0x01,0x99,0x14,0x57, - 0x54,0xd2,0xdb,0xa7,0xaa,0x78,0x6c,0xf9,0xee,0xd4,0x4f,0xc1,0xc9,0xd3,0xa5,0xa7, - 0x50,0x64,0xd8,0xb2,0xb1,0xcb,0xb5,0xe5,0xf4,0x3a,0xef,0xad,0xd3,0x09,0x27,0x4a, - 0x66,0xfe,0xce,0x60,0xa9,0xab,0xf9,0xa4,0x68,0x48,0xaa,0x04,0xe8,0xb8,0xfe,0x68, - 0xfa,0x12,0xa7,0x6f,0xdd,0xae,0x6c,0x40,0xdc,0x7d,0xbc,0x31,0xd0,0xbe,0x09,0x61, - 0xe9,0xaf,0x93,0xc6,0xb7,0x39,0xb3,0xf5,0xc0,0xd2,0x38,0x54,0x93,0x99,0x81,0xf1, - 0xaa,0x51,0x5a,0xf3,0x00,0x60,0xa3,0x50,0xd5,0xf5,0x60,0x87,0xc6,0x8e,0xb4,0x60, - 0xea,0x67,0xe1,0x7b,0x90,0xac,0xb6,0xd1,0xdd,0xf8,0x63,0xdd,0x65,0xf9,0x6c,0x1a, - 0x50,0x94,0xb1,0x3f,0x3c,0xce,0x2a,0xc4,0xcf,0x70,0xc1,0xed,0xd4,0x23,0x2d,0x84, - 0x48,0x4f,0x44,0x2b,0x34,0xe0,0xb8,0xb5,0xcc,0xba,0x53,0x9e,0x0e,0x16,0xf8,0x22, - 0xb3,0xac,0x19,0x3b,0x9a,0x2d,0x83,0xc1,0xa0,0x39,0x51,0xa3,0xfc,0xc3,0x8d,0xea, - 0x5b,0xed,0x56,0xe3,0xce,0x01,0xec,0xb2,0x9b,0x90,0xe6,0xa3,0x9f,0x0a,0xd3,0xdd, - 0xcc,0x4b,0xe4,0x22,0x12,0x43,0x2d,0xc1,0xa3,0x38,0x92,0x33,0x5a,0x9c,0xed,0xf0, - 0x23,0x3d,0x20,0xf2,0xbc,0x76,0xa7,0x6b,0xd0,0x73,0x4a,0xe0,0x65,0x5f,0xf6,0x4e, - 0x05,0x1d,0x6b,0x6d,0x71,0x9b,0x43,0x97,0x9a,0x11,0xae,0xe8,0x98,0x23,0xad,0x18, - 0xd9,0xb7,0xd3,0xa7,0xbd,0xd0,0xc6,0xe3,0x5f,0x17,0x54,0xf0,0x32,0x7f,0x3a,0x45, - 0x7b,0xd2,0x08,0xd2,0xd7,0xf6,0x79,0xf7,0xa7,0x9b,0x2d,0xa0,0xf9,0x78,0x0e,0x8a, - 0x97,0xce,0x82,0x92,0x8c,0xd3,0xd4,0x8d,0xab,0x50,0x4e,0x2f,0x1b,0x39,0x41,0x69, - 0x14,0x98,0x32,0x79,0x8c,0x91,0x22,0x64,0x4f,0x19,0xf2,0x60,0xbf,0x2e,0xf0,0xfa, - 0x50,0x76,0xb3,0x3a,0x23,0x43,0x93,0xb0,0x38,0x66,0x25,0xb3,0x4a,0xcc,0x4d,0x6f, - 0xe5,0x33,0x91,0xde,0xf4,0xb9,0x52,0x27,0x4b,0xf6,0x5c,0x0a,0x6e,0x40,0xfd,0xa7, - 0x91,0x75,0xc6,0xc8,0x0f,0x96,0x3c,0x48,0xb9,0xa6,0x12,0x39,0x58,0x17,0x99,0x99, - 0x0c,0x46,0xf2,0x83,0x7b,0xa4,0x88,0x9b,0x6f,0x2a,0x51,0x7c,0x9a,0x03,0x76,0x00, - 0x1f,0x10,0x93,0xbf,0x0d,0x47,0x0f,0x02,0x14,0x1a,0x0a,0x5b,0x03,0x20,0x92,0xa4, - 0x4d,0xe2,0x92,0x35,0x4b,0x94,0x2a,0x62,0xdf,0x1e,0xff,0x96,0x25,0x12,0x85,0xb7, - 0x48,0x25,0x8c,0x81,0xc4,0xde,0x32,0x4f,0xb1,0x9e,0x84,0xe3,0x18,0x0e,0x81,0x94, - 0x01,0x5b,0xef,0xee,0x31,0x41,0xf3,0x30,0x0c,0x13,0x2d,0x1d,0x43,0xa5,0x87,0x88, - 0x83,0x7a,0x6f,0x2c,0xfe,0xcb,0x3e,0xc9,0xcd,0xa5,0xc7,0x48,0x37,0xc5,0x05,0x53, - 0x98,0x9d,0x3d,0xa9,0x15,0xe1,0x2d,0xfe,0x4b,0xb1,0xe1,0x6e,0x48,0x71,0x75,0xae, - 0x0e,0x11,0x63,0x1b,0x50,0x8c,0x49,0x5f,0x64,0xb3,0xb3,0xcf,0x77,0x29,0x95,0xc6, - 0x97,0x3b,0x3f,0x1c,0x2e,0xc4,0x11,0xa5,0xd5,0x6a,0x3c,0x1b,0xd6,0x82,0x5c,0xa3, - 0x98,0xda,0x2a,0xd3,0x59,0x44,0x92,0xa7,0xb2,0x84,0x93,0x25,0xf3,0x48,0x36,0x18, - 0x03,0xe9,0x93,0x8f,0xb6,0x31,0x41,0xa2,0x91,0x85,0xbe,0x0b,0x9d,0xb3,0xf4,0xbf, - 0x35,0x69,0x64,0x89,0x6d,0x44,0x8a,0x0f,0x0d,0x13,0xf2,0xcc,0x49,0x31,0xe1,0x7d, - 0x17,0xce,0x5b,0x0a,0xa5,0x72,0xa5,0xbd,0x3b,0xcb,0x49,0x72,0x60,0x4a,0x9b,0x41, - 0xa2,0xb8,0xa3,0x09,0x39,0x38,0x17,0x20,0xaf,0x27,0x8f,0x4e,0x86,0x36,0x44,0x12, - 0xeb,0x54,0x28,0xae,0x20,0xc1,0x9d,0x29,0xb6,0x66,0xc0,0xf5,0x8a,0xb8,0x68,0x04, - 0xd1,0x19,0x6f,0x4e,0x86,0x10,0x5c,0x28,0x3b,0xfc,0x33,0xe3,0x5b,0x9b,0xf2,0x66, - 0x84,0x73,0xec,0xd4,0x67,0x90,0x9a,0x0a,0xe6,0x45,0x12,0x49,0x18,0x0b,0xa1,0x29, - 0x3a,0x48,0xac,0xe4,0xa8,0x9b,0xb0,0xdc,0x9e,0xaa,0xea,0x0a,0x59,0xf8,0x69,0x20, - 0x24,0xf0,0x4c,0x4a,0x23,0xf5,0x21,0x29,0xe9,0x6f,0xc1,0x21,0x1e,0x62,0xaf,0x9f, - 0xb8,0x04,0xaf,0x99,0xf8,0x41,0x0a,0x56,0x18,0x73,0x75,0xc6,0x45,0xef,0x29,0xd9, - 0x23,0x54,0xac,0x25,0x95,0x88,0xb5,0x5a,0x64,0x12,0x32,0x72,0x2a,0x57,0x68,0x48, - 0xa1,0x5a,0x6f,0x74,0x9b,0x17,0xf8,0xd3,0xfa,0x2a,0x8a,0xac,0x54,0x6d,0x37,0xc0, - 0xfc,0x26,0x12,0xd4,0x5c,0x35,0x7a,0x2c,0xd6,0xe3,0x9f,0x8b,0xbf,0x29,0x46,0x64, - 0xcc,0xce,0x45,0xc2,0xeb,0x01,0x70,0x71,0x1f,0x2b,0xdb,0x34,0xc7,0xd8,0x76,0x99, - 0x6c,0x1f,0xbc,0x35,0xb1,0x6f,0x17,0xe5,0x83,0x25,0xe1,0x1d,0xf7,0x84,0xaa,0xfe, - 0x8e,0x58,0x27,0xdd,0x49,0xa3,0x6e,0xce,0x95,0x4d,0xc4,0x97,0x64,0x66,0xc9,0xca, - 0x86,0x8c,0x53,0xa5,0x4a,0xcc,0x6c,0xdb,0x64,0xf8,0xeb,0xe4,0xe7,0x58,0x75,0x0d, - 0x9a,0x99,0x5e,0xb2,0xa2,0x09,0x42,0x8a,0x3e,0xed,0x87,0x51,0x3d,0xa2,0x77,0xe0, - 0x94,0x2a,0xc2,0x78,0x20,0x84,0xc8,0x54,0xe9,0x72,0x95,0x5d,0xf5,0x4d,0xcb,0xac, - 0xd3,0x22,0xb7,0x6b,0x2b,0xb9,0xa9,0xa3,0x67,0x58,0x51,0xbb,0x9a,0x28,0x8e,0xba, - 0xae,0xaf,0xca,0xd1,0xef,0x72,0x1e,0x31,0xce,0xb2,0xaf,0xe9,0xe8,0xad,0x31,0x33, - 0x7b,0xea,0x42,0xff,0x52,0xbf,0x89,0xbf,0xec,0x1b,0x56,0xd9,0x44,0xed,0x67,0x3d, - 0x2e,0x0d,0x38,0xc9,0x4e,0x18,0xd0,0xfd,0x82,0x81,0xec,0xeb,0x4d,0xf8,0x66,0xa9, - 0x43,0x46,0x9b,0xb5,0x83,0x5f,0xa2,0x7d,0x8a,0x0d,0x65,0xcd,0x66,0x97,0xca,0x97, - 0xe4,0x85,0xba,0x66,0x7d,0xb3,0x85,0x44,0xac,0xcf,0x08,0x25,0xfc,0x5c,0xa2,0x9b, - 0x21,0x00,0xeb,0xbc,0x5f,0xe6,0xcf,0xc7,0x1b,0x97,0x6d,0xce,0x34,0x04,0x24,0x87, - 0x93,0x98,0xe7,0xec,0x84,0xc9,0x9d,0xa2,0xd3,0x13,0x6c,0xab,0xcf,0xf2,0x24,0xed, - 0x20,0xdb,0x45,0x24,0xbb,0x86,0x71,0x77,0x75,0x23,0x1a,0xad,0x3f,0xbf,0x43,0x25, - 0xc4,0xaf,0x15,0xad,0x05,0xef,0x4c,0x40,0x79,0x08,0x95,0x3a,0xbb,0x2d,0x0d,0x43, - 0xf4,0x56,0xa5,0x5d,0xe5,0xe1,0xb5,0x43,0x0e,0x45,0xb1,0xf3,0x83,0x33,0x36,0xc1, - 0x4f,0xaa,0x9e,0xa6,0xd2,0x9e,0x54,0x57,0x42,0x3a,0xf7,0x83,0xeb,0x15,0xdf,0xae, - 0xdd,0x3f,0xa7,0xaf,0xb2,0x72,0xfc,0x74,0x47,0x68,0x98,0x91,0x9a,0xd0,0x4d,0xfb, - 0xba,0x38,0x15,0x81,0xeb,0x17,0xc4,0xad,0x32,0x5c,0x81,0x92,0x10,0xd6,0xd4,0x4f, - 0xf8,0xb2,0xca,0x3a,0xa0,0xdd,0x8d,0xcb,0x4d,0x8c,0xb8,0x56,0x93,0xed,0x45,0x07, - 0x17,0x4a,0xbb,0x7a,0xc0,0x79,0x2e,0x0f,0x0b,0xdf,0x9c,0xf9,0x29,0x00,0xcb,0x86, - 0x53,0x01,0xcd,0x8b,0xee,0x50,0x01,0x4b,0x7a,0xb7,0x6e,0x08,0xce,0xd2,0xfa,0x41, - 0x85,0xcc,0x9b,0x4f,0x26,0x22,0x87,0xe8,0x06,0x02,0x59,0xc1,0x8f,0x41,0x64,0x8c, - 0x42,0x01,0xbd,0x33,0x1a,0x0b,0x80,0x79,0x4f,0x91,0xd7,0x95,0x92,0x05,0x07,0xf8, - 0x55,0xd4,0xcc,0x01,0x0c,0x0c,0x1e,0xf6,0x85,0x2e,0x83,0xb9,0xd7,0x4e,0x66,0x40, - 0xc0,0xe7,0x43,0xdd,0xd3,0x54,0x8e,0xf1,0xef,0xf5,0xab,0x6f,0xfc,0xc4,0x3e,0x48, - 0x92,0x52,0x2b,0x54,0x6b,0x03,0x7d,0x44,0x89,0x82,0xea,0xe3,0xc9,0x94,0xd6,0x1c, - 0xaa,0x79,0xb9,0xe0,0xb9,0x8e,0x0f,0xbe,0xb2,0xbe,0xd4,0xec,0x6a,0x7a,0x96,0xd5, - 0x20,0x60,0x3c,0x84,0xc7,0xd9,0x3e,0x09,0x31,0x32,0x53,0x82,0xa5,0x21,0xd7,0x20, - 0xde,0x4d,0x7b,0x9c,0xa5,0x9a,0x17,0x21,0x85,0xc6,0x62,0xa2,0xd1,0xae,0x36,0xee, - 0xcd,0x83,0x63,0x9d,0x3f,0xa3,0x9e,0x27,0x69,0xa3,0x71,0x1a,0x07,0x27,0x9f,0x10, - 0x52,0xf0,0xb8,0x0e,0x91,0x3c,0x55,0xd3,0xf5,0x15,0x25,0x0c,0xf7,0xd4,0x5b,0xea, - 0x11,0xdb,0x6e,0x21,0x52,0x4c,0x58,0x4e,0x7d,0xeb,0x5e,0xbc,0x45,0x55,0xfc,0x69, - 0xee,0xa2,0x6a,0xe3,0x4d,0x6d,0x33,0xdf,0x58,0x35,0xa6,0x94,0x8e,0xb3,0x3d,0x4d, - 0xa6,0xee,0xcd,0xf5,0x6e,0x8a,0xc8,0x65,0x52,0x2c,0x44,0xf1,0x24,0x98,0xca,0xd7, - 0x2d,0x54,0xb1,0x8f,0x44,0x05,0x89,0x0e,0x8e,0x81,0xe8,0x10,0xc1,0x4a,0x92,0xa3, - 0xe9,0x14,0x57,0x48,0xdc,0xe3,0x3f,0xf5,0x68,0xd6,0x53,0xf9,0xa4,0x9f,0xfa,0x99, - 0xfb,0x54,0x6e,0x12,0xfd,0x5e,0x31,0xed,0x5c,0x95,0xc8,0xc7,0x2b,0xbf,0xbd,0x3f, - 0xdc,0x05,0x69,0x02,0x64,0x6e,0xc0,0x97,0x7d,0x7a,0x1a,0xbf,0x1c,0x5a,0xf1,0xe9, - 0xe1,0xae,0xad,0x49,0x5b,0x0a,0x17,0xc1,0x8f,0xb5,0x66,0x93,0x00,0x39,0x56,0xe9, - 0x38,0xc0,0xbb,0x36,0x25,0xb0,0xb6,0xa3,0x77,0xac,0x75,0x92,0x2f,0xee,0xa0,0xf3, - 0x98,0x5e,0x43,0x33,0x6e,0x05,0xbd,0x20,0xd8,0x04,0xe6,0x5e,0xd0,0x2b,0x66,0x12, - 0xa9,0x05,0x81,0xcf,0xeb,0x26,0x53,0xfb,0x2d,0xa8,0x6a,0x2f,0xcc,0x5a,0x96,0x01, - 0xa5,0x6b,0x57,0xc8,0x54,0x5a,0xdd,0xcb,0x95,0x42,0xbd,0x0b,0x2c,0x74,0xc8,0x20, - 0xe3,0x8b,0xad,0x8f,0xfd,0xe5,0x28,0x43,0xa4,0x22,0x12,0x12,0x92,0x9b,0xa3,0x55, - 0xc9,0x61,0x8f,0x49,0x3d,0x52,0xdd,0x7e,0xb8,0xfd,0xe9,0xd2,0x5a,0xaa,0x32,0x5c, - 0x1d,0x04,0x35,0x8d,0x69,0x04,0xb5,0x01,0x97,0x2e,0x6b,0x3c,0x01,0xcf,0x1b,0xc3, - 0x07,0x95,0x2c,0x8b,0xe8,0x8e,0x03,0x28,0xac,0xc8,0x44,0x78,0x8f,0x04,0xf4,0x65, - 0xfb,0x41,0xdc,0xda,0x99,0xc6,0x71,0xeb,0x87,0x6e,0xb8,0x99,0x86,0x70,0xfb,0xf9, - 0x71,0x93,0x07,0x40,0xad,0xa5,0x31,0xad,0x17,0x21,0x34,0xc9,0xd2,0xbc,0xd6,0xd9, - 0x41,0x55,0xeb,0x51,0x16,0x2a,0xfb,0xa3,0x6a,0x3f,0xe9,0x9d,0x1a,0x39,0xf8,0xc9, - 0x7c,0xbf,0x81,0xb0,0x42,0xe2,0x36,0x98,0x24,0x74,0x17,0x86,0x05,0x08,0x5c,0xc8, - 0x4e,0x59,0x47,0xc0,0x9b,0x92,0x42,0xe5,0x14,0x5a,0x3a,0xdb,0x76,0x55,0x7e,0xfa, - 0x63,0x3d,0x1d,0x66,0x73,0xfa,0xb6,0x2e,0x76,0xbc,0x40,0xec,0xac,0xfb,0x19,0x55, - 0x1a,0xa8,0x55,0xb6,0x6d,0xe3,0x13,0x62,0xcf,0x55,0xb3,0x9c,0x4e,0x28,0x6c,0x82, - 0xce,0x61,0x59,0x4d,0xd8,0x66,0x85,0xbc,0x0c,0xbe,0x29,0xc3,0xa4,0x97,0xc0,0x3e, - 0x15,0x7d,0x0a,0xe5,0x18,0xab,0x87,0xf7,0x43,0x2a,0x82,0xb2,0x38,0x45,0x95,0xc7, - 0x05,0xbe,0x96,0xc7,0x61,0x11,0x0a,0xa4,0x29,0x45,0xbc,0x1c,0x9c,0xf0,0xd5,0xa6, - 0x63,0xc5,0xb8,0xa8,0x78,0x85,0xba,0x52,0x8f,0x21,0x5d,0x19,0x9d,0x1c,0x3a,0xe5, - 0x7f,0xbf,0xe7,0xd7,0x75,0x50,0x3c,0xc2,0xa3,0xfe,0x8f,0x74,0xfa,0x45,0xab,0xf4, - 0x05,0x47,0xf9,0xf1,0xed,0xf3,0x38,0xd2,0xa1,0xb4,0x3a,0x75,0x0a,0x7d,0x8b,0x23, - 0x7a,0x0a,0xb3,0x7b,0x15,0xc7,0x86,0x81,0x3e,0x50,0xc4,0xd8,0x2f,0x83,0x47,0x65, - 0x97,0x91,0xee,0x13,0x70,0xa5,0x1a,0xff,0x06,0x82,0x87,0x04,0x69,0x26,0x07,0xed, - 0x33,0x06,0x9d,0xd8,0xe0,0x90,0xb8,0x59,0xba,0x1b,0x72,0x59,0x13,0xac,0x03,0x3c, - 0x5b,0x9b,0x46,0xd4,0x32,0x91,0xf7,0x90,0x6c,0x18,0x87,0x4f,0x46,0xf6,0xea,0x03, - 0x3c,0xa9,0xaa,0x45,0x74,0x9f,0x7f,0xd1,0x44,0xc1,0x97,0x8e,0xca,0xfa,0x32,0x10, - 0x65,0x15,0x10,0x1e,0xf6,0x86,0x19,0x74,0x43,0xa7,0x30,0x20,0xf4,0xb8,0xfb,0xb4, - 0xd5,0x0a,0x01,0x9e,0xb4,0xe2,0x42,0x4a,0x89,0xe6,0xa6,0xaf,0x4e,0x0b,0x2f,0x01, - 0x2a,0x3e,0x56,0xac,0x13,0x57,0x7b,0x36,0x0b,0x99,0x8c,0x06,0xcd,0x5c,0x22,0x0a, - 0x5f,0x22,0x3b,0xd3,0xc7,0xae,0x6f,0x37,0xeb,0xae,0xa6,0x72,0x20,0x74,0x6a,0xd2, - 0xf2,0x6d,0x88,0x42,0x0c,0x09,0x92,0x63,0x97,0xc6,0x00,0x80,0x0f,0xb1,0x13,0x50, - 0xd7,0x91,0x9d,0x7d,0xaa,0x49,0xb7,0xb3,0x30,0xa3,0xf2,0x34,0xf3,0xfa,0x75,0x7c, - 0xb3,0xbc,0x82,0xfd,0x34,0xf4,0x02,0xaf,0x3a,0x3f,0x19,0x9b,0x76,0xf3,0x21,0x0c, - 0x22,0x1d,0xe6,0xb3,0xae,0x9a,0xb4,0xae,0xd4,0xfc,0xc2,0x1b,0x13,0xe4,0x10,0x32, - 0xba,0x13,0x96,0xd6,0x2c,0x1a,0x67,0xbe,0xdc,0xc6,0x17,0xda,0x48,0x2d,0xb3,0xf4, - 0xc7,0x49,0x34,0x28,0x12,0x54,0x5a,0xa7,0x0f,0xf0,0xb4,0x71,0x39,0x5f,0x66,0xad, - 0x55,0x11,0x9c,0x42,0x27,0x47,0x2f,0x0a,0xa3,0xca,0x95,0x0d,0xd1,0x5c,0xab,0xf0, - 0x11,0x21,0x84,0x18,0x57,0x76,0x1d,0x94,0xed,0x4d,0xbe,0x44,0xee,0x4a,0xdb,0x38, - 0x46,0xba,0xed,0xa4,0x4b,0x38,0xa0,0x4e,0x3d,0xd0,0x2c,0x37,0x96,0xe3,0xde,0x8b, - 0x4b,0xb8,0xa4,0xe8,0xeb,0x9a,0xf2,0x64,0x7d,0x55,0x7d,0xaf,0xc7,0x28,0x85,0xd2, - 0x2e,0x62,0xa5,0x51,0x3b,0xcf,0xba,0x0c,0xb1,0x30,0x68,0x16,0xaf,0x2e,0x83,0x51, - 0xa5,0x0f,0xc8,0xbf,0x10,0xb7,0xc9,0x90,0x8d,0x36,0x99,0xd7,0xee,0x42,0x36,0x8a, - 0x43,0xa2,0xfe,0x5d,0x74,0x6e,0xdb,0x70,0x0c,0x37,0xaa,0x22,0x8f,0x26,0x75,0xcd, - 0x8b,0x31,0x07,0xc3,0x45,0x7d,0x25,0x2a,0x81,0x67,0x3b,0xa4,0xc6,0x03,0x65,0x7f, - 0x46,0x76,0xf1,0x33,0xd4,0xae,0xe1,0x6b,0xe3,0x27,0xa4,0x26,0x37,0xac,0x31,0x07, - 0x7a,0x67,0x46,0x13,0xa9,0xf8,0x99,0x5a,0xb7,0x5e,0xbb,0x80,0x04,0x99,0x6b,0x7b, - 0x5e,0x3b,0x8f,0x40,0x9a,0x14,0x54,0x69,0x77,0x60,0x81,0x00,0xc6,0x9d,0x03,0x10, - 0x04,0x0e,0xa8,0x4c,0xb0,0xed,0xac,0x26,0xf9,0x2e,0xfa,0x8e,0x5f,0xe0,0x1d,0xa3, - 0x15,0x88,0xb8,0xb8,0x30,0x35,0x5b,0x30,0xda,0x0f,0xc1,0x81,0x99,0x42,0x1e,0xa0, - 0x92,0x89,0xec,0xf9,0x70,0x39,0x8a,0x9e,0x60,0x2e,0x11,0xb5,0xde,0x56,0xcf,0xaf, - 0x3a,0x00,0x8b,0xd8,0xce,0x0c,0x84,0x7e,0x5d,0xc2,0xb9,0x30,0x0c,0x5c,0xad,0x19, - 0xda,0x4b,0xbf,0x7e,0x80,0x85,0xad,0x54,0xae,0xba,0x2c,0xf9,0x70,0x31,0xb1,0xc4, - 0x50,0x89,0x7a,0x0d,0xe3,0xcb,0xef,0x56,0x0c,0x2b,0x57,0x24,0x00,0x0e,0x7c,0xfd, - 0xb8,0x96,0x4d,0xac,0x41,0x1f,0xb3,0x11,0x22,0x1f,0x6a,0xf2,0xdb,0xf2,0x5b,0x0d, - 0x6a,0x57,0x08,0x9a,0x52,0xf2,0x9e,0x30,0xf2,0xc7,0x7d,0xe2,0x9a,0x03,0x5c,0x85, - 0xae,0x15,0xdb,0xf9,0x86,0x16,0x1b,0xfb,0x6e,0x64,0x24,0x57,0xcd,0x28,0xa6,0x60, - 0x76,0x6c,0x8a,0xd9,0x7f,0x3a,0xe3,0xae,0x8a,0x39,0x40,0xa4,0xc1,0x4f,0xbc,0xb2, - 0xe3,0xcd,0x15,0x7e,0x0a,0x35,0x00,0x02,0xe4,0x7b,0x18,0xb4,0x48,0xa0,0x45,0xd2, - 0x30,0x25,0x69,0x7c,0x8b,0x36,0x02,0x51,0x6c,0x94,0x0e,0x2a,0x96,0x1e,0x2d,0x5b, - 0xdf,0x19,0x7a,0xf8,0x56,0x8c,0x43,0x68,0x58,0x26,0x29,0xc8,0xd1,0xfb,0x5b,0xa6, - 0x58,0xc7,0xf2,0x9a,0xe4,0x41,0x26,0xa9,0x23,0x2f,0x36,0x9a,0xae,0x25,0x3f,0x37, - 0x8e,0x41,0x1c,0x9d,0x96,0xb9,0x53,0xfc,0x99,0x8d,0x5c,0xa8,0x24,0x9a,0x8e,0xf6, - 0x77,0x53,0xda,0x1c,0x4c,0xb8,0x92,0x0c,0xe9,0xca,0xa3,0x70,0x31,0x36,0xc4,0x9c, - 0x6e,0x34,0x6d,0x26,0x3d,0x44,0xe6,0x54,0x9b,0x27,0xbf,0x9d,0x8f,0x04,0x5f,0x2b, - 0x09,0xa4,0xf4,0xc5,0xdc,0xbf,0x38,0x01,0x2d,0x20,0x03,0x09,0x05,0xa5,0xe6,0x5e, - 0xef,0x1c,0xd0,0x8c,0x8e,0x92,0x3f,0x6f,0x74,0x05,0x5f,0xc3,0xc7,0x8b,0xbb,0x04, - 0xbc,0x62,0xa1,0xf7,0x86,0xa1,0x4e,0x09,0x74,0x81,0x7e,0x26,0x40,0xde,0x33,0x04, - 0x52,0x5d,0x5d,0xd1,0x84,0x09,0xf9,0x5b,0x11,0x48,0xf5,0x6f,0x13,0x2a,0x96,0x46, - 0x6e,0x8e,0x6f,0x6a,0x83,0xe9,0x38,0xfc,0x76,0xcc,0x4c,0x89,0x3b,0x94,0xab,0x30, - 0xb0,0x28,0xbd,0xaf,0x65,0x1d,0xc5,0x19,0xf2,0xae,0x67,0xcc,0x45,0xfc,0x2b,0xaa, - 0xea,0x65,0x1a,0x55,0x20,0x76,0x55,0xda,0x3f,0x08,0x47,0x3f,0xb2,0x55,0xd9,0xaa, - 0x72,0x75,0xdb,0xe3,0xa5,0x3c,0x27,0x1c,0xa2,0x13,0xf5,0x80,0x22,0xdb,0x74,0xda, - 0xc9,0x42,0xff,0x7e,0x76,0x47,0x1e,0xf9,0xb5,0xf6,0x6a,0xf2,0xf0,0x53,0x8c,0xf4, - 0x79,0xd3,0x6b,0x0b,0x5d,0x56,0xff,0x7e,0xea,0x2f,0x8f,0x56,0x47,0xc1,0xee,0xa0, - 0x3a,0x85,0x5f,0xfb,0x10,0xdd,0xa7,0x35,0x58,0xfa,0xd5,0x1a,0x5b,0x3b,0x7e,0x65, - 0x87,0xc2,0x7a,0x79,0xf5,0x4e,0x5a,0x5d,0x69,0xda,0x10,0x17,0x77,0x88,0xf8,0x02, - 0xc8,0xf1,0x90,0x3e,0x23,0x2d,0xbb,0x5c,0xe1,0x63,0x15,0x7d,0x7c,0xa0,0xa0,0x5b, - 0x10,0x0f,0xb9,0xa1,0xdb,0x87,0xd7,0x5d,0x34,0xbe,0x1b,0xc7,0x98,0xb0,0x3b,0x50, - 0xde,0x28,0xbc,0xbf,0x89,0x6a,0x36,0xc8,0xdb,0x38,0x6d,0xe1,0xb5,0xf2,0x3c,0x42, - 0xef,0x31,0x90,0x58,0x24,0x1f,0x37,0xa6,0x5b,0x69,0xf6,0xa3,0x97,0x9d,0xde,0x72, - 0x70,0x95,0x9c,0x97,0x1f,0x99,0xf5,0x91,0x40,0xf0,0x9f,0x71,0x25,0xe5,0x13,0x95, - 0x41,0xf0,0xd4,0x3a,0xaa,0x7f,0x02,0x03,0x6f,0xed,0xe9,0x4f,0xd8,0xc9,0x6e,0xb6, - 0xc8,0xee,0xe5,0x8b,0xab,0x21,0x09,0x9f,0xdf,0x08,0x54,0xef,0x5b,0x22,0x73,0xf0, - 0xaa,0xaf,0x7b,0xc5,0x39,0x1b,0xaa,0x97,0xee,0x31,0xac,0xbf,0x19,0x15,0xa1,0x64, - 0x8e,0xfe,0xc1,0xb8,0xec,0xbd,0xd9,0x39,0xa0,0xa7,0xec,0x9b,0xc1,0x76,0xa9,0xce, - 0x80,0xc6,0x4b,0xfe,0x91,0x7a,0xbc,0x3b,0x05,0x99,0x8d,0x62,0xac,0xa7,0xdb,0xd4, - 0xac,0x7f,0xfd,0x20,0xc9,0xc9,0x06,0xf4,0xf9,0x76,0x44,0xfc,0xe9,0x09,0x52,0xb2, - 0x00,0xbe,0x73,0x80,0xbd,0xd7,0xf8,0x38,0x12,0x77,0xf8,0xa9,0xb6,0x02,0x4a,0xaf, - 0xed,0x1c,0x3e,0x55,0x06,0xa6,0x5f,0xed,0xcb,0xd4,0x7c,0xb7,0x01,0x0a,0x79,0x86, - 0xf0,0x48,0x0d,0x81,0xa4,0x40,0xa4,0x76,0x4c,0x49,0xc0,0x79,0x20,0x19,0x62,0x7a, - 0x8b,0x86,0xfd,0xd7,0xb9,0xd1,0xfa,0x68,0xd1,0xb2,0x58,0x14,0xef,0xef,0xa7,0x75, - 0xe1,0xe6,0x7a,0x45,0xf8,0x86,0x8b,0xe4,0x07,0xc6,0xfa,0x2d,0x4b,0x41,0x40,0x20, - 0x99,0x74,0xee,0xdf,0xc2,0x8a,0x8e,0x82,0x29,0xdc,0x94,0xeb,0x13,0xff,0xbe,0x95, - 0xf6,0xfa,0x2f,0xd2,0xed,0x92,0x2f,0x6d,0xde,0x8b,0x78,0x73,0xd0,0x70,0x25,0x28, - 0xde,0x56,0xb5,0xa1,0xcf,0xfd,0x91,0x7f,0x77,0x8c,0xdb,0x78,0x18,0xf4,0xe3,0xed, - 0xfc,0x5d,0x4c,0x2f,0xa5,0xea,0xd5,0x3d,0xf6,0x6d,0x05,0x11,0xc8,0xc7,0x42,0xc0, - 0xac,0x02,0xb1,0xd0,0xa5,0xde,0xad,0xec,0x1c,0xb0,0x0f,0xf9,0xd4,0xc7,0x33,0x0a, - 0x5e,0x1b,0x24,0x12,0xb7,0xee,0xbd,0x7e,0xdf,0x26,0x8c,0x0b,0x2c,0xf8,0xe0,0xcc, - 0xe4,0x14,0xe8,0x93,0x22,0x7c,0x79,0xce,0x05,0x9c,0x80,0x8b,0xba,0x72,0x41,0x51, - 0x4f,0xdd,0x21,0xe2,0xd8,0x7b,0x9f,0xf2,0xb8,0xac,0xe6,0xc1,0x91,0x46,0xaf,0xd4, - 0x1f,0x9f,0xd5,0x5c,0x9f,0x38,0xfa,0x84,0xb7,0xeb,0xde,0xa3,0x8e,0xc0,0xb9,0xc5, - 0xd9,0xdb,0x32,0xa6,0x18,0x81,0x73,0x4f,0x31,0x0d,0x0a,0xfb,0x40,0x89,0x16,0xa2, - 0x38,0xf2,0x25,0x7e,0x40,0x42,0x1f,0x55,0x02,0x32,0xe7,0x37,0x35,0x22,0xac,0xcf, - 0x08,0x66,0x4a,0x35,0x82,0x13,0xd6,0x86,0x14,0x1b,0x10,0x8f,0x28,0x73,0xec,0xff, - 0x1e,0x60,0xae,0x4f,0xb7,0x51,0x5c,0x3b,0x5f,0x02,0xc8,0xa4,0xc0,0x9b,0x8d,0x7f, - 0xfb,0xd7,0xdb,0x1d,0x11,0xaf,0x8e,0x4b,0xea,0x4c,0x1c,0x3f,0x35,0x28,0xb1,0xf4, - 0x83,0x59,0xe7,0xdf,0x46,0xbd,0x0f,0xa1,0x8e,0xf4,0x93,0x65,0x32,0x30,0xdc,0xde, - 0xb2,0x93,0x78,0x83,0x98,0xfd,0x88,0x1e,0x82,0x88,0x76,0x78,0x94,0xd2,0x82,0xb5, - 0x3e,0xe0,0xf9,0xfe,0xe0,0xc1,0xaf,0x06,0x4b,0x30,0x05,0xe1,0x97,0x21,0x3e,0x17, - 0x14,0x04,0xdd,0x7d,0x19,0x3f,0xdb,0xa1,0x2d,0xa9,0x01,0x03,0x64,0xd2,0xac,0xd2, - 0x35,0x71,0xf3,0x6a,0x68,0x20,0x09,0x98,0x40,0xfa,0x4e,0x4a,0xf2,0xe3,0xf4,0x3a, - 0xbf,0x34,0x79,0x2f,0x36,0x7c,0xc9,0x2d,0xb4,0xd7,0xa5,0xb2,0xe2,0x21,0xb0,0x01, - 0x30,0x83,0x35,0xdc,0x7e,0xd5,0x42,0x04,0x9c,0x0d,0x7c,0xa1,0xfe,0x78,0xd1,0xe8, - 0x37,0x82,0xf0,0xa4,0x71,0x9e,0x9a,0xbd,0x68,0xa1,0x31,0x58,0xf6,0xb5,0x79,0x5f, - 0xce,0xd9,0xac,0x5a,0xfb,0x87,0x0b,0xc5,0x05,0xe8,0xfd,0x19,0xa7,0x61,0x92,0x31, - 0xf8,0xcb,0x35,0xb3,0xe9,0xec,0x84,0x78,0x91,0xcd,0x5a,0xc2,0xce,0x9f,0xa1,0x72, - 0x89,0x97,0xe1,0x8c,0xd7,0xee,0x6c,0x6d,0x70,0x85,0xb6,0x7c,0x7c,0xdb,0xb5,0x90, - 0x0f,0xd4,0x1d,0x3e,0xe6,0x64,0x89,0x62,0x32,0xfd,0x8c,0x74,0x39,0x74,0x72,0xc8, - 0x85,0x72,0x8a,0xb2,0x7b,0xb0,0xec,0xc5,0x59,0xf8,0xe6,0xce,0xf1,0x9f,0x84,0xdf, - 0x95,0xb8,0xff,0x63,0x81,0xce,0xe7,0xac,0xc6,0x8f,0xa8,0x73,0xd0,0xc4,0xc8,0xe9, - 0xe7,0xe9,0x1f,0x98,0xe2,0x64,0x31,0x37,0x2e,0xba,0x0b,0x1a,0xa4,0x51,0x31,0xd4, - 0x82,0xd9,0xae,0xeb,0xf9,0x0a,0xd1,0x48,0x29,0x7c,0x12,0x6b,0x90,0xdf,0x80,0xc9, - 0x36,0x39,0x76,0x0e,0xbf,0x42,0xba,0x81,0xdc,0x6d,0xd2,0xbf,0x92,0x42,0xd3,0x84, - 0x1e,0xbb,0x92,0xcd,0x31,0xa5,0xb2,0x4f,0x39,0xdf,0xac,0x86,0xee,0xda,0x2d,0xfc, - 0xf2,0x8e,0xce,0x1c,0x57,0xf5,0xaf,0xb4,0x8c,0xd1,0x58,0xa8,0xe1,0x8d,0x74,0x17, - 0x29,0xd0,0x94,0x01,0x4b,0x27,0x30,0xac,0x95,0x98,0xe1,0x5d,0x07,0xa0,0xb8,0x36, - 0x97,0x1b,0x96,0x6a,0x63,0xbb,0x88,0x9d,0x77,0xbd,0x83,0x6d,0x73,0x83,0x76,0x93, - 0x85,0x16,0xd2,0x2c,0x4c,0x24,0xaf,0x1d,0xe6,0x45,0xf4,0xa0,0x65,0x35,0xa3,0x9c, - 0x1d,0xe9,0x3c,0x91,0x87,0xdd,0x9c,0xb5,0x75,0xc1,0xbb,0xae,0xd1,0x9e,0x2c,0xeb, - 0x5f,0x28,0x35,0x5a,0x89,0xcb,0xb1,0xa5,0xb6,0xe3,0xaf,0xd8,0x1d,0xdb,0x1a,0xe7, - 0xe3,0x34,0xe1,0xa1,0x18,0xfb,0xeb,0x93,0x2b,0x41,0x2b,0x60,0x17,0xd5,0x57,0x1a, - 0xf8,0x02,0x17,0xfc,0xfc,0xaa,0xbf,0x42,0x44,0x7e,0x48,0x97,0x03,0x72,0x94,0x6a, - 0x2b,0xa5,0x7c,0x7f,0xa6,0x4c,0xde,0xdb,0x8f,0xb5,0xad,0xe5,0x3c,0x5b,0x48,0x96, - 0x81,0xa7,0xfd,0xa9,0x4b,0x97,0x41,0x86,0x21,0x87,0xe7,0xb3,0x33,0x96,0x97,0xf6, - 0x36,0x48,0x45,0x71,0x00,0x6b,0x7c,0xb2,0xd2,0xfd,0x67,0x6f,0xda,0x11,0x35,0x2b, - 0x5c,0x6c,0x0c,0x1d,0xbd,0xfe,0x11,0xaf,0x7d,0x42,0x47,0x19,0x23,0xea,0xbc,0x86, - 0x8f,0x1b,0x4a,0x38,0x8a,0xaa,0x88,0xe9,0x0a,0x29,0x03,0xed,0x2c,0xbb,0x54,0x81, - 0x6c,0x69,0x24,0xb1,0x18,0x39,0x47,0x7e,0xd8,0xa7,0x9c,0xd7,0x9c,0x50,0x17,0xc7, - 0x6c,0xf6,0x9d,0xd8,0x59,0xa2,0x1a,0x5f,0x7b,0xed,0xa5,0x4a,0x06,0x8f,0xea,0x76, - 0x68,0xcb,0xfb,0x39,0x2a,0x66,0xeb,0x45,0xa5,0x41,0x77,0x30,0x60,0x69,0xb9,0x69, - 0x67,0xa3,0xa1,0x85,0xc5,0x90,0x9d,0xdc,0xcc,0x4d,0xcc,0xfa,0xc3,0x39,0x51,0xcb, - 0x70,0xe7,0x31,0x41,0x07,0x62,0xe4,0x33,0x6d,0x6c,0x22,0xd4,0xb5,0x0f,0x95,0x70, - 0x67,0xfb,0x9b,0xed,0xc2,0x90,0xdc,0x08,0x3e,0x2f,0xf6,0x0c,0xcb,0xda,0xd3,0xed, - 0xb6,0x8e,0xf4,0x17,0xb5,0x2e,0xbb,0x5d,0xf9,0x48,0xe6,0xb0,0x27,0xe0,0x92,0x1a, - 0xf8,0x55,0x40,0x99,0xc6,0x38,0x42,0x2c,0x69,0xdf,0x4c,0x3b,0x6c,0x16,0x84,0x2a, - 0xa9,0x42,0x07,0x00,0x6d,0x37,0x31,0xe8,0xac,0x54,0x85,0x8c,0x5a,0x5e,0x16,0x99, - 0xf1,0x48,0xfa,0xcc,0xac,0x01,0x47,0x93,0xfc,0xb7,0x93,0x2a,0x3c,0xbb,0xd2,0xa3, - 0x20,0xb8,0xea,0xe2,0x7b,0x4c,0x32,0xc2,0x02,0x33,0x67,0xcd,0x1f,0x97,0xcd,0xf2, - 0xcd,0xb6,0x79,0x18,0x6c,0xc4,0x9f,0xbb,0x61,0xbd,0x56,0xb4,0x1d,0xef,0x59,0xbc, - 0xbd,0x16,0x98,0xc0,0x82,0x4f,0x0d,0x14,0x8c,0xce,0x6a,0xbf,0x5a,0x0d,0x71,0xb1, - 0x0d,0x3e,0x2e,0x61,0xf3,0x6a,0x59,0x6e,0x17,0x4f,0x97,0xaa,0x23,0x16,0xa9,0x54, - 0x38,0xb8,0x9f,0x4a,0x81,0x83,0x7e,0x25,0x44,0xe9,0x89,0xfd,0xb6,0xfb,0xf4,0x39, - 0x44,0x79,0x24,0x2e,0x33,0xaa,0xa9,0xab,0xf2,0x8b,0x94,0x5f,0x2b,0x97,0xfc,0xf2, - 0x0e,0x52,0x25,0x0e,0xf4,0x81,0xa6,0x74,0xe2,0x29,0xda,0xa1,0xfb,0x33,0x61,0xe1, - 0xa6,0x8a,0xa0,0xe7,0xe2,0xfb,0xab,0x8b,0xfd,0xc7,0x58,0xed,0xb8,0xfe,0x98,0xa7, - 0x6b,0x35,0x57,0xbe,0xeb,0xab,0x1e,0x6a,0xb6,0x96,0x27,0x61,0x60,0xca,0xb6,0x06, - 0xf2,0xee,0x2f,0x4a,0x81,0xa4,0x85,0xf4,0x52,0x0f,0x08,0x25,0x00,0x6d,0xb3,0xeb, - 0xbe,0x32,0x43,0xad,0xab,0x46,0xb4,0xa7,0x4d,0xdf,0x4a,0x25,0xf6,0xdf,0x86,0x87, - 0x86,0xda,0x66,0xb2,0x9e,0x74,0xf0,0x6d,0x76,0x28,0xd2,0x6d,0x4e,0x95,0xf3,0x06, - 0x73,0xa9,0x2e,0xa7,0x8c,0x5a,0xc8,0x98,0x69,0xae,0x30,0x5b,0xab,0xfe,0x74,0x66, - 0x89,0x91,0x68,0x71,0x36,0x0b,0x1f,0xc1,0xe0,0x27,0x43,0x05,0xc9,0xc7,0x27,0xcb, - 0x55,0xf7,0xd9,0xfc,0x52,0xbc,0xe5,0xbb,0xa8,0xd9,0xd4,0xa7,0x69,0x9e,0x66,0x4d, - 0x4b,0x23,0xc6,0xef,0x1a,0xd2,0x50,0xb8,0xf7,0x4d,0x7c,0xaa,0xf6,0x61,0xbd,0x7b, - 0x46,0xc4,0xa4,0xfa,0xf5,0x3d,0x0c,0xc7,0x4f,0xa6,0x51,0x08,0xf0,0x01,0x94,0x29, - 0xef,0x84,0x4d,0x86,0x41,0xcf,0x0a,0x64,0xe9,0xa3,0xcf,0xae,0x1b,0x10,0xa9,0x74, - 0x9d,0xab,0x28,0x27,0x41,0xa2,0x93,0x3d,0x54,0x85,0x73,0x59,0x95,0x95,0xfb,0xe9, - 0xdb,0x4b,0x6d,0x9c,0x58,0x43,0xd7,0xb6,0xc8,0xb3,0xca,0xf4,0x22,0xa9,0xda,0x9a, - 0x0d,0x92,0x6f,0x55,0x3d,0xa6,0x5c,0x61,0xba,0x33,0x47,0x6f,0xee,0x36,0x51,0x5c, - 0xd1,0x7d,0x44,0x81,0x9c,0x65,0xcc,0x7f,0x40,0x8f,0x52,0x0e,0xe3,0xf7,0xf6,0xb9, - 0xe4,0xa0,0x83,0x06,0x40,0xb1,0x3f,0xa4,0xe5,0x48,0xfa,0x0e,0x30,0x5e,0x30,0x05, - 0x5d,0x70,0x5c,0xba,0x9e,0x45,0x3f,0x3a,0x60,0xc4,0x10,0x50,0x2e,0xe1,0x10,0xde, - 0x77,0xe6,0x8f,0x0b,0x3e,0x4b,0xd3,0x02,0x71,0x24,0x57,0xaf,0xbc,0xac,0xc2,0xff, - 0x00,0x98,0x36,0x25,0x92,0x37,0x4a,0xbb,0x5e,0x3e,0x61,0x00,0x9c,0x78,0x1e,0xf8, - 0xf7,0x2f,0x1e,0x9e,0x02,0xea,0x16,0xe5,0x2f,0x1d,0xf8,0xb2,0x7d,0x40,0x6d,0x92, - 0x19,0x22,0x75,0x65,0x9e,0x9d,0x22,0xd0,0xd8,0x86,0x9a,0x85,0xcc,0x69,0xd4,0xcb, - 0xa4,0xd5,0xa2,0x99,0xdf,0xf1,0x7a,0x53,0xd3,0xde,0x63,0x25,0xeb,0xe1,0x9b,0x85, - 0x9a,0x87,0xc9,0xf1,0x47,0x64,0x10,0x0a,0x6c,0xe8,0x6b,0x26,0x46,0x70,0x6b,0xef, - 0x73,0x51,0x44,0x09,0x70,0x06,0x67,0xba,0xc8,0xd9,0x3a,0xee,0x26,0x78,0xab,0xf7, - 0x39,0x66,0x81,0xec,0xf4,0x00,0x67,0x46,0x7e,0xc6,0x12,0x23,0x06,0xe4,0x5a,0x22, - 0x6b,0x49,0x32,0x67,0xe6,0xa8,0x99,0x8b,0x34,0xc7,0xb5,0xb1,0x89,0x8b,0xa0,0xc5, - 0x3c,0x74,0xf7,0x70,0x9e,0x4c,0x44,0x5a,0x97,0x12,0x4e,0xcd,0x36,0x93,0x01,0x63, - 0x7f,0x53,0x24,0x93,0x2a,0x4c,0xf1,0xe1,0x5b,0xd4,0xe3,0xdc,0x78,0x81,0xf1,0xcc, - 0xe9,0x9d,0x62,0x09,0x7b,0xf9,0x52,0xad,0xeb,0xb5,0x77,0x6c,0x62,0x04,0x23,0x26, - 0x89,0xfc,0x07,0xb9,0x73,0xa8,0x49,0x89,0x06,0xf9,0x3c,0x48,0x6b,0x44,0xb3,0xa3, - 0xda,0x7e,0xb8,0xaa,0xc7,0xd5,0xb1,0xfe,0xa8,0xbd,0x35,0x40,0xb1,0x6f,0x4d,0x28, - 0xae,0x04,0x8f,0x32,0x1a,0x93,0x41,0xc4,0x88,0xbf,0x20,0x56,0xbf,0x6c,0x10,0xd8, - 0xed,0x56,0x21,0x4a,0x45,0xbc,0xaf,0x66,0x25,0x1c,0x5b,0x2c,0x42,0x32,0xa1,0xbd, - 0x9d,0xe2,0x56,0x9a,0x1f,0x6e,0x4b,0x63,0x73,0x83,0x93,0x95,0xab,0xa3,0x65,0x19, - 0xc7,0x26,0xda,0xc0,0xce,0x57,0xc7,0x6e,0x9a,0x59,0xbb,0x68,0x0e,0x31,0xa4,0x62, - 0x4e,0x8f,0xb4,0x28,0x07,0x11,0x86,0x74,0x1c,0x72,0xa6,0x85,0x6d,0x83,0x76,0xd6, - 0x3c,0x80,0x2a,0x1d,0xef,0xe9,0xf9,0x59,0x36,0xe3,0xe6,0x98,0x20,0xcb,0x66,0x97, - 0xde,0x7a,0x08,0xdf,0xdc,0x1e,0xca,0xe9,0x2f,0xce,0x99,0x2c,0x30,0x07,0xca,0x50, - 0xd5,0xe0,0x87,0xd7,0x3c,0xcd,0x2e,0x11,0x5a,0x54,0x66,0x89,0x21,0xc0,0x2d,0xa6, - 0xb2,0xbf,0x14,0x95,0x6c,0xf9,0x3c,0xe3,0x52,0xbc,0x98,0xae,0x9b,0xe0,0xb8,0x58, - 0x22,0xc4,0xcb,0x71,0xd2,0xed,0x19,0xcf,0x16,0x44,0x62,0x4d,0xa3,0x34,0xab,0x7f, - 0x0e,0x1e,0x6b,0x43,0xdf,0x93,0xc2,0x67,0x7a,0x52,0x68,0x8a,0xc1,0xa3,0x92,0x94, - 0x47,0x57,0x0d,0x1b,0x02,0x7f,0x72,0xb4,0x02,0x6c,0xdc,0x0f,0x5c,0x6f,0xe8,0x1e, - 0x2e,0x2f,0x13,0xe2,0x18,0x35,0x74,0x47,0x65,0x5b,0x79,0x42,0xd7,0xac,0xa7,0x32, - 0xec,0x1c,0xa9,0x8c,0x8a,0x77,0xe0,0x7b,0x78,0x4f,0xaf,0x7b,0x7a,0xa6,0xf6,0x4b, - 0x0c,0x17,0x5c,0xf3,0x03,0xbf,0xfe,0x81,0xd5,0x1a,0xea,0x09,0x3d,0xfd,0x64,0x0d, - 0x7f,0xdd,0xbc,0xfe,0xa5,0x17,0xac,0x4f,0xd1,0xc8,0xd4,0xbb,0xcf,0x7c,0x3f,0xbd, - 0x5a,0x5b,0xd0,0x57,0x8e,0xa7,0x79,0x37,0x93,0xfe,0x7b,0xed,0x50,0x0a,0xb6,0xe7, - 0xad,0xe8,0xac,0x0c,0xe2,0xa2,0xd6,0x71,0x9e,0x4a,0x9c,0x85,0x45,0xf2,0x35,0x71, - 0xdb,0x62,0xea,0x29,0x70,0xf9,0xa2,0xe2,0xa1,0xd9,0xfb,0xdd,0xff,0x82,0x58,0x5e, - 0x32,0x5e,0xa0,0x46,0xc8,0xd2,0xce,0xbd,0xa9,0x66,0x01,0x8d,0xe8,0x2f,0xd5,0x83, - 0x91,0xa1,0x91,0x25,0xc4,0x0b,0x5e,0x64,0xec,0xae,0x91,0xd6,0xe3,0x15,0xf2,0x86, - 0xa7,0x7a,0xfc,0x6a,0xdc,0x40,0xbf,0x56,0xa8,0x3e,0x8d,0x1c,0x8d,0x94,0x0e,0xeb, - 0x1b,0x49,0xa6,0x56,0x93,0xfa,0x62,0xd5,0x37,0x4f,0x7f,0x7c,0xf9,0x48,0xdf,0x67, - 0x37,0xaa,0x5e,0xe2,0x15,0x81,0x1c,0x99,0xcf,0x92,0x65,0x63,0xf2,0x8c,0xb9,0xae, - 0x68,0xb6,0x93,0x1f,0x02,0x54,0xbc,0xef,0x2f,0x45,0x8e,0xcc,0xcb,0x7c,0x79,0x6e, - 0x4d,0x77,0x70,0x27,0x8e,0x19,0x55,0x78,0xee,0x47,0x7c,0x97,0xee,0x4d,0x54,0xec, - 0x41,0xaf,0xb9,0xb0,0x79,0x04,0xad,0x46,0x4e,0x31,0xdf,0x8a,0x1b,0xa3,0xd7,0xf5, - 0x9a,0x34,0x54,0x72,0x7d,0xf5,0xba,0x5e,0xae,0x37,0x28,0x19,0xae,0xfb,0xe8,0x2f, - 0x4f,0xaa,0x42,0x8e,0xd4,0x00,0x8f,0xeb,0x0e,0x4c,0x77,0xf2,0x2b,0x56,0x4c,0x2e, - 0x4a,0xaa,0xce,0xe1,0x2a,0xa9,0xd3,0xf6,0xd5,0x5a,0x87,0x3d,0x45,0x98,0x8e,0x7d, - 0xb5,0xea,0xb8,0x98,0x81,0x5d,0x8b,0xa1,0x05,0xb8,0x74,0xaf,0x85,0x08,0x43,0x5a, - 0x28,0x58,0x19,0x1d,0xac,0x29,0x62,0x1f,0x88,0x99,0x8d,0x99,0xcb,0xe2,0x71,0x66, - 0x79,0x32,0x03,0x4c,0x3a,0xc7,0xbe,0x14,0x0e,0x72,0xc2,0xa3,0xd4,0xbc,0x07,0xcd, - 0x1a,0x10,0x72,0x52,0x49,0x28,0xc2,0xd8,0xe1,0xa3,0xbc,0x78,0x1e,0x8a,0x3b,0xd9, - 0xfa,0x36,0x0b,0x6d,0xcd,0x4a,0x43,0x90,0x62,0xbf,0x80,0x24,0x0c,0xe7,0xcc,0x38, - 0xcf,0x1a,0xe3,0xda,0xdc,0x13,0xbb,0xb1,0x46,0x07,0x08,0x19,0x2b,0x8b,0x58,0x23, - 0x89,0xcf,0x63,0xc2,0x62,0xf1,0x58,0xf6,0x4b,0x49,0x52,0x7a,0x26,0x61,0x2c,0xdc, - 0x22,0xf7,0x40,0x4a,0x9b,0x96,0x16,0xa8,0x3a,0x33,0xe6,0x79,0x69,0x24,0x39,0x92, - 0xd0,0x23,0x4a,0x00,0xba,0xb3,0x1f,0x11,0x37,0xbf,0x8a,0x69,0x3f,0x50,0x8b,0xe3, - 0xa8,0x42,0xd0,0xca,0x70,0x97,0x83,0x84,0xaf,0x05,0x53,0x25,0x88,0x46,0x51,0xd7, - 0x5a,0x4e,0xdd,0x21,0x98,0x40,0x97,0x0c,0xb3,0x30,0xa4,0x3b,0xa1,0x68,0x59,0x9a, - 0xce,0x87,0x33,0xd1,0x17,0x81,0xcb,0x91,0x5b,0x43,0xaf,0x84,0x83,0x47,0x5a,0x40, - 0xff,0x84,0xcb,0xf7,0x4a,0x85,0x96,0x4f,0x7d,0x30,0xda,0x6a,0xfe,0x9a,0x99,0x5c, - 0x10,0xb0,0x6e,0x66,0xcc,0xbc,0x22,0xf4,0x62,0x86,0xc1,0xb6,0x4b,0x2c,0xfc,0xc2, - 0x7e,0x72,0xb1,0xc4,0x27,0xfc,0xeb,0xe6,0x02,0x1b,0x56,0x99,0x14,0x1a,0x7d,0xc1, - 0x48,0xab,0x96,0x5a,0x6a,0x3f,0xc3,0x36,0x5e,0xcf,0x18,0xfe,0xe8,0x35,0x1c,0xaf, - 0x0f,0xf3,0x70,0x7c,0xb8,0x74,0x2a,0xc5,0xb8,0x07,0xd6,0x67,0x5e,0xac,0xd4,0xec, - 0x24,0xca,0xf1,0x81,0xaf,0x56,0x76,0x69,0x04,0xcc,0x39,0xcb,0x64,0xe2,0x95,0xd1, - 0xf7,0x74,0x1c,0x9b,0x3a,0x39,0xee,0x99,0xdd,0x58,0x45,0x1f,0xad,0x2e,0xfc,0xf6, - 0xab,0x4e,0x82,0x7d,0x6c,0xbc,0xe0,0x9d,0x68,0xa7,0x19,0xfb,0xab,0x01,0x66,0x93, - 0x92,0xab,0x3e,0x48,0x35,0xcc,0xe8,0x67,0x66,0xa3,0x8d,0x36,0xfb,0x68,0x41,0x3c, - 0x31,0xde,0x3c,0x94,0xcc,0xec,0x01,0x09,0xe9,0x77,0xf7,0x47,0xa4,0x6a,0xfe,0x23, - 0xb0,0x97,0xbb,0xdd,0x77,0xb1,0x4e,0xa4,0x53,0xfb,0xb2,0xf1,0xf7,0x4c,0x59,0x79, - 0xba,0x06,0x07,0xf6,0x83,0xf8,0xc1,0x1b,0xc6,0x42,0xf4,0x63,0xc7,0xc9,0xf8,0xd0, - 0xe6,0x9a,0x17,0xf5,0xf6,0x82,0xba,0xb4,0x2e,0xc9,0x84,0x59,0xd4,0x0e,0x43,0x4c, - 0xd4,0x69,0xe3,0xdf,0xae,0x84,0x0e,0x0b,0x35,0xf4,0x19,0x0f,0x93,0x95,0xc6,0x3b, - 0xde,0xf3,0xa1,0xd7,0x61,0xcb,0x4a,0xac,0xf8,0xcc,0x3c,0x41,0xbb,0x64,0xc7,0x12, - 0xb5,0x1e,0x39,0xfc,0x4f,0x76,0xc9,0xcb,0xe1,0x2a,0xfd,0x12,0xa1,0x11,0x8d,0x7c, - 0x48,0x77,0xe6,0xb3,0xf0,0x38,0xf7,0x89,0x3e,0x90,0x83,0x8e,0x8a,0x30,0xf6,0x18, - 0xc9,0x4c,0xb7,0x83,0xe0,0x0b,0x99,0x0e,0x21,0x90,0xe9,0x98,0xdf,0xa4,0x62,0xe1, - 0x47,0x8b,0x44,0x70,0xbf,0x26,0xa1,0x7b,0xa1,0x19,0x3e,0xb5,0xe4,0x5e,0xb9,0x2f, - 0x42,0x12,0xde,0x60,0x31,0x46,0xbf,0x25,0x04,0x5d,0x20,0xa0,0x83,0x8a,0x92,0xd2, - 0x39,0x21,0x2c,0x26,0x18,0xf5,0x11,0x70,0x9d,0x46,0xa7,0x43,0x9a,0x13,0xf7,0xca, - 0x6c,0x0c,0xad,0x48,0x3b,0x4d,0x53,0x75,0x56,0x4b,0xec,0x85,0x7a,0x68,0x2b,0x2f, - 0x42,0x7d,0xba,0x03,0x7a,0xe2,0xd0,0x7f,0xd3,0xde,0xbb,0x94,0xdb,0x38,0xd0,0x44, - 0xdd,0x88,0x7f,0x9b,0x24,0x62,0xe2,0xd7,0x24,0x4b,0x35,0x71,0x90,0x7b,0xb0,0x47, - 0xb3,0x25,0xb2,0x35,0x10,0xb7,0x19,0x3b,0x0c,0xd5,0xa8,0x90,0x0f,0x41,0xdf,0x7d, - 0xef,0x35,0xd7,0xcd,0x74,0xea,0xf7,0x3a,0x87,0xbb,0x9a,0x7e,0x62,0xb7,0x6a,0xc6, - 0xc1,0x6b,0xd0,0xe1,0xf8,0x93,0x98,0xec,0xe7,0xd3,0x1e,0x92,0x02,0xe1,0xf2,0x49, - 0xdc,0x1b,0x29,0x03,0x03,0x9f,0xac,0xa0,0xc8,0x61,0xfa,0xa2,0xca,0x05,0x4f,0xce, - 0x33,0x16,0x68,0x7a,0xba,0x9d,0x1e,0x30,0xa4,0x64,0xd3,0x41,0x2f,0x9b,0xa9,0x60, - 0x11,0xa7,0xa7,0xec,0xde,0xf9,0x69,0xee,0x0c,0x4d,0x21,0x10,0xae,0x9f,0xdd,0xf6, - 0xcc,0x6e,0xca,0x31,0xf9,0x4c,0xf9,0x84,0xb4,0x43,0xca,0xb4,0xe6,0x6d,0x7f,0x5a, - 0x2c,0x81,0xd9,0x7d,0xa7,0xdd,0xde,0x44,0xb2,0x21,0xf2,0x20,0xb2,0x89,0x3e,0x26, - 0x6a,0x99,0x23,0x2d,0x2a,0x51,0x7b,0x4e,0x27,0x59,0xe6,0x84,0xc0,0x12,0x68,0x1d, - 0xdc,0x0b,0xa8,0x1b,0x4b,0x27,0x79,0xd2,0xbf,0x9f,0xd7,0x28,0x96,0xb2,0xa4,0x98, - 0xfd,0xbb,0x02,0xdf,0x5d,0xcc,0xb8,0xd5,0x13,0x3c,0xe3,0x42,0x40,0x67,0xff,0x9d, - 0xf2,0x53,0xf6,0x85,0x2f,0x0f,0x86,0x69,0x7c,0x5c,0x57,0x42,0xb8,0xbc,0x38,0x77, - 0x2c,0x91,0x83,0x62,0x00,0xf3,0x3e,0x5e,0x69,0x5a,0xe4,0xf3,0x69,0x62,0x86,0xa0, - 0xa8,0xb6,0x1a,0x14,0x51,0x2f,0x1d,0x70,0xa5,0x52,0xd9,0x24,0x8e,0xf3,0xa0,0x87, - 0xcd,0xb0,0x2e,0x73,0xb6,0xa8,0xb7,0x30,0x21,0x21,0x2e,0xe7,0x12,0x26,0x93,0x52, - 0xe5,0x1d,0xfa,0x55,0x6f,0xa1,0x02,0x90,0x0a,0xfd,0x45,0x62,0xfa,0x72,0x03,0x82, - 0xe7,0xa7,0x37,0xe9,0xe3,0xef,0xe4,0x0b,0xce,0x34,0xf3,0x44,0xba,0x23,0xab,0x7f, - 0x03,0xa0,0x91,0xa6,0x4d,0x9a,0x83,0xc8,0x58,0x76,0x65,0x66,0xa7,0x7c,0x66,0x9d, - 0x1e,0x76,0xf3,0x5f,0xc4,0xa1,0x94,0x23,0x47,0x13,0x4f,0x74,0xbf,0x73,0xfb,0x19, - 0xa2,0x27,0xfb,0x0f,0x19,0x14,0xf0,0x5d,0xcd,0xe5,0x11,0x69,0xcc,0x27,0xc7,0x20, - 0xe9,0x26,0x40,0x0d,0xcf,0x61,0x60,0xdd,0x70,0xa2,0x29,0xb0,0x77,0xa4,0x07,0x69, - 0x34,0x2e,0xad,0x44,0x48,0x23,0x04,0x60,0xb2,0xd1,0x38,0xd2,0x42,0xd8,0x9b,0x19, - 0xd3,0x79,0x5c,0xba,0x51,0x9b,0x1e,0xa3,0xb4,0x87,0xca,0x58,0x0f,0x3e,0x5c,0x0f, - 0x2a,0xf0,0xee,0x82,0x81,0xa4,0x35,0x79,0x0b,0x27,0xf4,0x71,0x8e,0x98,0xae,0x84, - 0x82,0x9d,0x85,0x02,0x91,0x89,0x71,0xaa,0xc4,0x59,0x53,0x19,0x74,0x21,0x9f,0x02, - 0x82,0x3e,0xe3,0x3e,0x94,0x1f,0xf4,0xea,0xbd,0x7b,0x68,0x7a,0x76,0x0e,0x90,0x4e, - 0x6a,0x81,0x45,0x43,0x68,0x2a,0x86,0x86,0x82,0x16,0x66,0xd5,0x59,0x1e,0xe8,0x44, - 0x67,0x2b,0x7e,0x30,0x90,0xa3,0x34,0x3b,0x9d,0x4a,0x54,0xd7,0x43,0xf8,0xd5,0x12, - 0x9b,0x3a,0xe4,0x7c,0x67,0xa3,0xfa,0x84,0xec,0x51,0x3b,0x5e,0x1e,0xee,0x88,0xef, - 0x99,0xa6,0x6f,0x47,0xab,0x7e,0x14,0x72,0x4c,0x1e,0xa5,0x57,0x22,0x19,0xbb,0xbb, - 0x77,0x56,0xd8,0xfb,0x5f,0x5a,0x84,0x5c,0x2e,0x73,0xe6,0x0a,0xc2,0xe7,0x4d,0xbb, - 0xf3,0xe1,0x9e,0x63,0x90,0xb6,0xd9,0x75,0x11,0x70,0x1b,0x84,0xee,0xd1,0xd1,0xd6, - 0xc8,0xa5,0xf6,0x35,0xf0,0x6e,0x3f,0x61,0x8e,0x76,0xf4,0x79,0xde,0xbb,0x82,0xe8, - 0x6c,0x0d,0x8e,0x7e,0x14,0x02,0x90,0x77,0x37,0xc8,0x2f,0x1a,0x3c,0x1a,0xa9,0x20, - 0xbb,0x13,0x9c,0x17,0x01,0x79,0xf6,0x07,0x46,0xac,0xb7,0x81,0x41,0x54,0xd6,0xbc, - 0x79,0x9c,0x88,0xf7,0xd1,0xb6,0xc6,0x1d,0xc9,0x0f,0x06,0xda,0x93,0x22,0x99,0x33, - 0x32,0xa9,0x60,0x3b,0xfd,0x0c,0x0e,0xaa,0x36,0x0b,0xad,0x4f,0x7b,0xcc,0x7f,0x42, - 0x3e,0x9a,0xd8,0xc5,0x29,0xa0,0x90,0xe7,0xde,0x95,0xe2,0xea,0xae,0x47,0xcc,0xd7, - 0x0b,0x0e,0x92,0x5c,0x8a,0xa0,0xc6,0xef,0x62,0xec,0xf8,0x9a,0xa4,0x03,0x79,0x00, - 0xee,0x43,0x0f,0x85,0x11,0xe4,0x2b,0x34,0x15,0x1d,0x20,0x72,0x47,0x4e,0x02,0x47, - 0xe8,0x3a,0xbc,0x76,0xac,0x8b,0x85,0x4f,0x13,0x90,0x77,0x95,0xac,0x94,0x1a,0x32, - 0x6b,0x0b,0x23,0x16,0x8a,0x0e,0x9a,0x7e,0x55,0xf2,0x03,0xec,0x45,0x0f,0xc9,0x65, - 0x5f,0xf3,0xba,0xe2,0xe8,0x32,0x13,0xcd,0x51,0xe9,0xd6,0x93,0x6a,0x82,0x3f,0x18, - 0x61,0xc2,0xaa,0xe9,0x73,0x80,0xca,0xd5,0x94,0x38,0x00,0x3f,0x19,0x34,0xc1,0x1d, - 0xbf,0xdb,0xf4,0x79,0x3d,0x8d,0x5b,0xc3,0xd8,0xc3,0xec,0x78,0x24,0x33,0xea,0x7e, - 0x2d,0x8f,0xf6,0xdb,0xe3,0xf2,0x24,0xa2,0xb6,0x8d,0xe5,0xc6,0x12,0xc3,0x74,0x96, - 0xb7,0x95,0xdb,0xee,0x3d,0x9f,0x41,0xe4,0x4b,0x9e,0xd9,0x71,0x28,0x7a,0x66,0x6e, - 0xc7,0x7e,0xdb,0xf5,0x59,0x2f,0xbd,0x05,0x18,0xd8,0x85,0xf1,0x05,0x07,0xc2,0x03, - 0x96,0xc7,0x17,0x3f,0xd3,0xd8,0x49,0x34,0x61,0x6c,0x46,0xd6,0xbb,0x58,0x6e,0x8c, - 0x57,0x69,0x9d,0x81,0x47,0x2d,0x36,0x8c,0x45,0x13,0x12,0x1f,0x65,0xab,0xe3,0x38, - 0x25,0x4b,0x53,0x7e,0x66,0x26,0x9d,0x2b,0xb9,0x02,0x49,0x11,0xbd,0x71,0xec,0xf7, - 0x90,0xb4,0xf9,0x43,0xdd,0x24,0x35,0x30,0xb2,0x7a,0x78,0x05,0xa5,0xf0,0x0e,0x35, - 0x58,0x7d,0x91,0x57,0x67,0x61,0x9c,0xa0,0x94,0x44,0x71,0x8d,0xe5,0x16,0x27,0x2c, - 0xb6,0x70,0x0d,0x5a,0x53,0x45,0x71,0xaa,0x71,0xb0,0x03,0x49,0x85,0x9f,0xa8,0x7b, - 0x76,0x47,0xd5,0xa7,0x13,0x8b,0x76,0x47,0xf2,0x05,0x8e,0xdb,0xf4,0x4a,0x60,0xd3, - 0x1d,0x63,0x9d,0x65,0x22,0x6a,0xa2,0xd2,0x82,0xc1,0xcf,0x94,0xab,0x35,0x70,0x5a, - 0x55,0xd0,0x85,0x35,0xb9,0x8d,0xce,0x82,0x2d,0x08,0xcb,0x5f,0x39,0x3f,0x95,0x3f, - 0xf8,0xf7,0xb8,0xfe,0x73,0xde,0x7f,0xd0,0xf3,0xa9,0x0b,0x35,0x8f,0x5a,0x0a,0x28, - 0x1d,0x34,0xb3,0x35,0xde,0x5e,0xae,0xc1,0xbe,0xae,0xed,0xa2,0x3b,0x29,0x95,0xbe, - 0x10,0xb0,0x39,0x64,0x08,0x73,0xcf,0x94,0x7c,0x02,0xa8,0x75,0x0a,0x33,0x1d,0xde, - 0x00,0x2b,0xfa,0x72,0x27,0x2a,0x01,0x0b,0xf3,0x0a,0x53,0x9d,0xe5,0x72,0x1d,0x84, - 0x8e,0x6b,0x38,0x30,0xef,0x64,0xe1,0xc1,0x31,0x59,0x8d,0x25,0x02,0x26,0x9f,0x47, - 0xac,0x93,0x39,0xe6,0xab,0x6a,0xc9,0x24,0xa0,0x6e,0x62,0x8c,0xc5,0x02,0xa0,0x4e, - 0x20,0xea,0x7c,0xdc,0xbb,0xa3,0x2b,0x98,0x04,0xd5,0x62,0x52,0x96,0x10,0xd1,0x06, - 0x8f,0x4b,0x84,0xb6,0x23,0xac,0xab,0x69,0xd8,0x1e,0xa3,0x68,0x21,0xdd,0x65,0x25, - 0x32,0x2d,0x6a,0x2b,0x46,0xbf,0xa3,0x08,0xae,0x78,0xa5,0x1d,0x30,0xca,0x80,0x48, - 0x85,0xb3,0xf6,0x68,0xa0,0x7c,0x81,0xdd,0x31,0x6b,0xc1,0xc1,0x11,0x55,0x83,0x40, - 0x92,0xb1,0x33,0x7e,0x84,0xd8,0x76,0x1e,0xf9,0x8b,0xf5,0x9d,0x1f,0xee,0xb1,0x76, - 0xe2,0xac,0x42,0xdf,0x3a,0xea,0x98,0x9a,0x31,0x1c,0xf6,0xf6,0xfd,0x26,0x23,0x8e, - 0x6b,0x74,0x22,0x50,0x50,0x09,0x71,0x65,0xc9,0x65,0xed,0x9f,0x15,0x2f,0x0f,0x63, - 0xe4,0x89,0xd0,0x87,0xc4,0x88,0x3b,0x2e,0x61,0x1b,0x45,0x86,0xa3,0xcb,0xd2,0x35, - 0x68,0xf1,0xf4,0x84,0xea,0x99,0x5c,0xdf,0x96,0x57,0xb4,0x12,0x24,0x8a,0x65,0xb6, - 0x06,0xb3,0x86,0x90,0xd8,0x65,0x81,0x78,0x63,0xd3,0x1d,0xe3,0xe8,0xfc,0xa3,0xdf, - 0x1a,0xc3,0x29,0x5b,0x34,0x11,0xa3,0xa2,0xf2,0xb0,0x4e,0xf9,0x69,0xc9,0x63,0x57, - 0xf3,0x5d,0x5f,0xaf,0x52,0x97,0xc7,0x5f,0x12,0xdd,0x67,0x87,0x52,0xf0,0xbd,0x55, - 0xa7,0x5e,0x8d,0xbe,0xb8,0xe2,0x71,0x62,0x1c,0x81,0xa2,0x84,0x76,0xbf,0x23,0x98, - 0x27,0x17,0x5d,0xa0,0x62,0x45,0xc9,0xf2,0xab,0x82,0x63,0xa8,0xda,0xe4,0xb9,0x2d, - 0x7d,0x14,0xff,0x1d,0x6f,0x31,0xc1,0x34,0xa4,0x2e,0x90,0xfc,0x56,0x4f,0x64,0x26, - 0xa9,0x90,0xc2,0xfc,0x42,0xab,0x72,0x9b,0x8f,0xfe,0x45,0xbe,0x91,0xf7,0x90,0x8c, - 0xa1,0x14,0x35,0xf6,0x4c,0x71,0x8d,0xc5,0xd0,0x34,0x45,0x08,0x06,0x26,0xa1,0xac, - 0x45,0xb2,0x60,0xfb,0xb2,0xb8,0x79,0x68,0x09,0x6d,0x11,0x34,0xc3,0xb9,0x33,0x61, - 0x5d,0x62,0x26,0x5f,0xdb,0x66,0x07,0xe1,0x2e,0x44,0x04,0xdd,0xa4,0x98,0xb4,0x85, - 0x0c,0x28,0x84,0x52,0x7a,0x90,0x98,0x47,0x94,0x0f,0x2b,0x9b,0x8b,0x33,0x7f,0x24, - 0x31,0x45,0x6f,0x0f,0xb3,0x50,0x8e,0x5e,0xfb,0x19,0xfc,0xcd,0x91,0x97,0x06,0xa7, - 0xeb,0xb0,0xb2,0xd9,0xce,0xc9,0xbb,0x9e,0x2c,0xda,0xec,0x2d,0xac,0xb3,0x7b,0x37, - 0xc4,0xf2,0x43,0xc5,0xad,0xb4,0x2b,0xdb,0x88,0xc4,0xad,0xe3,0xf7,0x04,0x69,0x80, - 0xe2,0xda,0x20,0x70,0x78,0x61,0x3d,0x4c,0xf5,0x74,0x29,0x01,0xcc,0xd6,0xa5,0xe2, - 0xb7,0xf7,0x49,0xdc,0x78,0xc9,0x0f,0x40,0xcc,0x77,0x22,0xf6,0x50,0x45,0xc9,0xc9, - 0x97,0x3c,0x95,0x44,0xea,0x7d,0x89,0x43,0x86,0x54,0xbe,0xc2,0x91,0x41,0x1a,0xda, - 0xe3,0x2d,0x86,0x56,0x28,0x94,0xa4,0x88,0xca,0x0d,0xc0,0x69,0xdc,0x50,0x12,0x5e, - 0x75,0xe6,0x15,0xb2,0x24,0xf6,0x1a,0x93,0xdb,0x8d,0x4d,0x2d,0x17,0xb4,0x81,0x59, - 0x78,0x8e,0xf2,0xd1,0x56,0x40,0x33,0xd2,0xf1,0x95,0xa2,0x23,0xe5,0xee,0x56,0x68, - 0xc5,0x5a,0xdf,0x19,0x97,0xad,0xd6,0x4f,0xa9,0x4f,0x16,0xbb,0x4d,0x9b,0x75,0x62, - 0x24,0x91,0xa2,0xa1,0x06,0xd8,0x8b,0x1a,0x99,0x7d,0x30,0xb8,0x06,0x14,0xe2,0x5d, - 0x44,0x2a,0x5d,0xc0,0xd3,0x81,0xb3,0x19,0x95,0xf0,0x6f,0x95,0xd0,0x1d,0x89,0x3f, - 0xe1,0x8f,0xbe,0x96,0x36,0xfb,0xa6,0xbd,0x3e,0x64,0x49,0xf9,0x45,0xac,0x4d,0x51, - 0x27,0xc9,0xc0,0x4b,0x11,0x29,0x5b,0x88,0xfc,0x12,0x65,0xb3,0xc2,0x14,0xf9,0xd5, - 0x2a,0xd9,0xe6,0x86,0x43,0x44,0x0a,0x30,0xd8,0x48,0xf5,0x3c,0x10,0x2a,0x69,0xfb, - 0x4d,0xc9,0xb7,0x1f,0x70,0xfd,0x0d,0xe2,0x16,0x2c,0x75,0x6a,0xc6,0x2e,0xb2,0x2b, - 0x2c,0x01,0x18,0x22,0x16,0x7f,0x69,0xf0,0x3d,0xe6,0x1f,0xa5,0x20,0xd8,0xbb,0x54, - 0x4e,0xdc,0x44,0x44,0xa6,0x60,0x7d,0xe7,0x47,0xe6,0xd6,0x75,0x79,0xae,0xbd,0x1e, - 0xad,0x74,0x06,0x8c,0xf8,0xb6,0x53,0x6c,0x9e,0xf4,0x0d,0xfb,0xd1,0x04,0xa0,0x01, - 0x47,0x56,0x7b,0xf2,0xb9,0x4f,0xa1,0x34,0xa8,0xa6,0x6b,0x74,0x85,0x96,0x52,0x17, - 0x49,0xc3,0x56,0x04,0x2d,0x73,0x25,0x90,0x83,0xde,0xa6,0x4c,0x13,0xf8,0x16,0xfa, - 0x9a,0x55,0xc9,0x34,0x95,0x99,0xcd,0x96,0xb1,0xd4,0x18,0x73,0x65,0xd8,0x32,0x1d, - 0xec,0xfb,0x08,0x6d,0xe0,0xec,0xd0,0x60,0x89,0xa4,0xcd,0xc9,0x5d,0x14,0x02,0xa9, - 0xc0,0x03,0x97,0x44,0x27,0x21,0xbb,0x11,0x88,0xf7,0xdb,0xda,0xf9,0x64,0xdb,0xbe, - 0x9e,0xfe,0x78,0xd9,0xbd,0x72,0x50,0x62,0x24,0x11,0x5a,0x4f,0xee,0x73,0xae,0x7e, - 0xf6,0xca,0xa4,0xca,0xf2,0xd8,0x88,0x1b,0x5e,0xc9,0xc4,0xcd,0xf1,0x7a,0xcb,0x9e, - 0x42,0x6a,0x97,0x73,0x98,0xe7,0xac,0x05,0x8e,0xbc,0x5d,0x2f,0x25,0x04,0x34,0xe2, - 0xdc,0x8f,0xe4,0x55,0x3c,0xbd,0x08,0xfb,0xdc,0x48,0x73,0x66,0xac,0x04,0x74,0xe9, - 0x4b,0xbf,0x82,0x53,0xe9,0xfa,0xdf,0xd7,0xe4,0x7b,0xaa,0x1b,0x77,0x14,0x19,0x8c, - 0xc4,0x11,0xcc,0xb3,0x94,0x27,0xc0,0x19,0x7b,0x57,0xfc,0x3d,0x4e,0x2f,0x24,0x88, - 0x2e,0x31,0xb1,0x22,0xc6,0x37,0x41,0xc8,0x1c,0x64,0x31,0x4c,0x19,0xa0,0x08,0xe2, - 0x22,0xa2,0x8d,0x4a,0x6a,0xeb,0xc2,0x74,0x92,0x74,0x5f,0x63,0x09,0x2f,0x00,0x32, - 0x28,0x0b,0x76,0x16,0x8c,0xf0,0xc6,0xe6,0xa1,0xb5,0xb4,0xbd,0x89,0x88,0x67,0x7d, - 0xf7,0x22,0xb8,0x2b,0xaf,0x1b,0x3c,0x29,0xde,0x3c,0x4b,0x77,0xbc,0x8c,0x15,0xf6, - 0xd9,0xc6,0x68,0xe1,0x26,0x6e,0x8e,0xa2,0xcf,0x29,0x2c,0x2f,0x12,0x72,0xb4,0xbe, - 0xc5,0x9e,0x1c,0x4c,0x43,0x15,0x7d,0xcb,0xfa,0x63,0xab,0x24,0x3a,0xb9,0x24,0x5e, - 0x08,0x60,0x55,0x10,0x15,0xd7,0xe2,0x1a,0x2f,0x34,0xe8,0x91,0x75,0xfc,0xdb,0xc1, - 0xa9,0xac,0xdd,0xc4,0xc7,0xc1,0x4a,0x1c,0xcf,0x50,0xe3,0xf4,0xc0,0x91,0xb5,0x2a, - 0xa6,0x02,0xc5,0x54,0x2c,0x0f,0xd9,0x54,0x98,0x8e,0x11,0xa5,0x46,0x15,0x08,0x2c, - 0x3d,0xc4,0xd9,0x70,0xa7,0xcd,0xce,0x3c,0xfa,0x08,0x22,0xcc,0xd8,0x43,0xbc,0x4b, - 0x73,0xa0,0x6c,0x4b,0xbc,0xcf,0x06,0xf6,0x58,0x0a,0xa7,0x41,0x66,0x36,0xf4,0x15, - 0x0c,0x58,0x9d,0x4d,0x45,0x1f,0x57,0x99,0x12,0x1c,0x37,0x8a,0xb6,0xbd,0xed,0x6d, - 0x17,0x0d,0x73,0x38,0xec,0x00,0xcd,0xcf,0x46,0x26,0xcd,0x23,0x9a,0x11,0xdb,0x20, - 0xaf,0x2c,0x5d,0xa6,0xd8,0xbc,0x90,0xb5,0xb9,0xce,0xca,0x96,0xbe,0xaa,0xcc,0xa7, - 0x0f,0x40,0x98,0x41,0x3b,0x38,0x2a,0xd8,0x35,0x26,0x5e,0x88,0x84,0xf4,0xa4,0xe4, - 0x66,0x2a,0x95,0xa5,0xa0,0x2a,0xf6,0xb4,0x3a,0xd2,0xfd,0x04,0xb5,0xb4,0xb1,0x4a, - 0xe4,0x15,0x8b,0x5f,0xf8,0x40,0x06,0xb9,0x03,0x03,0x84,0x2f,0xf0,0x73,0xd7,0x5c, - 0x61,0x57,0x87,0xf5,0xd9,0xe5,0x23,0xc7,0xc2,0x35,0x53,0xb0,0x24,0x49,0xad,0x5e, - 0xcb,0x3c,0xcf,0x4e,0x86,0x1e,0x11,0xb9,0x05,0x0b,0x68,0x27,0x65,0x33,0x2f,0x22, - 0x74,0xc6,0x2a,0x92,0xac,0x0e,0x8e,0x4d,0xaf,0xe3,0xdf,0x55,0x8f,0x61,0x9e,0xb6, - 0x8b,0x1c,0xd0,0xdc,0x46,0x2c,0x1c,0xbc,0xbd,0xf5,0x44,0x46,0xfc,0xce,0x4b,0xf5, - 0xc6,0x7a,0x43,0x0b,0x27,0x49,0x97,0xd0,0x61,0xf0,0xba,0x1b,0xa4,0x81,0x42,0x8d, - 0xf6,0x43,0x8b,0xc9,0xeb,0x6d,0x30,0x03,0x8e,0x3b,0x9c,0x29,0x8b,0xc8,0x0e,0xde, - 0x87,0x1c,0x4e,0xe5,0x50,0xe9,0x96,0xc5,0x69,0xf2,0xc6,0xfd,0x7d,0x86,0x17,0xc4, - 0x3c,0x75,0xeb,0x83,0xab,0x39,0x52,0x71,0x57,0x38,0xde,0x44,0x11,0x4b,0x61,0xa6, - 0x24,0xbd,0x41,0x74,0x4f,0x53,0x57,0xf5,0xb8,0xad,0x96,0xee,0xc6,0xc3,0x75,0xdb, - 0x27,0xf1,0xa2,0xa6,0x4b,0x37,0x62,0x64,0x2f,0x19,0xf6,0xc7,0x38,0x21,0xf6,0x24, - 0x3a,0x8b,0x7d,0xe6,0x3e,0xb9,0xce,0x01,0x9d,0xb8,0xd2,0xb4,0xbe,0x31,0x37,0xb3, - 0x07,0xb5,0xe0,0xeb,0xc6,0x24,0x56,0x03,0x6a,0x49,0x36,0x8f,0x26,0x2f,0x59,0x81, - 0x05,0x16,0x1e,0xaf,0xec,0x2a,0x04,0x4c,0xd5,0x1f,0x2e,0xa2,0xd0,0x43,0xa7,0x25, - 0x4f,0xdb,0x72,0x6e,0xa5,0xf1,0xc5,0xfe,0x81,0x7b,0xe5,0xa2,0xe2,0xe6,0x56,0xbb, - 0xe4,0x7e,0x86,0x76,0xb8,0x28,0x39,0xc0,0xa1,0x8a,0x6e,0x5c,0xab,0xa0,0xd6,0x6e, - 0x44,0xc1,0x85,0x30,0x71,0x3d,0x3b,0x49,0xd7,0xb4,0x08,0x71,0xac,0x5b,0x4f,0x94, - 0x3d,0xa1,0x27,0x8b,0xc1,0xd7,0x3c,0x7d,0x94,0xa5,0x46,0x6b,0xae,0x60,0x89,0x79, - 0x95,0x7b,0xed,0xde,0x54,0x0b,0xc5,0xbe,0xd3,0x97,0x09,0xf5,0xcf,0x5c,0x26,0xd3, - 0xdf,0x59,0x16,0x6e,0x28,0xa5,0x45,0xc5,0x0c,0x0c,0x6d,0x9a,0xcd,0x66,0x57,0x2d, - 0x5b,0x74,0xb4,0xc9,0x8b,0xf0,0x11,0x6d,0xab,0x90,0xaf,0xc9,0x11,0x2d,0x5c,0xba, - 0x5b,0x6e,0x26,0x7f,0x1e,0x26,0x5b,0x48,0x19,0xea,0xb9,0x49,0x96,0x68,0xb5,0xde, - 0xdd,0x75,0xe4,0x99,0x70,0x53,0x72,0x8f,0x4c,0xa5,0x9c,0x24,0x20,0xe7,0x2f,0x45, - 0x0f,0x8f,0x1c,0x12,0xc7,0x60,0x21,0xf5,0x59,0x6e,0xc6,0x0b,0xc9,0xa0,0xdf,0xcc, - 0x52,0xe1,0xe0,0x42,0xa2,0x1c,0x86,0x94,0x79,0xf1,0xd8,0x20,0xf7,0x58,0xde,0xdb, - 0x0f,0x6f,0xc0,0x1b,0x97,0x67,0x07,0xac,0xc9,0xea,0x0a,0x60,0xb1,0x02,0x78,0x91, - 0xab,0xc7,0x8c,0x68,0x74,0x40,0x68,0xcf,0xb0,0xe8,0xf6,0xbc,0x16,0xce,0xb1,0x4c, - 0x76,0xb1,0x1a,0x34,0x96,0x2f,0xb5,0x88,0x0b,0x0d,0x6a,0x14,0xcc,0x16,0x81,0x2e, - 0x0a,0x62,0x04,0x22,0x71,0x36,0x2d,0xee,0x76,0x80,0xf2,0x57,0x96,0x96,0x19,0x75, - 0x56,0x2b,0x3c,0x95,0x63,0x51,0x10,0x65,0xf7,0x05,0xb9,0x82,0x2b,0xb4,0xca,0x2e, - 0x83,0xdf,0x5a,0xf3,0x26,0xe9,0xed,0xde,0x8e,0xbc,0x36,0x5f,0xa3,0x3f,0x9b,0xb7, - 0x35,0xd2,0x83,0x58,0x0e,0x79,0x71,0xac,0xa9,0x02,0x39,0x84,0x42,0x93,0x6b,0xc7, - 0xc9,0xe3,0xd2,0x34,0xb7,0x21,0x60,0x49,0x86,0x83,0x6c,0xe2,0x20,0x21,0x9d,0x29, - 0xa6,0xaf,0xbd,0x14,0xeb,0x1c,0x7c,0x3a,0x5f,0x66,0xfc,0xb0,0x79,0x41,0x37,0xad, - 0xe0,0x32,0xcd,0x74,0xda,0x17,0xd0,0x55,0xc9,0xa8,0x38,0x5f,0xa9,0x09,0xa7,0xd7, - 0xd0,0xf9,0x00,0x32,0x6b,0x58,0xc3,0xec,0x4b,0x05,0x92,0xcb,0xac,0x35,0xea,0x05, - 0xeb,0x5a,0xb5,0xd0,0x62,0x0d,0x8d,0x59,0x1a,0x2d,0x86,0xe0,0xd4,0xf7,0x95,0x59, - 0xed,0xb0,0x2c,0x57,0x53,0xe9,0x16,0xa6,0x05,0x2a,0xb6,0x5e,0xc8,0xd1,0x10,0xa6, - 0x47,0x49,0x0b,0xe1,0x56,0x76,0xa5,0x7a,0xa3,0x03,0xce,0xb4,0x1a,0x47,0x8f,0x63, - 0x13,0x8a,0x16,0xbb,0x79,0x1d,0x58,0x45,0xe6,0x77,0x18,0x7e,0x49,0x89,0x6e,0x35, - 0xac,0xd1,0xa6,0xce,0x25,0x7b,0x17,0x9f,0x50,0x23,0xd6,0x2c,0xc9,0x3d,0xaa,0xdf, - 0x78,0x0a,0xb0,0x57,0x0d,0xcf,0x1d,0x6e,0x5b,0x2d,0x78,0x4b,0x33,0x44,0x6b,0x70, - 0x02,0xf5,0xf0,0xcb,0x32,0x1d,0x66,0xea,0xef,0x31,0xb5,0xec,0xcc,0xe9,0x9c,0x47, - 0x5e,0xe9,0xc0,0xf1,0x11,0x54,0xaa,0x7e,0x59,0x49,0x03,0x2e,0x82,0x03,0x1e,0x19, - 0x04,0x9a,0xf3,0x53,0x04,0xd7,0xd1,0xfb,0xcd,0x5e,0xcf,0x2b,0x00,0x6e,0xa2,0x7f, - 0x7e,0xda,0x16,0x69,0xfe,0xbb,0x1f,0x1c,0xd3,0xde,0x93,0x90,0x38,0x6e,0x69,0x6e, - 0x9b,0x8d,0xdf,0x11,0xb6,0xc5,0x21,0x23,0xbb,0x7e,0xfb,0x28,0xb1,0x84,0x45,0x2e, - 0xed,0x43,0xd5,0xf7,0xa7,0xa4,0x6e,0xaf,0xe0,0xa5,0xb0,0xf9,0x3b,0xf0,0xeb,0xc9, - 0x9d,0x58,0xf5,0x72,0xfd,0xbd,0xb0,0x38,0xca,0x7b,0x87,0x17,0x92,0xc0,0x83,0xee, - 0x38,0xcb,0xa8,0x34,0x1e,0x62,0x6c,0xeb,0x12,0x2c,0x0e,0x7b,0xd8,0x80,0x01,0xe8, - 0x2e,0xdd,0xac,0x20,0x27,0x6a,0x42,0xa5,0x6c,0x64,0xb6,0x55,0x5a,0xaa,0x03,0x2b, - 0xe8,0xe4,0x10,0x28,0x6f,0xed,0x69,0x76,0x9d,0x84,0xb4,0xf2,0x4e,0x72,0x32,0x88, - 0xf2,0xd4,0xef,0x03,0x85,0x23,0xf0,0x76,0x65,0x27,0xa3,0x7a,0x3b,0xdf,0xad,0xd5, - 0x7b,0xb6,0xb8,0x82,0x96,0x06,0xc8,0xa7,0x74,0x27,0xab,0x88,0x5f,0x23,0xa9,0x94, - 0xae,0x60,0xf9,0xb0,0x3e,0xf2,0x4b,0x75,0x20,0x89,0x94,0x89,0x1f,0xdb,0x42,0xf6, - 0xa8,0x36,0xec,0x15,0x28,0x7b,0x78,0x69,0x50,0x05,0xa6,0x36,0xa6,0x3a,0x9d,0x73, - 0xf0,0x5f,0x0d,0x2e,0xac,0xa8,0x38,0xc6,0x4a,0x3b,0xf8,0x8b,0x2a,0x4a,0xd6,0x8f, - 0x99,0x0d,0x0f,0x30,0xf6,0xa0,0x86,0xcb,0x56,0x68,0xed,0x0e,0xed,0xef,0xfb,0xd9, - 0xb5,0x55,0x79,0x04,0x69,0x07,0xaf,0xcf,0x0d,0x70,0x78,0x14,0x71,0x49,0x14,0x68, - 0x15,0x6d,0x73,0x3f,0x50,0x98,0x3c,0x78,0x79,0xcc,0x7a,0x5a,0x8c,0x53,0xa4,0xbb, - 0x14,0x5d,0x4c,0x77,0x7d,0x1e,0x04,0xb7,0xba,0xf0,0xa8,0x7a,0xfb,0xd9,0x40,0xa4, - 0xaf,0x78,0x20,0xd0,0x24,0xd8,0xcf,0x03,0x3c,0xd3,0x56,0x67,0x20,0x1d,0xb5,0xd7, - 0x74,0xc5,0xec,0x03,0x1f,0xfb,0x5d,0xa0,0x2d,0x83,0x94,0x32,0x3c,0xcb,0x56,0x54, - 0x61,0xd3,0x04,0xd3,0xd2,0x07,0x2d,0x3d,0x86,0x63,0xa4,0xe6,0x5a,0xe0,0xf3,0xc2, - 0xda,0x55,0x69,0xa7,0xd7,0x26,0xab,0xd1,0xfc,0xd7,0x7c,0x8a,0xe5,0xab,0x6b,0xd0, - 0x88,0x57,0x4b,0x44,0x5a,0x7c,0x49,0xda,0x56,0x72,0x4b,0x86,0xc6,0x0a,0xfe,0x65, - 0xbd,0xf5,0x3a,0x94,0x6a,0xab,0x25,0x2e,0x27,0xe6,0x8a,0xf9,0xbd,0x2f,0x07,0xa6, - 0xc0,0x60,0x41,0xfe,0xab,0x8a,0x7f,0x89,0x77,0xf8,0xa7,0x9d,0xe7,0x28,0x4f,0xeb, - 0x85,0x61,0x05,0xc0,0x14,0x7a,0x8a,0xf8,0xb5,0xea,0xb6,0x02,0x5d,0x70,0x3e,0xb5, - 0xc4,0x89,0xda,0xb0,0x9d,0x45,0x2d,0xd8,0xfa,0x9d,0x1a,0x12,0xa8,0x70,0x89,0xde, - 0x4e,0x20,0xa1,0x19,0xa3,0xc3,0xa4,0x71,0x18,0x8c,0xa5,0x3f,0x20,0xb8,0xf0,0xc1, - 0x27,0x3b,0xf1,0x64,0x6e,0x31,0x79,0xab,0x66,0x08,0x0a,0x2d,0x20,0x5b,0x23,0x0f, - 0xe1,0xbf,0xed,0xb9,0x19,0x09,0xc4,0x31,0x63,0x04,0x9a,0xe7,0x77,0x2b,0xc6,0x59, - 0xd9,0xe0,0xdb,0xba,0x30,0x64,0xad,0x23,0xf2,0xde,0xce,0xbc,0xe6,0x3c,0x6a,0xe3, - 0x7c,0x27,0x9f,0x18,0xe0,0x08,0x90,0x98,0x19,0x32,0xc9,0xc0,0x3f,0xdb,0xde,0xe9, - 0xc8,0x39,0xf8,0x73,0xd7,0xeb,0x8a,0x9b,0x29,0x3e,0xb5,0x23,0x55,0xf2,0x03,0x27, - 0x29,0xf5,0x0b,0xe9,0xb5,0x58,0xf2,0x4b,0x04,0x2f,0xe4,0x53,0x7c,0x44,0xf3,0x2f, - 0x7c,0xd3,0x32,0xcd,0x91,0xca,0x70,0xa4,0x56,0x69,0x92,0x00,0xcd,0x07,0x28,0xae, - 0x61,0x66,0x67,0x11,0x6f,0xd9,0x2f,0x2f,0xcc,0xc5,0x91,0x55,0x28,0x3a,0x16,0x0c, - 0xe2,0xeb,0x43,0x10,0xce,0x20,0x84,0x04,0xb9,0x96,0x25,0xbe,0x6f,0xa7,0x0b,0xe9, - 0x6a,0xa0,0x9e,0x84,0x2a,0xdf,0xaa,0x79,0xea,0xc5,0xb2,0x57,0xdf,0x8f,0xac,0x0d, - 0x97,0x97,0x2f,0x44,0x81,0xb7,0x9f,0x47,0x35,0xc0,0x45,0xed,0xe0,0xae,0xd9,0x74, - 0x7b,0x58,0xb3,0xa4,0xc9,0xc5,0x77,0x1b,0xfb,0x21,0x34,0x2b,0xa1,0x67,0x1f,0x84, - 0x31,0x39,0x2a,0x15,0xca,0x87,0xa2,0x0f,0x92,0x06,0x68,0xd2,0x4c,0x9a,0x78,0x69, - 0x68,0x62,0x0e,0xdf,0x56,0x21,0x16,0x69,0xc6,0xdb,0xa6,0x35,0xb8,0xca,0xae,0xb1, - 0xc3,0xcd,0xa6,0x30,0x4c,0x2d,0xad,0x9d,0xac,0x56,0xf8,0x3a,0x1c,0xa4,0xbd,0xfc, - 0x51,0x1d,0x33,0x06,0xf3,0xbd,0x58,0x58,0xcd,0x45,0xb1,0xb5,0xc1,0x4f,0x05,0xe8, - 0xf5,0xe4,0x84,0x9f,0xd8,0xb6,0xf0,0x19,0x9b,0x1a,0x48,0x78,0xa2,0x78,0x67,0xb9, - 0x3e,0xa2,0xab,0xd2,0xcb,0xec,0x76,0x72,0x4f,0x83,0x01,0xd4,0x3c,0xe0,0x92,0x9e, - 0xe2,0x6c,0x41,0xd0,0xe9,0xe1,0x59,0x13,0x8e,0x53,0x52,0xcd,0x2a,0x05,0x3f,0xb0, - 0xec,0x0e,0x85,0x67,0x03,0x88,0x89,0x7d,0x56,0x5b,0x54,0x4d,0xc8,0x9c,0x1d,0xd7, - 0x87,0xd9,0xb6,0xac,0x68,0x48,0x7b,0x9c,0x72,0x5b,0xb5,0x36,0xcd,0x82,0x9d,0x7a, - 0xae,0x2d,0xad,0x11,0x69,0x46,0x00,0x4f,0xe3,0xbe,0x1e,0x9c,0x06,0xaf,0x47,0x03, - 0xa0,0x81,0xd8,0xc6,0x68,0x5c,0xec,0xba,0x39,0x3b,0xbc,0xdf,0xed,0x58,0x35,0x9c, - 0xc4,0x15,0x96,0x54,0x63,0x61,0xe8,0xd4,0xf5,0xd0,0x0a,0xd3,0xea,0x46,0x9a,0x95, - 0xe9,0x35,0x3c,0x13,0xa7,0x4e,0xf2,0x91,0xfa,0x84,0xa6,0x99,0x68,0x26,0x9d,0xa8, - 0x71,0xc5,0xaf,0x75,0x7e,0x84,0xb5,0x27,0x28,0xe0,0x16,0x54,0xc6,0x26,0x9a,0x91, - 0x8a,0x81,0x0a,0xe2,0x6c,0x79,0xcf,0x63,0xf4,0x54,0x63,0xcc,0x3e,0xe0,0x60,0xb7, - 0x4c,0x93,0xbe,0xaf,0x42,0xb9,0x81,0xa8,0x2c,0x49,0x17,0xc7,0x86,0x26,0x58,0xa2, - 0x12,0xca,0xf9,0x50,0x42,0xd6,0x53,0x41,0x4d,0xfb,0x40,0x6f,0xcb,0x0e,0xbc,0x89, - 0xcc,0xc9,0x12,0xae,0x2f,0xaf,0xe9,0x1c,0x50,0xa2,0x32,0xc2,0x1a,0x5e,0xe9,0x7c, - 0xa6,0x47,0xe4,0xc0,0x5a,0x67,0x08,0x6c,0x3a,0x07,0x14,0x9f,0x3c,0x0a,0xa0,0x75, - 0x9e,0xf4,0xf7,0x8e,0x2b,0xc1,0xa9,0x04,0xa1,0x0b,0x6d,0xfc,0x84,0x3a,0x43,0x85, - 0x80,0x7e,0x56,0xd2,0x8b,0x09,0x57,0x7d,0xde,0xd3,0x8a,0x1d,0x7d,0x53,0x51,0xae, - 0xd6,0xa1,0x12,0xb4,0xc7,0x6c,0xc8,0xdc,0xec,0x1f,0x9d,0xfc,0x0e,0xa7,0x6e,0x06, - 0x00,0xb5,0x99,0xbe,0x60,0x91,0xc8,0x64,0x61,0x7c,0xdb,0xfc,0x2f,0x9a,0xed,0x29, - 0x06,0x27,0x96,0xd4,0x66,0xcf,0x53,0x14,0x94,0xf6,0xae,0x50,0xa0,0xc4,0x4f,0xd0, - 0xb1,0x37,0x67,0x93,0xa9,0xc1,0xd0,0xd7,0x3e,0xd1,0xb0,0x8f,0x60,0x36,0x7d,0x1f, - 0x0e,0xe6,0x5f,0x8e,0x5b,0x94,0x4a,0xa8,0x30,0x29,0x15,0x11,0xbc,0x64,0x41,0xc2, - 0x9e,0xca,0x94,0x97,0xb4,0x3e,0xa8,0x19,0x4c,0xe6,0x7f,0x86,0x3f,0xdf,0xae,0xcf, - 0xc5,0x4f,0xe8,0xf5,0x0d,0x06,0x7f,0x10,0xfe,0x2b,0xb3,0x5e,0x72,0x58,0x87,0x86, - 0xb6,0xdb,0x00,0x08,0x82,0xaf,0xaf,0x94,0x1c,0xb2,0xdc,0xfa,0x0d,0x59,0x41,0xdf, - 0x75,0xa1,0xfd,0xc0,0x1c,0xf1,0x77,0x19,0xf3,0x0f,0x37,0x32,0x58,0x38,0x3c,0x70, - 0xcc,0x75,0x8e,0x0a,0x7b,0x79,0xa9,0x6e,0x4d,0x18,0x98,0xb2,0x7e,0x5d,0x93,0xe4, - 0xa5,0xe0,0x34,0x29,0xc9,0x3f,0x24,0x55,0x0f,0x5f,0xcb,0x98,0xe1,0x8a,0x5f,0xb4, - 0x40,0xaa,0x38,0x06,0x38,0xd9,0x3b,0x9a,0x1a,0xdc,0x30,0xae,0xc6,0x0f,0x22,0x80, - 0x81,0xb8,0xd3,0x12,0xc6,0x87,0xaf,0x89,0xb0,0x98,0x87,0x18,0x06,0x77,0xef,0x33, - 0x3c,0x27,0xed,0x1a,0x89,0x12,0xf4,0x57,0x76,0x4c,0x09,0x8e,0x80,0x6b,0x39,0x81, - 0x3e,0x7e,0x5e,0x01,0x14,0x58,0x31,0x30,0xbe,0x34,0x80,0x42,0x1c,0xe3,0x46,0x3b, - 0x8a,0xfd,0xa4,0x15,0xdf,0x40,0xec,0xf4,0x03,0xa1,0x0d,0x1e,0x2d,0xbe,0xaf,0x88, - 0x30,0xc2,0x09,0xef,0x3d,0xb1,0x0c,0x88,0xae,0x86,0x2c,0xf9,0x62,0xc3,0xb4,0x7e, - 0x78,0x21,0xb7,0x20,0x06,0x3c,0x35,0x3b,0xa8,0x00,0x11,0x4c,0x28,0x6b,0xf3,0xe8, - 0xe5,0x58,0x89,0xf5,0x86,0x2d,0xdc,0xd1,0xf7,0x8b,0x6a,0x96,0xb4,0x99,0x00,0x7b, - 0xc5,0x58,0xcc,0xc0,0x17,0xbc,0xe5,0x1d,0x6d,0xfd,0x49,0xc5,0xa0,0xd6,0x89,0xb4, - 0x42,0x05,0x08,0x1f,0xe1,0x92,0x86,0xb9,0x9d,0xce,0xf4,0xef,0x58,0x91,0x33,0x3e, - 0x1d,0xab,0x56,0xed,0xea,0xaa,0xd7,0xf8,0xaf,0x9f,0x3f,0xd3,0x45,0x08,0xf3,0xbc, - 0xa7,0x40,0xff,0x42,0xb2,0xd6,0x20,0x57,0x25,0xf5,0x89,0x5f,0xa3,0xe5,0xcb,0x5e, - 0x22,0xff,0x96,0xc8,0x67,0x67,0x98,0xff,0x9e,0xd4,0xdf,0x1c,0x3a,0x43,0x63,0xf0, - 0xf2,0x1f,0xbb,0x2d,0x1b,0x27,0xb8,0x4b,0xd8,0xec,0x3e,0x09,0x52,0x38,0x1e,0x69, - 0xba,0x63,0x16,0xe3,0x11,0xda,0x31,0x8f,0x8a,0x77,0x38,0x7a,0x46,0x61,0x9a,0x7d, - 0x89,0x37,0x27,0x6c,0xd2,0x67,0x4f,0xa9,0x5f,0xd0,0xd7,0xc0,0x4c,0xe5,0x02,0x63, - 0x15,0x75,0x33,0xb0,0x00,0x80,0xac,0x1b,0x04,0x45,0x82,0x7c,0xda,0x3e,0x5d,0xb0, - 0xd2,0xd8,0xe6,0x9b,0x75,0x60,0x27,0x7a,0x82,0x00,0x2c,0x2c,0x63,0xce,0x64,0xbb, - 0x53,0x2d,0xd0,0xd7,0xd0,0xc1,0xd1,0x84,0x10,0x9b,0xb4,0x9f,0x71,0xaa,0x28,0x38, - 0xc3,0x3d,0x94,0xa0,0x68,0xab,0x2a,0xee,0x5a,0xe3,0x3e,0xb6,0x95,0x76,0x37,0xf1, - 0x1a,0xca,0x8c,0xf0,0x55,0xf4,0x70,0x62,0x3a,0x49,0x07,0x08,0xac,0x67,0xf9,0x41, - 0x8e,0x1b,0xa2,0x11,0xa6,0x38,0x31,0x9e,0x5d,0x13,0xbe,0x0d,0xc9,0xe4,0x42,0x79, - 0xb6,0xec,0x1a,0x0d,0x3e,0x04,0xb0,0xb6,0x4a,0xf0,0x86,0x75,0xd0,0x6f,0x78,0x2f, - 0xdd,0xa5,0x72,0x17,0x17,0x3a,0x2e,0x58,0x5c,0x4c,0x36,0x8f,0x2c,0x2b,0xa9,0x39, - 0xee,0xa0,0xe7,0xc8,0xca,0xf8,0xb0,0x71,0xd9,0xaf,0x80,0xe3,0x7a,0x5a,0x9b,0xae, - 0x40,0x86,0x91,0xf9,0x36,0x4f,0x86,0xa2,0x7d,0xa5,0xbe,0x50,0x92,0xde,0x97,0x76, - 0x28,0xf2,0x0f,0xaa,0x0d,0xc6,0xf1,0xd1,0xc4,0xc2,0x2f,0x54,0xce,0xd8,0x91,0xbc, - 0x53,0xf6,0xa8,0x3c,0x9f,0x0d,0x04,0xa4,0xbc,0xc8,0x65,0xb5,0x3a,0xf3,0x85,0x8b, - 0x31,0x11,0x95,0xe8,0xe7,0x2c,0xbf,0xc7,0x79,0x37,0xdc,0xeb,0x8e,0xe3,0x28,0xce, - 0xc3,0x4c,0x96,0x60,0xdd,0x6d,0xcd,0x47,0x58,0x26,0xd7,0xf2,0x16,0xd2,0x6d,0xc5, - 0xe1,0xb3,0x7c,0x50,0x3a,0xa3,0xcf,0xfa,0x47,0xab,0x6b,0x3b,0x78,0xf8,0x9c,0xdf, - 0x49,0x14,0xe7,0x28,0xa9,0xe3,0x34,0xd6,0x20,0xca,0xd0,0x3b,0x46,0x5b,0x49,0x56, - 0x09,0x1a,0x53,0x88,0x0d,0xf8,0x51,0x93,0x72,0x64,0xe0,0x3b,0xe4,0x13,0xe1,0xe2, - 0x76,0xab,0xf8,0x72,0x2e,0x51,0x0b,0x93,0x4b,0xc7,0x75,0x8b,0x68,0x8d,0x1d,0x98, - 0x41,0x3d,0x5c,0x4c,0x19,0xc3,0x44,0xf0,0x66,0x1c,0x8f,0x58,0xc9,0x9e,0x9f,0x8e, - 0x23,0x7f,0x78,0x48,0x5f,0xec,0x18,0x7d,0x86,0x5f,0x75,0x8a,0xdc,0xb3,0xa9,0x18, - 0xd5,0xd1,0x8a,0x03,0xb6,0xdd,0x2f,0xc0,0xfc,0xfb,0xca,0x69,0xa9,0x5c,0xfb,0xf9, - 0x96,0x1b,0x74,0x10,0xdf,0x4a,0x83,0x3a,0x38,0xc8,0x1d,0x7c,0x47,0x3a,0x64,0x70, - 0x49,0x38,0x14,0x8c,0xd5,0x34,0xa3,0xb4,0xd9,0xca,0xc7,0x2c,0x7d,0x83,0xca,0x41, - 0x80,0xdf,0xad,0xa1,0x52,0x23,0x1f,0xad,0xe4,0x6e,0xfa,0xde,0x0d,0x67,0x7c,0x46, - 0x4d,0xdf,0x68,0xf6,0x06,0xc0,0x11,0xb2,0xc7,0xf3,0xdf,0x75,0x9c,0x8e,0xa9,0xcf, - 0xd4,0x30,0xea,0xec,0x2c,0x52,0x82,0xfa,0x5b,0x98,0x1c,0xe9,0xe3,0x40,0x7b,0xac, - 0x8c,0xba,0xc2,0xbd,0xf7,0x72,0x0b,0x0e,0x56,0xd2,0xd1,0xf6,0x11,0x5c,0x16,0x8c, - 0x00,0xf6,0x4c,0x15,0x96,0x13,0xc8,0x26,0xb9,0x27,0x4d,0xc8,0x26,0x91,0x22,0x4e, - 0xb2,0xf4,0x24,0x00,0xd7,0x3e,0xce,0x6d,0xa1,0x47,0xcf,0xbb,0xdd,0x7d,0xde,0xeb, - 0x41,0x82,0xc3,0x43,0xfe,0x63,0x14,0xe7,0xd2,0x61,0x03,0x5a,0x74,0x48,0x0c,0x61, - 0xae,0x48,0xa1,0xb0,0x1c,0x33,0x19,0x9e,0xb3,0x39,0x57,0xb0,0x09,0x23,0xf4,0x44, - 0xf9,0x88,0x19,0x8a,0xbf,0x94,0xf8,0x2f,0x2d,0x8e,0x40,0xf2,0x58,0x51,0xbb,0xcd, - 0x57,0x44,0x12,0x3c,0x24,0x2f,0xf9,0xf0,0x27,0xe6,0x27,0x9e,0x0b,0x6f,0x72,0x6c, - 0x3c,0x8a,0xc5,0x1a,0x25,0x64,0xf7,0x69,0xe3,0x3e,0xdd,0xdd,0x1d,0x07,0x58,0xc3, - 0x2f,0x5a,0x31,0xf2,0xc0,0x96,0x04,0x01,0x4f,0x39,0xff,0xc1,0xf2,0x44,0xf1,0xc8, - 0x82,0xb0,0xf8,0x08,0x40,0x68,0x22,0x24,0x6e,0x62,0x43,0xe7,0x18,0xc1,0x7e,0xc6, - 0xf0,0xa9,0x78,0xb0,0xe3,0xa1,0x0b,0x37,0xae,0x0a,0x12,0x63,0x9c,0x03,0xda,0x32, - 0x4c,0xdc,0x61,0x5c,0xea,0xd3,0x1b,0xc1,0xc4,0x6b,0x92,0xd5,0x8e,0x70,0x70,0x16, - 0x6e,0x93,0xe3,0xb1,0xfc,0xa1,0x57,0x26,0x85,0x1a,0xb3,0xac,0x18,0x86,0x3f,0x81, - 0x90,0xe5,0xf0,0x33,0x47,0xc4,0x41,0x3a,0x71,0xde,0x98,0x0b,0x24,0x73,0xf4,0x08, - 0x0d,0xca,0xf4,0x25,0xcd,0x7a,0xf2,0xb3,0x9a,0xb0,0x9c,0xca,0x65,0x4c,0xe2,0x43, - 0xcb,0x3d,0xf2,0x39,0x3c,0x27,0x01,0x70,0x32,0x3f,0x01,0xee,0xe9,0x5c,0x6b,0x0f, - 0xec,0xf9,0x79,0x55,0x93,0x5f,0xac,0xc1,0xef,0xb6,0x88,0x7c,0xdf,0x12,0xb9,0x2a, - 0xb6,0x33,0x05,0x73,0x30,0xa4,0xe8,0xf1,0xb8,0x9b,0x41,0xd4,0x7e,0x48,0xf9,0x68, - 0x1f,0x79,0x14,0xb2,0xc7,0x93,0xfe,0x38,0x42,0xe7,0xa3,0x24,0x8c,0x79,0x62,0xee, - 0x37,0x5f,0x64,0xf0,0x44,0xe4,0x27,0x31,0xbe,0xa5,0xea,0xd8,0xce,0x50,0x03,0x5c, - 0x0f,0x21,0xb4,0x5e,0x36,0x5e,0x29,0x98,0xf8,0x61,0x2b,0x37,0xe5,0x5d,0x6f,0x80, - 0x27,0xa6,0x4c,0x84,0x80,0xf7,0xfb,0x43,0xcf,0xa9,0x0e,0x33,0x51,0x1a,0x55,0x02, - 0x50,0xbd,0x53,0xd2,0xb0,0x2d,0x2d,0x52,0xf5,0x00,0xdd,0xce,0x70,0xed,0xf0,0x60, - 0xe5,0x50,0xf9,0x70,0x7c,0xa0,0x4a,0xbb,0x72,0xa8,0x76,0xec,0x0c,0xf5,0xae,0xd5, - 0x00,0xf9,0x0e,0x98,0xf7,0x7b,0xa6,0xda,0xa3,0xc9,0xd4,0xc8,0x43,0x79,0xac,0xf2, - 0xee,0xe3,0xb0,0x8b,0x76,0x4c,0xeb,0xa1,0xef,0xc6,0x91,0x6e,0xd9,0x40,0x51,0x0c, - 0x0e,0xbc,0x2c,0x53,0x7a,0x62,0x00,0xe9,0xa0,0x80,0x51,0x90,0x9b,0xf5,0x69,0x39, - 0x69,0x8d,0x5e,0x9a,0x29,0x8e,0xde,0x9b,0xf2,0x79,0x92,0x87,0xfc,0xba,0xb8,0x39, - 0x72,0xa6,0x2e,0xab,0x9f,0xd3,0x3a,0xec,0xad,0xdb,0xc7,0x0f,0x24,0xf6,0x34,0x3c, - 0x80,0x4c,0xd9,0x90,0xa7,0x59,0x23,0xef,0x0f,0x9a,0xda,0x9c,0x0c,0x31,0x95,0xac, - 0x8e,0x27,0x40,0x04,0xa1,0x8a,0x51,0xd0,0xd5,0xa5,0x47,0xeb,0x6a,0xbc,0x07,0x63, - 0xda,0x35,0x6a,0x8d,0x0c,0x25,0x0c,0xb2,0xdd,0x32,0xec,0x5e,0x98,0xfe,0x2f,0x06, - 0xd9,0x53,0xe9,0x82,0xff,0x22,0x0e,0x1b,0xee,0xbd,0xeb,0xab,0x47,0x9d,0x4a,0xde, - 0x31,0x40,0xea,0x74,0x05,0xb7,0x59,0x65,0x55,0x57,0xd7,0xc0,0x95,0x8c,0xa1,0x8f, - 0x51,0x8f,0x9e,0x4b,0xd9,0xfd,0xe5,0xe0,0x99,0x7a,0xbb,0x47,0xb7,0xb2,0xe6,0xa0, - 0xde,0x9d,0x6b,0x38,0x4f,0x60,0x3d,0x6b,0xbd,0xdd,0x0d,0xa8,0xbe,0x51,0xd3,0x4f, - 0x57,0x42,0x21,0x88,0xf8,0xfe,0xf9,0xe4,0x66,0x6f,0xd5,0x9e,0xf1,0x04,0x7b,0x8c, - 0x89,0xa8,0x6c,0xe6,0x5f,0x34,0x05,0x49,0xd0,0xcc,0x3b,0x06,0x99,0xfd,0x66,0xea, - 0x78,0x00,0x90,0x03,0x62,0xf7,0x72,0x72,0x70,0xcc,0x90,0xd4,0x2a,0xc7,0x53,0xf3, - 0x98,0xb8,0x05,0xd6,0x62,0x99,0x28,0xf8,0xa2,0xc9,0x51,0xcc,0xf4,0xcf,0x93,0x26, - 0x15,0xd9,0xc5,0x92,0x7b,0x92,0x7b,0xc4,0x85,0x9a,0xe9,0x0c,0x52,0xa1,0xe6,0x6c, - 0x71,0xb0,0x0b,0x09,0x5b,0x2b,0xe9,0xee,0x91,0xba,0x56,0x05,0x12,0xb4,0x46,0x06, - 0x5e,0x8c,0x25,0xd7,0x2b,0x94,0xa0,0x8a,0xf8,0x2f,0x98,0x79,0x49,0x88,0x75,0xab, - 0xb8,0xa7,0x66,0xf9,0x4a,0x8b,0x15,0xd0,0x49,0xf1,0x75,0x5b,0x14,0x2f,0x9e,0x53, - 0xef,0x31,0xee,0x60,0xfb,0xd1,0x66,0xbf,0x62,0x4e,0x63,0x27,0x7b,0x3e,0xd1,0xb2, - 0xda,0xc6,0x96,0xa4,0x28,0xbe,0xea,0x24,0x68,0x64,0xc8,0x3e,0x21,0xd0,0x51,0xe8, - 0x5b,0x92,0x4a,0xfb,0x31,0xc4,0x9b,0x60,0xf5,0x40,0xa2,0x1f,0x9b,0x40,0xf5,0x16, - 0xc1,0x77,0x9d,0x94,0xb6,0xaf,0xc8,0x92,0x92,0x2b,0xf4,0x94,0x60,0xa7,0x52,0x35, - 0x5c,0x0b,0x2e,0x45,0x1f,0x22,0xe5,0x1e,0xe4,0xd1,0x0a,0xea,0x28,0x9e,0x91,0xd1, - 0xc1,0x49,0x3a,0x21,0xdd,0xc3,0xf3,0x7c,0x22,0xab,0xe7,0x61,0xbf,0xd0,0x28,0x71, - 0xaf,0x10,0xf7,0xdf,0x4b,0x0f,0x96,0x1e,0x2e,0x3d,0x5a,0x7a,0xbc,0xf4,0x64,0xe9, - 0xe9,0xd2,0xb3,0xde,0x3d,0xdc,0x8e,0xc9,0x31,0x3d,0x63,0x65,0x0e,0x55,0x35,0xc6, - 0xd7,0x70,0xea,0x22,0x7f,0x26,0x1e,0x02,0x57,0x0e,0x0c,0x2b,0xa2,0xcf,0x33,0x5c, - 0x59,0xe7,0xab,0xda,0x81,0x60,0x66,0x39,0x46,0x61,0x39,0x7a,0x1b,0xaa,0xc8,0x5b, - 0x83,0xa8,0x3c,0xf5,0x6e,0x74,0xeb,0xd4,0x5f,0x6d,0x3a,0x3a,0x69,0x22,0x6b,0x72, - 0x37,0x07,0x7e,0x4c,0x0c,0x53,0xa7,0x04,0x2d,0x51,0xd2,0x2b,0xb5,0xcf,0x29,0x93, - 0x5f,0x23,0xa2,0xc7,0x9e,0x28,0x16,0xf4,0xc4,0xc4,0x3e,0x0d,0x8c,0x17,0x7c,0xc0, - 0xda,0x49,0x81,0xe0,0xf6,0x56,0x53,0xf1,0xb4,0x66,0xa7,0xc3,0xf5,0x89,0xf5,0xdb, - 0x4d,0xe4,0xbc,0x86,0x3c,0xa4,0xf7,0xbd,0x9c,0xa9,0x60,0x48,0x73,0x5a,0xaa,0xf9, - 0xdc,0x29,0x63,0xdd,0x10,0x3b,0x03,0x98,0x05,0x54,0x39,0x34,0x86,0x36,0x1d,0x8d, - 0x37,0xf9,0x80,0x79,0x73,0x65,0x33,0x33,0xc1,0x5b,0xb1,0xf9,0x9e,0x8c,0xbe,0x69, - 0xa2,0x81,0xb5,0x5d,0x9b,0x3c,0xf7,0x16,0x44,0x0e,0xe2,0x1d,0x2c,0xb6,0x8f,0x6d, - 0x57,0xf0,0x53,0x80,0x12,0x69,0xee,0x3a,0x53,0xeb,0x49,0xdb,0xb6,0xc5,0xbf,0x5c, - 0x40,0xa8,0xc5,0x3f,0xed,0x7c,0x72,0x17,0x72,0x43,0x62,0xc6,0x3f,0xbe,0xf8,0xd5, - 0x54,0xc2,0x09,0xf7,0x5c,0x98,0x65,0x65,0x7c,0x17,0xfe,0x78,0xa8,0xde,0x1e,0xe7, - 0x77,0xd6,0x39,0x7d,0xd9,0xe9,0x7a,0x2d,0x82,0xb8,0xda,0x9c,0x96,0x8c,0xc3,0xda, - 0x11,0xd3,0x08,0xc3,0x81,0x7b,0x31,0x51,0x9e,0xa6,0x6a,0x19,0xd2,0x7b,0x9d,0xd0, - 0x65,0x0f,0x87,0x70,0xc0,0x0b,0xa0,0xf3,0x3d,0xd7,0xed,0xdc,0xdc,0x72,0x84,0x03, - 0x50,0x3c,0x5f,0xc9,0x49,0x6d,0xf9,0x66,0xe8,0x2e,0xb0,0x5b,0xdc,0x96,0xc8,0xb2, - 0x25,0x01,0x95,0x3e,0xfe,0x38,0x83,0x39,0xdf,0x02,0xc5,0xb0,0x04,0x92,0xb8,0xf4, - 0x39,0xf1,0xb1,0xc0,0xae,0x31,0x38,0xe2,0xfa,0xdc,0x12,0x19,0x5e,0x9f,0x65,0x5c, - 0xfd,0x36,0x01,0x8e,0xa8,0x0b,0xa4,0x41,0xe7,0x32,0x16,0xef,0x57,0x2a,0xf0,0xf1, - 0x78,0x1a,0xa4,0xad,0x7b,0xa0,0x5d,0x73,0xae,0xf5,0x49,0xb6,0xc8,0x2c,0xd8,0x32, - 0xd4,0x9b,0xff,0xc5,0xed,0xbc,0x12,0xf5,0xb0,0xfb,0xc8,0x64,0xc6,0xe5,0xdb,0x9f, - 0x66,0xdb,0xe2,0x84,0xd9,0xd8,0xd9,0x9e,0x80,0x38,0x9a,0x8f,0xc6,0xe6,0xb1,0xc2, - 0xc4,0xdf,0x1a,0x37,0x7f,0x7c,0xf3,0xb2,0xe0,0x6c,0x0e,0x3d,0x1e,0xb8,0xbf,0x96, - 0xe1,0xc0,0x41,0xe4,0xe5,0x42,0xfb,0x1f,0xad,0xf7,0xb5,0xb5,0xb0,0xbd,0x65,0xb2, - 0x6b,0x4a,0xe7,0x28,0x5a,0x5b,0x58,0xd4,0xff,0xd0,0x16,0xa4,0x4b,0x01,0x02,0x22, - 0x1e,0xe3,0xf2,0x01,0xf4,0x4b,0x45,0x0a,0xa6,0x87,0xa4,0x98,0xb8,0x98,0x5c,0x89, - 0x22,0x04,0xfd,0x92,0x2e,0x6a,0x63,0xcc,0x57,0x0b,0xe0,0xf6,0xe2,0x57,0xac,0x8a, - 0xf4,0x53,0x85,0xd5,0xd6,0xa3,0x2e,0x79,0x86,0xf8,0x0f,0x3f,0x2b,0xc1,0xc5,0xaf, - 0xd8,0xbc,0xb4,0x76,0xfb,0x60,0x55,0xf3,0x73,0x22,0x07,0x0d,0x15,0xe1,0xdc,0x90, - 0xa6,0xab,0x74,0x34,0x5c,0x26,0x99,0xe6,0x72,0xde,0x1c,0x09,0xbe,0xde,0x27,0x19, - 0xce,0x1b,0x7e,0x9b,0x4d,0x6a,0xba,0xb8,0x45,0x8f,0x44,0x4f,0xb7,0x67,0xee,0x90, - 0x03,0x91,0x72,0x66,0x6c,0xa4,0xc1,0x84,0x8d,0x26,0xd2,0xa6,0x1e,0x17,0x3d,0x49, - 0x65,0x0c,0xe3,0x2d,0x61,0x25,0x69,0x23,0x53,0x43,0x35,0xa9,0x1f,0xad,0x14,0xf0, - 0xf7,0xe1,0x83,0x8a,0xb1,0x9d,0x53,0xa0,0xb8,0x49,0x40,0x65,0xc7,0x25,0x12,0x9f, - 0x53,0x68,0xee,0xe4,0x59,0x9d,0xf6,0xf1,0x20,0x18,0x17,0xdf,0xcc,0x24,0x9b,0x12, - 0x67,0xe7,0x17,0x2e,0x1b,0xb1,0x17,0x4e,0x14,0x2c,0x40,0xa2,0xbe,0x73,0xd3,0xfb, - 0xd8,0x38,0x9e,0xe0,0x33,0x69,0x31,0x19,0x93,0xfa,0x41,0xf1,0x81,0x8b,0xb1,0x7f, - 0x15,0x2c,0x83,0x32,0xb5,0xc3,0x3a,0xd7,0xf5,0xec,0x1f,0x2f,0x4c,0xb7,0xe3,0xcf, - 0x2d,0xc6,0xfe,0xb8,0x92,0xa4,0x47,0x0a,0x35,0x1c,0x53,0x29,0xc4,0x72,0x96,0xda, - 0xa0,0xf2,0xf9,0xed,0x7d,0xd8,0x53,0xa6,0x54,0xfc,0xd6,0x7e,0x62,0x66,0x27,0x3b, - 0x3a,0xe9,0x57,0xfc,0xf1,0xf5,0x6b,0x56,0xe1,0xfe,0xf9,0x91,0x54,0x99,0x13,0x61, - 0x7e,0xf6,0xd1,0x2e,0x74,0x80,0x7e,0xbd,0x65,0x67,0xdd,0xd1,0x69,0xc3,0xd0,0xf5, - 0x71,0x18,0x37,0x72,0x50,0x8a,0xa7,0x3f,0x8b,0xce,0xf8,0xb4,0x06,0xde,0x0c,0x74, - 0xbc,0x9f,0xa4,0x88,0x63,0x0a,0x85,0x48,0x63,0x9c,0x7a,0x02,0xaf,0x98,0x48,0x3e, - 0xfc,0x3d,0x94,0xfe,0xae,0x99,0x8a,0x33,0xf2,0x83,0xaa,0x9f,0x33,0x54,0x3c,0xa0, - 0x33,0x64,0xae,0x48,0xe4,0xa3,0x73,0x9b,0x05,0xde,0xf7,0x18,0x98,0xa8,0xae,0x80, - 0x24,0x23,0x0c,0xa2,0xc5,0x60,0x51,0x4c,0x18,0xae,0x7a,0xc1,0x24,0x4e,0x5f,0x25, - 0x06,0xf8,0xee,0xc6,0xca,0x2d,0x1b,0x94,0xed,0x46,0x8b,0x59,0x1f,0x04,0x29,0xd0, - 0xdd,0xf8,0x5a,0x5c,0xf6,0x7d,0xbc,0xa1,0x68,0x88,0x55,0x0c,0xe3,0x65,0xef,0x1c, - 0x70,0xd2,0xa9,0x4e,0x46,0x2d,0xae,0xc0,0x47,0xbe,0xb4,0xe8,0xb4,0x32,0x95,0x6f, - 0x6b,0x23,0x74,0x28,0xa0,0x01,0x5c,0x7f,0x02,0x59,0x4f,0x70,0x3d,0x60,0x60,0x52, - 0xee,0x2c,0xb7,0x3e,0x5b,0x07,0xb5,0x4b,0xeb,0x40,0xd6,0x3e,0xb5,0x00,0xd0,0xa5, - 0xfb,0xbb,0x11,0xc7,0x65,0x56,0xf1,0xf8,0xcf,0xcf,0xe2,0xf5,0xea,0xc3,0xdd,0xaf, - 0xc3,0xc9,0x08,0x99,0x4d,0x2d,0x6d,0x4a,0x89,0x82,0xb3,0xee,0xc2,0x9d,0x8e,0x65, - 0x3b,0x2d,0x4d,0x11,0x6e,0x95,0x48,0xc7,0xc1,0x58,0x45,0x3a,0x7d,0xb2,0x60,0x17, - 0x4c,0x62,0x6f,0xcf,0x12,0xb3,0x14,0xa9,0xd7,0x47,0xa4,0x47,0x7c,0x66,0x69,0x0e, - 0xa1,0x3d,0x53,0x9b,0x42,0x63,0x65,0x14,0x96,0xbf,0x52,0x9c,0x55,0x91,0x76,0xfe, - 0xb4,0x32,0xd2,0x01,0xfb,0x89,0x7b,0x9d,0xbe,0x08,0xbf,0x3c,0x9f,0x14,0xa8,0x0a, - 0x26,0x73,0xa5,0xc6,0x00,0x17,0x0a,0xe5,0x1d,0x81,0xbe,0x77,0x51,0x72,0x83,0xcb, - 0x52,0x8b,0x2b,0xdf,0xda,0x35,0x68,0x6b,0xbf,0xd8,0xf6,0x4e,0x71,0x86,0x82,0x9d, - 0xf9,0x6c,0x8b,0xf9,0x37,0x7d,0x85,0x78,0x13,0x3a,0x05,0x83,0xef,0xc6,0x2a,0x33, - 0x95,0x2d,0xce,0xe8,0x99,0xbc,0x26,0x6d,0xc1,0xce,0x92,0x93,0xc7,0x25,0xc1,0x76, - 0x73,0xe2,0x09,0x2d,0xd0,0x25,0xca,0x2c,0x7a,0x98,0x22,0x87,0xfa,0x80,0xf8,0x46, - 0x52,0x2c,0x6c,0x7e,0xc6,0x8c,0x9c,0xa7,0x47,0x8a,0x64,0xc0,0x15,0xcc,0x7b,0xab, - 0x8f,0x23,0xb9,0x62,0x95,0xf4,0x48,0xff,0x27,0xf4,0xe2,0x02,0x74,0x58,0xf8,0xb4, - 0x78,0x86,0xe5,0x3d,0xf9,0xd8,0x88,0x56,0xbe,0x2e,0xf6,0xc5,0xaf,0x68,0xf6,0xb7, - 0x6a,0xfb,0x0b,0xed,0x39,0xa7,0x5a,0x0b,0xae,0x4a,0x79,0x65,0xc8,0xc6,0x92,0x00, - 0xed,0xf2,0xdc,0xab,0xae,0x5d,0x55,0xaa,0x61,0x0e,0x1c,0xbe,0x35,0xa3,0xfc,0xea, - 0x5d,0x50,0x01,0xa1,0xa5,0xd6,0xe0,0x53,0x48,0xd5,0xb8,0x04,0x4b,0xc3,0xa3,0xec, - 0x03,0xd3,0x7b,0xeb,0x94,0x80,0xd2,0x59,0xdc,0x5b,0xea,0xfc,0x50,0x31,0x1c,0x1f, - 0x19,0xd0,0xed,0x4d,0xb5,0x6c,0x5d,0x59,0xcf,0x95,0x38,0xdb,0x46,0x51,0x23,0xc5, - 0x0d,0x2d,0x4e,0x6f,0x34,0xb8,0x17,0xb7,0x3a,0x21,0xf8,0xbf,0xfd,0x37,0xd4,0x60, - 0x49,0x6d,0xc7,0x22,0x6a,0x2b,0xcd,0xb4,0x82,0xd6,0x4e,0x63,0xaf,0x8b,0x59,0xc4, - 0x12,0x29,0x02,0x2c,0x9e,0xf4,0x85,0x3a,0x90,0xa5,0x66,0xa2,0xc4,0x5a,0x87,0x8b, - 0x11,0x2f,0xbe,0xb4,0x08,0x46,0x6a,0xfc,0x1c,0xf2,0x74,0xa4,0x58,0x17,0x27,0x6b, - 0xfd,0x78,0xea,0x0c,0x5f,0x10,0xcd,0x08,0x96,0xba,0xbc,0xc4,0xec,0xcb,0x75,0x52, - 0xeb,0x24,0x93,0xd0,0x6d,0x7c,0xcc,0xf4,0xb0,0xad,0x07,0x46,0xa2,0x89,0x5d,0xbc, - 0xa2,0x6b,0xd5,0x1e,0x1b,0x5b,0xd2,0xbc,0x6e,0xa2,0x73,0xb0,0x29,0x2d,0x8e,0x59, - 0xc5,0x92,0x34,0x6a,0xef,0xa1,0x8a,0x6f,0x1c,0xf9,0x14,0x97,0x69,0x59,0x06,0x85, - 0x78,0x86,0x48,0x22,0x9d,0x2a,0x0b,0x70,0xf8,0x0d,0xc6,0x04,0x30,0xb1,0x82,0xfd, - 0xc7,0x20,0x1e,0xf2,0x70,0x60,0xa0,0x60,0xbc,0xd6,0x13,0x59,0x2c,0x54,0x8a,0xb7, - 0x93,0x37,0xd1,0x77,0xc5,0xc0,0xa7,0x4f,0xd2,0x69,0x0d,0x9b,0x98,0x1d,0x3a,0x7d, - 0x6a,0x74,0x2e,0x43,0xa6,0xe3,0xd4,0xbe,0x5c,0x7e,0x7e,0xb8,0x06,0x68,0x8f,0x3e, - 0xa4,0x0c,0x1d,0xd0,0x67,0x00,0x68,0x33,0xeb,0x5a,0x0d,0x2f,0x88,0xe5,0x34,0x6f, - 0x82,0x6f,0x2b,0xec,0xb3,0xb9,0x3d,0x93,0x2b,0x06,0xb3,0xb2,0xa0,0x1a,0xcb,0x5c, - 0x4a,0x8d,0x42,0xcc,0x77,0x94,0xea,0xa8,0x04,0xa7,0x6c,0x4f,0xe3,0x94,0x01,0x37, - 0x3f,0x5f,0x38,0x47,0xb4,0x1a,0xab,0xf4,0xb0,0x89,0x8b,0xdf,0xaa,0xb2,0x6e,0x7c, - 0x05,0x77,0x5a,0xea,0xa9,0x9e,0xc8,0x38,0xa7,0x51,0x59,0x98,0x41,0x28,0x34,0x49, - 0x99,0x49,0x4a,0x6f,0xfd,0x98,0x6e,0x6a,0x8b,0xd4,0x3b,0x1a,0x33,0xa4,0x3e,0x87, - 0x00,0x2d,0x86,0x18,0x7e,0x16,0xf6,0x70,0xf0,0x92,0x56,0x34,0x9d,0xc2,0x99,0x0d, - 0xc7,0xc7,0x53,0x47,0xc4,0xeb,0x9b,0xe0,0x2d,0x01,0xfb,0xf2,0x31,0x7c,0xc4,0x4b, - 0x82,0xb7,0xeb,0xd5,0xe7,0xc1,0x9e,0x09,0x95,0x7c,0x73,0x6b,0xa9,0xd0,0x09,0xf7, - 0x38,0xd5,0x96,0x1c,0x7b,0xa5,0xe8,0x45,0x8a,0x99,0xdb,0xe1,0x70,0xef,0xe1,0x5a, - 0x48,0x6d,0x96,0xd2,0x94,0x4c,0x66,0xeb,0x8c,0x8b,0x72,0xaa,0x77,0x2e,0xb9,0x61, - 0xb8,0xf7,0xf9,0xa5,0xf1,0xf2,0x10,0x9c,0x75,0x12,0xdd,0x4d,0x8f,0x17,0x78,0xd1, - 0x0b,0x7f,0xee,0xa0,0x4b,0x9f,0x3a,0xb1,0x87,0xcf,0xbe,0xe8,0x29,0x0b,0x34,0x6f, - 0x20,0x19,0xb1,0x4b,0x96,0x28,0xf5,0x9d,0xe2,0x61,0x0d,0x10,0x4b,0x6d,0x1b,0xa5, - 0x42,0xa4,0xcf,0xa1,0x5f,0x11,0x9c,0x60,0xfe,0xc9,0xd4,0xc7,0xb4,0x1f,0x56,0x3d, - 0x14,0x05,0x9e,0x2f,0xd6,0xd4,0xb0,0x2c,0x29,0x9b,0xe9,0x34,0x9b,0xfb,0x75,0x7d, - 0xfa,0x30,0xd4,0xc7,0xe5,0xd1,0x10,0x6f,0xc6,0xea,0x36,0xf8,0x9c,0xa8,0x2b,0x98, - 0x2c,0xd5,0x21,0x26,0x85,0xe4,0x2d,0xa0,0x19,0x90,0xfb,0x14,0xc7,0xea,0x86,0x56, - 0x4d,0xda,0x35,0xc0,0xf3,0xea,0xbd,0x5d,0x59,0xfc,0x49,0x8a,0x03,0xe1,0xd0,0xc9, - 0x88,0x87,0xc3,0xab,0x3c,0xae,0x20,0xb5,0x62,0x91,0x96,0xe4,0x55,0x4b,0x41,0x75, - 0x5d,0x95,0xbe,0xc7,0xb9,0x18,0xdc,0xcc,0xfe,0xf2,0x0f,0xaa,0x45,0x97,0xaa,0x72, - 0x27,0x5f,0xbf,0x97,0x4a,0xe7,0x9c,0xb1,0xa3,0x94,0x3a,0x49,0x85,0xa5,0x26,0xe4, - 0x7d,0x53,0x8b,0x44,0xb0,0x46,0xd9,0x32,0x7d,0xef,0x52,0x36,0x64,0x00,0x00,0xe6, - 0x5e,0x0b,0x68,0x72,0xd5,0x65,0xdb,0x51,0xa9,0x2e,0xba,0x90,0x52,0xbc,0xed,0xa8, - 0xa7,0xdf,0xf7,0x6c,0x19,0xc7,0x93,0x44,0xc7,0x3f,0x0a,0xce,0xcf,0x3b,0xed,0x20, - 0xcf,0x70,0x4b,0x61,0x2b,0xdb,0x16,0x7c,0x4d,0x07,0x6d,0x61,0xb7,0x04,0xd5,0x42, - 0x31,0x36,0x3f,0x31,0x0a,0xc5,0xc2,0xbe,0xc5,0x5e,0xef,0xa3,0x4d,0x7b,0xf3,0x5a, - 0x29,0x92,0x64,0x3a,0xeb,0xe6,0xed,0x75,0x78,0x53,0x3d,0x43,0xb7,0xb8,0xe6,0x53, - 0x5d,0xd4,0x10,0xc5,0xb8,0xc3,0x90,0x8e,0xed,0x83,0x34,0x17,0xb3,0xa1,0xa2,0x8e, - 0x89,0xfa,0x2a,0x65,0xd0,0x25,0x8b,0x17,0xfe,0x30,0xdf,0x72,0x29,0xcb,0x72,0x9b, - 0x54,0xbc,0x5e,0xaf,0xac,0x6b,0x51,0x1d,0xef,0x5b,0x1b,0x6a,0xa0,0x7c,0xf2,0x0f, - 0x25,0x6c,0xb4,0x11,0x5d,0x34,0xa8,0x12,0xc9,0x92,0xad,0x1c,0xc6,0x7c,0xac,0x66, - 0x89,0x8f,0x63,0x0d,0xad,0xbf,0xf1,0x3a,0x3e,0x1c,0x3b,0xeb,0xf6,0x20,0x3e,0x5e, - 0x15,0x33,0xb4,0x5e,0x9c,0xe0,0x60,0x4a,0xf6,0x37,0x4f,0x8d,0x9c,0x0c,0x61,0x74, - 0x6a,0xc2,0xce,0x43,0xee,0xd7,0xac,0xf4,0xb8,0x75,0xbc,0xe5,0x7e,0x57,0xfb,0xe4, - 0x61,0x67,0xdd,0x6c,0x59,0xaa,0xc1,0x7f,0xc4,0xcb,0xb1,0xa4,0xe2,0xfd,0x35,0x67, - 0xf1,0x23,0x5c,0xb1,0x9c,0xfc,0xea,0x99,0xed,0x76,0x3a,0xc5,0xa6,0xaf,0x14,0x2d, - 0x5e,0xb7,0xa9,0xd7,0x5e,0xab,0x64,0x8f,0x48,0x4c,0xe4,0x8c,0xa0,0xcd,0x93,0x08, - 0xb8,0xcc,0xf8,0x6c,0xe7,0xc8,0xaf,0x27,0xf1,0xb3,0x0a,0x18,0xb6,0xeb,0x83,0x92, - 0xbc,0x3c,0x86,0xff,0xc9,0x15,0x0f,0xb8,0x71,0x46,0x25,0x49,0x9a,0x0d,0xfa,0xea, - 0x77,0x5b,0xda,0xe6,0x4d,0xf9,0x83,0x40,0x1c,0x64,0x78,0xee,0x31,0xb2,0x59,0x56, - 0x87,0x0f,0x08,0xe1,0x2b,0xbd,0x9d,0xb5,0x78,0x8d,0xa3,0x88,0x81,0x9a,0x9b,0x98, - 0x5b,0xad,0x58,0x26,0xe5,0x32,0xc0,0xf7,0x6e,0x45,0x7a,0xf5,0x7c,0x4a,0x07,0x2b, - 0xaa,0xe5,0x06,0x59,0x96,0xaf,0x61,0x5b,0xa5,0x5d,0x27,0x5a,0x75,0x5c,0xb9,0xb7, - 0x3f,0x5b,0x02,0x4f,0x2c,0x77,0x41,0x2d,0xcc,0xe3,0x56,0x5f,0xb4,0x94,0x48,0x8a, - 0xad,0x77,0x22,0x16,0x59,0xcf,0x44,0x96,0xd1,0x4f,0xce,0xac,0x55,0x4d,0x7a,0x6e, - 0x00,0xc4,0x1c,0x2a,0xc8,0xc8,0x29,0xbe,0x2c,0x5f,0x8f,0xe1,0xeb,0xd1,0x9d,0x72, - 0xd5,0x71,0x1d,0xd6,0xb1,0x41,0x6c,0x14,0xce,0x78,0x6e,0xf8,0xf2,0x21,0x23,0x52, - 0xca,0x4e,0x29,0xdd,0x5b,0xed,0xc0,0x7e,0xbd,0xe9,0x20,0xcf,0x81,0x74,0xd0,0xa7, - 0x27,0x6c,0xb4,0xf9,0xcd,0x3e,0x0e,0xd9,0xa9,0x97,0x89,0xef,0x3e,0x96,0xdf,0x6e, - 0x3d,0x2f,0xb0,0x17,0xcf,0x2d,0xf3,0x21,0xb6,0xf5,0xe6,0x19,0x15,0x66,0x24,0x57, - 0x58,0xf6,0xaa,0x81,0xd0,0xf6,0x5d,0xda,0x8e,0x77,0x58,0x2f,0x04,0xce,0xf1,0x44, - 0x95,0x0d,0x93,0x43,0x85,0x02,0xd9,0x81,0xc1,0x5e,0x49,0xa7,0x52,0x13,0x41,0xd2, - 0xf4,0xcb,0xd3,0xed,0xf4,0xed,0xf2,0x2d,0xde,0xcc,0x64,0x5c,0x3e,0x3e,0x78,0x8d, - 0xed,0x61,0x69,0x40,0x6d,0x48,0x52,0xc5,0x55,0xd4,0x9a,0xa2,0x30,0xef,0xa1,0x61, - 0x93,0x7a,0xe4,0x2e,0xdf,0x44,0xb0,0x7e,0x64,0x71,0xea,0x08,0x24,0x44,0x9d,0x01, - 0x69,0xd1,0x26,0x1e,0xbe,0xed,0x7c,0x67,0x9f,0x22,0x26,0xc2,0x18,0xd5,0x9a,0x1e, - 0xb7,0x63,0x7c,0xeb,0x39,0xbe,0x6b,0x2b,0x87,0xfd,0x5d,0xb3,0x3c,0x4e,0x3f,0x62, - 0xb2,0xab,0xfb,0x73,0xed,0x7a,0x7e,0x72,0xed,0x59,0x25,0x06,0xa6,0xf8,0xdb,0x95, - 0xb4,0x34,0x76,0x98,0x37,0x8b,0x6b,0x3a,0xad,0x61,0x58,0x08,0xf4,0x6f,0x38,0x30, - 0xcb,0x96,0x5c,0x27,0x96,0xc6,0x1b,0xd4,0xc2,0x7c,0xa6,0x16,0x7a,0x79,0x62,0xda, - 0x69,0xc2,0xe2,0x9f,0x26,0xd5,0x9c,0x95,0x90,0x59,0xe9,0x71,0x9d,0x6c,0x75,0xbd, - 0x64,0xe2,0x85,0x91,0x89,0xb4,0x81,0xee,0xdc,0x56,0xf1,0x69,0xa1,0xd7,0x2a,0x29, - 0x30,0x9a,0x35,0x71,0x8c,0xbf,0xa9,0x57,0xab,0xf9,0xd4,0xb3,0x61,0x68,0xe4,0x1f, - 0xa1,0xd6,0xc7,0xbd,0xf8,0x80,0x2f,0xaa,0x8f,0xed,0x49,0x0f,0xcb,0xf4,0x9f,0x45, - 0x49,0x20,0x9c,0xcd,0x9e,0x3a,0xd1,0x5d,0x8d,0xf7,0x80,0x11,0xf1,0xce,0x84,0x49, - 0xe4,0xd0,0x8a,0x42,0x3a,0x9c,0xb8,0x2c,0x99,0x10,0xf2,0x94,0x87,0x3f,0xd8,0x19, - 0x57,0x3d,0xf3,0x1c,0x5c,0x88,0x1a,0x3f,0x92,0xbd,0x5f,0x85,0xee,0x1e,0x63,0x7e, - 0xbf,0xd5,0x6d,0x86,0x72,0x62,0x94,0xe4,0xce,0x0f,0xec,0x56,0xe7,0x1a,0x5f,0xea, - 0x93,0xc1,0xda,0xc7,0x29,0x36,0xae,0x0b,0x94,0xb6,0x1c,0xc5,0x11,0x87,0x63,0xc8, - 0xbc,0xb4,0x64,0x25,0x8f,0x30,0xd6,0x12,0x59,0xc7,0x14,0xb2,0x97,0xfb,0xd1,0x27, - 0x47,0x71,0xfc,0x5e,0x66,0xbf,0x83,0x37,0xc5,0x4a,0x6e,0x7a,0x0d,0xb4,0x69,0xf1, - 0xb3,0x83,0x15,0x18,0x0f,0xa3,0x4b,0x37,0x91,0x62,0xa2,0xfb,0xa0,0xa1,0xc7,0x26, - 0xbb,0x4e,0x07,0xdb,0x3e,0xb9,0x12,0x06,0x0a,0xce,0x2f,0x09,0xd6,0xd9,0x12,0x46, - 0x1c,0xb8,0xe0,0xd8,0x09,0x24,0x92,0xa9,0xf6,0xaa,0x78,0x57,0xf7,0xeb,0x52,0xab, - 0xb6,0xe3,0x42,0x18,0x99,0xb9,0x73,0x19,0xae,0xd9,0x24,0xa7,0xf2,0x1a,0x22,0x79, - 0xef,0xc5,0xc7,0x8c,0x74,0x25,0xa2,0x5a,0xe9,0xbb,0x98,0xdb,0x53,0x5c,0x54,0x4d, - 0x0d,0x9b,0x27,0xc0,0x5f,0xa1,0xce,0xa7,0x69,0xe7,0x0b,0x73,0xdd,0x84,0x4f,0x36, - 0x78,0x62,0xae,0x60,0x85,0x27,0x9d,0x7d,0xf1,0xf8,0xa1,0x58,0x77,0x81,0xe1,0xe5, - 0x68,0xb0,0x1f,0x63,0x95,0x51,0x1b,0xe9,0xd0,0x06,0xeb,0x1e,0xb6,0xc3,0xe7,0x1b, - 0xc4,0x39,0x3a,0x7e,0x18,0xdb,0x69,0x39,0x87,0xd1,0xd3,0x07,0x91,0xa4,0x44,0xe7, - 0x16,0xf7,0x41,0x06,0xec,0x56,0x28,0xd6,0x56,0x6f,0x0a,0x2b,0xf8,0xc5,0x89,0x4f, - 0x8a,0xcb,0x47,0x9b,0x12,0xb1,0x77,0xeb,0xce,0x42,0xe2,0x24,0xe8,0xa9,0x95,0x5f, - 0x1f,0x2a,0xb4,0x3d,0xae,0x68,0xdd,0xc2,0xeb,0x5e,0x96,0x9d,0xd4,0x47,0xc0,0xd4, - 0x2f,0x67,0x00,0xd1,0x8c,0x45,0xcf,0xc7,0x22,0xdd,0x39,0xbc,0x38,0x93,0x07,0xba, - 0x9e,0xa0,0xf3,0xa7,0x0c,0x4f,0x11,0xe4,0x5f,0x16,0x41,0x65,0x50,0xc9,0xf7,0xa1, - 0x94,0x11,0x77,0x28,0xf3,0x98,0x7e,0x19,0x23,0xa9,0xb3,0x63,0x21,0xdd,0x13,0x83, - 0x68,0x80,0x2c,0x63,0xdf,0x65,0xc9,0x37,0x12,0x7c,0xb3,0x8d,0xc9,0x24,0x9e,0x19, - 0xe6,0xa7,0x51,0xdc,0xba,0x43,0x82,0xaf,0x9d,0x40,0xcf,0x19,0x48,0xb4,0x47,0x36, - 0x31,0xe7,0x53,0x4e,0x27,0x32,0xdd,0x4a,0x48,0x8f,0xd7,0xe1,0x68,0xa5,0xc9,0x85, - 0x7a,0xdd,0x3e,0x3a,0x29,0xcb,0x67,0x15,0x0b,0x8d,0xca,0x82,0x89,0x5f,0xd2,0x5d, - 0x39,0x29,0x17,0x0e,0x8b,0xc8,0x8b,0x6c,0x7c,0x58,0x78,0x5a,0x3d,0xd3,0x5b,0x7a, - 0x72,0x96,0x78,0x6c,0x0a,0x33,0xea,0xbe,0x1e,0x36,0x27,0x71,0x33,0x3f,0xc4,0x26, - 0xa1,0xf0,0xc6,0xce,0x7c,0x53,0x82,0x0d,0xf7,0x9d,0x45,0x82,0x93,0x5b,0xf1,0x83, - 0xcf,0x1c,0x95,0x49,0xe4,0x95,0x17,0x6d,0x29,0x4a,0xf9,0xa6,0x2a,0xb7,0x9c,0x75, - 0x0c,0x2c,0xa8,0x09,0x59,0x07,0x99,0xc8,0x3c,0xee,0x7d,0x16,0xd4,0x81,0x25,0xe7, - 0x5a,0x1c,0x71,0x34,0xf9,0x74,0x39,0xf1,0xff,0xf4,0x4e,0x3c,0x3c,0xa2,0xd0,0x1b, - 0x59,0xee,0x34,0xf2,0x40,0xd3,0xa9,0x47,0x99,0xaf,0x0f,0x2e,0x2c,0x90,0x1d,0x9a, - 0x05,0x63,0x99,0xe2,0x98,0x9a,0xd5,0xdb,0xb1,0x23,0xa4,0x96,0x0b,0x40,0x0c,0x15, - 0x9c,0xa4,0x6e,0x87,0x3d,0xe8,0x18,0x86,0x3c,0xc7,0x21,0x9e,0x43,0x54,0x77,0x1e, - 0xfa,0x26,0x75,0x4e,0xd8,0x89,0x9b,0x54,0x3e,0x4a,0x0a,0xf4,0xbd,0x0d,0x2e,0x30, - 0x72,0xcf,0x0d,0x65,0x4b,0xef,0xb1,0x44,0x17,0xbb,0x4f,0xaa,0x92,0x1b,0x54,0xcf, - 0x38,0x2b,0x61,0xa0,0xb6,0x8b,0xcb,0x36,0xe1,0x64,0x6d,0xaa,0x45,0xab,0x5c,0x45, - 0xbb,0x1c,0x27,0xa0,0x41,0x7a,0x86,0x16,0xbc,0xfd,0xea,0x9b,0x76,0x9b,0x37,0xd1, - 0x9a,0x05,0x64,0x81,0xb4,0x63,0x53,0x7e,0x75,0xfc,0xf7,0xe4,0x30,0xee,0x6a,0xc4, - 0xa4,0x60,0x66,0xcb,0x88,0x28,0xa6,0x11,0x67,0x95,0xcf,0x56,0x70,0xc6,0x75,0x73, - 0x52,0x2c,0x67,0x89,0x07,0x85,0x50,0x9a,0xdf,0x04,0xcb,0x8d,0x6d,0x87,0x01,0xae, - 0x5b,0xb0,0x45,0x59,0xe1,0x87,0x5e,0x55,0x91,0xb0,0xaa,0xbc,0xa3,0x6b,0x97,0xf9, - 0xd4,0xdc,0x52,0x51,0x72,0x9f,0xbf,0x42,0xf1,0x5a,0x33,0x69,0x72,0x58,0x85,0xc2, - 0x63,0xe8,0x21,0xcf,0x0a,0x7f,0xc6,0x97,0xc3,0x4e,0xd2,0xa7,0xf0,0x71,0x24,0xf9, - 0xe4,0x64,0x3a,0x54,0x96,0x1c,0x0e,0x8b,0xb9,0xef,0x5c,0x60,0x6d,0xab,0x3e,0xad, - 0xfb,0x05,0x17,0x0b,0xf8,0x0c,0x10,0xef,0x62,0x7f,0x19,0xaa,0x96,0x9e,0x27,0x70, - 0xf8,0x88,0x1d,0x63,0xef,0x1a,0xf5,0xd9,0x39,0xfd,0xdc,0xd0,0x78,0xc1,0xcc,0xca, - 0x5b,0xed,0x40,0x0c,0x1a,0xc6,0x73,0xd3,0x9e,0x6d,0x49,0x6a,0xdb,0x71,0x40,0x88, - 0xb6,0x75,0xaa,0x2c,0x4c,0x5e,0xf7,0xec,0xf1,0x42,0x08,0x94,0x8b,0xe4,0xeb,0x0f, - 0xc2,0x2c,0xbe,0xcd,0x70,0x2f,0x0c,0x3a,0x53,0x2e,0x6a,0x96,0xe6,0x15,0xcb,0x5a, - 0x98,0xcf,0xd4,0x00,0x30,0xec,0xe1,0xee,0xe0,0xe6,0x25,0xf7,0x75,0x2d,0x59,0x73, - 0xf4,0xe6,0x55,0x95,0xb4,0xea,0x06,0x8b,0x10,0x62,0xce,0x21,0x99,0x44,0x98,0xb9, - 0x34,0xec,0x56,0x5e,0x71,0xb3,0x41,0x59,0x1e,0x10,0xd4,0xab,0xda,0xa5,0xcf,0x9c, - 0xe2,0x8c,0xb2,0xe9,0x7a,0xeb,0x0d,0x59,0xa7,0xce,0x88,0x55,0x32,0x95,0xba,0xc7, - 0x7d,0xb2,0xa1,0x99,0xdb,0x55,0x5b,0x49,0x4e,0xd7,0xc8,0x42,0x47,0xf8,0x0a,0xae, - 0x31,0x2d,0xa3,0x3a,0x5d,0x15,0x6d,0x4c,0x5e,0xbc,0xf7,0x69,0x69,0x7e,0x8f,0xf7, - 0xf5,0x54,0x2b,0x09,0x8c,0x02,0x4d,0x9d,0x4b,0x13,0x7c,0xf5,0xab,0x43,0x5a,0xe0, - 0xd8,0x19,0x34,0x85,0x47,0x8a,0x97,0x65,0xdf,0xdf,0x94,0x1c,0x17,0x1e,0xa5,0x9e, - 0x36,0xdc,0x81,0x1d,0x8e,0x4a,0x88,0x58,0x47,0x94,0x8d,0x17,0x59,0xbf,0xc1,0x3f, - 0x97,0xa3,0x09,0x09,0xab,0xa2,0x8a,0xf0,0x79,0x79,0xee,0x92,0x51,0xa6,0x5c,0x06, - 0x99,0xff,0x8c,0x31,0x56,0xd1,0x14,0xc5,0x69,0xe6,0xc0,0xcd,0xff,0x92,0x64,0x83, - 0x46,0xf7,0x91,0x14,0xbc,0xf5,0xbf,0xac,0xfb,0x1e,0xfb,0xdd,0x91,0x95,0x19,0x3c, - 0xe4,0x18,0x4b,0x5b,0x84,0x74,0x89,0xba,0x54,0xef,0xfa,0x54,0x6d,0x62,0x6f,0x25, - 0xdf,0x04,0xd4,0xf3,0x04,0xc2,0x5d,0xea,0x7f,0xce,0xab,0xb1,0x5b,0xb0,0x60,0xf0, - 0x69,0x26,0xa4,0x3a,0x67,0x53,0x9d,0x9e,0xb0,0x35,0xd8,0xa4,0x70,0xba,0x1f,0x27, - 0x69,0x09,0xc3,0x63,0x1c,0x53,0x91,0x06,0xef,0x8e,0x63,0x38,0xf5,0x93,0x20,0xb8, - 0x5a,0x28,0xaf,0xe9,0x40,0x03,0xe2,0x5f,0x26,0x78,0x32,0xe1,0xa6,0xcc,0x54,0x9d, - 0x74,0x83,0x7f,0x56,0x1f,0xa4,0x25,0xf3,0x1f,0xe9,0xc6,0xfe,0x25,0x50,0x62,0xe9, - 0x9c,0x54,0x94,0x76,0xa7,0xcc,0x73,0xc7,0xdc,0x10,0xb1,0x9d,0x8d,0x21,0xbd,0x5a, - 0xd9,0x09,0x3e,0x5d,0xa4,0x4a,0x9a,0xd3,0x4d,0x35,0x4f,0xcf,0x96,0x17,0x48,0x7a, - 0x24,0xac,0x28,0xe7,0x81,0xb9,0x5f,0x08,0x32,0x3d,0xe0,0x5b,0x6d,0x5a,0xa0,0xcb, - 0xce,0xa1,0x8b,0x60,0x11,0x42,0x4b,0xe7,0xfd,0xae,0x04,0x39,0xad,0x7b,0xeb,0xcd, - 0xb9,0x61,0x34,0x16,0x40,0x2d,0xf7,0xf5,0xab,0x20,0xca,0x2b,0x3a,0xce,0xe9,0x97, - 0x48,0x3e,0xd3,0x93,0x9a,0x33,0x1d,0xa7,0x9a,0x96,0xc5,0xb6,0x43,0x6e,0xf5,0xe9, - 0x2e,0x8d,0x81,0x80,0xbd,0x9f,0xb2,0x58,0x87,0x46,0x12,0x07,0xf9,0xff,0x51,0x12, - 0xfd,0xe0,0xb5,0x3f,0x90,0xe4,0x28,0xd3,0xfc,0x20,0x5b,0x1e,0x7e,0xab,0x69,0xef, - 0xdf,0x8b,0xb1,0x2a,0x64,0xd6,0xcf,0xbe,0x60,0x31,0x60,0x36,0x8b,0x10,0xae,0x27, - 0x76,0x9b,0xe8,0xc3,0xfe,0xed,0x96,0x5e,0x94,0xf9,0x7d,0xc8,0xf3,0x63,0xe4,0x77, - 0x23,0xef,0xe7,0x27,0x5b,0x34,0x2b,0xcb,0xec,0x3b,0x51,0xd6,0x37,0xc4,0x61,0xa4, - 0x46,0x8f,0x4c,0x4d,0x6d,0xee,0x45,0x32,0x1e,0x85,0xb1,0x8d,0x6c,0x28,0xcd,0x55, - 0x20,0x79,0x95,0x7f,0x33,0x28,0x25,0xd3,0xb5,0x4e,0x33,0xa4,0xbd,0x87,0x73,0x3c, - 0xc1,0x89,0x12,0x5d,0x5c,0xa8,0xb4,0x99,0xf2,0x67,0xb7,0xc6,0x7e,0x4a,0x8f,0x8d, - 0x15,0xfd,0xe3,0xe6,0xa9,0x28,0x2e,0xdf,0xff,0xe4,0xa2,0xd9,0x63,0x5b,0xf5,0x3d, - 0x37,0xe1,0x61,0xb6,0x7d,0x17,0x24,0x57,0xe7,0x9c,0x84,0xba,0x89,0xe6,0x6f,0x3f, - 0xb9,0xd4,0x6e,0x99,0xae,0x7f,0xa2,0xe6,0x96,0x4c,0x63,0xa7,0xb3,0xdb,0xbe,0xd8, - 0x3d,0x88,0x29,0xc0,0xf8,0x68,0xa9,0xf3,0x34,0x6d,0x9a,0xd2,0x15,0x6d,0x6e,0xf0, - 0xab,0x34,0x90,0xb6,0x5d,0xc8,0x45,0x6a,0x7f,0x61,0x71,0x44,0x7b,0x94,0x96,0x06, - 0x87,0xea,0xf2,0x29,0x63,0x1c,0x00,0xa1,0x08,0xd7,0x1b,0x92,0x1f,0x8f,0xe6,0xa9, - 0xaa,0x81,0x8c,0x06,0x09,0xf0,0xc8,0xe3,0xac,0x72,0xf5,0xb3,0x24,0x5e,0x68,0x1b, - 0x61,0xce,0x34,0xc3,0x52,0x19,0x91,0x54,0x5b,0x0b,0x87,0xa0,0xf7,0x6b,0xc2,0x11, - 0xa9,0x61,0x6b,0x11,0xce,0x95,0xbf,0xd8,0x1a,0x92,0x9f,0xff,0x8a,0xda,0xfa,0xf7, - 0x0c,0x46,0x79,0x14,0x97,0x9c,0xd6,0x79,0x10,0xcc,0x92,0xfc,0xe0,0x9d,0x04,0x8b, - 0x50,0x87,0x1b,0x92,0x0f,0xcc,0xbf,0x3f,0x21,0xb2,0xc5,0x54,0x33,0x87,0x70,0x20, - 0x01,0x12,0xff,0x0c,0xde,0x4e,0xf5,0x48,0xf8,0x2c,0x58,0xe6,0xb4,0xbc,0xa6,0x29, - 0x9f,0x7c,0xe3,0x5c,0xba,0x69,0xda,0x8a,0xd7,0x86,0x6d,0xe4,0xe6,0xb6,0x0c,0xa4, - 0x6e,0x58,0x88,0x86,0xd0,0xc4,0x33,0x59,0x5a,0x57,0x8e,0xfc,0x13,0xf2,0x3e,0xab, - 0xa4,0x92,0x6f,0x3c,0x73,0xb9,0xd3,0x2d,0xce,0xc3,0xea,0x76,0x3b,0x77,0x67,0x96, - 0x80,0xca,0x73,0x1e,0x05,0xd7,0xaf,0x66,0x55,0x55,0xfd,0xde,0x4b,0xf6,0x23,0x70, - 0x8e,0xef,0x43,0xb9,0x2c,0x0e,0x2d,0x67,0x5e,0x13,0x19,0x9d,0xa5,0x51,0x73,0xae, - 0x48,0xf5,0x0c,0x85,0x8a,0xbf,0x5d,0xe5,0x87,0xd5,0x7c,0x07,0x9b,0x04,0x47,0x98, - 0x13,0x40,0x9b,0x34,0x7c,0x95,0x64,0x34,0x2f,0x52,0xfb,0x77,0xbb,0x34,0x20,0x82, - 0xd9,0x0c,0xba,0xfb,0xb0,0x55,0x2d,0x9f,0x82,0x4e,0x0a,0x51,0x6e,0xb5,0xde,0xb4, - 0x96,0x2f,0xdc,0x6e,0xeb,0xe3,0xed,0x17,0x27,0xa0,0xdd,0x41,0x94,0xf5,0x2b,0xde, - 0xae,0x03,0x71,0xee,0x1d,0xa4,0x10,0xc8,0xe6,0xe9,0x9e,0x0c,0x83,0xad,0x8b,0x5a, - 0xc6,0xb6,0x85,0x69,0x66,0x27,0xe4,0x43,0xdd,0x38,0xda,0xf6,0xd7,0xc6,0xe4,0x81, - 0xb8,0xc7,0x2f,0xac,0x7c,0x73,0x70,0x9e,0xb8,0x77,0xf9,0xa8,0x5e,0x68,0xf3,0x6e, - 0xf3,0xa6,0x0d,0xbd,0x6d,0xdd,0x56,0x95,0x35,0xf8,0x86,0xd4,0x31,0xc6,0xf6,0x90, - 0x06,0xa5,0xf0,0xc7,0x00,0xd8,0x3e,0x21,0x14,0xd9,0x71,0x8b,0x1c,0x3c,0x18,0x3a, - 0x22,0x0b,0xac,0x2b,0x4e,0xfe,0x99,0x49,0x9d,0x2e,0x4b,0x8c,0x47,0xa7,0x1d,0xd3, - 0x28,0xb5,0xdf,0xdb,0xa4,0xb3,0x90,0xc9,0x67,0xac,0xa9,0x85,0x95,0x99,0xa4,0xad, - 0x1c,0x89,0x82,0x1b,0xd4,0xb4,0x51,0xa8,0xed,0x41,0x3f,0x36,0x6d,0xcd,0x3c,0x25, - 0x33,0x28,0x06,0x05,0xd4,0x93,0x0d,0x7a,0xf4,0x34,0x5b,0x99,0x3c,0x73,0xb9,0xcc, - 0x3f,0xd3,0xce,0xfd,0x44,0xa6,0xde,0x07,0x4f,0x51,0xa8,0xb0,0x56,0x79,0x6d,0xb6, - 0x7b,0xaf,0x71,0x38,0x4e,0x56,0xc9,0x8d,0x13,0x7a,0x1c,0x4d,0x7a,0x2e,0x54,0xa6, - 0x57,0x87,0x4f,0x16,0x41,0x0c,0xa1,0x31,0x9e,0x99,0x56,0x47,0xc9,0x84,0xb6,0x13, - 0xd1,0x50,0xa1,0x8d,0xf2,0xca,0x9a,0xb3,0x68,0x33,0xc7,0xf2,0x58,0x35,0x54,0x43, - 0x49,0x5f,0x44,0xe5,0x0d,0xc8,0x56,0xfc,0xc8,0xb8,0x87,0xe3,0xf7,0x9e,0x49,0x46, - 0xd6,0xde,0xeb,0xd0,0x2d,0xe1,0xd4,0xe4,0x31,0x2c,0x2f,0x9b,0x24,0xc7,0x78,0x30, - 0xc9,0x1d,0xdf,0xae,0xe9,0xf6,0x17,0x56,0xec,0x2d,0xe0,0x11,0xa4,0x31,0xd1,0x59, - 0x04,0xee,0xef,0x2b,0x7a,0x40,0x01,0xe2,0x28,0xfa,0x67,0x4f,0x17,0x7e,0x65,0xa6, - 0x3a,0x22,0x96,0xbc,0x36,0x8b,0x4a,0x90,0x52,0xdc,0x90,0x35,0x0f,0x54,0x20,0xbc, - 0x7d,0xb8,0x73,0xb6,0xb3,0x41,0xa5,0x79,0x7b,0x72,0x17,0x40,0x69,0x5d,0x22,0x99, - 0x5f,0xfc,0x15,0x01,0xe0,0x40,0xff,0xeb,0x0f,0x34,0xb9,0xb4,0x4e,0x09,0x39,0x19, - 0x52,0xa7,0x07,0x72,0xbc,0xbb,0xec,0x9a,0xd8,0x32,0x77,0x60,0xb6,0x28,0xa4,0xb0, - 0x4b,0x25,0x47,0x35,0x54,0x70,0x75,0x51,0x48,0x57,0x03,0xd6,0x9e,0x80,0x40,0x3f, - 0x2d,0x4f,0x80,0xbb,0xe1,0x21,0x07,0x34,0xaf,0x1d,0x92,0xdd,0x0f,0xbb,0xbb,0x54, - 0x23,0xce,0xd5,0xfd,0xc6,0xdc,0x20,0x79,0x3c,0x72,0xec,0x45,0x33,0x4a,0x44,0xb9, - 0x94,0x35,0x58,0x9d,0xe8,0x4c,0xc0,0xeb,0xf3,0x82,0x38,0x0e,0xfe,0x27,0xf0,0x1e, - 0xab,0xc4,0xb5,0x32,0xa1,0xc5,0x61,0x1a,0xea,0xe3,0x00,0x0f,0x66,0xb2,0xa3,0x95, - 0x13,0x64,0x3a,0xf5,0x8a,0x4b,0xe4,0xdc,0x56,0xbe,0xd0,0x40,0xfc,0x62,0x4b,0x0a, - 0x04,0xcd,0xd6,0xa7,0xc5,0xc1,0x17,0x86,0x99,0x3a,0x85,0xf5,0x6d,0x96,0x88,0x61, - 0xd9,0x35,0xd3,0x66,0xc2,0x80,0xa3,0x87,0x87,0x78,0x40,0x72,0x55,0xb9,0x89,0x43, - 0xa4,0xbb,0x6f,0xa9,0x25,0x67,0x69,0x92,0xc5,0x09,0xbe,0x4c,0x33,0xb0,0x3d,0x9f, - 0xb3,0x06,0x65,0xc5,0xa3,0x67,0xfd,0x54,0xf5,0x1e,0x2e,0x7a,0x6c,0xfa,0xf1,0x6f, - 0x62,0xa5,0x46,0x3f,0x64,0xb0,0x4d,0x17,0x35,0xd5,0xc3,0xc3,0x6a,0x49,0xbe,0x9f, - 0x46,0x17,0x66,0xc1,0xd5,0xd3,0x79,0x22,0xf9,0x1a,0x1b,0x7f,0x18,0xfe,0x0d,0x45, - 0x45,0x55,0xa4,0xa1,0xb7,0xfb,0x56,0xfc,0xf2,0x05,0xf0,0xc9,0x87,0x48,0x06,0xdf, - 0x86,0xd3,0xb4,0x8d,0xb1,0xd6,0xa0,0x23,0x4a,0x38,0xed,0x24,0xa4,0x13,0x63,0xb2, - 0x2b,0xa3,0xd9,0x9b,0xc5,0xe8,0x0c,0xb3,0x1a,0xfc,0xd8,0x49,0x00,0xf0,0xcf,0x89, - 0xad,0x6c,0xcf,0x88,0x03,0x87,0x14,0xd1,0x47,0x85,0xbc,0x91,0x52,0x7d,0x42,0x66, - 0xa5,0xf3,0x14,0x82,0xe9,0xb7,0xe6,0x7d,0x94,0xde,0x68,0xda,0xed,0x99,0xd2,0xc0, - 0x94,0x68,0x57,0xe9,0xc9,0x57,0xfc,0x5a,0xd2,0x4f,0x4e,0x03,0xb5,0x25,0xf5,0x21, - 0xda,0x68,0xfe,0xb9,0x0c,0x0f,0x71,0x30,0x79,0xcb,0xc0,0x40,0xeb,0x25,0x34,0xf3, - 0x46,0x4a,0xd9,0x6b,0xf4,0x63,0x8c,0xdc,0x93,0xea,0x6d,0xc6,0x66,0xfa,0xbd,0x09, - 0x5d,0xbf,0x60,0xf9,0xc0,0x5a,0xf9,0x18,0x62,0xed,0xdb,0x34,0xd8,0x51,0x91,0x0a, - 0x62,0x25,0xe1,0xb2,0xcc,0xbb,0x98,0xd9,0xd2,0x34,0x74,0x89,0x88,0xb8,0x81,0xf5, - 0x0e,0xe6,0x7a,0x01,0x1b,0xfa,0xde,0x81,0x25,0xdd,0x6f,0x08,0xbb,0xc8,0x63,0x89, - 0xa9,0x77,0x2c,0xfe,0xe2,0x9d,0xaa,0x99,0x4a,0xb4,0x17,0xd4,0xc4,0x37,0x6b,0x0d, - 0x46,0x04,0x93,0xf4,0xb6,0x14,0xd5,0xa4,0x8f,0xa5,0x0a,0x2d,0x38,0x1d,0xc0,0x2a, - 0x86,0x87,0x0f,0x0f,0x4a,0x30,0xf4,0xa3,0x97,0xd4,0x9c,0x1b,0x56,0x5a,0x25,0xd2, - 0x59,0x17,0x32,0x2f,0x7b,0xf1,0x8a,0xa4,0x13,0xcc,0xa3,0x63,0x03,0x5a,0x42,0x1e, - 0x04,0x05,0x4c,0xbc,0xe5,0x14,0xc0,0x60,0x68,0x99,0x99,0x54,0x91,0x99,0xb6,0x71, - 0xad,0xa8,0xe9,0x5b,0x3b,0x47,0xd8,0xce,0x8b,0x08,0xeb,0x7c,0x73,0x3d,0xa3,0x13, - 0x80,0x64,0xd3,0xfa,0x28,0x66,0x80,0x0e,0x76,0xb5,0x11,0xb6,0x5e,0x7a,0x2d,0x94, - 0x0b,0xad,0x71,0xf9,0x0d,0x11,0x11,0xc7,0x71,0xce,0xee,0xf2,0xfb,0x3b,0xff,0x08, + 0x5f,0xc9,0xcc,0x11,0x45,0xc5,0xec,0xdf,0x28,0x60,0xb7,0x32,0xbb,0x1d,0x40,0xde, + 0x7f,0x5f,0x40,0x40,0x8f,0xc3,0x1d,0xcb,0x05,0xec,0x4f,0x34,0x72,0x52,0x1e,0x09, + 0x55,0x1b,0xa2,0x50,0x13,0x7d,0x28,0x34,0xc1,0x34,0xe3,0xb6,0x91,0x29,0x88,0x82, + 0xf3,0x52,0x75,0x9a,0xdd,0x3b,0x26,0x20,0xec,0x63,0x1e,0x3c,0xf2,0x47,0x9a,0x49, + 0xb3,0xec,0x46,0x3b,0xaf,0xd9,0xc0,0x6f,0x41,0xdf,0x2d,0xe1,0x7f,0x15,0x18,0xbb, + 0x3c,0x46,0x5a,0x2b,0x4e,0x9c,0x78,0x7f,0x55,0xed,0xdd,0xbd,0x4c,0x84,0x2e,0xe9, + 0x36,0xf1,0x3a,0x49,0x2b,0xad,0x4c,0xbf,0x63,0x0f,0x48,0x89,0x3c,0x97,0x06,0x4b, + 0x2e,0x69,0x9b,0xa9,0xfa,0xfa,0xe2,0x98,0xb4,0x15,0x52,0x03,0x1d,0x9b,0xcc,0x1a, + 0xaf,0xae,0xfd,0xa2,0x2d,0x58,0x82,0x17,0x75,0x02,0x33,0x71,0xf6,0x3f,0x9d,0x3a, + 0xed,0x6f,0x78,0x92,0xab,0xf8,0x80,0xdd,0x35,0x65,0x2e,0xa5,0x60,0xc7,0xba,0x84, + 0x72,0x88,0xf4,0xbf,0x99,0x6a,0xbd,0xbe,0x1e,0x6e,0xc3,0x16,0x59,0x2e,0x7b,0xdd, + 0xb9,0x19,0xa5,0x55,0xaf,0x65,0x4f,0x7c,0xd7,0x41,0x89,0x8a,0xa0,0x42,0x70,0x09, + 0x28,0x4d,0x9b,0xba,0xdc,0xb5,0x4c,0x3a,0x17,0xfd,0x48,0x4e,0xae,0x97,0xb0,0x03, + 0x8a,0x6b,0xab,0x0c,0x13,0x6f,0x0f,0x7e,0xf9,0x33,0xbf,0xff,0xdf,0x9f,0x2f,0x79, + 0x6a,0xcb,0x0b,0x6b,0x98,0x0d,0x79,0xe6,0x62,0x6f,0x7e,0x29,0x6c,0x8a,0x02,0x21, + 0xac,0xa2,0x39,0x6a,0x77,0x37,0x83,0x70,0xe0,0x9f,0xd7,0xc9,0xcf,0x39,0x92,0x1b, + 0x8e,0x50,0xaf,0x62,0x41,0x68,0x74,0x05,0xc1,0x7e,0xb7,0xc9,0x55,0x43,0x5b,0xd6, + 0xbb,0xa9,0x36,0x1b,0xd4,0x8d,0x42,0x64,0xc5,0xf6,0x43,0xcf,0x65,0x6e,0x1f,0xb0, + 0x22,0x56,0xc6,0x4a,0xd5,0x2a,0x9f,0x24,0x1a,0xf6,0xa9,0xa8,0x91,0x07,0xc8,0xb3, + 0x36,0xbe,0x37,0x21,0x25,0x96,0xb1,0xd8,0x15,0xcd,0x12,0x90,0x71,0xf6,0x9a,0xcd, + 0x3f,0x5d,0x69,0xff,0x6a,0x12,0xdc,0xe5,0x08,0x7d,0x20,0xfd,0xcb,0x35,0x5d,0xfe, + 0x18,0x4d,0x88,0xd5,0x84,0x89,0x1c,0x87,0x98,0x2e,0xa6,0xae,0x92,0x1f,0x41,0x7f, + 0xa4,0x69,0x9d,0xdb,0x89,0xf3,0xec,0xe3,0x4a,0x46,0xc8,0xac,0x04,0x7c,0xd9,0xcb, + 0x96,0xd6,0xdf,0x9f,0x57,0xa7,0x33,0x8b,0xd5,0x23,0x21,0x67,0x8e,0x4b,0xd0,0x90, + 0x39,0x4f,0x27,0x7b,0xe1,0x14,0x4b,0x4c,0xc7,0xa1,0x4c,0x0c,0x85,0x34,0x87,0x6b, + 0xe4,0xf5,0xff,0xd7,0xf2,0x5d,0xad,0x79,0xbf,0x83,0xfc,0xc9,0x87,0x43,0xe7,0xdb, + 0x69,0xb3,0xb5,0x1b,0x41,0x93,0x10,0x22,0x52,0x9e,0x25,0xf6,0xe8,0xf7,0xdf,0x5b, + 0x5a,0xce,0xd1,0x2a,0x0b,0x6c,0x90,0x92,0x67,0x8f,0x8c,0x75,0x8b,0x0d,0x0d,0xe4, + 0x9c,0xdb,0x31,0x23,0x6e,0xbc,0x98,0xfa,0x26,0x73,0x90,0xa6,0x8a,0x2c,0x83,0x52, + 0x17,0x4c,0x9d,0x81,0xe1,0xa8,0x61,0x38,0xea,0x26,0x9b,0x7c,0x11,0xef,0xfd,0xac, + 0x34,0x05,0x76,0x56,0x16,0xd8,0x83,0x2a,0xa0,0xd9,0x00,0xd8,0x9c,0x43,0xa2,0xcd, + 0x80,0x63,0x4d,0x1b,0x79,0xbb,0xd7,0x66,0xad,0xd1,0x6a,0xdc,0x6a,0xa4,0xe5,0x82, + 0x94,0x5f,0x6a,0x69,0xac,0xda,0x18,0x76,0x42,0x29,0x02,0x3a,0x27,0x69,0x93,0xfd, + 0xef,0x8b,0xaa,0xdf,0x4b,0x6b,0xbb,0x6d,0x1c,0x27,0x77,0x16,0xb7,0x38,0xc0,0x21, + 0x0a,0x04,0x48,0x7d,0xbf,0x1f,0xa6,0xf6,0xd4,0x75,0x2e,0xcb,0x4e,0xbb,0xb1,0xc4, + 0x71,0x0b,0x01,0xf3,0x19,0xb0,0xb3,0x0c,0xa7,0x6e,0x2b,0x12,0x22,0x06,0x93,0xfe, + 0x8f,0x61,0x56,0xfb,0xa4,0x9d,0xb9,0x3e,0xd3,0x7d,0xda,0x68,0x8c,0x1a,0x44,0x20, + 0x80,0xe9,0xde,0x63,0xa8,0xf6,0xd8,0xee,0x66,0x97,0x27,0x82,0xb9,0x46,0xda,0x64, + 0xfc,0x3f,0xea,0xc0,0x2c,0xb6,0x60,0x52,0x5b,0xc7,0x2f,0x03,0x4a,0x5c,0x64,0x0e, + 0x04,0x32,0x43,0x73,0x28,0x36,0x85,0xcf,0x9e,0xea,0x64,0xe9,0xf1,0xd1,0xc6,0xa0, + 0xd8,0x05,0x8a,0xc9,0x0e,0x90,0xd6,0xd4,0x75,0xb6,0x6b,0x37,0xf5,0xed,0x3a,0xc0, + 0x6b,0x52,0x97,0x14,0x16,0x9d,0x8b,0x18,0xc8,0xff,0x00,0x4e,0x44,0x65,0x8a,0x2f, + 0xed,0xfd,0x66,0x2d,0xf6,0x2e,0xa1,0xd0,0x69,0xcf,0x5e,0x9c,0xff,0x7d,0x7a,0x8b, + 0xa5,0x5d,0x86,0x99,0x98,0xe1,0xdf,0xa3,0xc7,0xd5,0x7e,0x16,0xb3,0xc0,0x31,0x93, + 0x7f,0x3d,0x55,0x7f,0x81,0xfa,0x6e,0x0d,0xb5,0x9e,0x17,0x4f,0xe7,0x61,0x76,0xfc, + 0x62,0x54,0xc2,0x58,0x3f,0xe9,0x1d,0x14,0x11,0x05,0x8b,0xf3,0xed,0xf4,0x98,0x46, + 0xdd,0xf2,0x74,0x95,0xf1,0xf8,0x59,0xc6,0x0f,0x45,0x45,0x7f,0xc4,0xc3,0xcb,0xe6, + 0x67,0x19,0x3e,0x8e,0x01,0xf3,0x5f,0x1c,0xee,0x95,0xeb,0x55,0x75,0x8c,0x2f,0x5b, + 0x30,0x0d,0x9b,0x55,0xcd,0xc6,0x06,0x20,0x4d,0xdb,0x23,0x8d,0x55,0x18,0xfe,0xfe, + 0x2f,0x15,0xc1,0xc9,0xe5,0x09,0xcb,0xcb,0x13,0xe2,0x69,0x9a,0x2b,0x6d,0x4b,0x8a, + 0x4b,0xd1,0xa5,0x87,0x98,0x98,0x94,0xc7,0xe9,0x79,0x17,0xf0,0xe3,0x2b,0x4b,0x25, + 0x2a,0x7a,0xda,0x6c,0x28,0x62,0xee,0xc7,0x8d,0xe3,0xfc,0x3c,0x08,0xa8,0x38,0xb0, + 0x83,0x6c,0x21,0x95,0xbf,0x3f,0x5f,0xfd,0xb0,0x96,0xf9,0xcb,0x3f,0x4e,0x2c,0x29, + 0xe6,0xf2,0xf3,0x51,0x66,0x11,0xfa,0x59,0x24,0x27,0x69,0x00,0x2b,0xfe,0x71,0x89, + 0x69,0xe4,0xfc,0x96,0x28,0x98,0x89,0xbe,0xfe,0x34,0x72,0x16,0x53,0xeb,0xa9,0xe5, + 0xff,0xf6,0xbc,0xec,0xe1,0xe5,0x09,0x7b,0x6e,0x73,0x01,0x65,0xf7,0x50,0x74,0x91, + 0x89,0x81,0x95,0x92,0xd4,0x15,0xad,0xd4,0xfb,0x1f,0x38,0xb7,0x76,0x95,0x53,0x10, + 0xa3,0x53,0x8d,0x6d,0x69,0x7d,0xd8,0xe1,0x1d,0x12,0xbc,0xde,0x01,0x11,0x28,0x7c, + 0x77,0x80,0x48,0xf3,0x5d,0x7c,0xf6,0x8e,0x17,0x3d,0x22,0xcc,0x05,0x5a,0x53,0xb3, + 0x92,0xe9,0xba,0xbd,0x5c,0x78,0xdf,0xfe,0x4f,0xee,0xb5,0x8c,0x6e,0x77,0x21,0x58, + 0x2e,0xc5,0x4a,0x23,0x7f,0xde,0x8a,0xec,0xed,0xbb,0x97,0x06,0xad,0x7d,0x54,0x68, + 0xe7,0xc3,0x18,0x91,0x8b,0x50,0x09,0x5c,0x91,0x54,0x65,0x50,0x81,0x1b,0x54,0x4e, + 0xb2,0x7f,0xd7,0x16,0xfa,0x07,0x7d,0x41,0xca,0xd4,0xe8,0xed,0x9e,0xe9,0x00,0x27, + 0x1e,0x8b,0x3d,0x89,0x94,0xfd,0xa8,0x75,0x67,0x80,0x58,0xe9,0x90,0x4e,0xa8,0xce, + 0xca,0xa2,0xa6,0x7f,0xcb,0xd0,0x1b,0x3d,0x68,0x3d,0x82,0xcb,0x44,0xee,0x20,0x2e, + 0xf9,0x18,0x67,0x3d,0x98,0xcd,0xc5,0x52,0xc7,0xe5,0x5a,0x41,0x94,0xa4,0xe2,0xc6, + 0xfd,0x08,0x45,0x84,0xf2,0xb9,0xfc,0xd4,0x0e,0x73,0xc2,0x06,0xee,0xc0,0x02,0x4c, + 0xf5,0x45,0x20,0xe1,0x92,0xdc,0x96,0xc9,0x68,0x94,0xb4,0x4b,0x43,0xe2,0x79,0x9e, + 0x7e,0xf5,0x1c,0x95,0x72,0xd0,0xd5,0xe4,0x22,0x16,0x73,0x95,0xed,0xe1,0x16,0x0c, + 0xba,0x00,0x95,0xd6,0x8a,0x8f,0xb7,0x84,0x72,0x3f,0xe2,0x90,0x20,0x6a,0xa7,0x8b, + 0xc9,0xda,0xf4,0xef,0x13,0xac,0x9d,0x5e,0xed,0xad,0x20,0x80,0x78,0x1e,0xe4,0xd2, + 0x39,0x78,0xf1,0x0e,0x75,0x7e,0xd6,0x17,0xe0,0xfb,0x45,0x2c,0x3f,0xb5,0x09,0x76, + 0xba,0x03,0x87,0xdf,0xe5,0xca,0x78,0x41,0x7d,0x8b,0x12,0xc8,0x63,0x3d,0xca,0x18, + 0x1e,0xc8,0xc9,0x52,0xb8,0xca,0x17,0xe4,0xd1,0x0d,0xdf,0xb1,0x4a,0x2b,0x65,0x53, + 0xdd,0x02,0xf7,0x3e,0x74,0xf2,0xa4,0xa0,0xd9,0x22,0x29,0x80,0xc6,0x12,0xcc,0x40, + 0xba,0x2b,0x0e,0x49,0x6e,0xc8,0x61,0x10,0x54,0x7d,0x7d,0xc4,0x07,0x5d,0x35,0xa6, + 0x84,0x54,0x08,0xe9,0x74,0x1c,0x4a,0x00,0x88,0x2f,0x2b,0xc8,0xa4,0xdb,0x8c,0x67, + 0xdf,0xab,0x71,0x64,0x9f,0xe1,0x42,0xcc,0x3a,0x00,0x96,0xc8,0x72,0x8d,0x39,0xb8, + 0x66,0x24,0x64,0xfd,0x0d,0x7c,0x8f,0xfc,0xec,0xd3,0x6f,0xb8,0xc5,0xb3,0x03,0x3f, + 0x9d,0xa3,0x80,0x0b,0x3f,0x14,0x4a,0xe2,0x75,0x9a,0x32,0x63,0xc6,0xaa,0x5d,0x40, + 0xcf,0xfd,0x42,0xea,0xaf,0x08,0x00,0x4e,0x48,0xf2,0x9f,0xcf,0xee,0x33,0xb5,0x4b, + 0x46,0x21,0xdd,0xdf,0xb5,0x79,0xe3,0x4e,0xab,0xd2,0xfc,0xca,0x27,0x2b,0x94,0x75, + 0xb2,0x31,0x8c,0x14,0x8e,0x98,0xcb,0xf3,0x0a,0xb6,0xbb,0xad,0xb9,0x3e,0xce,0x43, + 0xf9,0xcf,0xc3,0x99,0x1a,0xca,0xdf,0xbe,0xbe,0x5d,0x44,0x87,0xff,0x77,0xb0,0x46, + 0x82,0xb7,0xbe,0xf0,0x69,0x61,0xce,0x8f,0x2a,0x40,0x5e,0xc7,0xa0,0x12,0x55,0x98, + 0x00,0xd3,0x85,0x11,0xd9,0xb3,0xbf,0xfb,0x04,0x49,0x3f,0x11,0xda,0x6c,0xf3,0x6d, + 0x4e,0xa7,0xa8,0x6d,0x54,0xc5,0x01,0x41,0x8f,0xa8,0xa4,0x96,0x02,0x0a,0x79,0x75, + 0x56,0x2b,0xb0,0x0a,0xd8,0xa3,0xb0,0xa7,0xf4,0x87,0x62,0x0e,0x38,0x2d,0xc8,0xec, + 0x08,0xc7,0x97,0x04,0x5b,0x76,0x70,0x98,0xe3,0xd0,0x15,0x98,0xd5,0xe7,0x20,0xe6, + 0x10,0x3d,0xaf,0x56,0x23,0x75,0x47,0xb2,0xd7,0xc7,0xc7,0xc0,0x52,0xf0,0xc1,0xa4, + 0x2d,0x1e,0x47,0x3a,0x10,0xde,0x0e,0x67,0xd0,0xc5,0xb7,0x20,0x59,0xb8,0x26,0x79, + 0x5d,0x14,0x9f,0x50,0xf1,0x10,0x97,0x71,0x79,0xc8,0xa4,0xbb,0xdc,0x66,0x58,0x4f, + 0x4e,0x4e,0x7b,0xb5,0xdc,0xbd,0x69,0x7a,0x9f,0x50,0x55,0xe0,0x2d,0xd1,0xeb,0x63, + 0x6c,0x1a,0x18,0x12,0xf6,0x3a,0xcb,0xff,0xe1,0x13,0x9d,0xdd,0xd4,0x78,0xe7,0xc0, + 0xe0,0xb4,0xda,0x0d,0xf0,0x49,0xed,0x03,0x9f,0xcb,0x56,0xd5,0xf1,0xa9,0xe7,0x9d, + 0xc2,0x9a,0x40,0x82,0xa5,0xc8,0x3c,0x91,0x41,0x41,0x70,0xab,0x8f,0xd6,0x2c,0xad, + 0xf2,0x32,0x82,0x86,0x5a,0x8a,0x12,0x0f,0xc0,0x90,0x5c,0x8e,0x13,0xb7,0xe7,0x7e, + 0x6f,0x1d,0x17,0x71,0xb5,0xd0,0x79,0x03,0xfa,0xcf,0x37,0x2b,0x96,0x4e,0x53,0x06, + 0x45,0xe5,0x05,0x78,0xe2,0xe4,0xcf,0x57,0x74,0x01,0x5c,0x64,0x87,0x21,0xfb,0x17, + 0x59,0x3b,0x76,0x06,0xf1,0xd3,0x33,0x14,0x96,0xb1,0x16,0x70,0x20,0x07,0xec,0xc1, + 0x35,0x8e,0x65,0x95,0x1e,0xb8,0xaf,0x64,0x50,0xa1,0x75,0xfe,0xb5,0x96,0x54,0x1a, + 0x03,0x90,0xd4,0x4d,0x27,0xb5,0xde,0x88,0x0b,0xfd,0x9c,0xf7,0x5f,0x23,0xdd,0xae, + 0xe1,0x90,0xa4,0xde,0x77,0x8c,0x03,0x12,0xd7,0x70,0x6a,0x89,0x0f,0xb7,0x78,0xee, + 0x98,0x8d,0x02,0xbe,0x22,0xfd,0xd0,0xa1,0x00,0xa3,0x6e,0xff,0xd9,0x4d,0xf8,0x7f, + 0xa6,0x92,0x96,0x2a,0xda,0x3f,0xe3,0xde,0x3f,0xf2,0x31,0x61,0x9d,0x4b,0xa3,0x89, + 0x2e,0xcf,0x09,0xb6,0x2b,0x4a,0xf5,0xe1,0x39,0x92,0xad,0x18,0x35,0x39,0x0c,0x5f, + 0x64,0x51,0x99,0xb8,0x1a,0xc3,0x2a,0x01,0xf8,0xfc,0xb1,0x35,0x77,0x62,0x88,0xc7, + 0xf2,0xa5,0xeb,0x11,0xd9,0x8e,0xd0,0x2f,0x5c,0x8c,0x10,0xfd,0x4f,0x37,0x45,0xc1, + 0x5d,0xf3,0x72,0x2d,0xc9,0x51,0x70,0xbc,0x8b,0x4a,0xf8,0x5d,0x9b,0x53,0xb3,0x8b, + 0x8a,0x14,0xe5,0xbe,0x0c,0xee,0x75,0xa4,0xfc,0x15,0x6e,0xe7,0xe5,0xc9,0x5e,0x9b, + 0x11,0x78,0x1d,0xb3,0x6a,0x08,0x56,0x1e,0xf7,0x24,0x2c,0x5d,0xed,0x9a,0x0c,0x80, + 0x26,0x51,0xd2,0xd2,0x9b,0xd6,0x35,0xe0,0xf5,0x69,0x60,0xe9,0xd3,0x01,0xed,0x60, + 0xa5,0xb8,0xb9,0x7f,0xb4,0xeb,0xc5,0xd5,0x95,0xeb,0x6d,0xb5,0xd9,0xb7,0x90,0xbc, + 0x59,0x28,0x76,0x81,0x69,0xf3,0xa9,0xc3,0x5e,0xb3,0x29,0x8e,0x8f,0xb8,0xc2,0x5b, + 0xe5,0x34,0xea,0x2e,0x9f,0x6c,0x14,0x9b,0xf5,0xf7,0xc4,0x99,0xa1,0x12,0xa8,0x9c, + 0xdb,0xea,0x32,0x6c,0x29,0x34,0x8f,0x3d,0xd2,0xbe,0x51,0x1b,0xaf,0x4c,0x37,0x42, + 0x49,0xd6,0x2b,0x3e,0x77,0xb1,0x32,0xd2,0xba,0x6e,0x93,0x15,0x09,0xc7,0xbb,0x48, + 0xde,0x3e,0xb7,0x4e,0x13,0x25,0x7b,0xb4,0xa6,0xe3,0xc9,0xd8,0x54,0xaf,0xc8,0x54, + 0xf0,0x9e,0xc6,0x21,0xd1,0x90,0x4d,0x54,0x75,0x3b,0x5f,0xc3,0xa6,0x95,0x27,0x21, + 0x30,0xf6,0x96,0xa8,0x10,0x70,0x02,0x4b,0x79,0x1f,0x95,0x05,0x9f,0x89,0x0c,0x46, + 0x75,0xfe,0x8f,0x54,0x8d,0x43,0x22,0x46,0x1a,0xc3,0xef,0x2a,0x4d,0x0e,0x53,0x49, + 0xd3,0xb3,0x86,0x66,0xef,0xb3,0x85,0x89,0xb9,0x13,0xd9,0x8a,0x09,0xde,0x77,0xb4, + 0xcb,0x75,0x97,0x3c,0xea,0xd4,0x77,0x55,0x51,0xde,0xc5,0x8c,0x66,0x30,0x9c,0xf2, + 0x44,0x9d,0x27,0xea,0xdd,0xa2,0xeb,0x7a,0x40,0xc4,0xc8,0x16,0x89,0x83,0xf9,0x17, + 0x19,0xe2,0x78,0x54,0x16,0x56,0x0b,0x22,0xe3,0xe1,0x81,0x77,0xa4,0xc2,0xe7,0x77, + 0x06,0xa7,0x75,0x4c,0xd5,0xce,0x3f,0x5d,0x05,0x39,0x96,0xc4,0x74,0x79,0x1d,0x03, + 0x83,0xd7,0x23,0x64,0x5a,0x71,0x79,0x5e,0xbb,0xb7,0x8d,0x2f,0x33,0x18,0x05,0x0b, + 0xbb,0xfa,0x16,0x43,0x49,0xa8,0x8e,0xfc,0xc0,0x78,0x62,0xc1,0xf0,0xe2,0xc0,0x5a, + 0x62,0xf9,0xda,0x78,0x76,0x1a,0xba,0xab,0x91,0xd8,0xa3,0x30,0x03,0xfd,0x04,0x59, + 0xc7,0xc1,0xe3,0x2d,0xbf,0x6e,0x27,0x26,0xea,0x3a,0xce,0xba,0x2b,0x5e,0xa1,0x92, + 0xf4,0x9c,0xd3,0xd5,0xe2,0xc5,0x0d,0x4f,0x18,0x67,0xcb,0x24,0x78,0x2f,0xb8,0xf3, + 0xd9,0x9e,0xde,0x1e,0x45,0x54,0x09,0x8b,0x9c,0xbe,0xb6,0x8a,0x94,0xb0,0xea,0x65, + 0x12,0xbb,0x08,0xc4,0x7e,0xce,0xd6,0x20,0xcb,0x2d,0xb9,0xdf,0x79,0x46,0x9c,0xdf, + 0x09,0xde,0xb4,0x50,0x68,0xf5,0xc3,0x1e,0x65,0xbc,0x6f,0x53,0xb3,0x5f,0x51,0x8a, + 0x5e,0x29,0x4b,0x7b,0x53,0x9f,0x45,0xec,0x39,0xe7,0x0a,0x31,0xeb,0x43,0x7f,0x2a, + 0x29,0xf4,0x33,0x9c,0xe3,0x38,0xa1,0xf0,0x4a,0x08,0x92,0x15,0x4f,0x9d,0x27,0xc2, + 0xca,0x95,0x43,0x84,0xfb,0x2b,0xa0,0x00,0xcd,0x9a,0x83,0xfe,0xa6,0x9f,0xc1,0xe1, + 0xa6,0xb1,0x3e,0x4a,0xeb,0x45,0x7c,0xab,0x7b,0xc4,0x37,0x3f,0x84,0x52,0x25,0xca, + 0xf3,0x2c,0x75,0x8b,0xa2,0xc1,0x1d,0xc1,0x7a,0x6f,0xaa,0xe2,0xed,0x47,0x81,0xfd, + 0x54,0xf3,0xe6,0x75,0x73,0xaa,0x6c,0xab,0x68,0xc3,0x97,0x10,0x15,0xf3,0xb8,0xd1, + 0x4f,0xf0,0xf8,0x91,0x5b,0x0b,0xa4,0xe9,0xd7,0x0f,0x53,0x35,0x17,0xe4,0xba,0x62, + 0x4b,0x19,0x63,0xba,0x8b,0x13,0xad,0xb6,0x4d,0x07,0x73,0xd6,0x0a,0x0e,0xeb,0xef, + 0x5e,0x32,0x65,0x54,0xb9,0xb8,0x96,0x08,0x90,0x6f,0x1f,0x69,0x41,0xab,0xf4,0x77, + 0xa0,0xc4,0xaf,0x34,0x6f,0xf5,0xb6,0x91,0x1c,0xb4,0xfc,0x7b,0xba,0xf9,0x64,0x70, + 0xad,0xf3,0x5f,0xd5,0xfb,0xfe,0xd2,0xb3,0x44,0xa2,0x71,0xc5,0xaf,0x20,0x00,0x2e, + 0x41,0xdb,0x19,0x0a,0x3a,0x9f,0x79,0x21,0xa5,0x5d,0x6a,0x26,0xed,0xea,0x04,0x88, + 0x1b,0x6b,0xd8,0xdd,0x65,0x18,0x80,0x62,0x79,0x7d,0x46,0xec,0x2a,0x94,0x3d,0x50, + 0x3e,0xa7,0x78,0x1a,0x3b,0x67,0x5f,0x9e,0x19,0x70,0x93,0xd5,0x7d,0xa8,0x42,0x95, + 0xbe,0x1d,0xf6,0x57,0xa1,0x2d,0x30,0x46,0x0b,0x22,0xe2,0x76,0x9b,0x67,0x69,0x7e, + 0x23,0x5b,0x2c,0x3d,0x2d,0xda,0xb6,0xc6,0x19,0x62,0xd7,0xd2,0xbb,0x4b,0x23,0x30, + 0x92,0xad,0x78,0xf0,0x09,0x6f,0xa7,0xdd,0x0a,0x0a,0x9d,0x85,0xa9,0xaa,0x66,0xf4, + 0x13,0x29,0xbb,0x14,0x86,0xa1,0x79,0x9e,0x93,0x9b,0xe1,0xf4,0x38,0xc9,0xda,0x79, + 0x3a,0x73,0xa4,0x5a,0x38,0xd3,0x4e,0xe5,0xe7,0xf0,0x86,0x71,0x35,0x0f,0xd0,0x62, + 0x03,0x02,0x99,0x05,0xdd,0x4d,0x8a,0xd1,0x87,0xc8,0x6f,0xb3,0x59,0x0b,0x5f,0x54, + 0x17,0xc1,0x57,0xa0,0x8b,0x37,0xbf,0x16,0x34,0x7d,0xca,0xd9,0x53,0xe1,0xe3,0x3b, + 0x44,0xef,0x1b,0x8a,0xd9,0x9b,0x35,0x70,0x73,0xb6,0x42,0x53,0xb7,0x32,0xe1,0xe4, + 0xe5,0x0c,0x33,0x45,0x71,0x9d,0x15,0x20,0x16,0x09,0x1d,0xfa,0x06,0x65,0x2a,0xdd, + 0x29,0x19,0xa3,0x86,0x6e,0xf3,0x98,0xe1,0x82,0xdf,0x2b,0x7b,0xad,0x4e,0x0b,0xc7, + 0x07,0x43,0x93,0x7b,0xf8,0xf9,0x8a,0xdb,0xe8,0x84,0xe0,0x9e,0xf9,0x11,0x28,0xdb, + 0xcd,0x93,0x79,0x62,0x81,0xc8,0x19,0x74,0x23,0x43,0xd6,0x2c,0x31,0xda,0xd4,0xd5, + 0xd6,0xd0,0xcc,0x86,0x20,0x7b,0xa0,0xe0,0x68,0xec,0x9c,0xed,0x3e,0x97,0xe0,0xfe, + 0x18,0x3a,0x5c,0x1a,0x69,0x8d,0xbd,0x13,0x99,0x51,0x77,0x71,0x22,0x41,0x9b,0x0e, + 0xf7,0x71,0xaa,0xa3,0x4b,0x7a,0x55,0xcd,0xe3,0x92,0xc4,0xcc,0xb9,0x3a,0x11,0xe0, + 0x43,0x01,0x2d,0xc3,0x05,0xdb,0x64,0x85,0x7a,0x9d,0xa0,0x38,0x77,0x8c,0x02,0x9d, + 0x3d,0xb3,0x94,0x1f,0x6d,0x99,0x13,0x81,0xa9,0x40,0x2f,0x9c,0xcd,0x3d,0xdf,0x9d, + 0xbd,0xba,0xf9,0x74,0x5a,0xa3,0x5f,0x5f,0xc2,0x5c,0xa1,0x26,0xe7,0x00,0xe1,0x8a, + 0x2d,0x1c,0x2f,0xc7,0x7d,0x89,0xc3,0x83,0x14,0xe2,0xa7,0xcb,0x4f,0x9c,0xf4,0xcc, + 0x35,0xdb,0xf9,0x3d,0xb3,0x0a,0x0d,0xc6,0x3a,0xe1,0x6e,0x07,0x3c,0xca,0x48,0x36, + 0x96,0xea,0x5e,0x82,0xcd,0x1e,0xd8,0xbc,0x11,0x1c,0xb9,0xf6,0xa9,0x31,0x2b,0x5f, + 0x1f,0x3d,0x5f,0x9c,0xcb,0x0c,0xe2,0x1a,0x67,0x37,0x1e,0x4b,0xc7,0xac,0xb1,0x65, + 0xe0,0xfe,0x73,0x35,0x3f,0x97,0x49,0x9a,0x7e,0x5f,0x23,0xa1,0x74,0xcb,0x7a,0xc2, + 0x61,0x96,0x8b,0xd0,0x86,0x11,0xcd,0x0f,0xb6,0x39,0xfb,0xe4,0x89,0x47,0xe3,0x93, + 0x9d,0x24,0xab,0x71,0x74,0x36,0x89,0x06,0x13,0x7a,0xb2,0xb1,0xe3,0xc3,0x84,0xb1, + 0x42,0xbc,0x84,0xe9,0x39,0x86,0xbf,0x0f,0x1b,0x65,0xed,0xab,0xd5,0x1c,0xe3,0xcb, + 0xf8,0x51,0x85,0x9a,0xcf,0x81,0xa7,0x83,0x2e,0xfd,0x67,0xb1,0x31,0x0c,0xb1,0xf1, + 0x9a,0x80,0x0b,0x1a,0xb3,0xb5,0xeb,0x77,0x4f,0xe3,0xe6,0x27,0x85,0x81,0xac,0xf2, + 0x02,0x89,0xcb,0x5a,0x7c,0x57,0x02,0x5d,0xe3,0xfa,0x67,0xa8,0xef,0x15,0x16,0x34, + 0xd9,0x8b,0xb7,0x84,0x02,0x15,0x69,0x54,0x07,0xcd,0x71,0xf2,0xaa,0x78,0xb3,0xd4, + 0xeb,0x40,0xa6,0x89,0xab,0x89,0xc5,0xf2,0x16,0x3b,0xe9,0xf7,0xcc,0xa7,0xd3,0x1a, + 0xd7,0xed,0x99,0x74,0xb9,0x73,0x80,0x63,0xdd,0x42,0x46,0x2a,0xbb,0x7a,0x60,0x6d, + 0x69,0x57,0xf9,0xdb,0x9b,0x6e,0x9c,0xa2,0xac,0x4b,0x3f,0x8c,0xd1,0xc2,0x2e,0x78, + 0xb0,0x3e,0x17,0xd4,0x8b,0x26,0xee,0x0a,0xf1,0xbe,0x11,0x90,0x3e,0xc9,0x2d,0xe6, + 0x13,0xeb,0x4a,0x51,0xbe,0x30,0x0e,0xd9,0x8b,0x49,0xbd,0xa1,0x87,0x33,0xe7,0x51, + 0x6d,0x17,0x39,0xd0,0x9c,0xd3,0x0e,0x0d,0xa4,0xa7,0xfb,0x6a,0x58,0x9a,0x6a,0xbe, + 0x3a,0x74,0x1f,0xa2,0x2e,0x4d,0xbc,0xf9,0x99,0x06,0x87,0x64,0x5f,0x41,0x88,0x68, + 0x38,0xca,0x9d,0x52,0x2a,0x82,0xf9,0xb0,0x8f,0x64,0xd8,0xc1,0x4c,0x63,0x08,0xa6, + 0x89,0x42,0x75,0x83,0xce,0xf3,0x29,0x68,0x19,0xe9,0x66,0xdb,0xfd,0xbd,0x33,0x33, + 0xa7,0xc2,0x68,0x10,0x3e,0x04,0x8e,0xb3,0xa9,0x77,0x08,0x0c,0xfd,0x94,0xa1,0x05, + 0x2c,0x3d,0x53,0xbc,0x68,0x8e,0x77,0xcf,0x7d,0xe1,0x51,0xb2,0xe6,0xfa,0x63,0x39, + 0x21,0xac,0x4b,0x43,0xaa,0xdd,0x2d,0xf1,0x97,0x8a,0x58,0x9f,0xa7,0x93,0xd6,0xba, + 0x68,0x51,0xdd,0x59,0x69,0x5e,0xac,0x16,0xf7,0x52,0x1c,0xae,0x64,0x30,0xae,0xe7, + 0xf6,0x45,0xa4,0x7d,0x2c,0xd2,0x6c,0x5c,0x49,0xfb,0x9f,0xcc,0x3f,0x15,0x74,0x60, + 0x5c,0xfb,0x22,0x4c,0x87,0xa5,0x1d,0x14,0xa7,0x13,0xdd,0xcd,0x7e,0xea,0xf2,0xd0, + 0x0f,0x68,0xc8,0xca,0x1a,0x60,0x12,0x6b,0x9e,0x92,0x91,0x1b,0x7d,0xcb,0x50,0xeb, + 0x47,0x31,0x3c,0x2f,0x1a,0x05,0x87,0xed,0xa0,0xd3,0xc6,0xa3,0xba,0x5b,0x92,0x71, + 0xb4,0xd4,0xd9,0xc9,0xb3,0xef,0x25,0xc8,0x39,0xd5,0x7a,0x2c,0x80,0xa5,0x7f,0xa9, + 0x94,0x33,0x2a,0x98,0xc9,0x95,0x28,0xd7,0x13,0x1a,0xb8,0x85,0xae,0x53,0x6a,0x38, + 0x2f,0x55,0x14,0x39,0x9c,0x80,0x94,0x9a,0x68,0xc7,0xbf,0x8c,0x13,0x91,0xfb,0x06, + 0xa9,0xed,0xa9,0xbe,0x37,0x56,0x64,0xcc,0xe6,0x3e,0x25,0x48,0x76,0xd2,0xaf,0x1c, + 0xb9,0xc0,0x8b,0x16,0xb2,0x72,0xaa,0xaf,0xea,0x52,0xce,0x9e,0xe6,0x37,0x1c,0xa9, + 0xa7,0x45,0x84,0xf3,0xa4,0x52,0xfe,0xb0,0xfa,0x4c,0x7f,0xa7,0x4e,0x60,0xe5,0xcf, + 0x18,0xbc,0x25,0x15,0xe2,0x7e,0xd9,0x86,0x28,0xef,0xb5,0x96,0xd8,0x4e,0x9a,0x58, + 0xb0,0x1a,0x68,0xc8,0x1e,0x8c,0x9b,0x92,0x49,0xc6,0xae,0x68,0x63,0x82,0xd6,0xea, + 0x4c,0xef,0x6d,0xb3,0x55,0x32,0x4f,0x2a,0x5f,0x6c,0x0a,0x82,0xb5,0x15,0x9d,0xdc, + 0x73,0x55,0x7e,0x6f,0xaa,0x54,0x38,0xd3,0x85,0xfd,0x4f,0x5e,0xca,0x46,0x13,0xb2, + 0xf1,0x50,0x43,0x1b,0xf3,0x60,0xe5,0x4a,0x37,0x1c,0x27,0x5a,0x6e,0xb7,0x5a,0xb2, + 0x28,0x12,0x75,0x76,0x4b,0x63,0x1f,0x8f,0xa3,0xe5,0xb4,0x00,0xc3,0x1c,0x2b,0xd1, + 0x93,0xf2,0xfd,0xd0,0xce,0x41,0x09,0x13,0x5b,0x51,0x68,0xa5,0xe1,0xbe,0xa3,0x89, + 0xf3,0xc2,0x7f,0xbe,0x18,0x15,0x46,0x21,0xeb,0x94,0x3b,0x4a,0x7e,0xbc,0x5e,0xc4, + 0x08,0x22,0x9d,0x36,0xd7,0xae,0x95,0x44,0xd4,0x48,0x5c,0x78,0x7c,0xbd,0x2e,0x36, + 0x50,0xe1,0x81,0x92,0x34,0x58,0x28,0xa8,0x89,0xfa,0x3c,0xf5,0x73,0x8b,0x29,0x3f, + 0x11,0xe0,0x38,0x8d,0xc4,0x30,0x1d,0x33,0x1f,0x2b,0xf9,0x86,0xca,0xbd,0x51,0x90, + 0x7c,0x8b,0x04,0x3c,0x65,0xbe,0xa3,0x6a,0x6a,0x4e,0xe2,0x89,0x05,0x15,0x5e,0xd7, + 0x10,0xd7,0x3e,0x38,0xd6,0x92,0x5e,0x44,0x03,0xcf,0xcf,0x77,0x44,0x7d,0xaf,0xe2, + 0xfe,0x84,0x11,0x1b,0x33,0x8b,0x73,0x0a,0x3f,0x3f,0x06,0x67,0x13,0xa6,0xf7,0x03, + 0xb6,0x1d,0x59,0x57,0x96,0xb4,0x9b,0xad,0xb6,0x42,0x20,0xfb,0x57,0xa5,0xfc,0x49, + 0x09,0x83,0xf5,0xa6,0x52,0x53,0x51,0x18,0x27,0x3a,0xbe,0x78,0x6a,0x78,0xd8,0x64, + 0xf6,0xd8,0x8a,0xac,0xa3,0xc6,0x04,0xff,0x9b,0x56,0xe8,0xfa,0x50,0x6c,0x9a,0x04, + 0x25,0x2b,0x5f,0x97,0xe6,0x39,0xad,0x3b,0x6b,0x1b,0x75,0xe6,0x2c,0xfd,0xdd,0x3e, + 0xd5,0x63,0x13,0xb7,0xe8,0x6d,0x93,0xe4,0x50,0x5d,0xc2,0xe3,0x2f,0xe2,0x0f,0x5e, + 0x10,0x67,0xda,0x11,0x97,0x6c,0x54,0x3c,0x6e,0xc9,0x7c,0xff,0x42,0xca,0xe0,0xe7, + 0xcf,0x06,0x4f,0xac,0x92,0x4c,0x4f,0xfa,0xd5,0x42,0x74,0x04,0x4f,0x59,0x4b,0xdf, + 0x6f,0xe4,0x42,0x91,0xf7,0xbf,0x08,0x35,0x2b,0xa2,0x0b,0x1b,0x3f,0x46,0xab,0x6f, + 0x67,0x6d,0x2e,0x29,0x11,0x33,0xf4,0xfe,0x2b,0x6b,0x20,0x6d,0x2d,0xf1,0x72,0x51, + 0x83,0x4b,0xca,0x8a,0xf8,0xe8,0x5f,0x8c,0x74,0x1f,0xf5,0xf0,0x66,0x68,0x43,0xeb, + 0xd8,0xc9,0x0b,0x71,0x10,0xd3,0xe8,0x61,0x59,0x91,0xe0,0x14,0xb8,0x7f,0xac,0x54, + 0x90,0x4f,0x53,0x78,0x12,0x22,0x38,0xb0,0xe1,0x42,0x61,0xd6,0xae,0xa7,0xe4,0xd2, + 0x61,0x59,0xc5,0xd4,0x09,0xb4,0x4d,0xdd,0xf8,0x2f,0x9c,0xf2,0xf3,0x00,0xed,0x92, + 0x96,0xe5,0x55,0x74,0xd3,0xb8,0x4e,0x83,0xb7,0x7f,0x4d,0x93,0xe4,0xb1,0xcc,0xd2, + 0xa1,0x24,0x23,0x6c,0xef,0xb4,0xaa,0xea,0x37,0x81,0xff,0x0b,0x43,0xe6,0x03,0xd8, + 0x84,0x4e,0x07,0x10,0x1e,0x97,0xde,0xcb,0x15,0xe5,0x00,0xc8,0x1d,0x14,0xd7,0x9f, + 0x97,0xa3,0x72,0xe8,0x49,0xb3,0x94,0xf2,0x62,0x80,0xed,0xc3,0x1f,0x60,0xff,0x74, + 0xaa,0xf7,0x29,0x0d,0x6f,0x7e,0xf2,0xc1,0xbd,0x9f,0xce,0xe6,0xfc,0x78,0xf2,0xb5, + 0xce,0xbd,0xbd,0x19,0x9a,0xe7,0x9d,0xc7,0xe5,0x3d,0x13,0x9f,0x5c,0x39,0x99,0x31, + 0xcc,0x52,0x20,0xe2,0xeb,0x24,0x9e,0xde,0x0c,0x93,0xc7,0xf7,0xe3,0xc2,0x1a,0xbf, + 0x39,0x9d,0x2e,0xdd,0x21,0x59,0x0b,0xb7,0x36,0x66,0x42,0x8b,0xe2,0x1d,0x64,0x56, + 0x83,0x4d,0x4b,0xca,0x13,0x28,0x1d,0x98,0xc2,0x07,0xb2,0x20,0xe4,0x0d,0xba,0xf6, + 0xa1,0x53,0x18,0x05,0x4a,0x1a,0x4b,0x34,0xe3,0x10,0xc8,0x70,0x73,0x53,0xc2,0x35, + 0x55,0x1f,0xd4,0xe1,0xad,0x31,0x3f,0x7d,0x1d,0xa0,0x2c,0x12,0x39,0xdc,0xf0,0xd5, + 0x2e,0x32,0x76,0x17,0x87,0x6c,0x5f,0x09,0x54,0x38,0x2b,0x22,0x2f,0xf0,0xd1,0xcd, + 0x99,0x58,0x50,0xcc,0xc8,0xd6,0x35,0x97,0xd0,0x19,0xc3,0x8c,0x44,0xfe,0xdc,0x00, + 0xad,0xe2,0x90,0xca,0x16,0x63,0x6f,0x19,0x2b,0x73,0xaa,0x49,0x88,0x2a,0x64,0xd8, + 0x70,0x74,0x3e,0xce,0xd8,0x5f,0x34,0x50,0xca,0x88,0xcd,0xf6,0x7e,0xef,0xd3,0x4d, + 0x88,0x67,0xd8,0xd8,0xc3,0x7b,0x4b,0x52,0x26,0xd6,0x62,0x0b,0x39,0x8e,0x4f,0x0d, + 0xe2,0x7c,0xed,0xbf,0xfb,0x03,0xb2,0x08,0xcb,0x62,0xde,0x64,0x0e,0xda,0x0f,0xc4, + 0x34,0x33,0xb9,0x9c,0xc5,0x3d,0xcc,0x10,0xb5,0x23,0x8c,0x16,0x4c,0xa7,0xed,0x12, + 0x2b,0x15,0x0c,0x5d,0x18,0x88,0xf6,0xba,0x40,0x01,0x76,0x17,0x43,0x1c,0x5f,0x43, + 0x20,0x8e,0xde,0x38,0xba,0xd6,0x92,0x7a,0xd8,0x23,0xff,0x26,0x22,0xf6,0x61,0x73, + 0x16,0x24,0xe4,0xd9,0xe8,0x50,0x3b,0x74,0xca,0x1e,0x88,0x7d,0x96,0xb7,0x36,0x74, + 0xa0,0x60,0xa5,0x5d,0x4a,0xe3,0x56,0x04,0x53,0xc1,0xb7,0x55,0x6a,0x1a,0xe0,0x43, + 0x28,0x8c,0x6a,0x92,0x22,0x62,0x38,0xa7,0x15,0xf1,0xd0,0x28,0x01,0x29,0x66,0xa2, + 0xc1,0x03,0x00,0x34,0xba,0x90,0x82,0xa2,0x63,0x32,0x59,0x25,0x78,0xab,0xb5,0x93, + 0x94,0x30,0x1a,0x99,0xf4,0xa9,0x34,0x77,0x81,0xa2,0x4e,0x37,0x49,0x08,0xf0,0xc3, + 0xc2,0xda,0x96,0x1e,0x03,0x3b,0x77,0xdd,0x3c,0x65,0x0b,0xec,0xa7,0x07,0xe4,0x76, + 0x4b,0xdd,0x89,0x03,0xaf,0xb8,0xa7,0x3f,0xc8,0x49,0x9e,0xbb,0x04,0x82,0xdb,0xe9, + 0x23,0x77,0xa1,0xd8,0x69,0x67,0x14,0x28,0x12,0xda,0x31,0x91,0x25,0x93,0x00,0xde, + 0xca,0xf8,0x35,0x7c,0x35,0x8d,0x24,0x6d,0xfd,0x97,0xe9,0xf3,0x3a,0x37,0x33,0x85, + 0x47,0xa6,0x44,0x87,0x89,0xf3,0x8d,0x7e,0xe8,0x11,0x60,0x40,0xd0,0x45,0x68,0xb8, + 0x68,0x1c,0x6a,0x3a,0xbb,0x0c,0x3b,0x03,0xc1,0x57,0x0a,0xe1,0x85,0x19,0x72,0xe9, + 0x7b,0x64,0xbf,0x9d,0xc9,0x86,0x17,0x2e,0xd1,0x3b,0xc3,0x33,0xc7,0xb7,0xfb,0xa7, + 0xbe,0xdc,0xf8,0x84,0xaf,0x8e,0xbf,0x8e,0x34,0xe3,0xbd,0xb7,0xf9,0x78,0x7c,0x11, + 0xb9,0x08,0x17,0xcf,0xa7,0x99,0x3b,0xae,0x53,0x68,0x8b,0x25,0x37,0xdd,0xfd,0x58, + 0x26,0xda,0x5f,0x46,0x5b,0x8a,0xda,0x12,0xe7,0x22,0x70,0xbb,0x1a,0xf3,0xc8,0xb7, + 0xc8,0xa3,0x58,0x67,0x81,0xc0,0xd9,0x12,0x39,0x66,0x1d,0x19,0x09,0xec,0xec,0xcd, + 0x37,0xe6,0x7e,0xda,0x10,0xeb,0xfc,0x30,0x72,0xa1,0x7b,0xf6,0xd6,0x24,0x58,0x87, + 0x14,0x5d,0x7c,0xfd,0x54,0x25,0x79,0x55,0xf6,0xb5,0xa0,0x1e,0x9d,0x3f,0xcc,0x34, + 0x8a,0x08,0x78,0x8c,0xde,0xa0,0x81,0x49,0xe8,0x77,0xaf,0x8a,0xec,0x4b,0xb6,0x54, + 0x9a,0x89,0x48,0xf9,0xe8,0xf6,0x13,0x98,0x82,0x45,0xe9,0x46,0x4c,0x26,0x32,0xe4, + 0x26,0xb2,0x02,0xd6,0x08,0x28,0xa0,0x6b,0x4f,0x72,0xd3,0xa5,0xbb,0x8b,0x6e,0x7e, + 0x64,0x9e,0xc8,0xfa,0x17,0x95,0xc8,0xc8,0x50,0x6a,0x6f,0x76,0x94,0xae,0x51,0xfc, + 0xd3,0x90,0x81,0xff,0x68,0x83,0x8a,0xdb,0xe5,0x21,0x46,0x8a,0x7a,0x02,0x34,0x58, + 0xd9,0xdb,0x41,0x90,0x7d,0xaa,0x65,0xd4,0x7e,0x56,0x44,0x8e,0x29,0x0f,0x8b,0xb0, + 0x16,0x67,0xa8,0xa2,0x2a,0x2e,0xf9,0xfd,0x85,0xa3,0xaa,0x06,0x6c,0x48,0x08,0xb2, + 0x02,0xfa,0xbc,0x5d,0x88,0xa7,0x4a,0xf6,0x16,0xea,0x62,0x42,0x48,0x49,0x03,0x51, + 0x65,0xd4,0x59,0xc6,0x15,0x91,0x36,0xea,0x88,0x6f,0x1a,0x59,0x48,0x43,0x79,0x32, + 0xe1,0xab,0x0f,0xa9,0x30,0x99,0x5e,0xfb,0x39,0x90,0xe7,0x3a,0x96,0x69,0x9e,0x95, + 0xb5,0x75,0xcd,0x5b,0xcc,0x93,0x1c,0x2f,0x45,0xd7,0x04,0x9d,0x24,0x7b,0xce,0xd6, + 0xdc,0xc1,0xb2,0x1a,0xec,0x78,0x03,0x27,0x81,0x11,0xb7,0x9e,0x57,0x3f,0x4a,0x87, + 0x73,0x9c,0xef,0x10,0x12,0x4c,0xf9,0x14,0xed,0x70,0x82,0x3c,0xb3,0x4b,0x28,0xef, + 0x00,0xe1,0xa0,0x7e,0x7f,0xc8,0x09,0xa4,0x7b,0xb0,0xe5,0x23,0x63,0x98,0x93,0x52, + 0x16,0xca,0xf5,0x9c,0xb2,0x1b,0xb4,0x9f,0x2b,0x12,0x88,0xed,0xe3,0x09,0x43,0xe5, + 0xca,0x35,0x97,0x3a,0x74,0x7c,0x96,0x42,0xd1,0x19,0xa1,0xd7,0x7c,0x2f,0x32,0x9a, + 0xa9,0x1d,0xb7,0x9f,0x40,0xfc,0x20,0xa8,0xe9,0xb3,0xa4,0xb5,0xd9,0xfe,0xe0,0x1f, + 0x6c,0xac,0x50,0x6e,0xe2,0xba,0xb7,0x70,0x00,0xb2,0x4e,0xce,0x7f,0x4d,0x24,0xe7, + 0x8d,0x31,0xa5,0xeb,0xc1,0x26,0x04,0xdc,0x59,0x2e,0x7c,0x06,0x64,0x80,0xa6,0xb5, + 0x69,0xa7,0x15,0x04,0x01,0x71,0x3e,0xdf,0xbd,0xad,0x39,0xd4,0xd5,0x40,0xac,0x4b, + 0x29,0x3b,0xd8,0x9c,0x49,0x92,0xc9,0xeb,0x7e,0x63,0xf5,0x79,0xf3,0x32,0x7d,0x17, + 0x12,0x6a,0xe8,0xb8,0x66,0xcc,0x75,0x61,0x0f,0x81,0x96,0x43,0xa6,0xea,0x2c,0x4a, + 0x23,0xd4,0x0c,0x05,0x69,0x67,0xa7,0x16,0xe4,0x96,0x88,0x53,0x33,0x65,0x53,0x6c, + 0xee,0x47,0x06,0xf7,0x7c,0x3a,0x39,0x0c,0xfe,0x20,0x59,0x9d,0x85,0x96,0x3b,0xec, + 0xd8,0xd9,0x9a,0x25,0x0f,0xae,0x50,0x92,0x90,0x9f,0x80,0x0b,0x2f,0x5f,0xbc,0x48, + 0x61,0x43,0xfa,0xf3,0x7c,0x0d,0x71,0x42,0xa4,0xc2,0xe4,0x86,0x00,0x37,0x19,0xd3, + 0x20,0x11,0x92,0xaa,0xca,0x25,0x80,0x9a,0x62,0x25,0x73,0x22,0x20,0x03,0x89,0x82, + 0xc2,0xb5,0x55,0x87,0x4d,0xd9,0x58,0xde,0xf3,0xc2,0xd4,0x47,0x1c,0x00,0xbf,0xdb, + 0xfb,0x1e,0x77,0x6b,0x3c,0xd0,0xc5,0x48,0x16,0xd5,0x19,0x17,0x48,0xe9,0x49,0xd2, + 0xd9,0x09,0xc9,0x1b,0x43,0x32,0x7a,0x96,0x66,0x62,0x70,0x0a,0x8b,0xb2,0x45,0x6c, + 0x09,0x76,0x20,0x5a,0xd8,0x29,0x45,0xc8,0x48,0xe9,0xf9,0xec,0x02,0xe9,0x3a,0x64, + 0x0d,0x9f,0xfc,0x78,0xbe,0x75,0x7b,0x3b,0x21,0xac,0xa2,0x83,0xdb,0x15,0x22,0x47, + 0x66,0xf4,0xae,0x9b,0x55,0x29,0x7f,0x6c,0x60,0x16,0x73,0xb0,0x80,0x79,0x68,0x1f, + 0xce,0x4c,0x9c,0x28,0xe7,0x2a,0x32,0x6e,0x1b,0xed,0xaf,0x8e,0xf9,0x76,0x40,0x95, + 0xcb,0x26,0x1b,0x3a,0xae,0xf3,0x28,0x9f,0x92,0xfb,0xf9,0x10,0x8f,0xe6,0xb5,0x5b, + 0xdb,0x41,0x8c,0xd9,0xa9,0x1b,0x28,0x05,0xa9,0xda,0x0c,0x66,0x1d,0x75,0x7d,0xc6, + 0x99,0x1a,0x10,0xce,0xcd,0x3e,0xa1,0x7d,0x85,0xa6,0xb9,0xb0,0xf3,0xbc,0x93,0xf6, + 0x5c,0x1c,0x52,0xb6,0x39,0x5a,0xe0,0xa7,0xbd,0xe2,0xaf,0x82,0xaf,0xc5,0x0f,0xe4, + 0x9e,0x35,0xba,0xba,0x9d,0xde,0xd2,0x24,0x79,0xd7,0xff,0x12,0xfb,0x17,0x24,0xe5, + 0x91,0x05,0x22,0xdf,0xfd,0x2b,0x67,0x3e,0x36,0x21,0x52,0xd4,0x14,0x0d,0xd7,0x59, + 0x55,0x2c,0xb0,0xda,0x9e,0xe0,0xb3,0x3b,0xa9,0x46,0x8c,0x7d,0xbf,0x2d,0x0d,0x8d, + 0x41,0x05,0x42,0xde,0x6e,0x0d,0x2a,0x88,0x4a,0xb2,0xd0,0xa1,0xf3,0x1f,0x31,0x68, + 0xc1,0x07,0x35,0x08,0x52,0x7a,0x37,0x0b,0x07,0x57,0x65,0xe9,0x49,0x5e,0xf7,0x53, + 0xdf,0xb8,0x03,0x24,0x53,0x4d,0x01,0x99,0x15,0xe0,0xbc,0x30,0x0d,0x2b,0x52,0xde, + 0xb0,0x1e,0xf6,0x79,0xaf,0x86,0xe8,0x93,0x00,0xe5,0xe7,0xfd,0xd7,0x60,0x60,0x38, + 0x97,0x4d,0x7f,0xb8,0x4a,0xa7,0x0f,0x21,0xc3,0x26,0x0f,0xbd,0x02,0xac,0x4a,0x09, + 0x69,0xe8,0x3f,0x02,0xbf,0x18,0xd8,0xab,0x62,0xc4,0x2b,0xdf,0xaf,0x43,0xd6,0x3e, + 0xa9,0x5b,0x42,0x4e,0x1f,0x1d,0x67,0xaa,0xa6,0x3e,0x4a,0x48,0x6a,0x19,0x83,0xa3, + 0xd5,0x57,0xa1,0x08,0x9e,0xfc,0x34,0x10,0x59,0x1d,0x1d,0x6e,0x31,0xc2,0x8b,0x48, + 0x19,0xa4,0xf4,0xa2,0x34,0x1c,0x21,0x47,0x70,0xcd,0x95,0x4d,0x74,0xb7,0xad,0xc0, + 0xd3,0x2f,0x90,0xd6,0x56,0x88,0xa3,0x2d,0xca,0xef,0x54,0x68,0xaf,0xfb,0xc8,0x13, + 0xbe,0xdc,0xbb,0x5d,0xa7,0x05,0xb4,0x4d,0x90,0xeb,0x4a,0x76,0x63,0xf3,0x37,0x07, + 0xed,0x99,0x4e,0xa5,0x6e,0xb1,0xbe,0xfa,0x36,0x78,0x88,0xd7,0x39,0xb5,0xbe,0x41, + 0x1b,0xfa,0x43,0x87,0x12,0x2b,0x23,0x7e,0x21,0x3f,0x17,0x48,0xbb,0x0d,0x1b,0xb9, + 0x6a,0x97,0x15,0x0c,0x8a,0x80,0x19,0xb7,0xc4,0xbf,0x2a,0x16,0xa2,0x7c,0x2b,0x1c, + 0xca,0xde,0x54,0xb6,0xc8,0x3d,0x96,0x2f,0x97,0x46,0x18,0x8a,0x3e,0x6b,0xc1,0xe4, + 0x42,0x54,0x84,0x64,0xeb,0x34,0x6e,0x9d,0xe5,0xfc,0xea,0x39,0x3f,0xd7,0x56,0xbb, + 0x31,0x40,0x17,0x93,0x24,0x23,0x4b,0x3c,0xd1,0x34,0x77,0xe3,0x9e,0x59,0x77,0x04, + 0xa1,0x4b,0xe3,0x5c,0x2e,0xe8,0x5e,0xd2,0x64,0x6c,0x48,0x61,0x76,0x4e,0x58,0xa1, + 0x3a,0x59,0xb4,0x59,0x21,0x0e,0x43,0xca,0xa2,0xa5,0x24,0xd9,0x45,0x90,0x25,0x2a, + 0x86,0x5f,0xdb,0xd5,0x4c,0xfc,0xf0,0x04,0x40,0x6a,0xf6,0xe2,0x1a,0x2c,0xe5,0x77, + 0xc4,0x58,0xea,0xe6,0x4f,0xad,0x93,0x34,0x40,0xdc,0xaa,0x79,0x97,0x64,0x33,0xf4, + 0x4b,0xed,0xd5,0x23,0x4b,0x2c,0x02,0x97,0x74,0x3d,0x10,0xcf,0x7c,0x6a,0xe9,0xef, + 0x40,0xe9,0xcc,0x75,0x63,0x0b,0x7f,0xf1,0xf8,0x50,0x2b,0x87,0x49,0x77,0x62,0xd2, + 0xf5,0x75,0x23,0xe7,0x47,0xb7,0xba,0xc3,0xcb,0xf6,0x6d,0x80,0xc0,0xbc,0xfc,0x2a, + 0x41,0x13,0x1d,0xda,0xfb,0xe2,0x99,0xe2,0x9c,0x39,0xb1,0x66,0xdf,0xbc,0x0f,0x2f, + 0xd4,0x36,0x2a,0x04,0xde,0xf2,0x32,0x3a,0x18,0x54,0xe9,0xf6,0x58,0x92,0x59,0xf6, + 0x2d,0x25,0x8f,0x0d,0xe2,0xe6,0x75,0xac,0x3a,0xbf,0x3b,0x1e,0xc3,0x69,0xbc,0x05, + 0x9d,0xd5,0x19,0x07,0xc0,0x9f,0xb4,0xdf,0x8f,0x26,0xdf,0x96,0x53,0xc0,0x41,0x8d, + 0x12,0x79,0x18,0x6d,0xcc,0x5a,0xc9,0xf2,0x84,0x5c,0x1b,0x37,0x61,0x64,0xfd,0x6c, + 0x53,0xb4,0xea,0xcb,0x26,0x7b,0xfd,0xdb,0xee,0x38,0x1d,0x9b,0x95,0x8d,0xf8,0x84, + 0x7a,0xd7,0xc1,0x98,0x1c,0xe7,0x1c,0x59,0x08,0x68,0x0e,0x4c,0x58,0x01,0x33,0x14, + 0x02,0x51,0xf7,0x60,0x44,0x55,0x88,0x02,0xfb,0x1d,0xb2,0xe6,0x3d,0x62,0x0b,0x6f, + 0x72,0x6b,0x5d,0x50,0x08,0x2d,0x55,0x24,0xf4,0x65,0xa8,0xeb,0x12,0x27,0x7b,0x08, + 0x4c,0x82,0x53,0x17,0xa7,0x87,0x19,0xe8,0x7a,0x50,0xc8,0xdc,0x27,0x54,0xa3,0xf3, + 0x70,0x79,0xcf,0xff,0x58,0x75,0xf0,0x7f,0x5e,0x34,0x20,0x0a,0x45,0xa8,0xea,0xd0, + 0x2d,0xd6,0x25,0xa9,0x84,0xa4,0x11,0x65,0x28,0xef,0xb7,0x9e,0x91,0x97,0xfc,0xb2, + 0x77,0xc5,0xf3,0xe9,0xdc,0x6b,0x9e,0x31,0xd6,0x06,0x97,0xae,0x2e,0x6f,0x49,0xbe, + 0x21,0x08,0x25,0x89,0xf5,0x18,0xaa,0x27,0x43,0x56,0xd8,0xd5,0x03,0x38,0x02,0x19, + 0x2c,0x82,0x40,0x4a,0x9b,0xf8,0xff,0x82,0x8a,0x59,0x9b,0xf0,0x4b,0x23,0xf0,0x80, + 0xb5,0x0f,0xfb,0x77,0x3e,0x7e,0x9f,0xeb,0x64,0x00,0x73,0xd3,0x8b,0x0b,0xe6,0x43, + 0x7c,0x50,0x0b,0xd6,0x14,0xc2,0xff,0x52,0x78,0xad,0x0d,0x0c,0xc7,0x1d,0xd4,0xa8, + 0x31,0xd8,0x7f,0xcc,0x57,0x2c,0x59,0x94,0x86,0x11,0x99,0xcc,0x2f,0x05,0x89,0x24, + 0xfb,0x0a,0xdc,0x74,0xcd,0xe1,0xbd,0xe4,0x95,0xfa,0xa8,0xda,0xd1,0xb8,0x4f,0xd9, + 0x5f,0x3a,0x7b,0x04,0xc2,0x9c,0xd8,0xf2,0xdc,0x68,0x85,0xa2,0x3b,0x4c,0x90,0x51, + 0xf4,0x35,0xc9,0xde,0x92,0x68,0x73,0xd4,0x81,0x84,0xc4,0xea,0xe6,0x59,0xe9,0x9d, + 0x92,0x18,0xc5,0x5c,0xbe,0xa1,0x19,0x5e,0xc9,0xfe,0x3a,0x39,0x06,0xe0,0x1a,0x69, + 0x1d,0xf2,0x32,0x92,0x58,0x9a,0x6e,0xbd,0x3a,0x1e,0x8e,0xbc,0xf1,0xa7,0x4c,0x37, + 0x71,0x32,0xfd,0x96,0xec,0x37,0x52,0xa5,0xa0,0x3f,0xa3,0x70,0x24,0x4f,0xfc,0xfa, + 0x91,0xe6,0x5c,0x48,0xfc,0xe6,0x4b,0xc3,0x28,0x26,0x9d,0x10,0x25,0x37,0x5a,0x00, + 0x0b,0x6b,0x1c,0x46,0x87,0xff,0x27,0x31,0x74,0x8a,0x28,0xd5,0x2d,0x00,0x72,0x9c, + 0xc7,0x38,0xb9,0x6d,0xcf,0xc3,0xe7,0x8f,0x9a,0x7d,0x6f,0xf2,0x37,0xcd,0x70,0x40, + 0xb9,0x96,0x31,0x3e,0x65,0x39,0x0e,0xb6,0xd7,0xee,0x06,0x02,0x58,0x3c,0x38,0xf4, + 0x0d,0x59,0xe7,0xfb,0x11,0x8f,0x14,0x95,0xaa,0x72,0xe6,0x77,0xf6,0x84,0x92,0x0d, + 0xa2,0x66,0x7e,0x7c,0x03,0x0e,0xa4,0x87,0x1e,0x5d,0x6b,0x2a,0x42,0x35,0xa3,0x84, + 0x79,0xdb,0x36,0xf7,0xf0,0xb3,0x31,0xb5,0x71,0xa2,0xba,0x8c,0x72,0x6a,0x46,0x6b, + 0xfb,0xe9,0x68,0x1c,0x85,0x74,0x27,0x7e,0x72,0xac,0x64,0xeb,0x29,0x3d,0x9d,0x12, + 0x6a,0x26,0x27,0xc1,0xd1,0x2b,0x48,0x64,0xad,0xc0,0x8e,0xfe,0xc2,0xf6,0xfa,0x60, + 0x09,0xeb,0x22,0x9e,0x6c,0x7e,0x73,0x15,0x94,0x0e,0x6b,0x32,0x61,0xe5,0x80,0x06, + 0x2d,0x63,0xe8,0xa0,0x73,0x2a,0x6d,0xdb,0x8d,0x51,0x3b,0x93,0x2b,0x7f,0x28,0x53, + 0x65,0x13,0xa0,0x36,0xc2,0xc7,0xe1,0xc5,0x0f,0xd3,0xaf,0x82,0x44,0xbb,0xb0,0xb2, + 0x94,0x74,0x66,0xd0,0xbc,0xff,0x08,0x47,0x8b,0x35,0xe2,0x9a,0x68,0xcd,0xbc,0x16, + 0x59,0xab,0x2e,0x3d,0x45,0x08,0x7f,0x2e,0x89,0xe2,0x58,0x11,0xe9,0x6f,0x85,0xe5, + 0x15,0x26,0xf9,0x75,0x48,0xbd,0x2d,0x1b,0x76,0x10,0xd5,0x98,0x4e,0x27,0x5a,0xfe, + 0xc1,0xa7,0xaa,0x1a,0x49,0xc3,0x3b,0xba,0x2c,0x8b,0xa7,0xda,0x1b,0xa5,0x1a,0x45, + 0xa6,0x7e,0xb9,0x90,0x11,0x02,0x9d,0x24,0x3e,0x97,0xb6,0x94,0xca,0x4a,0x99,0x7b, + 0x51,0xe8,0xea,0xe6,0x81,0xe5,0x6c,0x35,0x55,0x53,0x6c,0xe9,0xce,0xb3,0x0c,0xeb, + 0xf8,0x29,0x9b,0x1a,0x35,0xde,0x6d,0x91,0xd2,0xfa,0x4a,0x8e,0xc8,0x9b,0x74,0xae, + 0x06,0x2f,0x82,0x32,0x4f,0xd6,0x08,0x0e,0x9d,0xa8,0xa4,0x84,0xb4,0xcd,0x95,0x66, + 0x0f,0xca,0xc6,0x69,0x78,0x1c,0x74,0x50,0xa6,0x5e,0x12,0x38,0x0a,0xbb,0xcc,0x2f, + 0x82,0x76,0x89,0xe1,0x84,0x3f,0x37,0x32,0xb3,0xc0,0xe2,0xaa,0x79,0x18,0x30,0x72, + 0x60,0xd0,0xd0,0x76,0x68,0xe6,0x27,0xdb,0x3f,0x7b,0xdf,0x53,0x07,0x57,0x1e,0x50, + 0xe1,0xac,0x76,0xdd,0x77,0xc9,0xa7,0xa1,0x9d,0x3a,0x78,0x23,0x95,0x6f,0x66,0xdc, + 0x03,0x96,0xbc,0xd8,0x5f,0x2d,0x3e,0x75,0xa7,0x5f,0x65,0xc6,0xee,0x53,0x9a,0x92, + 0x78,0x0d,0x9b,0x83,0x56,0x7a,0xd0,0x21,0x44,0xdb,0x3b,0xac,0xc4,0xa1,0x1c,0xa6, + 0x0d,0x05,0xad,0xf9,0x96,0x1a,0xe4,0x03,0x1c,0x45,0x5f,0x84,0x36,0x17,0xd3,0xa2, + 0x72,0x29,0x34,0xef,0x68,0x82,0xd2,0xbf,0x0f,0x29,0x44,0x71,0x29,0x9f,0xad,0xf8, + 0x23,0x92,0xb9,0xad,0x5c,0x12,0x89,0xa1,0xdd,0x09,0x4e,0xc6,0x07,0xcf,0xc9,0x3b, + 0x84,0xaf,0x86,0xce,0xe7,0x60,0xcb,0x79,0xc2,0xa8,0xca,0xaa,0x24,0x7a,0xd0,0xfd, + 0x96,0xad,0x8b,0xa6,0xd9,0x7e,0x7e,0x5a,0x5f,0x76,0x8e,0x36,0x58,0x72,0x7f,0xb8, + 0xd7,0xc8,0xb5,0x42,0xac,0xf8,0x68,0xa7,0x8a,0x4d,0x09,0x02,0x14,0x09,0x7f,0x46, + 0x3b,0x50,0x62,0x45,0x69,0x0b,0x93,0xc0,0x90,0x8d,0x22,0xa1,0xa6,0x81,0x89,0x9e, + 0x8b,0xdb,0xa6,0x8b,0x4c,0x4d,0x05,0x7d,0x82,0x70,0x73,0xbe,0xfe,0x7a,0xf3,0x3b, + 0x29,0xd3,0x4f,0x9c,0x12,0x79,0xb8,0x3f,0x0b,0x1e,0x00,0x19,0x64,0x43,0x85,0x8f, + 0xd7,0x43,0x0a,0x50,0x59,0x3a,0x61,0x46,0xbd,0x3a,0x00,0xed,0xd2,0xe7,0xca,0x76, + 0xd6,0xa9,0x0e,0x67,0x33,0x8d,0x32,0x2b,0x86,0x2e,0xe8,0x2f,0x96,0x56,0xcd,0x6f, + 0x5e,0x34,0x15,0xc5,0x14,0x50,0x9a,0x86,0xce,0xb4,0x91,0xd0,0x67,0x9f,0x78,0xf6, + 0xc4,0xf3,0x27,0x5e,0x3c,0xf1,0xf2,0x80,0x21,0x9c,0x9e,0x04,0xa7,0x53,0x2b,0xd5, + 0x68,0x03,0xe5,0xf5,0x24,0xf5,0xd0,0x99,0xe7,0x5f,0xf7,0x83,0xa4,0x93,0x36,0x6a, + 0x2e,0xcd,0xdb,0x63,0x6a,0x04,0x30,0x62,0x48,0x20,0x92,0xb1,0x1d,0xe2,0x95,0x08, + 0x2c,0x11,0x1d,0xe7,0x0a,0x05,0x9a,0x57,0xaf,0x61,0xe3,0xfd,0x32,0xd2,0xb5,0xb2, + 0x28,0x8b,0x2e,0x91,0xc6,0xf1,0xb6,0x8b,0xd8,0x8a,0x3f,0x47,0xd0,0xec,0x0e,0x75, + 0xe3,0x59,0x73,0x0a,0xee,0x40,0xa2,0x7a,0xfc,0x17,0xc6,0x3f,0x1a,0x44,0xdb,0xa1, + 0x70,0x12,0xfd,0x26,0x7c,0x86,0x67,0xb3,0xc2,0xaa,0xd7,0xc5,0xea,0x80,0xc1,0x28, + 0xab,0xb0,0xd8,0x9e,0xaa,0x41,0xcf,0x7b,0xf3,0x7a,0xa2,0x59,0x5c,0x59,0x0c,0x1e, + 0x33,0x7f,0x87,0x0d,0xe0,0x63,0xe4,0x20,0x04,0xe5,0xcc,0x72,0x4c,0x5c,0x83,0x1b, + 0x95,0xf4,0xff,0xd6,0x58,0x75,0x5a,0xda,0x94,0xcd,0xbb,0x59,0xe2,0xc0,0xef,0xb5, + 0xb2,0x0a,0xd9,0x8a,0xb5,0xd8,0x43,0x82,0x58,0x19,0x0b,0xb1,0x35,0x87,0x6d,0xe4, + 0x01,0xba,0x40,0xab,0x51,0x47,0x19,0x17,0xd9,0x61,0x64,0xe4,0xaf,0xb6,0x37,0xc4, + 0x89,0x5a,0x7d,0x6c,0x54,0xd4,0xf5,0x92,0x87,0x98,0xcc,0x23,0xb2,0xf0,0xd7,0xf0, + 0x84,0x59,0x1c,0x19,0x57,0xb2,0xb3,0x50,0xd2,0x88,0x25,0x8e,0xed,0x05,0x76,0xae, + 0xb7,0x31,0x5a,0xa4,0x24,0x99,0xc6,0xf0,0xcc,0x76,0xcc,0xa2,0x3e,0xd9,0x5a,0x40, + 0xd7,0x8c,0x96,0x56,0xb3,0x79,0x21,0xcd,0xe5,0xd8,0x84,0x87,0x69,0x6f,0x20,0xe0, + 0xf1,0x55,0x21,0x47,0x0a,0x43,0xe8,0x1d,0xc6,0x88,0x1e,0xd1,0xb7,0x7b,0xbb,0x51, + 0xb4,0x63,0x61,0xf3,0xa4,0xf5,0xaf,0x25,0x50,0x32,0x7d,0x82,0xd2,0x44,0xe7,0x46, + 0x69,0xb9,0x49,0x91,0x60,0x96,0xdc,0x47,0x96,0x4d,0xd7,0x37,0xdf,0x1b,0xb5,0x71, + 0x36,0x7d,0xfb,0xa6,0xed,0x44,0xc2,0x51,0x40,0x64,0xaf,0xb6,0xb7,0x51,0x16,0xa3, + 0x35,0x74,0x25,0x82,0xa1,0xb1,0x8b,0xfa,0x15,0x8e,0x6f,0x61,0x48,0xb7,0x16,0x33, + 0x82,0x2d,0x27,0xad,0x7d,0x10,0xc4,0xe5,0xe8,0x1c,0x51,0xff,0x7b,0xcc,0xd3,0x2a, + 0xac,0x64,0x30,0x2a,0x12,0x7d,0xf4,0x06,0x8f,0xbc,0x2f,0x0f,0xa3,0xbe,0x45,0xd4, + 0x30,0xf5,0x73,0x68,0x27,0x2a,0xe5,0x67,0x5e,0x94,0x4b,0x11,0x8c,0x68,0x4b,0x8a, + 0xaf,0x71,0xfb,0x21,0xd9,0xd3,0xb7,0xa6,0x4a,0x44,0x5f,0x76,0x2f,0xb1,0xec,0xcd, + 0x72,0x4f,0xca,0x82,0x46,0x9b,0xea,0x43,0x04,0x92,0xe5,0xe7,0xd2,0x93,0x1a,0xd3, + 0x2e,0x89,0x0e,0x16,0x30,0xd9,0x82,0xc6,0x45,0x1a,0xd1,0x92,0x99,0xac,0x8f,0xf4, + 0xf5,0x6d,0x70,0xfd,0x88,0xc4,0x71,0x59,0x81,0xdf,0x3e,0x62,0x22,0x38,0x06,0x01, + 0x10,0x54,0x0a,0x85,0x5f,0xd6,0xe3,0x3d,0xd6,0x8d,0xd7,0x59,0x78,0x0e,0x7d,0xed, + 0xd9,0xda,0x61,0x08,0xab,0x10,0xbb,0xb7,0x2a,0x1c,0x0b,0x16,0x99,0xbb,0x16,0x06, + 0x10,0x6c,0x42,0xb2,0xbe,0xdc,0x99,0x32,0x18,0x09,0xb2,0x7b,0xab,0x6a,0xeb,0x52, + 0x72,0xb5,0xc8,0xed,0x93,0x92,0x6c,0x2b,0xa3,0x03,0x29,0x15,0xab,0x95,0xfa,0x71, + 0xde,0x77,0x8f,0x9c,0x5a,0x90,0x59,0x76,0x69,0x85,0x29,0xc9,0xc3,0x03,0x58,0x54, + 0x49,0x5f,0x7c,0x40,0x1d,0xaf,0xab,0x0c,0xb4,0x3e,0x4f,0x22,0x6b,0x7d,0x6f,0x9c, + 0xd9,0x75,0xf7,0xd3,0xa4,0x80,0x67,0xf2,0x70,0x50,0x6e,0x29,0x0f,0x0d,0x9d,0x35, + 0xde,0xb2,0x87,0x1a,0xcb,0xe3,0xe6,0x61,0x4f,0xa3,0xd7,0x5b,0x7c,0x42,0xe3,0x96, + 0x9c,0xd0,0xa4,0xa5,0x9b,0x53,0x67,0xad,0xcf,0xec,0x2d,0x2c,0xbe,0x65,0x27,0x34, + 0x6b,0x85,0x13,0x9a,0xb7,0xe2,0x09,0x2d,0x5a,0x69,0x4f,0xcb,0xef,0x9b,0x08,0x5d, + 0x3f,0x2d,0x79,0xc7,0x91,0x00,0x81,0x47,0x20,0xa5,0x32,0x42,0x67,0x18,0xc2,0x9b, + 0x61,0x13,0xca,0x87,0x40,0x37,0x34,0x18,0x45,0x5e,0x2b,0x01,0xf5,0x60,0x2f,0x2c, + 0xd3,0x95,0xb4,0x8e,0x35,0xab,0x40,0xb4,0xbc,0x94,0x5d,0xf2,0x21,0xb8,0xff,0xa8, + 0x00,0x05,0x22,0x3b,0x7e,0xd3,0xa4,0x8f,0x9c,0x97,0x37,0x4b,0x56,0x9b,0x17,0x65, + 0x79,0x15,0x62,0x99,0xda,0x74,0x9a,0x53,0x7f,0xe6,0x23,0xe2,0xd2,0x55,0xd3,0xf5, + 0x47,0x86,0x67,0xd6,0x7f,0x6c,0x9e,0x62,0x00,0xb5,0x0f,0xef,0x8d,0x57,0x5d,0xf7, + 0x19,0xab,0x44,0x26,0x75,0xae,0xdd,0x4c,0xb2,0x0c,0xa6,0x1f,0xf8,0x25,0x85,0x4e, + 0xa6,0x13,0xc2,0x96,0xb9,0x77,0xe7,0x5c,0x4c,0x51,0x34,0x78,0x34,0x47,0x6a,0xe3, + 0x9c,0xe3,0xa7,0x34,0x48,0xa3,0x26,0x61,0x82,0xcf,0x70,0x0e,0x59,0x00,0xa6,0xf8, + 0x7b,0x0c,0x8a,0x96,0x1c,0x48,0xe2,0x8b,0x77,0x55,0x83,0x03,0x27,0xda,0x4a,0x22, + 0x66,0x97,0x60,0x43,0x4e,0x64,0x78,0xf6,0x2b,0x38,0xeb,0xf0,0x11,0x54,0xec,0xb5, + 0x78,0x9c,0xa8,0x51,0x40,0xce,0x94,0x11,0x2a,0x62,0x74,0x1a,0x5e,0xce,0xde,0xa4, + 0x42,0xb1,0x49,0x6b,0x1d,0xbe,0xc6,0x27,0x01,0xa0,0x4f,0xe8,0x9b,0x20,0x50,0x18, + 0x66,0xac,0x8b,0xd4,0xcd,0x16,0x34,0x78,0xbb,0x0f,0x9c,0x6f,0x71,0x9a,0xca,0x7f, + 0x7c,0x61,0xda,0x9d,0x73,0x48,0xda,0x6f,0x85,0x5a,0xac,0x68,0x41,0xaf,0x83,0x13, + 0xf8,0x9b,0x8d,0x16,0xc9,0x2d,0xc1,0xf5,0xe5,0x17,0x5f,0x34,0xcc,0xb6,0x02,0x89, + 0x6d,0x4e,0x91,0x37,0x54,0x57,0x4e,0x8f,0xa1,0xcc,0xf3,0x7a,0x11,0xd0,0x01,0xef, + 0xbb,0x1d,0xb9,0x21,0x36,0xf2,0xeb,0x99,0x9c,0x2f,0x70,0x68,0xd4,0x38,0xbe,0x50, + 0x21,0x63,0x12,0xaa,0xd8,0x26,0xeb,0x1b,0x3b,0x3f,0xca,0x10,0x49,0x1c,0x0a,0x7d, + 0x0b,0xaf,0xa4,0xf7,0x30,0x2c,0x93,0xcf,0x62,0xc9,0xa9,0xb2,0xeb,0xb4,0xd1,0x62, + 0xad,0xe1,0x33,0xae,0xf3,0x62,0x95,0x8e,0xbd,0xb9,0x6f,0xca,0x58,0xb9,0x21,0x8a, + 0x3f,0x48,0x22,0x53,0xd2,0x5e,0xd6,0x2b,0x3b,0x9a,0x22,0x3c,0xbc,0xf8,0x52,0x6c, + 0x5a,0x87,0xfd,0x8b,0x94,0xd3,0xa6,0x89,0x77,0x13,0xa0,0x8d,0xf3,0xab,0x98,0xa6, + 0x4f,0x6e,0xa3,0xbe,0xca,0x63,0x97,0xd2,0x39,0xe5,0xe7,0x29,0x99,0x5a,0x2f,0xa3, + 0x6d,0xe2,0xfb,0x03,0x8c,0xe8,0x7d,0x70,0x42,0x0e,0x77,0x38,0x16,0x7f,0x35,0x46, + 0x27,0x0d,0x2e,0x8e,0x24,0x6d,0xa8,0x9c,0x64,0x22,0xf9,0xcf,0xb2,0xe2,0xf5,0xc5, + 0x83,0x7d,0xd5,0x7c,0xc8,0x2e,0x9f,0xa6,0xa0,0xec,0x66,0x52,0x83,0x5d,0x73,0x67, + 0xee,0xc0,0xe5,0xf1,0x4e,0x69,0x8c,0x07,0x98,0x75,0xb4,0xb4,0x48,0x39,0x8a,0x37, + 0xe2,0xce,0x7b,0xde,0xf5,0xbd,0x73,0x10,0xc9,0x26,0x4d,0xfe,0x96,0x75,0xdd,0x9e, + 0x6c,0xd4,0xc4,0x94,0xee,0xcf,0xcd,0xf9,0xb1,0xe4,0x1f,0x55,0x6d,0xa5,0x2d,0x39, + 0x0d,0x36,0xaa,0x58,0x3e,0x66,0x5b,0x92,0x76,0xbf,0x68,0x1a,0x3c,0x2e,0x96,0x73, + 0xb9,0x08,0x1c,0x40,0x45,0xf8,0x80,0x76,0x85,0x8a,0xac,0xa4,0x84,0x76,0x42,0x3f, + 0x79,0x50,0x26,0x33,0x97,0xa9,0x9a,0x99,0x94,0xe2,0x60,0xb9,0x92,0xe6,0x92,0x5a, + 0x2c,0x7c,0x12,0xfb,0x74,0x92,0x2d,0xdd,0x91,0xdf,0x2a,0x8a,0x80,0x9f,0xf6,0x28, + 0x30,0x8c,0x53,0x5a,0x88,0x94,0x7f,0x32,0x03,0xc9,0x93,0x2c,0xb0,0x99,0xc6,0x45, + 0xc6,0xba,0x08,0x48,0x2b,0x18,0x8c,0x52,0x47,0xc8,0x5d,0x62,0x02,0x92,0x0d,0x6d, + 0x07,0x3a,0x79,0x2a,0x53,0xf2,0x56,0x37,0x78,0x99,0xb5,0x4b,0x62,0xc6,0xef,0xe8, + 0x49,0x49,0x80,0x47,0x27,0x47,0x72,0xc5,0x25,0x3b,0x32,0xfc,0x5f,0xc1,0x81,0x78, + 0xf0,0x3b,0x7b,0x1a,0xbd,0x24,0xef,0xdb,0x75,0x4a,0x97,0x62,0x9e,0x90,0x2e,0x1f, + 0xe7,0x99,0x45,0x4f,0x7e,0xc8,0xea,0xae,0x38,0x30,0xfc,0xfa,0xc1,0x40,0x39,0xdb, + 0x51,0x4c,0x23,0xd8,0x34,0x22,0xab,0xaf,0x59,0xd8,0x4e,0x87,0xa1,0x17,0xd7,0x35, + 0xde,0x51,0x90,0x24,0x1c,0x61,0x90,0xb5,0x30,0xdf,0xd1,0x19,0x9a,0x0c,0x47,0xf0, + 0x36,0xf0,0xd4,0xb8,0x21,0x13,0x91,0x7a,0x9d,0xb0,0x20,0x50,0xb3,0x64,0xa5,0xa2, + 0x34,0xc8,0x85,0x4c,0x92,0x09,0x8b,0x9c,0x89,0x74,0xbd,0xf4,0x00,0xe0,0x25,0xfe, + 0x40,0x07,0x8f,0x30,0xcb,0x67,0x36,0xc0,0x11,0xaf,0xcc,0x0d,0xc1,0xf0,0x5d,0xc3, + 0xf1,0x91,0x97,0x88,0xb1,0x29,0xa2,0x6f,0x93,0x2d,0xb9,0x2a,0x0d,0x42,0x48,0x3a, + 0xdc,0xce,0xc2,0x51,0xe9,0x23,0x40,0x87,0xf9,0x14,0x77,0x64,0x0b,0xb7,0xbb,0x9c, + 0x76,0xc4,0x3c,0xda,0xeb,0x95,0x41,0x39,0x42,0xc4,0xe6,0xea,0x4f,0xf8,0x41,0xbe, + 0x78,0x90,0x0b,0x30,0x64,0x5c,0x97,0x6b,0x3c,0xcf,0x27,0x39,0xcf,0x01,0xdf,0x0e, + 0x5f,0xaf,0xaa,0xf8,0xed,0x33,0xf8,0x1e,0xe7,0x9d,0x60,0x76,0x58,0x5e,0x60,0x97, + 0xa9,0x54,0x3e,0xe6,0x23,0x8d,0x49,0x12,0xfc,0x41,0x29,0xf5,0x23,0x1e,0x20,0x96, + 0x5b,0xb1,0xf5,0xc5,0x12,0x7c,0x16,0x64,0x3c,0xed,0x05,0x0a,0xb0,0xce,0x6d,0x50, + 0xf3,0x5c,0x40,0x6b,0xfe,0x20,0xe3,0x5a,0x68,0x5a,0x76,0xb1,0x37,0x9b,0x05,0xc0, + 0x62,0xff,0x53,0xa4,0x30,0xd2,0xc8,0xa0,0xa6,0xe9,0x43,0x6f,0x85,0x21,0x2d,0xc7, + 0x49,0xed,0x86,0xb6,0xfb,0xb9,0xa4,0x47,0x40,0xe0,0x54,0xfa,0x15,0xc8,0xc3,0xc6, + 0x28,0x9e,0x5b,0x95,0x14,0x95,0xe3,0xed,0xa2,0xf9,0x6e,0x27,0x70,0x37,0x2d,0x74, + 0x78,0x9b,0xf7,0xe3,0x35,0x5b,0xfc,0xdb,0x71,0x1c,0x37,0x16,0xd1,0xee,0x97,0x57, + 0x4d,0xd5,0xc1,0xa4,0x96,0x8d,0x6e,0x8f,0xea,0x43,0xab,0x94,0x9f,0xf2,0x9a,0x4e, + 0xb7,0xc7,0x6c,0xf8,0x10,0x3b,0xfe,0x2f,0x1e,0x74,0x7a,0x1b,0xc5,0xb5,0x30,0xa7, + 0xd5,0x98,0x6d,0x04,0x8f,0x5f,0x62,0x0b,0xf9,0xba,0x47,0x03,0xc8,0xde,0xe9,0x63, + 0x2b,0xf3,0x70,0x6a,0x1a,0x13,0x73,0x8d,0x85,0x5e,0xf0,0xd1,0xe7,0xb7,0xb5,0x11, + 0x8d,0x1e,0x6e,0x8d,0xb2,0x95,0x91,0xe0,0x2b,0xb7,0x86,0x0d,0xe8,0x89,0x27,0x97, + 0x4b,0xf6,0xee,0x69,0x7e,0xb2,0xc2,0x9f,0xce,0xdd,0x8d,0xc4,0xcf,0x8d,0xf6,0xb9, + 0xaf,0x0c,0xf9,0xe4,0xf1,0xd2,0xe4,0x4b,0x67,0x66,0x0b,0x45,0x90,0x33,0x07,0x5f, + 0xc9,0xb0,0xbe,0x73,0xfa,0x12,0x43,0xae,0xe7,0x60,0x8d,0xd7,0xe9,0xdf,0x2d,0x6f, + 0x72,0x9e,0xbf,0x89,0xb9,0xf3,0x66,0xe9,0xc9,0xc3,0xf2,0xcd,0x1c,0x3d,0x7a,0xd9, + 0xae,0x64,0x87,0x78,0x09,0x35,0xbd,0x1b,0x67,0xdb,0xc8,0x63,0xdc,0xc6,0xf5,0x58, + 0xd3,0x5a,0x1d,0xc3,0x49,0xfd,0xed,0xae,0x4e,0xab,0x28,0x69,0x69,0x04,0xec,0xa9, + 0x4e,0xb0,0xd3,0x5e,0xda,0x24,0x31,0x33,0x3f,0x38,0xa5,0xb5,0x7b,0xf0,0xfb,0xf5, + 0x4e,0x58,0x0f,0x50,0x5b,0x0b,0x0e,0x49,0x52,0xc3,0xf7,0xcd,0x6e,0xa0,0xa3,0x2e, + 0x5d,0x96,0x94,0xe1,0x79,0xcd,0x4e,0x46,0x7f,0x6f,0x6c,0x29,0x2a,0xe0,0x32,0x74, + 0xc9,0xca,0x8f,0x06,0x5e,0x86,0x58,0xce,0x20,0x92,0xe9,0x51,0x55,0x40,0x09,0xdc, + 0x91,0x60,0xaf,0x05,0x4c,0x8c,0x85,0x10,0x25,0xa3,0x31,0x05,0xb5,0x3c,0x29,0xd8, + 0x74,0x8b,0x09,0x83,0x0a,0xa6,0x22,0x7e,0x9d,0xcc,0xf6,0xf4,0x2f,0xd6,0xf9,0x5a, + 0xb4,0xa5,0x14,0xdc,0x8c,0x3e,0x8b,0x44,0xb4,0x84,0x0c,0xa0,0x6d,0xef,0x74,0xcc, + 0x1e,0x24,0x67,0x6f,0xc7,0x15,0x1a,0xbc,0xc3,0x57,0x36,0xc8,0x3b,0x7e,0x55,0x77, + 0x79,0x47,0xaf,0xf8,0xef,0x3f,0x78,0xd6,0x7f,0xef,0x43,0xf3,0x68,0x6b,0x97,0xd3, + 0xf3,0xd5,0x90,0x39,0xa2,0x13,0xde,0xd7,0x74,0x82,0xc9,0xf2,0x61,0x7a,0xe2,0x86, + 0xde,0x15,0xf3,0x83,0xcd,0xb0,0x62,0x6b,0x4e,0x8e,0x76,0x74,0x82,0x47,0x09,0x88, + 0xcf,0x29,0x32,0xb3,0xff,0xab,0x9b,0x5c,0x41,0xb7,0x61,0x1d,0x99,0x18,0x97,0xd2, + 0x68,0x15,0x5a,0x36,0xe4,0x54,0xff,0x6a,0xac,0x21,0xb5,0x74,0x9b,0x75,0x28,0xd2, + 0x95,0xe2,0xdc,0x5f,0xad,0xeb,0x85,0xf8,0x5f,0x2b,0x29,0x0f,0x22,0x4c,0xa5,0xac, + 0x75,0xb0,0x0e,0xe5,0xb3,0x51,0x1a,0xfc,0x23,0x42,0x9f,0xa8,0xa1,0x6d,0xec,0x0c, + 0x3c,0x01,0x68,0x9e,0xed,0x8b,0xd9,0x52,0xcd,0x68,0xca,0x36,0x62,0xc2,0xde,0xb5, + 0x31,0xff,0xdf,0xe3,0xf9,0x86,0x47,0xec,0xb7,0xa3,0xa5,0x14,0x16,0xcc,0xc8,0xf5, + 0xb2,0x5a,0xda,0x6c,0x34,0x29,0xfe,0x29,0xc5,0x0b,0xe3,0x4f,0xb6,0x71,0xb4,0x36, + 0x3a,0x90,0x83,0xba,0xb0,0xf9,0x2a,0xed,0x76,0x22,0xd6,0xff,0x58,0x81,0x1d,0xf2, + 0x93,0x98,0xd8,0x70,0xf7,0xed,0x63,0xe9,0x7b,0x25,0x84,0x14,0xde,0x6e,0xbf,0x58, + 0x9c,0x1b,0xcc,0xa1,0x8b,0xe0,0xae,0xf4,0xe0,0x16,0x78,0x38,0x02,0x6f,0x25,0xca, + 0xc0,0x9e,0x5f,0xd3,0x33,0xc0,0xd5,0xa1,0xfc,0xaa,0xbc,0xce,0xe0,0x60,0x0d,0x22, + 0x64,0xa4,0x20,0x35,0x11,0xd4,0x2f,0x57,0x75,0x54,0xa9,0xc0,0x40,0x1a,0xd9,0xdf, + 0xea,0xf0,0x90,0xa4,0x39,0x79,0x5a,0xad,0x02,0x6a,0x33,0xd6,0xfc,0x7a,0x4b,0x9c, + 0x18,0x54,0xe4,0xa6,0x6e,0x21,0xfe,0xec,0x78,0x46,0x43,0xea,0x65,0x1d,0x0d,0x84, + 0x0d,0x25,0x2f,0x8e,0xb2,0x9f,0x90,0x7b,0xa1,0x71,0xf0,0xf8,0xb0,0x06,0xd2,0x77, + 0xd5,0xde,0xf4,0x8c,0xe9,0x52,0xd6,0x7e,0xee,0x28,0x6b,0x3c,0x4a,0x09,0xb8,0x17, + 0xdd,0x87,0x90,0x53,0x3e,0x60,0x62,0x24,0x5f,0x7b,0xcc,0xb4,0x66,0x53,0x0d,0x4a, + 0x1a,0x13,0x58,0xf3,0x8c,0xc7,0x23,0x0b,0xca,0x92,0xcb,0xdf,0x14,0xd2,0x94,0x8c, + 0xae,0x3c,0x3c,0x78,0x19,0x93,0x53,0x4d,0xa3,0x52,0xda,0x20,0x23,0xcd,0xe0,0xb4, + 0xb7,0x44,0xb2,0x2e,0x59,0xb4,0xf5,0x39,0x92,0x06,0x23,0xb4,0x65,0x54,0x95,0x32, + 0x52,0xab,0x12,0x69,0x32,0x6d,0xf8,0xed,0x39,0xf6,0xab,0xde,0xe3,0x0b,0xe9,0xff, + 0x87,0x53,0x13,0x7d,0x50,0xf3,0x0d,0x4f,0x16,0x29,0x7e,0xd8,0xf4,0xf6,0xb2,0x3f, + 0xd3,0x7b,0xd2,0x93,0xcf,0x50,0xf3,0xb3,0x26,0xa1,0xeb,0x13,0xd8,0x5d,0xb7,0xec, + 0xa9,0x0b,0xc7,0xfc,0xa7,0xf9,0x3b,0x77,0x74,0x9d,0xc0,0x11,0x75,0x73,0x6e,0x23, + 0x60,0xed,0xa0,0xc2,0x0d,0x95,0xd2,0x73,0x04,0x30,0x9b,0x11,0x3c,0xd3,0x99,0x76, + 0xd5,0x6b,0x71,0x42,0xe6,0x30,0x9d,0x3d,0x4f,0xe7,0xe2,0xeb,0x32,0x31,0xd2,0x7c, + 0x76,0xa8,0x19,0x42,0x26,0x91,0xff,0x37,0xb5,0x94,0xbd,0x57,0xd4,0x03,0xbc,0xe6, + 0xb3,0x6b,0x62,0xf4,0x5e,0x68,0x05,0xfd,0x29,0x48,0x66,0x05,0x87,0x91,0xce,0x11, + 0x07,0xe5,0xe3,0x16,0x20,0xa9,0x87,0xee,0x47,0xff,0xad,0x78,0xa4,0xbc,0x55,0x90, + 0xbd,0x87,0xaf,0x4f,0x75,0xe8,0xb5,0x7d,0x7b,0xc8,0x58,0xf6,0x37,0x1b,0x7a,0x46, + 0xb5,0xf8,0x6b,0xac,0xae,0x77,0x78,0x4b,0x8d,0xf8,0x81,0xe0,0x63,0x46,0xa1,0x03, + 0x1f,0x5a,0xad,0xf9,0x3f,0x34,0x91,0x41,0xe8,0x5a,0xb2,0x37,0xa0,0xe9,0x56,0x3a, + 0x79,0x98,0xcd,0x24,0xc2,0xec,0xd0,0x41,0x32,0x3e,0x45,0x9b,0xdd,0xb5,0x34,0x66, + 0xe6,0x2a,0xc5,0xd4,0x6d,0x76,0x5a,0xc6,0x1b,0x46,0x7c,0x10,0x01,0x0e,0x13,0x15, + 0x2c,0x5b,0x5c,0xc5,0xad,0x92,0x0d,0xf7,0xd2,0x35,0x88,0x38,0x59,0x51,0x48,0x5d, + 0x90,0x7a,0x42,0x87,0xd2,0x05,0x0b,0x34,0x28,0x58,0x8c,0x0d,0xae,0xb2,0xc5,0x08, + 0xae,0x5c,0x58,0xe4,0x10,0x52,0x78,0xcc,0x4f,0xa7,0x3a,0x26,0xa5,0x26,0x32,0x5b, + 0x25,0x14,0x3a,0x87,0x30,0x53,0x4f,0xd1,0x92,0xb2,0x12,0x1a,0xa0,0xfd,0xd3,0x7b, + 0x14,0xc6,0xb7,0x61,0x61,0xa2,0xcf,0xca,0xda,0x29,0x23,0x75,0x0e,0x42,0x37,0x42, + 0x75,0xc3,0x1f,0x6d,0x81,0xa9,0xb1,0x5f,0xee,0x1e,0x44,0xe3,0xb6,0x09,0xae,0xab, + 0x92,0x63,0x39,0x08,0xc6,0xa6,0x7a,0xea,0xdb,0xd4,0x6e,0x46,0xd2,0x4d,0x1f,0x14, + 0x5a,0x4c,0xea,0xb4,0x5a,0xeb,0x66,0xe1,0x3a,0x4e,0xa8,0xf8,0x2e,0x2d,0x95,0x54, + 0x60,0x9c,0xb6,0x16,0x61,0xca,0x0c,0x82,0x77,0xf3,0x2d,0x0f,0x87,0x87,0xe6,0xf0, + 0x4b,0xd1,0x8d,0xb9,0xab,0x8a,0x3f,0x8d,0x8e,0xd9,0xf3,0x88,0x97,0x88,0x2e,0xd8, + 0x4c,0x82,0x61,0x19,0x68,0x12,0x4a,0xfb,0xb5,0x8c,0x08,0x26,0xf1,0x21,0x51,0x07, + 0x3b,0x26,0xee,0xd0,0xb7,0x18,0x7a,0x40,0x35,0xf8,0x68,0xfb,0x12,0x14,0x73,0x06, + 0x0a,0x18,0x5d,0xfc,0xe4,0x18,0xab,0xe0,0x20,0xa6,0x82,0xd6,0x74,0x1d,0x2d,0x6f, + 0x7f,0xea,0x87,0x50,0x99,0x4a,0x63,0x66,0xac,0xb5,0x09,0x1d,0x78,0x59,0x97,0x6e, + 0x19,0x2f,0x2d,0xb7,0x0f,0xc7,0x6b,0xc0,0x22,0x56,0x44,0xd5,0x8f,0x82,0x5e,0x67, + 0x24,0x12,0x2e,0xc5,0x41,0xaa,0xd9,0x0b,0x1b,0x0c,0x9b,0xaf,0xac,0x00,0xbe,0x64, + 0x09,0x30,0xfd,0xe8,0xeb,0x6a,0xce,0x5f,0x3a,0x05,0x1e,0x47,0xc6,0xe7,0x10,0xc8, + 0x00,0xf7,0xe9,0x68,0x66,0x37,0x15,0xe9,0x83,0x88,0x7f,0xd4,0x93,0x8f,0x48,0x2e, + 0xaa,0xa6,0xf7,0x0f,0x69,0x67,0x80,0xd4,0xfd,0x85,0x39,0xb6,0x2c,0xea,0x58,0x26, + 0xf5,0x42,0xe8,0x58,0xc4,0xfc,0x9f,0x45,0x5a,0x7a,0x19,0x03,0xdc,0x83,0x56,0xd6, + 0xe5,0xad,0x10,0x07,0xfc,0xa5,0x55,0x56,0xa1,0x53,0x54,0xf6,0xa9,0x30,0x91,0x47, + 0x8b,0x5e,0x3c,0x3a,0x44,0x4c,0xbc,0x45,0x7a,0xa6,0x86,0xc4,0xe4,0xb1,0x91,0x1e, + 0xca,0xdd,0xd9,0x21,0x72,0x49,0xec,0xca,0xde,0x7f,0x7b,0xe3,0xde,0x67,0x2e,0xf8, + 0x31,0x70,0x62,0x7f,0xd0,0x36,0x90,0x89,0x3f,0xf0,0xd2,0x0b,0x3b,0x27,0x9b,0xbb, + 0xf9,0x43,0x7b,0x26,0xc5,0xdb,0xb8,0x6d,0x92,0x59,0xd3,0xd3,0x56,0x4c,0x09,0x4e, + 0x99,0xb3,0x84,0x98,0xf3,0x65,0x61,0x56,0xa3,0xd2,0x45,0xcc,0x5d,0x87,0x4e,0x1c, + 0x6f,0x8e,0x12,0xb9,0xce,0x89,0x31,0x8b,0x20,0x33,0x49,0x61,0xeb,0xf3,0x0e,0x7c, + 0x91,0x28,0x32,0x97,0xab,0x6a,0xac,0x78,0x3f,0x95,0x4a,0x23,0xc0,0xc6,0x43,0x01, + 0x4b,0x18,0x8c,0x14,0x0b,0x8f,0xb8,0xbe,0x51,0x02,0x47,0x8b,0x84,0xbc,0xf0,0xe5, + 0x82,0x17,0x97,0xd0,0xb7,0xd5,0xb0,0x8d,0x2e,0xcb,0xdb,0x0a,0x7d,0x12,0x89,0x9e, + 0xb1,0x0d,0x95,0x30,0xfc,0xb1,0xb5,0x11,0xf8,0xaa,0x50,0x1d,0xb7,0x83,0x8d,0x20, + 0xb1,0x4f,0x34,0xea,0xb7,0xca,0x69,0xe3,0x88,0x14,0x3a,0x50,0x0b,0x88,0x6a,0xdc, + 0xfd,0xa9,0x4d,0xe1,0x5d,0x4d,0xbc,0xc1,0xc0,0x11,0x74,0xc6,0x23,0x94,0x55,0x85, + 0x4b,0xe6,0x0b,0x6e,0x52,0x53,0x98,0x59,0x4a,0x0d,0xe7,0x44,0xa0,0x90,0x73,0xdc, + 0x61,0xa9,0xc9,0x79,0x9d,0xd4,0x89,0x39,0xce,0x18,0xcf,0x8c,0x79,0xb2,0x61,0x9c, + 0x22,0x74,0xe3,0xa5,0x82,0x3b,0xf0,0x39,0x5c,0x00,0x11,0xbf,0x74,0xb9,0x2b,0x17, + 0xcd,0x64,0x34,0xbb,0x91,0xd7,0x6a,0x4a,0x2a,0x1f,0xb7,0xff,0x47,0x24,0xb7,0x25, + 0xf3,0x31,0xe1,0xc8,0xeb,0x40,0x83,0x04,0xa3,0x0e,0xb4,0x96,0xad,0x35,0x50,0x1c, + 0x66,0x91,0xc8,0xe6,0xf3,0x9e,0x6e,0xd4,0xdc,0x74,0xe9,0xbf,0x53,0xfb,0x50,0x7e, + 0x42,0x13,0xae,0x92,0x2f,0x2f,0x72,0x4c,0x04,0x59,0x68,0x19,0x15,0x71,0xee,0x21, + 0x1c,0x10,0xfa,0xc8,0xaf,0x8e,0xc5,0xb9,0x19,0x8b,0xc5,0xf6,0x7f,0xba,0x1c,0xec, + 0x9d,0x92,0xbc,0xdd,0x38,0xea,0xd0,0x3e,0x75,0x2f,0xdd,0xe4,0x6e,0x0f,0x16,0x51, + 0xc2,0x7e,0x03,0x98,0x89,0xaf,0xf0,0x2e,0xda,0xb1,0xab,0x97,0xb7,0x15,0x5c,0xa1, + 0xa7,0x43,0x6a,0xcb,0x12,0xa0,0x12,0xeb,0x15,0xee,0xd6,0xd0,0xb3,0x3a,0x6a,0x2a, + 0x68,0x83,0x5e,0x32,0xab,0x06,0x1b,0x83,0xe4,0x05,0x2c,0x02,0x5d,0xfc,0xf5,0x13, + 0x5f,0x32,0x0f,0xd7,0x18,0xc0,0x20,0xfc,0x16,0x6c,0x5e,0x6d,0x0e,0xc1,0x5f,0xdd, + 0x5f,0x28,0x24,0x82,0xeb,0x85,0x61,0x43,0xb8,0x97,0xbd,0x4b,0x7c,0x81,0xce,0xc0, + 0xe0,0xaa,0x58,0xd0,0x38,0xf7,0x22,0x4a,0xd1,0x4e,0xbd,0x15,0x4b,0x69,0x9e,0x42, + 0x0d,0x26,0x35,0x0d,0x4d,0x8f,0x27,0x07,0x21,0x8d,0xa7,0x1e,0x73,0xe7,0xc5,0x65, + 0x55,0x7e,0x4d,0x99,0x4f,0x58,0x9a,0xd9,0xfd,0x0c,0xf3,0x9e,0x79,0x4a,0xdd,0x30, + 0x77,0x2e,0x15,0x0c,0xd4,0x42,0xb8,0x5a,0x4f,0x8d,0x98,0x36,0x16,0x3e,0x8f,0xc9, + 0x79,0xf0,0x27,0x24,0xa3,0xdd,0xc9,0xcb,0xce,0xc1,0xac,0xf3,0x18,0x5a,0x45,0x7f, + 0x5b,0x68,0xe6,0xf4,0xff,0xb2,0xcd,0xff,0xd7,0x38,0xbd,0x9b,0x6d,0x04,0xa1,0x1d, + 0x60,0x07,0xf9,0xc4,0xb0,0xb7,0x48,0x06,0x83,0x74,0xe0,0xcd,0x4e,0xd7,0x7b,0x2c, + 0xf4,0xfc,0xcd,0x89,0x23,0x77,0xed,0xa5,0x91,0xff,0xf9,0xeb,0x7c,0x71,0x58,0xd7, + 0x96,0x74,0x9c,0x96,0x2b,0x7e,0x53,0x02,0x07,0xa6,0x36,0xd7,0x0c,0xf2,0xed,0xde, + 0x3e,0xdf,0x8e,0x15,0xc7,0xea,0x47,0xa7,0x38,0xc7,0xac,0x95,0xbd,0xe9,0x70,0x9b, + 0xbf,0xa4,0xfd,0xa9,0x36,0xfe,0x0b,0x36,0xef,0xc8,0x29,0x88,0x6b,0xa1,0x7b,0x60, + 0x28,0xcf,0x6a,0xcd,0x62,0x3a,0x4d,0xd2,0x61,0x85,0xf3,0x18,0x44,0x6d,0x03,0x6c, + 0x52,0x45,0x4e,0x46,0xca,0x24,0xcf,0x28,0x59,0x8a,0x67,0x8c,0x67,0x1c,0xc7,0x49, + 0xe6,0x17,0xbd,0x48,0x71,0x55,0x56,0x80,0x27,0x46,0x19,0x59,0x6f,0x42,0x0e,0x6a, + 0x89,0x35,0x80,0xd6,0x81,0x0e,0x4e,0x88,0xba,0x19,0xe2,0x44,0x99,0xfc,0xb8,0x8a, + 0x3e,0x9e,0x25,0x69,0xa9,0x0a,0xcf,0xee,0xa5,0x35,0x8c,0x5b,0x20,0xb1,0x6c,0xa3, + 0x40,0x8d,0x43,0x9d,0x58,0xb7,0x1b,0xca,0x6e,0x74,0xe4,0xe7,0x4c,0x69,0xf4,0xd9, + 0x3f,0x29,0xca,0x9b,0xff,0xc9,0xab,0x85,0x25,0xdb,0x6a,0x89,0x0a,0x34,0xad,0xd5, + 0xb1,0x1c,0x0f,0x77,0x45,0x75,0xb7,0x7e,0xb3,0x6e,0xbf,0x7d,0xfc,0xf7,0xd9,0x7b, + 0x63,0x76,0xb8,0x2e,0x8b,0x0c,0xea,0xb4,0x90,0x57,0x3e,0xdf,0x96,0x43,0xd9,0x98, + 0xa8,0x62,0x86,0x10,0x2c,0x29,0x33,0x99,0x86,0x20,0x78,0xdf,0x7a,0x55,0xf0,0xa2, + 0x5e,0xee,0x93,0xf9,0xa3,0x1c,0x35,0x9c,0xc7,0x8f,0xca,0x93,0xdc,0xcd,0xb8,0xf8, + 0x7f,0xae,0x75,0x1b,0xbe,0xdb,0x06,0x0f,0x6b,0xa1,0xff,0xfe,0x0f,0x67,0x59,0xe6, + 0x67,0xb4,0x46,0x71,0x39,0x3b,0x77,0x82,0x8d,0x24,0xe1,0xe4,0x93,0x25,0xf9,0xc9, + 0xa6,0xf5,0xd1,0xe9,0xe7,0xbe,0x7f,0x32,0xbb,0x1a,0x7d,0x8a,0x47,0x22,0xea,0x59, + 0x74,0xef,0x4b,0x9e,0xcf,0x9d,0x17,0x95,0xb1,0x02,0x00,0xb4,0xd8,0x5b,0x6a,0xd0, + 0xec,0xac,0xdf,0x6d,0x23,0x77,0xd5,0x62,0x6e,0x5e,0xde,0x73,0xf0,0x64,0x7a,0x5b, + 0xf0,0x43,0x26,0x8f,0x16,0x71,0x8d,0x44,0x78,0xbe,0x79,0xba,0xf5,0x5f,0x6e,0xfa, + 0x2f,0x5b,0x76,0x51,0x8b,0xe5,0x34,0x22,0x33,0x89,0x25,0x4b,0xa5,0xb7,0xbb,0x48, + 0x89,0x8c,0xbc,0x3a,0x5b,0x6b,0x3c,0x3b,0x61,0xfe,0xbe,0x02,0xa1,0x80,0x64,0x36, + 0xdf,0xe4,0x14,0xfd,0x61,0xc2,0x52,0xf2,0xa5,0xcc,0xb2,0x04,0xda,0xf6,0x36,0x7b, + 0x91,0x00,0xdd,0x2e,0x72,0xcf,0x07,0x7d,0x3d,0x15,0xeb,0x4a,0xcb,0x20,0x90,0xf2, + 0xb7,0xcc,0x4c,0xd9,0xbc,0x81,0x8c,0x00,0x08,0xa9,0x2a,0xd0,0x9c,0xbb,0x94,0x4e, + 0xba,0x81,0xe3,0x53,0x28,0x39,0x11,0xc5,0x3c,0xb1,0xbf,0xd0,0x52,0x5b,0xa9,0x49, + 0x6b,0xd9,0xf9,0x55,0xe7,0xde,0x88,0xef,0xc7,0x40,0xc7,0x02,0x47,0x62,0x5e,0xb5, + 0x83,0x9f,0xa0,0xe5,0xba,0x89,0x8f,0x52,0xf3,0xa2,0xb7,0x16,0x94,0x4b,0xae,0x62, + 0xb6,0x14,0x71,0xfd,0xb4,0x4a,0xbd,0x80,0x59,0x6a,0x7c,0xb8,0x1d,0xcd,0x33,0x19, + 0xd3,0xfb,0x8e,0xde,0xeb,0xdc,0xe7,0x86,0xa7,0x65,0x4d,0x8e,0x9c,0x73,0x2a,0x13, + 0x0b,0x28,0xe4,0xa6,0x3e,0x1c,0xfe,0xae,0x6b,0xa1,0xcc,0x5f,0x49,0xe8,0xfe,0xd6, + 0xd1,0x66,0x43,0xf5,0xe7,0x39,0xd7,0xd9,0x58,0x5e,0x27,0xeb,0xe7,0x74,0x54,0x41, + 0x50,0xae,0x98,0xd0,0x76,0x8e,0xa0,0x72,0xef,0x83,0x78,0xdb,0xaf,0x8e,0x7c,0xe8, + 0x02,0x5f,0xdf,0xb7,0xaf,0xa7,0x5b,0xee,0x4e,0xef,0xc4,0x3f,0xc6,0x9d,0x1f,0x17, + 0x8d,0x1b,0xe5,0xff,0x35,0x2e,0x12,0xcd,0xe0,0xb8,0xd3,0xd0,0x7e,0x0a,0xb8,0x35, + 0x8a,0x56,0xb7,0xcb,0x0d,0xa7,0xc4,0x6a,0x8f,0x62,0xcc,0xb5,0xb3,0xde,0xdd,0x00, + 0xae,0xca,0x74,0x62,0xbc,0x27,0x40,0x58,0x20,0xf9,0x74,0x1f,0x8f,0xa1,0x85,0xe3, + 0xe1,0x18,0x74,0x17,0x9e,0xee,0xe2,0x5e,0x59,0x64,0x81,0xf6,0x73,0xfb,0xf7,0x6f, + 0x7c,0x78,0x1b,0x60,0x48,0x89,0x5e,0x72,0x61,0x47,0x08,0x8f,0xb3,0xca,0x81,0xfa, + 0x94,0xf4,0x25,0xae,0xbe,0xa0,0x48,0xfb,0x31,0x0c,0xd7,0x7c,0x4f,0x20,0x1b,0x4c, + 0x97,0x82,0x35,0xd2,0x3d,0x90,0xd4,0x19,0x35,0xd6,0x4a,0xf4,0x81,0xb4,0xc2,0x6f, + 0x3f,0x75,0x6c,0xe6,0xd5,0x27,0x33,0x37,0x83,0xd9,0xeb,0x5f,0xfc,0x6f,0x8d,0xbc, + 0x42,0x4b,0x16,0xe1,0xce,0x2a,0xe8,0x23,0x9c,0xfd,0xcc,0x7b,0xa3,0x07,0x3f,0xc6, + 0xc6,0xdc,0xac,0x65,0x45,0xcb,0xdf,0x49,0xd9,0x27,0x33,0x1c,0x27,0xf7,0x0a,0xa4, + 0xc8,0x16,0xd7,0xab,0x6f,0x46,0x58,0xd0,0x8a,0x6e,0xed,0x27,0x0c,0x14,0xe0,0xbb, + 0x0a,0xac,0x59,0x90,0xcf,0x3c,0x3b,0x99,0xc8,0xb4,0x3a,0xd8,0xf8,0xb5,0x5d,0xec, + 0xd2,0x41,0x25,0x79,0xe9,0xe3,0xf0,0xc9,0x99,0xfa,0x7c,0x49,0xb9,0x34,0x72,0xc2, + 0xaa,0x2a,0x5a,0x3f,0xc3,0x93,0x30,0x15,0xcd,0xaa,0xe4,0xa2,0x55,0x6b,0xf3,0xc9, + 0xd0,0xbe,0x8a,0xd4,0x90,0x10,0x35,0x86,0x47,0x9c,0xc0,0x45,0x4c,0x6c,0x70,0xb9, + 0xc2,0x3f,0x41,0x0c,0x01,0xa2,0x0a,0xbb,0xb4,0xd5,0xd4,0x01,0xe7,0xad,0xd6,0x6d, + 0xfa,0x69,0xfb,0x6f,0xd2,0x9e,0x2d,0x80,0x45,0x09,0x97,0xb3,0x77,0xd9,0xb7,0xb6, + 0xf9,0x25,0xda,0x82,0x76,0x47,0x3d,0xce,0xf6,0x50,0xc8,0xf3,0xc1,0xb6,0x6d,0xf4, + 0x28,0x2c,0xb3,0x52,0x1e,0xa6,0xc5,0xe6,0x65,0x1f,0xab,0x6f,0xab,0xa9,0x89,0x23, + 0xfb,0xd9,0x81,0x62,0xb2,0x75,0x6b,0xf2,0xff,0x4f,0x17,0x67,0xd3,0x23,0xe0,0x55, + 0x31,0xb3,0x8f,0x5f,0x03,0x6b,0x82,0x9c,0x02,0xd9,0xc1,0xac,0xbf,0xf7,0x7c,0xdb, + 0xd6,0x07,0x10,0x19,0x48,0x0a,0xf5,0x8d,0x90,0x6b,0x5c,0xd6,0x77,0xdf,0xa2,0x67, + 0xba,0x2a,0x63,0xaa,0xd7,0xc6,0x2b,0xc4,0xab,0x14,0x10,0xcb,0x92,0x43,0x75,0x45, + 0x6f,0x43,0xb1,0x52,0x5c,0x86,0x43,0x6a,0xd3,0x2a,0xbc,0xc2,0x39,0x14,0x5f,0xc9, + 0x7a,0xbe,0x71,0xbd,0xc7,0x16,0xc7,0xe8,0xf0,0x60,0xb6,0x2b,0x48,0x4d,0x78,0x8a, + 0xfa,0x9a,0xde,0xfb,0x0e,0xe1,0x5f,0x79,0x4f,0x78,0xe1,0x75,0xdc,0x53,0xf4,0xe1, + 0xd8,0x3c,0xde,0xdd,0xe3,0x99,0xf9,0x1a,0xec,0x88,0x77,0x93,0xc5,0xb1,0x97,0x8d, + 0xc6,0xbf,0xb3,0x74,0x3f,0x73,0xe7,0x30,0x33,0xe9,0xb5,0xac,0xff,0xd2,0x75,0x46, + 0x3d,0x38,0xc0,0x0c,0xf8,0xe3,0x7d,0x60,0xf8,0x9f,0x81,0x6a,0x80,0x1b,0x76,0xc2, + 0x84,0x8e,0x06,0xa4,0xe6,0x98,0x71,0x16,0xdc,0x27,0xd0,0x60,0xab,0x6a,0x8b,0x34, + 0xbb,0x7d,0xeb,0xf2,0x0d,0x32,0x02,0xed,0x13,0x5d,0xaa,0x41,0x16,0x69,0xf4,0x4a, + 0x07,0xf7,0x38,0xff,0x17,0x9c,0xe4,0x93,0x09,0x89,0xd1,0x11,0xa1,0x67,0xca,0x0b, + 0xaf,0xa1,0x45,0xca,0xdd,0x5b,0x27,0x41,0xb8,0xb9,0xfc,0x92,0xf4,0x6d,0xc6,0x2a, + 0xd5,0xef,0xe4,0xed,0xf2,0x39,0x84,0xea,0x79,0x9f,0x65,0x63,0x2c,0x8b,0xae,0xe7, + 0x59,0x79,0xd6,0x87,0x7a,0x37,0x4b,0x3c,0x2c,0xdc,0xbe,0x8a,0xb3,0x51,0x20,0x02, + 0x34,0x30,0x4a,0xc3,0xd2,0xb5,0x0a,0x54,0xf5,0x93,0x34,0x07,0xe1,0x3b,0x3f,0xa2, + 0xb0,0xa2,0xb3,0x25,0x4a,0x7d,0x54,0xeb,0x62,0xd4,0x37,0xad,0x78,0x83,0x7b,0x30, + 0x34,0x3b,0x9d,0x5b,0x47,0xe0,0x69,0x40,0x17,0xb9,0x89,0x45,0x7a,0x7f,0x34,0x77, + 0x56,0xe0,0x83,0x60,0x52,0xa8,0x32,0x2b,0x75,0xbc,0x93,0xdb,0x4d,0x23,0x03,0xab, + 0x85,0x68,0xa7,0xd6,0xc1,0x86,0x5a,0x48,0xc3,0x0a,0x59,0x74,0xf8,0x47,0x7d,0xa7, + 0x5f,0xd0,0xcb,0x3c,0xed,0xc4,0x46,0x15,0x51,0xac,0xce,0x72,0x9c,0x7d,0x2c,0xf3, + 0x2b,0xb5,0x1e,0x55,0x69,0x46,0xa3,0xc3,0x18,0x87,0x4a,0x59,0x66,0xf9,0x17,0xfb, + 0x08,0x25,0x6b,0x25,0x55,0xfc,0xa1,0xac,0x2d,0x7a,0x89,0xf5,0x71,0x46,0xe8,0x16, + 0xc1,0xc5,0x4a,0xfe,0xb8,0xfa,0x4e,0x2b,0x54,0x05,0x1c,0xfb,0xe2,0x43,0xe4,0xdb, + 0x31,0xb4,0xbe,0x38,0xc2,0xc3,0x6b,0xfd,0xb0,0x9f,0x5d,0xfa,0x12,0xec,0x1e,0xaa, + 0x2e,0xc9,0xad,0x93,0xd5,0x16,0x06,0x2c,0xef,0x9f,0xad,0x0b,0x98,0xc8,0xf2,0x11, + 0xa2,0x52,0xde,0xaa,0x86,0x77,0xcb,0x0b,0x9e,0x24,0xc1,0xc5,0xef,0xe2,0xd9,0xf3, + 0xd2,0xf3,0xa1,0xf4,0x4a,0x96,0x2d,0x14,0xf8,0x81,0x81,0x85,0xbd,0x74,0x77,0x52, + 0x7c,0x82,0x4c,0x0e,0x38,0x9e,0x3b,0x07,0x0d,0x47,0xc5,0xb9,0xbf,0xc1,0x15,0x0f, + 0xba,0x01,0x7c,0x62,0x13,0x75,0x3f,0x11,0x14,0x5b,0x01,0x89,0xfb,0xd6,0x3e,0x64, + 0x9c,0xe1,0xa3,0x53,0xd6,0x82,0xa0,0xb0,0x4d,0x7c,0xac,0xaf,0x50,0x75,0x46,0xbf, + 0x84,0x23,0x72,0x06,0x1d,0xf8,0xf2,0x45,0x50,0xa3,0x14,0x3e,0x8a,0x16,0x90,0x26, + 0xeb,0xe9,0xbb,0xf4,0x21,0x23,0x91,0x3b,0x24,0x7d,0x52,0x33,0x01,0xac,0x57,0xf2, + 0xd2,0x52,0x5f,0x1c,0x59,0x22,0x70,0x20,0x8d,0x58,0xd3,0xb1,0x32,0xa1,0x0d,0x19, + 0x51,0x33,0xd7,0x9d,0x99,0xa8,0x42,0xc9,0x8a,0x42,0x95,0xc0,0x88,0x28,0x5c,0xe1, + 0xb4,0xc5,0xc4,0xd5,0xb2,0x17,0x4d,0xcf,0x77,0xd3,0x15,0xa3,0x9b,0x15,0xda,0xae, + 0x02,0x3f,0xb6,0x72,0x04,0x45,0x9d,0x27,0xb4,0xf1,0x24,0x38,0xfd,0xe1,0xfe,0x6a, + 0xae,0xae,0xd4,0xf3,0xb2,0x60,0x6d,0x5e,0x79,0xd4,0xa1,0xf6,0xe4,0x48,0x31,0x4e, + 0x7d,0x8d,0x41,0xcb,0xf5,0x4e,0xc2,0x91,0x73,0x1c,0x31,0x8f,0xab,0x3e,0xc8,0xd8, + 0xad,0x89,0x4e,0x5f,0xb6,0xde,0x6d,0x44,0x78,0xd1,0xa6,0x8a,0x73,0x84,0xe3,0x41, + 0x9b,0x0b,0x9b,0x68,0xbc,0xe3,0x27,0xa3,0xa3,0x9f,0xb1,0x8b,0x5a,0x27,0x7d,0xf8, + 0xff,0xe8,0x5d,0x3a,0x64,0xa9,0x2c,0xf8,0xd1,0x4e,0xe4,0xe8,0xa2,0x9f,0x43,0x28, + 0x6d,0x42,0xad,0x10,0x52,0xd2,0x7e,0xd0,0x0e,0x70,0x28,0xb2,0x9d,0x0d,0x6e,0x61, + 0xdc,0xaf,0xcd,0x61,0x3a,0xb0,0x95,0xe9,0x3a,0x1e,0xba,0x39,0x9e,0xb9,0x9c,0x52, + 0xf6,0x70,0xb0,0x9b,0x51,0x5b,0x4b,0x47,0x8c,0x8b,0xcf,0x7b,0x76,0x18,0x1f,0xd0, + 0x90,0x42,0xa8,0x8d,0x29,0x9f,0xa8,0x8a,0xc0,0xf1,0x88,0xcf,0xd3,0x63,0x32,0x25, + 0x8c,0xad,0x3c,0x26,0x2c,0x97,0x2f,0x6d,0x71,0x79,0x39,0x3a,0x2a,0x89,0xb3,0x9f, + 0x77,0x7f,0x74,0x18,0x66,0x7a,0xad,0xe4,0xdd,0x54,0x71,0x15,0x7c,0x21,0x39,0xa4, + 0xb1,0x73,0xa9,0x76,0xf5,0x08,0x4f,0xea,0x06,0xe1,0x3a,0x04,0x02,0x00,0xef,0x5a, + 0xac,0x38,0x93,0xee,0x3b,0xc7,0xdf,0xb6,0x3e,0x02,0xe8,0xdd,0xcd,0xd2,0xf2,0x72, + 0xc6,0x8f,0xf1,0x82,0x44,0xc9,0x12,0xb8,0xc1,0xbe,0x1f,0x91,0x8b,0x8c,0xae,0xc8, + 0xf6,0xed,0x63,0x9a,0xa7,0xed,0xd3,0x77,0x8b,0xad,0x7d,0x92,0xb0,0xc3,0x69,0x35, + 0x96,0xc9,0xed,0xdd,0x8b,0x85,0xf1,0x2d,0xaa,0xd0,0x01,0x79,0x69,0x78,0x09,0x6d, + 0x41,0xfe,0x54,0x62,0xb3,0xd1,0xbc,0xba,0xfb,0x64,0x40,0x89,0x72,0x22,0x61,0xec, + 0xbb,0x27,0xf4,0x4e,0x0a,0x52,0xdb,0x43,0xae,0xe4,0x72,0x4f,0x1d,0x4c,0x0d,0xe8, + 0x43,0xb4,0x52,0xb2,0x74,0x8e,0x40,0xa8,0xcd,0x87,0xb7,0x97,0xaf,0xc5,0x14,0x17, + 0x0a,0x44,0xcc,0xdb,0x49,0xb0,0x6d,0x16,0xe0,0x17,0x28,0xda,0xcd,0x9f,0x20,0x15, + 0x48,0xce,0x3e,0x5d,0x0f,0x06,0x74,0xff,0x5b,0xda,0x7f,0x01,0x4f,0xad,0x3e,0xab, + 0x9c,0x4c,0x37,0x63,0x15,0xff,0xc7,0x39,0x9c,0x40,0xd2,0xc5,0x6c,0x8b,0x76,0x13, + 0x82,0x54,0x76,0xc0,0x55,0xa6,0xad,0x47,0x73,0xde,0xc3,0xe9,0xe6,0xc5,0x9c,0xdf, + 0xb5,0x1e,0xf5,0x66,0xaa,0x79,0x3e,0x61,0xfd,0x64,0xce,0x9d,0x61,0xa2,0x9e,0xad, + 0x5a,0x0b,0x97,0xd3,0xb9,0x57,0xc7,0xc5,0xff,0x11,0xd4,0xa0,0xf3,0x22,0xb0,0x5e, + 0xcb,0xf6,0x54,0xf5,0xb6,0x36,0x33,0x64,0xdb,0xcf,0x8b,0x55,0x2f,0xbe,0x21,0x56, + 0xd0,0x6b,0xb8,0x5d,0xa4,0x2c,0xd7,0xf7,0x75,0x24,0xee,0xa8,0xd0,0x8b,0x1f,0x4d, + 0x9a,0xa5,0x69,0x62,0x99,0x0f,0x5c,0x7b,0x34,0xcc,0x2e,0x9c,0x2d,0x81,0x2e,0x03, + 0x70,0xa6,0xb8,0x2c,0x47,0x7f,0xa5,0x61,0x17,0xb4,0xcf,0xf6,0x6c,0x9d,0xbb,0xc3, + 0xc1,0xf4,0xd7,0x06,0x95,0x67,0xa4,0x79,0xa8,0x06,0x4b,0xa6,0x97,0x63,0x35,0x96, + 0x02,0x3c,0xae,0x5b,0xf7,0x18,0x52,0x3b,0x97,0x7e,0x97,0x80,0xfd,0x69,0x3e,0xc1, + 0x5f,0x51,0x62,0x00,0xce,0x9e,0x57,0x22,0x62,0xeb,0x03,0x63,0x92,0x42,0x5e,0x9d, + 0x7d,0x07,0x23,0x91,0xfc,0xaa,0x84,0x4d,0x81,0xae,0x07,0x3c,0xe5,0x3c,0xd4,0xf2, + 0x79,0xc0,0x5f,0x4c,0x43,0x8c,0x49,0x23,0x47,0xfa,0x64,0x82,0x14,0x41,0x7b,0x7a, + 0x48,0xe5,0x12,0x44,0xde,0xfc,0x8f,0x50,0xfa,0x76,0xc4,0x94,0x97,0x93,0x0d,0x49, + 0xa8,0xe4,0x02,0xf4,0xad,0x93,0x08,0x04,0xa8,0x6c,0x84,0xd8,0x73,0xcd,0x8a,0xd0, + 0x63,0xca,0x44,0x80,0xf2,0xf9,0x88,0x72,0xf6,0xfb,0x58,0x65,0xa5,0x4d,0x84,0xbe, + 0x58,0x7c,0x8c,0xf1,0x3f,0x6c,0xb4,0x63,0x1d,0x2a,0x18,0x6d,0x6a,0x4b,0x40,0xd5, + 0xb9,0x00,0x15,0x55,0x2c,0xac,0x40,0xbb,0x22,0x64,0x03,0xae,0x6b,0xd6,0xb4,0x30, + 0xa1,0x3f,0x1b,0x55,0x77,0xe5,0x4d,0xa8,0xd8,0x86,0xda,0x10,0xe5,0xec,0x5a,0x23, + 0x23,0xaa,0xa9,0x56,0x56,0x68,0x4a,0x33,0x44,0x1d,0x89,0xad,0x09,0xa0,0x6f,0x48, + 0x8d,0x4e,0x93,0xaa,0xbd,0x8c,0x5e,0xaa,0x45,0xb0,0x1f,0x8a,0x27,0x97,0xad,0xaa, + 0xa9,0x94,0xdb,0x8f,0x81,0x93,0x3d,0x04,0x3a,0x19,0x4c,0x34,0x99,0xb8,0x54,0x84, + 0x79,0x57,0x0d,0x5a,0x3f,0x3a,0x96,0x7f,0x05,0xd1,0xc3,0xb5,0xa3,0x61,0x33,0x09, + 0xf8,0xce,0x91,0x13,0x66,0xf2,0xe1,0xa2,0x53,0x25,0xed,0xc2,0xa5,0x42,0xcb,0x27, + 0xd0,0x58,0x46,0x31,0x1f,0x96,0x44,0x10,0x79,0xb7,0x1d,0x2b,0x62,0x2a,0x85,0x4b, + 0x36,0xb6,0x23,0x8b,0xaf,0xfc,0xe0,0xee,0x69,0x8e,0xd7,0x9b,0x51,0xb5,0xe2,0x36, + 0xba,0x8b,0xb2,0x76,0xbe,0x43,0xfd,0x0a,0x63,0x03,0xa2,0x28,0x8b,0x00,0xa1,0x77, + 0x14,0x46,0x44,0x69,0x18,0x64,0x84,0xc8,0xf6,0x07,0x3d,0x0b,0xd0,0x9f,0x4a,0xd9, + 0xa8,0x07,0xca,0x11,0xa0,0x69,0x0d,0x11,0x6a,0x40,0xbf,0x08,0x92,0x21,0x7a,0x5e, + 0x0b,0xe5,0xbc,0x16,0xec,0xe3,0xe2,0xc1,0xb1,0x64,0x95,0x59,0x53,0x9e,0x92,0x79, + 0x95,0xc3,0xed,0x91,0xaf,0xf2,0x15,0x9e,0x53,0x78,0x25,0xc9,0xcd,0x4f,0xe9,0xfc, + 0x2a,0xa9,0x9d,0x8d,0x35,0x4f,0x82,0x28,0x81,0x46,0x4d,0xd1,0x01,0xb0,0xa0,0x83, + 0x86,0x1b,0x51,0x1a,0x5c,0x21,0x44,0xbb,0xd4,0xc6,0x9f,0x01,0x8c,0x6f,0xb7,0xcf, + 0xad,0xaf,0x7d,0xb8,0x54,0x7f,0x10,0x05,0xd5,0x0f,0xdd,0xe7,0x1b,0xb5,0x09,0xe4, + 0x5a,0xc8,0xeb,0xc4,0xea,0x71,0x74,0x6b,0xa4,0xb4,0x17,0xc9,0xe8,0x68,0xda,0xf4, + 0x0b,0x5a,0x46,0x1b,0xce,0xb4,0x96,0xd8,0xa5,0x86,0x6e,0xed,0x91,0x5b,0x27,0xb6, + 0x9d,0x67,0xb8,0x37,0x3a,0x28,0x05,0x16,0x8a,0x6d,0x06,0x3f,0x4a,0x68,0x2f,0x6f, + 0xd4,0x1c,0x5f,0x22,0xd9,0xcf,0x70,0x75,0x4c,0xd3,0x55,0xda,0x75,0x54,0xf2,0xfe, + 0xae,0xbc,0xc8,0x63,0x25,0x75,0xbf,0xd8,0xd9,0x83,0x0e,0x24,0x70,0xe8,0xd5,0xf3, + 0x73,0x97,0xb6,0x39,0x81,0xd8,0xad,0xc8,0x17,0x79,0xdb,0x79,0x7e,0xae,0xed,0x71, + 0x73,0xcf,0x73,0x6a,0xe8,0xe7,0xcd,0x1f,0x63,0x1f,0x2f,0x39,0x12,0x31,0x9a,0x80, + 0x44,0x14,0x74,0x99,0x57,0x33,0x15,0xbb,0x47,0xc5,0xf7,0x29,0x1e,0x5b,0x5d,0xdc, + 0x1b,0x5f,0x20,0xd3,0x08,0x8b,0x6a,0x0b,0xaf,0xc7,0xcb,0x61,0x10,0x96,0xa4,0x22, + 0x14,0x73,0x6e,0x37,0x60,0x1f,0x22,0x5e,0xc6,0x34,0x12,0x2c,0x2d,0xb9,0x3a,0x90, + 0xa4,0xf7,0x7e,0x91,0x55,0x1b,0xd9,0xea,0xde,0x88,0xbc,0xc4,0x4b,0x4e,0xa1,0x55, + 0xbd,0x21,0x61,0x73,0x81,0x7c,0x7e,0x15,0x08,0xcb,0x89,0x02,0xdb,0x73,0xaf,0xdf, + 0xd2,0xcc,0x7a,0x67,0x5f,0xd9,0xcc,0x32,0x8c,0xbe,0x7b,0xb6,0xd4,0xaf,0x86,0x16, + 0x95,0xf5,0xc8,0xf2,0x51,0x79,0x3d,0xf5,0x4e,0xe0,0x08,0x1b,0x88,0x9a,0xb8,0xa8, + 0xdd,0xa5,0xd6,0xd2,0x93,0xec,0xf7,0xec,0x98,0x68,0xa4,0xe2,0x95,0x0f,0xac,0xb2, + 0x78,0x45,0x1b,0x84,0x97,0x7d,0xb5,0xe6,0xb8,0xa8,0xd4,0x4e,0xd8,0x46,0xb5,0xcc, + 0x66,0xaf,0x7d,0x26,0x36,0x2f,0x3e,0xb8,0x35,0x20,0x38,0x8f,0xe4,0xb3,0xd5,0x9e, + 0xc7,0x99,0x56,0x98,0x37,0xb6,0x11,0x91,0x30,0x80,0xda,0x54,0xfe,0xe7,0x8a,0x2a, + 0xbc,0xb4,0xb2,0x33,0x1d,0x8e,0xc0,0x23,0xc6,0x62,0x0d,0x36,0x69,0x04,0x79,0xfa, + 0xfe,0xe9,0x17,0xa7,0x79,0xf5,0x57,0xaf,0xbd,0x71,0x4a,0xd6,0x66,0xf3,0xa0,0x93, + 0x1e,0x2f,0x3f,0xb2,0xe3,0x4a,0xa2,0x24,0x42,0x80,0xb5,0xd1,0xc5,0xb5,0x15,0x55, + 0x7c,0xae,0xa3,0x36,0x1d,0xb1,0xae,0x78,0x90,0x98,0x4b,0x73,0xfd,0x5c,0x99,0x76, + 0x2c,0x52,0x52,0x8d,0x6c,0x85,0xde,0xfc,0x4b,0x78,0x69,0xda,0x95,0x29,0x62,0x19, + 0xf6,0xdd,0x2b,0xbb,0xcb,0xf3,0xbe,0xd0,0x72,0x39,0x54,0x9a,0x80,0xf2,0x4b,0xc7, + 0xf7,0x54,0x0e,0x3f,0xfc,0xd5,0x03,0xb0,0xd4,0x4d,0x5d,0x10,0x65,0xa5,0x3e,0x88, + 0x4a,0x79,0x1f,0xb9,0xee,0x8e,0xb3,0xad,0xe9,0x1b,0x50,0xeb,0x76,0x64,0x39,0xd9, + 0xa9,0x93,0xae,0x05,0x20,0x76,0x26,0x54,0xbc,0x12,0x95,0xb6,0x39,0xd0,0xa3,0x78, + 0x27,0xf2,0xa6,0x03,0x91,0x46,0xef,0xfd,0x91,0x87,0x92,0xb0,0xfc,0x2d,0xc1,0xdd, + 0x1e,0x68,0xb0,0x73,0x27,0xbb,0x4a,0xa7,0x7b,0x89,0xd0,0xb5,0xae,0x17,0x26,0x65, + 0xa6,0x84,0x0f,0xd6,0x8c,0x23,0x84,0xd7,0xdc,0x86,0x2f,0x0c,0x0c,0x2f,0xa8,0x71, + 0x22,0x44,0x92,0xf6,0x88,0x02,0x8a,0xbe,0xd9,0xd4,0xcc,0x75,0xa1,0x68,0x26,0xf1, + 0xbf,0x56,0xde,0x61,0x76,0x0c,0x5c,0x07,0x13,0x9f,0x5b,0xda,0x8a,0xd8,0x07,0x02, + 0x66,0x4c,0x05,0x3d,0xa7,0x55,0x0c,0xc0,0xb5,0x2d,0x0b,0xff,0x96,0xa7,0xfd,0x19, + 0xec,0xc2,0x4b,0xd0,0xe6,0x7b,0x40,0x5b,0xea,0x4f,0x8d,0xfa,0xb6,0x0f,0xed,0x08, + 0x80,0x09,0x1a,0x0e,0xb3,0x8c,0xef,0x65,0x4e,0x67,0x33,0x31,0x05,0x58,0x63,0x8b, + 0x86,0x7d,0x93,0xc4,0x52,0xae,0xaf,0x04,0x45,0x43,0xc9,0xa2,0xb8,0x44,0x8c,0xa0, + 0x4f,0x34,0x60,0x0b,0xcf,0x7a,0x54,0xef,0xae,0x4b,0x02,0x82,0xd3,0xc5,0x8e,0x69, + 0xca,0x43,0xf0,0xca,0x9e,0xbc,0x47,0x4a,0xfb,0x4f,0xa6,0x10,0x65,0xb4,0x78,0xd1, + 0x59,0xbb,0xf6,0x62,0x9f,0x8a,0xae,0x86,0x29,0x5f,0xb4,0x48,0xcb,0x60,0x4e,0xfa, + 0x16,0x29,0x8e,0xb1,0x3c,0xd7,0x24,0x30,0x47,0xb5,0xea,0xe9,0xe8,0x93,0x42,0x5e, + 0x8b,0xa7,0x92,0x4b,0xda,0x5d,0x3e,0x33,0x7f,0xda,0xef,0x7c,0x57,0xda,0x11,0x42, + 0x0e,0x58,0xc4,0x24,0x43,0x42,0x07,0x2d,0x31,0x1a,0x27,0x07,0x07,0x65,0x3b,0x5b, + 0x35,0x85,0xd3,0x60,0xf7,0x8a,0x99,0xba,0x08,0x15,0x1f,0x8d,0x40,0xcd,0xfc,0x81, + 0xf6,0x31,0x13,0xfa,0x3c,0xb7,0x45,0x15,0x54,0x1d,0xe2,0xf3,0x43,0xc5,0xe7,0xf2, + 0x4b,0x62,0xd5,0x4d,0xfc,0x2f,0xae,0xba,0x92,0xc8,0x5a,0x8c,0x05,0xc3,0xed,0xce, + 0x2e,0x76,0x33,0x8f,0x75,0x0d,0xbc,0x79,0xd4,0x6b,0x03,0xd3,0x01,0x4d,0xad,0xab, + 0xdb,0xa6,0x93,0xfb,0x78,0x5f,0x3e,0xb4,0x95,0x4e,0x69,0x9a,0x97,0x0d,0xa4,0xcf, + 0xa3,0x1e,0xa8,0xa4,0xfa,0xc4,0xee,0xc1,0x72,0x07,0x55,0x82,0x7e,0x42,0x94,0x59, + 0x20,0x32,0x72,0xcc,0x0c,0x88,0xa0,0xa3,0x1f,0xc6,0x8b,0xb9,0x0f,0x6a,0x1e,0xfd, + 0xc1,0x73,0xa0,0x09,0x95,0x63,0x49,0x9d,0xaa,0x51,0xdc,0x38,0x33,0xd5,0x31,0x52, + 0x10,0x01,0xa0,0x90,0x78,0xcf,0x6b,0x3c,0xae,0x2a,0x67,0xbf,0x42,0x74,0xb2,0x9b, + 0xaf,0x7e,0xbf,0x97,0xdd,0xd1,0x52,0xac,0xcc,0x90,0x8d,0x24,0xd8,0xfc,0x5b,0x51, + 0x77,0xfd,0x59,0x0f,0x28,0x87,0x3f,0x36,0x1e,0xc3,0xaf,0x1c,0xb1,0xab,0xfd,0x12, + 0xdc,0x48,0x81,0x60,0x10,0x0f,0xf8,0xab,0x52,0x6b,0xf0,0x6d,0x9f,0x8b,0x3c,0xa8, + 0x59,0xd6,0x4a,0xb8,0x18,0x4d,0x54,0x33,0x8a,0xe0,0x6e,0xf1,0xc1,0xa1,0x71,0x7a, + 0x86,0x06,0x91,0xc0,0x96,0x7b,0x3e,0xd8,0xf1,0x90,0x70,0x97,0x22,0x08,0x27,0x32, + 0xcf,0x0f,0x0d,0x56,0xd5,0xe6,0x76,0x1a,0xcc,0x1c,0x7b,0x69,0x44,0x7a,0xc1,0xdb, + 0x3a,0xfc,0x40,0x0d,0x03,0x3d,0x78,0xbb,0xfc,0xe5,0x07,0x48,0xbb,0xb8,0x48,0xed, + 0x04,0xfa,0x7b,0x73,0xea,0x26,0xd9,0x1f,0x40,0x0a,0xed,0x10,0xf0,0x40,0x7e,0x5a, + 0xd8,0x6c,0xf7,0x10,0xe0,0x2a,0x60,0x02,0xc4,0x7f,0x3f,0x76,0xe4,0x39,0x4b,0x8e, + 0x40,0x53,0x16,0x71,0x82,0x11,0x9b,0x2f,0x14,0x52,0xb9,0x46,0x9d,0x43,0x72,0x4d, + 0x36,0x8b,0x9d,0xa4,0x01,0x5a,0x83,0x44,0xb9,0xc9,0x6e,0x57,0xdf,0x29,0x0f,0x03, + 0x66,0x23,0x7f,0xd7,0x1d,0x2e,0x1e,0xea,0xf0,0x34,0x1e,0x5d,0x8e,0xa9,0x49,0x9f, + 0xc3,0x13,0x99,0x2a,0x2d,0x65,0x40,0x23,0xfe,0xbd,0xc3,0x2b,0x3a,0x56,0xf6,0xb6, + 0x3f,0xbd,0xa8,0x66,0xff,0x89,0x19,0xa9,0x05,0xbb,0xa7,0xf7,0x09,0xb9,0xbd,0xaf, + 0xb5,0x4e,0xc0,0x56,0x7d,0x34,0x06,0xcf,0x50,0xb4,0xa2,0x40,0xe7,0xd3,0x3d,0x03, + 0xe5,0xbf,0xea,0x77,0x81,0x83,0x6b,0x1d,0xfa,0xc8,0xe5,0xdf,0xa7,0xe5,0x33,0x64, + 0xab,0x2c,0x4d,0xcf,0x14,0x1d,0x8f,0xfb,0x25,0xdc,0xa3,0xdf,0x05,0xa3,0x24,0x8f, + 0xb1,0x2b,0x94,0x37,0x3b,0xd7,0xd1,0xdb,0x2e,0x76,0x60,0x6a,0x58,0x2d,0xc5,0xff, + 0x33,0x05,0x10,0x95,0x8f,0xe7,0x04,0x7c,0x85,0xed,0x69,0x92,0xf6,0x51,0x78,0x51, + 0x5e,0xb5,0x6f,0xb0,0xea,0x41,0x46,0xcf,0xb5,0x86,0x98,0xfd,0x18,0xe6,0x3e,0x84, + 0xa0,0xe9,0x7e,0x04,0x18,0xa4,0xfc,0xb4,0xca,0xf4,0xe0,0x0d,0x6e,0xce,0x9d,0xfe, + 0xca,0x06,0xbc,0xd2,0x0e,0xac,0x2a,0x49,0xd1,0x6a,0xc2,0xbf,0xd6,0x36,0x16,0x5e, + 0x7f,0x65,0x5b,0x6a,0x48,0x5a,0xf1,0x9f,0x62,0xaf,0xbb,0xf5,0x0b,0x11,0x20,0x60, + 0x91,0x0c,0x45,0x03,0x25,0x43,0xa3,0x2a,0x85,0xe7,0x6c,0xb7,0xe6,0x72,0xa5,0xf1, + 0x4d,0x44,0x08,0x1b,0x09,0xfd,0x2e,0x99,0x2e,0xa4,0x80,0x58,0xfa,0xb7,0x36,0x06, + 0x42,0xb5,0x1e,0xff,0x4f,0xf6,0x4c,0x79,0xb3,0x55,0xbc,0x26,0x4d,0xad,0x19,0xb1, + 0x85,0xe8,0xa5,0xcc,0xa4,0x97,0x5f,0x48,0xad,0x38,0xb8,0x2a,0x7c,0xcb,0x20,0x43, + 0x59,0xb0,0x33,0x55,0xf2,0x01,0x0a,0x6c,0xa4,0x77,0xef,0xa0,0x4c,0xe9,0x1c,0x3a, + 0x65,0x8a,0x18,0x22,0xfb,0x10,0x6b,0x24,0x29,0x37,0x81,0xb1,0xee,0xc8,0x16,0x4b, + 0xbc,0x15,0xdb,0x64,0x0f,0xe6,0x7a,0x9e,0x35,0x6d,0xec,0xeb,0x16,0xfb,0x49,0xcf, + 0xaa,0xdc,0x17,0x7a,0x68,0xa9,0x56,0x95,0xc8,0x0a,0x10,0x97,0xd5,0xf7,0xfe,0xcc, + 0x18,0x26,0xad,0x81,0x09,0xb1,0xf4,0xa8,0x41,0x3e,0x17,0xea,0x63,0x4d,0x5c,0xd8, + 0x57,0x8c,0x28,0x71,0x00,0x4c,0x0a,0x80,0x24,0x90,0xa5,0x1a,0x54,0xdf,0x64,0x89, + 0x3d,0x13,0x46,0x40,0xe3,0x2e,0xd0,0xa8,0x80,0x17,0x14,0x21,0x91,0x3b,0x4d,0xc4, + 0x2a,0x93,0xbe,0x62,0xd9,0x68,0xfb,0xdf,0xfb,0x4d,0x99,0x5a,0xb3,0x2b,0x2b,0xbf, + 0xbc,0xed,0x9a,0xcb,0xe2,0x74,0xcf,0x00,0xae,0x8d,0x6c,0x85,0x8f,0xc1,0xd8,0x14, + 0x45,0xa8,0x5c,0xc7,0xc8,0x43,0x37,0x7a,0xc0,0xd7,0x3d,0x7b,0x53,0xe5,0xc3,0x49, + 0xd7,0x92,0x23,0x32,0xa9,0xc5,0x54,0xfe,0xd1,0xbd,0xbe,0x8a,0xe8,0x4c,0xaa,0x31, + 0xd2,0x8e,0x9f,0xc6,0xa2,0xb1,0xe3,0x7f,0x36,0x21,0xf9,0xce,0xef,0x99,0x1a,0x99, + 0xb9,0x59,0x5e,0x58,0x9f,0x4a,0x0b,0x70,0xa8,0x89,0xc0,0x1f,0x43,0x31,0xe3,0x03, + 0x9e,0x53,0x0d,0x85,0x58,0xe5,0x67,0x12,0x72,0x29,0xbc,0xc7,0x90,0x7b,0x11,0xbf, + 0xac,0x7a,0x3d,0x98,0x2f,0x0b,0x11,0x3a,0x2b,0x6b,0x31,0x8a,0x1a,0xd6,0x2e,0x7c, + 0xf9,0x5e,0x79,0x21,0x42,0x8c,0xb2,0x34,0x73,0x4a,0xd7,0xf5,0x53,0x96,0x97,0x36, + 0x1c,0x2d,0x89,0xc5,0x5b,0x0d,0xca,0x96,0xb5,0x31,0x9e,0x74,0x6e,0x51,0x30,0x4d, + 0xde,0x53,0x61,0x9c,0x34,0x2c,0xf8,0x95,0x7c,0x6d,0xd5,0xb3,0x3a,0x6c,0x2b,0x13, + 0x92,0x8e,0x51,0x71,0x03,0x95,0x01,0xa6,0xe5,0xda,0xea,0xb4,0xb3,0x5e,0x79,0x34, + 0x37,0x8c,0xaf,0xee,0xa2,0x04,0xa3,0xa9,0xc4,0x5a,0x19,0x29,0x6c,0x23,0x75,0x97, + 0xdf,0x82,0xe5,0xb6,0x7d,0xa9,0xdb,0x54,0x55,0xf3,0x57,0xf5,0x25,0x9a,0x99,0xd2, + 0x5b,0xda,0xd6,0x95,0x78,0x6a,0x6f,0xb4,0x70,0x3a,0x3f,0x3f,0x55,0x2b,0xf7,0xd8, + 0x27,0x5d,0x6d,0xa4,0x0c,0xd9,0x80,0xfa,0x8e,0x29,0xcc,0xb7,0xb9,0x7a,0x82,0x59, + 0xe8,0x14,0xbc,0x3e,0x62,0xa7,0x4f,0xe9,0x10,0xf0,0x42,0xad,0x1b,0xba,0xde,0x05, + 0xf6,0xda,0xae,0xa8,0x05,0xd1,0x50,0x80,0xda,0xfc,0x4d,0xbb,0x9a,0xa6,0xc2,0x2a, + 0x58,0x80,0xa2,0xa7,0xed,0x45,0xdb,0xaa,0x1b,0xf4,0x1f,0x8e,0x96,0x5a,0x61,0x96, + 0x03,0xbb,0xfd,0xda,0x78,0x5e,0x68,0x60,0x83,0x5d,0xf0,0x8b,0xe7,0x27,0xc7,0xa3, + 0xc3,0x27,0xf3,0xf9,0x9f,0x78,0xeb,0xd6,0xb2,0x6f,0x0d,0x06,0xad,0xa5,0x23,0xfb, + 0x63,0x81,0x55,0x6f,0x60,0x1f,0x86,0x38,0x1a,0xd1,0xd0,0x64,0x1a,0xd7,0xc9,0x87, + 0xfc,0x53,0x5d,0x4d,0xc3,0xe4,0xdc,0x35,0x8b,0x55,0x66,0x3b,0x6a,0x2c,0x7b,0x0d, + 0x65,0xa3,0xa6,0xdd,0x44,0x83,0xb8,0x51,0xf1,0xd4,0xad,0x51,0xb1,0x41,0x32,0x8f, + 0x8c,0xca,0x4b,0xd3,0x7b,0x52,0x80,0x80,0x9c,0x2c,0x16,0xf1,0x61,0x05,0x78,0x40, + 0x4e,0x9c,0xf7,0x1b,0x69,0x9d,0x2f,0x72,0x74,0xc8,0xe8,0xd2,0x71,0xd8,0x39,0x5e, + 0x24,0x11,0xce,0x8a,0x50,0x79,0x5d,0x77,0x28,0x55,0xe0,0xb3,0xfe,0xe2,0xbb,0x55, + 0xa1,0x8b,0xb5,0x0b,0xc2,0x46,0x40,0x6d,0xd2,0x66,0x47,0xcf,0x10,0xcf,0xaa,0x29, + 0x8f,0x8e,0x5d,0x5e,0x06,0x54,0xbb,0x21,0xcb,0xb4,0x92,0x6a,0x04,0x93,0x88,0x2e, + 0xf9,0xcd,0x90,0xc7,0x89,0xe3,0xf9,0xfc,0x4e,0xb9,0xf4,0xc9,0xb4,0x85,0xd1,0xc0, + 0x92,0x97,0x77,0xfe,0x03,0x30,0xfa,0x24,0x8b,0xad,0x38,0x7d,0xf8,0x01,0xba,0xfd, + 0x51,0xa2,0x15,0xb1,0xde,0x45,0x6d,0x55,0xc7,0xde,0x8e,0x95,0xed,0xda,0xbd,0x86, + 0x0e,0xa4,0x3b,0x2b,0x87,0xd9,0x9a,0xa6,0x67,0x51,0xc5,0xf8,0x7e,0xc6,0x5d,0x35, + 0x74,0x2b,0x6b,0x52,0x9d,0xa6,0xe4,0xa9,0xdb,0x38,0xb5,0xba,0x22,0x24,0x41,0x3d, + 0x09,0x65,0x71,0xa4,0x2b,0x5a,0x1f,0x09,0xea,0xc7,0x7d,0xa1,0x4a,0xc8,0xbf,0xad, + 0x3b,0xd2,0xdf,0xed,0xf5,0x2a,0x07,0x15,0xd9,0x35,0x8b,0x9c,0xc2,0x22,0x7d,0x16, + 0x37,0xde,0x56,0x41,0x44,0x47,0x5b,0xbc,0xc8,0x48,0xa7,0x3e,0x74,0x61,0xc7,0x8b, + 0xce,0x28,0x82,0xd7,0x9e,0x5e,0x5f,0xf1,0xc3,0x92,0x40,0xfc,0x1d,0xfd,0x28,0x52, + 0x82,0x6f,0x27,0xa7,0x62,0x61,0xa4,0x05,0xab,0xfc,0x40,0x42,0xad,0xe0,0xf2,0xb3, + 0x3d,0x3f,0xec,0xe7,0xd9,0xad,0x15,0xae,0x3d,0x3d,0x2a,0xb7,0x96,0x5e,0x7f,0xc1, + 0xf1,0x79,0x62,0x79,0xbc,0x2f,0x45,0x13,0xc1,0xeb,0x8d,0x79,0x60,0x93,0x7c,0xf5, + 0x56,0x84,0x56,0xf7,0x81,0xee,0xad,0x77,0x97,0x9e,0xde,0x36,0xf4,0x60,0x49,0xeb, + 0x3d,0x2d,0x22,0x04,0x6d,0xb6,0x3e,0x14,0x67,0x0b,0x12,0xc1,0xe6,0x9c,0x16,0x0a, + 0x16,0x53,0x82,0xd6,0x19,0x82,0x5d,0xd3,0x6e,0x72,0x49,0xe1,0xb0,0x50,0x4b,0x03, + 0xd7,0x60,0x7c,0x7f,0xa2,0xfa,0x98,0x06,0x43,0x5b,0xfd,0xcc,0xb7,0xec,0xe2,0xe1, + 0x3f,0x53,0xc8,0xb9,0x65,0xd9,0x75,0x5e,0x1d,0x09,0x89,0x7d,0xb8,0x58,0xe1,0xd7, + 0xe2,0x4c,0x51,0x57,0x7d,0x26,0x05,0x4b,0xf9,0xb1,0x96,0x1a,0x73,0xe8,0x34,0xb2, + 0xaf,0x9b,0xa9,0xc5,0x8d,0xbc,0xe5,0x7d,0xec,0xad,0xf5,0xd2,0x52,0xc3,0x91,0x16, + 0xc0,0xfd,0xd8,0xf9,0x8f,0xd0,0xad,0x8a,0x64,0xf2,0xac,0xb5,0xc6,0xc6,0xe2,0x51, + 0xbf,0x3d,0x56,0x45,0x6b,0x04,0x0d,0x90,0x56,0x6e,0x30,0xa7,0x1f,0xef,0xef,0xb7, + 0x1a,0xea,0x0f,0x7f,0x0f,0x67,0x3f,0x0b,0xe4,0xa2,0xea,0x80,0xa1,0x53,0x15,0x84, + 0x56,0xc8,0x6b,0x75,0xcb,0x2c,0xfd,0x7c,0xec,0xae,0xe3,0x2e,0x55,0x85,0x64,0x1e, + 0xb8,0x95,0x20,0x2e,0x6c,0xcb,0x48,0x48,0x5c,0x73,0x91,0x9d,0xbd,0xe8,0x33,0xa2, + 0x3f,0x20,0x8e,0x54,0x5e,0x44,0x4c,0x6e,0x6d,0xf2,0x0e,0xe1,0xb3,0x4d,0x2b,0x23, + 0x8b,0xed,0x18,0x4d,0x40,0x37,0x7a,0x3a,0xbe,0x44,0x19,0x8b,0xfa,0x62,0x5b,0x1e, + 0xf9,0xa8,0xaf,0x1c,0x87,0x54,0x3f,0x7b,0x7c,0xe2,0xa9,0xdd,0xfe,0xb8,0xc3,0xfd, + 0x5c,0xec,0xc2,0xae,0xf6,0x0e,0x65,0x27,0xaf,0x8d,0xbe,0xd2,0x5f,0xab,0xae,0x6c, + 0x2f,0x9e,0xb0,0xc6,0x73,0x29,0xdf,0x71,0x3e,0x35,0xf5,0x11,0x26,0x74,0x55,0x4a, + 0x90,0x32,0x40,0x42,0xf6,0xad,0x01,0xa0,0x45,0x7c,0x92,0xbd,0x7c,0x62,0xa9,0x10, + 0x49,0xf8,0xb7,0x1c,0xc1,0x5f,0x5b,0x8d,0xbb,0xce,0x3b,0x67,0x7b,0xf6,0xcd,0xb8, + 0x8b,0xf6,0x22,0x71,0xe4,0x33,0xa6,0x06,0x1f,0xdc,0xbf,0x8d,0x79,0xc7,0x92,0x38, + 0xce,0xcd,0x9c,0x66,0xee,0x1d,0xa9,0x04,0xd2,0x45,0x51,0xb1,0xed,0x9b,0xaa,0xee, + 0x1c,0x50,0x36,0x57,0xe3,0x02,0xb5,0x0a,0xea,0xc9,0x9f,0x93,0x73,0x4c,0xb1,0x2f, + 0x5d,0x49,0x9b,0x1a,0x5d,0x55,0x06,0x45,0x6c,0x7f,0x57,0x3f,0x0f,0xd6,0x06,0x01, + 0x79,0x6f,0xae,0xdf,0xb7,0x25,0x16,0x0f,0xfe,0xd3,0xf3,0x6f,0xb3,0x2a,0x6b,0xd6, + 0x6e,0x91,0xdb,0xb4,0xb6,0xab,0xc5,0xb9,0x93,0xa5,0x33,0x49,0x94,0xa4,0xe9,0x46, + 0x0e,0x6b,0x97,0xa7,0x22,0x3b,0x6e,0x3a,0xa7,0x9b,0x73,0xda,0x70,0x5c,0xd7,0x85, + 0x7f,0x20,0xa6,0x32,0x63,0xd9,0x63,0x9c,0x8a,0x0f,0x95,0xe0,0x14,0xac,0x5e,0x04, + 0xaf,0x08,0xaf,0x57,0x30,0xbe,0xe3,0x79,0x3f,0xdd,0xb4,0x4c,0x3e,0xa0,0x13,0x97, + 0x5d,0xe8,0x84,0x4d,0x9e,0x5a,0x4d,0xa8,0xea,0x82,0x60,0x01,0x1b,0x4b,0x46,0x91, + 0x2f,0x89,0xa7,0x3b,0xa7,0xdc,0xe6,0x05,0x15,0xa2,0xa3,0x3e,0xb9,0x52,0x0f,0x97, + 0x75,0xd5,0xb8,0xdb,0x9c,0x2d,0xa6,0x43,0xc7,0xda,0x00,0x13,0x13,0x59,0x9b,0xb1, + 0x6e,0x6d,0x7c,0xdf,0xf8,0x38,0xfb,0x98,0x3e,0x7d,0x75,0xad,0x26,0x1f,0xdd,0xe5, + 0x56,0x7f,0xde,0x7a,0xd2,0xa6,0x17,0xfb,0x77,0xda,0xa5,0xd4,0x8f,0x03,0xa2,0xf8, + 0xce,0xd8,0xf4,0x51,0x1b,0x16,0x61,0x18,0xb6,0x2f,0x8b,0x78,0x88,0xd9,0xec,0x71, + 0x90,0x9a,0x41,0xa1,0x1f,0xc1,0x98,0xd1,0xdd,0xb5,0x80,0x3d,0x53,0x66,0xb7,0xa0, + 0x4d,0x1b,0xa3,0x27,0xc5,0x58,0xa6,0x30,0x52,0xd2,0x9c,0x9d,0x8c,0xd9,0x47,0x5c, + 0x6d,0x22,0xe2,0xa1,0xbd,0x7b,0x88,0x4d,0xef,0x86,0xcf,0x78,0x02,0xbb,0xb4,0x7f, + 0x17,0x9b,0xce,0x7c,0x39,0x22,0x1c,0x98,0x16,0x00,0x5e,0x90,0x23,0x46,0x1d,0x4d, + 0xf1,0x35,0x18,0x84,0xc1,0x9a,0x14,0x8f,0x54,0x32,0xda,0xa7,0x9a,0x78,0x6c,0xfd, + 0xee,0xd4,0x4f,0x4f,0x41,0x9e,0xae,0x3d,0x85,0x2a,0xc3,0x16,0x75,0x97,0x52,0x5b, + 0x4e,0xaf,0xf3,0xde,0x66,0xc6,0x8c,0xa2,0x14,0xe6,0xef,0x94,0x96,0x2f,0x2d,0x9f, + 0x04,0x86,0xa4,0x49,0x80,0xe4,0xf5,0x47,0xf3,0x97,0x38,0x7f,0xeb,0x5e,0xea,0x06, + 0xa4,0xdc,0xc7,0x29,0x03,0xe7,0x9b,0x14,0x96,0xfe,0x3a,0xe9,0x42,0x9b,0xcb,0x43, + 0x0f,0x2c,0x85,0xa1,0x9a,0xcd,0x0c,0x5c,0xb0,0x8d,0xf2,0x9a,0x07,0x00,0x1b,0x5f, + 0xc0,0x5d,0x0f,0x76,0x64,0x5e,0xd8,0x09,0xa6,0x7d,0x16,0xb1,0x07,0xd9,0x6a,0x1b, + 0xdd,0x4d,0x3f,0xe6,0xa5,0xc8,0x67,0xf3,0x80,0xe2,0x04,0xfa,0x23,0xe2,0xac,0xe2, + 0xfc,0x0c,0x1d,0x61,0xa7,0x11,0x69,0x21,0x4e,0x7e,0x22,0x4e,0xa1,0xc1,0xc8,0xad, + 0x67,0xd6,0x95,0xf5,0x24,0x59,0xd0,0x9b,0xcc,0xba,0x66,0x1c,0x68,0xb6,0x0e,0x86, + 0x1d,0xcd,0x01,0x8d,0xf2,0x1f,0x75,0x54,0xdf,0x37,0x61,0x35,0xee,0x12,0xc0,0x2e, + 0x87,0x09,0x39,0x3e,0xfa,0xa9,0x28,0xdf,0xcd,0xfc,0x88,0x42,0x44,0x20,0xd4,0x12, + 0x3e,0x8c,0x23,0x1d,0xcd,0xe3,0x6c,0x87,0x1f,0xe9,0x01,0x91,0x17,0xb5,0x3b,0xcd, + 0x01,0x3d,0xa7,0x06,0x5e,0x86,0xba,0x77,0x2a,0xe9,0x58,0x6f,0x8b,0x8f,0x39,0x74, + 0xe5,0x30,0xc2,0x15,0xb5,0x34,0xf0,0x1b,0x41,0x8e,0xed,0xf4,0x69,0x3f,0x68,0x51, + 0xf2,0xaf,0x0b,0x1b,0x78,0x59,0x3d,0x5d,0xbe,0x3d,0x69,0xe4,0xe9,0x6b,0xfb,0xec, + 0xff,0x74,0x93,0xc9,0x35,0x1f,0xcf,0x4e,0xc5,0x4b,0x17,0x41,0xc9,0xc4,0x69,0xfa, + 0xce,0x4d,0x28,0xa7,0x75,0xad,0xd2,0x59,0x1a,0x45,0x9d,0x33,0x79,0x82,0x91,0x25, + 0xe4,0x4f,0x19,0xe6,0x60,0x2d,0x2f,0xf0,0xfe,0x90,0x9d,0xae,0x5d,0x46,0x3b,0x4d, + 0xda,0x62,0xc8,0x4a,0xfb,0x2a,0x90,0x9b,0x36,0xe5,0x33,0x91,0xdf,0xf4,0x7d,0xa6, + 0x5c,0x96,0xfc,0xb9,0x04,0x65,0x40,0x0b,0xa8,0xc0,0x3a,0x63,0x54,0x08,0x4b,0x3a, + 0xa4,0xdc,0x52,0x99,0x1c,0xbc,0x8b,0xf6,0x99,0x76,0x8c,0xcc,0x87,0xf2,0xc8,0x12, + 0xb7,0xdc,0x54,0xa2,0xfa,0x34,0x87,0x3a,0x80,0x0f,0x80,0x31,0xdc,0x20,0x7b,0x10, + 0x92,0xd6,0x50,0xd9,0x1a,0x1c,0x20,0x50,0xda,0x84,0x73,0xd1,0x2c,0x5d,0x6a,0x89, + 0xdd,0x3c,0xfe,0x25,0x4b,0x27,0x2a,0x6f,0x91,0x4d,0x18,0x1f,0x89,0xa3,0x65,0x9e, + 0x65,0x3d,0x89,0x3c,0x86,0x4a,0x20,0x6b,0x20,0xd6,0x3b,0xb9,0x32,0x6f,0x1e,0x86, + 0x68,0xa2,0x69,0x65,0xa8,0x70,0xf8,0x38,0xd8,0xf7,0xda,0xb0,0xdb,0x54,0x66,0x73, + 0xed,0x31,0x72,0x4d,0x71,0x26,0x14,0x38,0xb7,0x27,0xbb,0x22,0x9c,0xc6,0x9f,0xc9, + 0x3b,0x1e,0x83,0xb7,0xe6,0x65,0x1a,0x91,0x34,0xb6,0x01,0x41,0x4c,0xfa,0x22,0x9f, + 0x9d,0x7d,0x78,0x48,0xad,0x34,0xfe,0xb8,0xf3,0xdd,0x3d,0xa3,0x8c,0xd2,0x71,0x35, + 0x9e,0x0c,0x79,0x41,0xa1,0x51,0x2c,0x7c,0x95,0x69,0x30,0x22,0xc3,0x53,0x45,0xc2, + 0xc9,0x52,0x78,0x24,0x1f,0x8c,0x4f,0xe0,0xa7,0x18,0x6d,0x21,0x41,0xe2,0x20,0x0b, + 0x7d,0x17,0xa6,0x64,0xe9,0x7f,0x6b,0xd6,0xc8,0x06,0x5b,0x40,0x8a,0xbf,0x92,0x26, + 0xf4,0x95,0x93,0x63,0x22,0xfa,0x2e,0x7c,0x49,0x39,0x94,0x9a,0x95,0x8e,0xee,0x6c, + 0x26,0x9b,0xc1,0xec,0x6e,0x06,0x83,0xe2,0x8e,0x26,0x14,0xe0,0x5c,0x81,0xbc,0x9e, + 0x0c,0x9c,0x0c,0x4d,0x04,0x12,0xeb,0x1d,0x00,0x2b,0x48,0x73,0x27,0x41,0x6b,0x3e, + 0xa9,0xbd,0x62,0x25,0x0a,0x20,0x3a,0xd7,0xc6,0xc9,0x11,0xc1,0x85,0xb2,0x60,0xb4, + 0x6a,0x6b,0x57,0xdf,0x8c,0xf0,0x91,0x9d,0xfa,0x08,0x6e,0xa9,0x60,0x55,0x64,0x90, + 0xa4,0xb1,0x90,0x9a,0x22,0x49,0x12,0xa5,0x40,0xdd,0xc4,0xf7,0xfe,0x52,0x5b,0x57, + 0x50,0xfa,0x69,0xa0,0x25,0xa8,0x4c,0x1a,0x23,0xed,0x21,0x29,0xe3,0x6f,0x21,0x09, + 0x64,0xbf,0xc4,0x55,0x3f,0xf1,0x3d,0x54,0xcd,0xc4,0x03,0x2d,0x58,0xe1,0xd6,0xab, + 0x73,0xd5,0xf5,0x9e,0x72,0x24,0x42,0x25,0x5b,0x52,0x8d,0x58,0xeb,0x04,0x24,0x21, + 0x03,0x53,0xb9,0xc2,0xb6,0x29,0x74,0x55,0x8d,0x6e,0xf3,0xee,0xfe,0x70,0x5f,0x65, + 0x21,0x2b,0xd5,0x49,0x0c,0x30,0x9f,0x45,0x02,0xca,0x55,0xa3,0xeb,0x62,0xd3,0x7e, + 0x5c,0xfa,0x4d,0x69,0xed,0xc9,0x5c,0x2c,0x12,0x55,0x0f,0x3b,0x2e,0xee,0xa3,0x88, + 0xa7,0x39,0x86,0x77,0x99,0xe4,0x0f,0xde,0x5a,0x48,0x7c,0x51,0x7e,0xb1,0xe4,0xfe, + 0x8e,0x7b,0x02,0xa9,0xbf,0x13,0xb2,0x93,0xce,0x94,0x50,0x17,0x73,0xe5,0x35,0xe2, + 0xef,0x49,0x64,0xc9,0xc6,0x06,0xc4,0xa9,0x12,0x11,0x33,0x3b,0x37,0x79,0xff,0xeb, + 0xe4,0x65,0xcc,0x4e,0x21,0x31,0xd3,0xcb,0x67,0xc1,0x82,0x90,0xae,0x4f,0xfb,0x61, + 0x35,0x90,0x90,0x0e,0x9c,0x92,0x01,0x8c,0x07,0x42,0x82,0x67,0x9b,0xca,0x55,0x2f, + 0xe4,0x9b,0x96,0x5b,0xa7,0xe9,0x66,0xbb,0xb6,0xe2,0x60,0x4a,0xfd,0x13,0x2b,0x26, + 0xc8,0x44,0x31,0xe8,0xba,0x3e,0x8b,0xd1,0xef,0x32,0x8e,0x18,0xa3,0xec,0x6b,0x23, + 0xf5,0xd9,0x98,0x89,0x9e,0xba,0x7b,0xff,0x92,0xdc,0xc4,0x67,0x7d,0x25,0x51,0x33, + 0x99,0x7e,0x36,0xed,0xc4,0xc0,0x49,0x0a,0x61,0x20,0xf5,0x0b,0xf6,0xc8,0xaf,0xd7, + 0xc1,0xd4,0xb2,0x40,0x46,0x9b,0xb5,0x43,0x5f,0xa8,0xbd,0x4b,0x0e,0x65,0x8d,0x74, + 0x97,0xfa,0x97,0x05,0x76,0x65,0xf4,0xd8,0x67,0x8b,0xfb,0x58,0x9f,0xd6,0x84,0xf4, + 0x73,0x89,0x61,0xc6,0xc1,0xbe,0xce,0xfb,0x95,0x7f,0x7c,0xac,0x65,0xda,0x64,0x94, + 0x20,0x28,0x40,0x9c,0x6c,0x0c,0xb4,0x13,0x0e,0x3b,0x85,0xd0,0x13,0x72,0xab,0xaf, + 0xea,0x1f,0x70,0x07,0xe5,0x2e,0x80,0xec,0x1a,0xed,0x66,0x52,0x40,0xe3,0xd2,0xcf, + 0xef,0xb0,0x92,0x70,0x5b,0x19,0x9b,0xc0,0x3b,0x01,0x5d,0xbd,0x85,0x0a,0xcd,0x6e, + 0x6b,0xac,0x47,0xe8,0xad,0x6a,0xfc,0x8d,0x78,0x78,0xf5,0xa5,0x0e,0x8d,0x1a,0x9c, + 0x0f,0x08,0x21,0xf0,0xe3,0xec,0x93,0x58,0x95,0xa4,0xba,0x12,0x6d,0x13,0xa2,0xa6, + 0x47,0x83,0xbb,0x96,0xff,0xd5,0xbe,0x4a,0x5b,0xf8,0x69,0x41,0x68,0xac,0x23,0xb1, + 0xd0,0x0d,0x7f,0x5d,0xe2,0x0f,0xbc,0x8a,0x4e,0xd7,0x2f,0x58,0x59,0xe5,0x84,0x02, + 0xae,0x10,0xce,0xd4,0xbf,0xe6,0x8f,0xd5,0xb1,0x01,0xda,0xdd,0x74,0x77,0x97,0xde, + 0xd8,0x6a,0xb8,0x5e,0xb4,0x73,0x61,0x58,0x2e,0x1e,0x71,0x9e,0x2b,0xc2,0xd2,0x37, + 0x67,0x5e,0x85,0x60,0xd9,0x08,0x2a,0xe0,0x78,0x31,0x1d,0x17,0xc0,0xb2,0xd9,0xad, + 0x1f,0x42,0xb0,0xd4,0x7e,0x50,0x25,0xf3,0xe6,0x44,0x4f,0xe6,0x90,0x5c,0x41,0x20, + 0xb3,0xfb,0x31,0x50,0xa1,0x0d,0x05,0xe8,0x67,0x54,0x16,0x00,0x95,0x4f,0x81,0xed, + 0x4a,0xa9,0x82,0x1d,0xfc,0x53,0x54,0xcd,0x01,0x04,0x06,0x0f,0x7d,0xa1,0x4b,0x34, + 0xf7,0xda,0xc8,0x0c,0xe0,0x7c,0x3e,0xd5,0x3d,0xb1,0x79,0x8c,0xdf,0xe5,0xaf,0xbe, + 0x0b,0x83,0xfe,0x20,0x43,0xca,0x46,0xa3,0xda,0x58,0xe8,0xc3,0x4a,0x14,0xa8,0x8f, + 0xc7,0x77,0x69,0xc3,0xa1,0x98,0x97,0x4f,0x3c,0xd7,0xe9,0x6d,0x28,0xac,0x2f,0xcd, + 0x76,0xb5,0x3d,0xab,0x6a,0xc0,0x19,0x0f,0x71,0xea,0xb6,0x4f,0xa0,0x54,0x98,0xb4, + 0x60,0x65,0x28,0x34,0x48,0x75,0xd3,0x16,0x67,0xa9,0xea,0x45,0x28,0xa1,0xa9,0x98, + 0x18,0xb4,0xdb,0x58,0xf7,0xe6,0x67,0xc5,0x1c,0x80,0x46,0x2d,0x4f,0xd2,0x56,0xe3, + 0x63,0x1c,0xbc,0x7c,0xa2,0x52,0x82,0xfb,0x7c,0x88,0xd4,0xa9,0xc2,0xd4,0x57,0x94, + 0x70,0x6c,0xe2,0x21,0xf5,0x88,0x6d,0xb7,0x90,0x28,0x26,0x1c,0xa7,0xde,0x4d,0x2f, + 0xc1,0xa2,0xc2,0x47,0x73,0x1f,0x55,0x17,0x6f,0xea,0x9a,0xf9,0xd6,0xaa,0x69,0xb8, + 0xe9,0x78,0x25,0xa8,0xc9,0xb0,0xbe,0xb9,0xdc,0x4d,0x81,0x5c,0x26,0x61,0x92,0x8a, + 0x27,0xd1,0x56,0xbe,0x69,0xa1,0x8b,0x5d,0x13,0x05,0x24,0xda,0x71,0x06,0x92,0x43, + 0x44,0x2b,0x39,0x1c,0x4d,0xe7,0xb4,0x42,0xd2,0x1e,0xff,0xae,0x7b,0xb3,0xee,0x2a, + 0x26,0x7d,0xd7,0x6b,0xee,0x5d,0x85,0x49,0xf2,0x7b,0xc5,0xd2,0xbe,0x94,0xc8,0xac, + 0xe5,0x95,0x5f,0x1e,0x1f,0x1e,0x44,0xd9,0x00,0x99,0x1b,0x88,0xe5,0x90,0x9e,0xc6, + 0x9e,0x43,0x2d,0x3e,0x3d,0xdd,0x79,0x37,0x69,0x4b,0xe1,0x23,0xf8,0x6b,0x9d,0xd9, + 0x1c,0x80,0x1c,0xa7,0x74,0x3c,0xe0,0x53,0x96,0x32,0x79,0x63,0x42,0x2f,0x6a,0xd2, + 0x2c,0x5f,0xfc,0x41,0xc7,0x38,0xbd,0x46,0x26,0x65,0x05,0xbf,0xa1,0x73,0x13,0x58, + 0x78,0xc1,0xef,0x78,0x93,0x28,0x2d,0x00,0x3e,0xaf,0x9a,0xd2,0x0e,0x5b,0xd0,0xd5, + 0x2e,0xbc,0xb5,0x2c,0x23,0x4a,0x37,0xcc,0x9e,0xa9,0xd4,0xba,0x97,0x8d,0x46,0xbd, + 0x27,0x4c,0x82,0xc8,0x20,0xe1,0x89,0xd8,0xc7,0x73,0xcf,0x51,0x8e,0x4c,0x05,0x12, + 0x12,0x76,0x9c,0xa3,0x19,0xcb,0xe1,0x80,0x49,0x3d,0x52,0xdd,0x76,0xb8,0xfd,0x45, + 0xeb,0x2c,0x55,0x19,0xaf,0x0e,0x22,0x3d,0xc4,0x69,0x44,0xb5,0x01,0x6f,0x4d,0xd6, + 0x78,0x70,0x9e,0x37,0xc6,0x13,0x66,0x96,0x65,0x74,0x8f,0x22,0x28,0x9c,0xc8,0x24, + 0x78,0x0f,0x65,0xb4,0x65,0xfb,0xc1,0x44,0x3b,0xd3,0xf8,0xb7,0x7e,0xec,0x86,0x9f, + 0x69,0x0c,0xb7,0xd7,0x8f,0x99,0x7c,0x4d,0xea,0xb5,0x74,0x45,0x73,0x49,0x08,0x43, + 0xb2,0x32,0xaf,0x34,0xef,0x74,0xb5,0x01,0x65,0xa1,0x96,0x0f,0xd5,0xfb,0x71,0xef, + 0xd4,0xca,0x21,0x4c,0xe6,0x87,0x0d,0xc4,0x15,0xd2,0xb7,0xe1,0x99,0xa9,0xbb,0xd0, + 0x65,0x40,0x10,0x42,0x7e,0xca,0x26,0x02,0x6e,0x4a,0x0a,0xca,0x29,0xd4,0x74,0xb6, + 0xed,0xaa,0x3a,0xfe,0x7b,0xd5,0x0f,0xd9,0x9c,0xbe,0xb7,0x89,0x90,0x17,0x8a,0x9d, + 0xf5,0x7e,0x26,0x9d,0x06,0x7a,0xb0,0x6d,0x3b,0x0f,0x09,0x31,0xeb,0xaa,0x5d,0x4e, + 0x27,0x14,0x73,0x40,0xe7,0xb8,0xac,0x36,0x6c,0xb3,0x42,0x5e,0x06,0xdf,0x54,0x60, + 0xd2,0x25,0x6c,0x9f,0x8a,0x36,0x85,0xb2,0x8f,0xf5,0xc3,0xe3,0x21,0x23,0x2a,0x8b, + 0x57,0x54,0x75,0x5a,0xe0,0x1b,0x79,0x1c,0x0e,0xa1,0x44,0x9a,0x72,0x8a,0x97,0x83, + 0x17,0x5f,0xbd,0x6f,0x58,0x31,0x0e,0x05,0xaf,0xd0,0x57,0xca,0x31,0xa4,0x29,0xa3, + 0x93,0x43,0xa7,0xf2,0xef,0xf7,0xfe,0x7c,0x15,0x34,0x8f,0x30,0xd6,0xff,0x91,0xe2, + 0x3f,0x31,0xaa,0x55,0x68,0x44,0x1f,0x97,0xbb,0xb1,0xb5,0x6b,0x67,0x9a,0xa3,0x53, + 0x68,0x5b,0x1c,0xf1,0x5a,0x98,0xdd,0xaa,0x38,0xb6,0x0c,0xcc,0x81,0x53,0x8c,0xfd, + 0x2a,0x07,0x54,0xf6,0x19,0x69,0x3e,0x01,0x5f,0xaa,0xf1,0xfb,0x11,0x3c,0x14,0x77, + 0xcc,0xe4,0xa8,0x7d,0x46,0x38,0xba,0x27,0x3f,0x24,0xae,0x96,0xee,0xe6,0x5c,0xd6, + 0x04,0x35,0x80,0x67,0x67,0xd3,0x84,0x5a,0x06,0xf9,0x1e,0x0e,0x1b,0xc6,0xe3,0x93, + 0x89,0xbd,0x86,0x00,0x4f,0xa9,0x6a,0x99,0xdc,0xe7,0x2f,0x7a,0x50,0xf0,0x95,0xa3, + 0xba,0xbe,0x74,0x52,0x59,0x65,0x30,0xc4,0x5e,0xe0,0x53,0x37,0x74,0x78,0x03,0xc2, + 0xab,0xbb,0xcf,0x77,0xad,0x30,0xe7,0x49,0xb3,0x31,0xa4,0x5c,0x6a,0x6e,0xe6,0x66, + 0x9f,0x94,0x09,0x70,0xf8,0xb1,0x42,0xc6,0x78,0xed,0x59,0x3b,0xd9,0xb8,0x64,0xd0, + 0x8c,0x33,0xa2,0xe0,0x1a,0xd9,0x19,0x0e,0x03,0xd7,0x9b,0x75,0x9b,0x61,0x1e,0x08, + 0x0f,0x9b,0x34,0xb5,0x1b,0xa2,0x11,0x53,0x82,0xe4,0xb8,0xa5,0xb1,0x00,0xe8,0x43, + 0xec,0xe0,0xd4,0xb5,0xd7,0x67,0x9f,0xa3,0xd2,0x6d,0x3b,0x39,0xe5,0xfa,0x34,0x8b, + 0xfa,0xf5,0x98,0x5a,0x9e,0xdd,0x7e,0x1a,0x96,0x81,0x67,0xa4,0x9f,0x76,0x9b,0x56, + 0xfa,0x21,0x74,0x30,0x1d,0xc6,0xba,0xae,0x86,0xb4,0xbe,0xd4,0x7c,0xe1,0x27,0x2d, + 0xc8,0x61,0x72,0x74,0x67,0x72,0xa1,0xe2,0xd0,0x78,0x55,0xcc,0x6d,0x0c,0x58,0x2b, + 0x2d,0x23,0xf8,0xc7,0x0b,0x6c,0x50,0x14,0xa8,0x8c,0x49,0x1f,0xc0,0x58,0xcb,0x99, + 0xa7,0x60,0x6b,0x15,0xa2,0x57,0xe8,0xc0,0xe9,0x45,0x63,0x14,0xb9,0xb2,0x25,0x9a, + 0x1b,0x15,0x21,0x22,0xc4,0x10,0xe3,0xcb,0xae,0x87,0xb2,0xbb,0xc9,0x4d,0xd4,0xae, + 0xd0,0xc5,0xd1,0x0b,0x6e,0x27,0x9d,0xde,0x01,0xf5,0xea,0x81,0xa1,0xdc,0x58,0x8e, + 0x7f,0x2f,0x2e,0xe1,0x93,0x62,0xae,0x6b,0xfe,0x3a,0xbc,0xba,0x9b,0x92,0xa0,0xc7, + 0x90,0x42,0x69,0x1f,0xb1,0xca,0xa8,0x9b,0x67,0x2d,0x43,0x2c,0x2d,0x9a,0x25,0xaa, + 0x2b,0x1a,0x55,0x66,0x87,0xfc,0xf6,0xb8,0x4d,0xe6,0x6c,0xb4,0xc9,0xbc,0x76,0x97, + 0xaa,0x11,0x0c,0x89,0xda,0x77,0xd1,0x75,0x6f,0xc3,0x29,0xdc,0xa8,0x4e,0x79,0xf4, + 0x50,0xd7,0xfc,0x34,0xe6,0x60,0x36,0x59,0x5f,0x85,0x64,0xf2,0x79,0xc3,0xa3,0xf1, + 0x40,0xcb,0xc7,0xc8,0x16,0x3f,0x43,0xed,0x5a,0xbe,0x36,0x3e,0x21,0x1d,0x72,0xc3, + 0xfc,0x73,0xa0,0x75,0x66,0x34,0xc8,0x8a,0x9f,0xa5,0x1f,0xfa,0x4b,0x11,0x1c,0x90, + 0xb9,0xb4,0xe7,0x95,0xfb,0x19,0x49,0x93,0x92,0x2a,0xed,0x0e,0x2d,0x10,0xc8,0xb8, + 0x73,0x08,0x82,0x20,0x00,0x85,0x09,0xb6,0x9e,0xd5,0x1c,0xbe,0x8b,0xd0,0xf1,0x0b, + 0xa2,0x63,0x58,0x81,0x48,0x88,0x4b,0x53,0xb3,0x85,0xa1,0xfd,0x14,0x0c,0xcc,0x14, + 0x78,0x80,0x2a,0x26,0xaa,0xe7,0xd3,0xe5,0x28,0x3c,0xc1,0x9c,0x92,0x52,0x6f,0x6b, + 0xe6,0x97,0x1d,0x84,0x45,0xec,0x66,0x86,0x42,0xbf,0x1e,0xe8,0x5c,0x98,0x06,0xae, + 0x36,0x1b,0xda,0xb7,0xde,0x7e,0x90,0xb4,0x5b,0x45,0xba,0x68,0xb2,0xe4,0xd3,0xc5, + 0xc4,0x0a,0xb3,0x4e,0xdc,0xea,0x19,0x37,0xbf,0x59,0x31,0x9c,0x5c,0x41,0x00,0x1c, + 0xfa,0xfa,0xf1,0x46,0x35,0x71,0x06,0x5d,0x67,0xd7,0x14,0xf9,0xd0,0x93,0x1f,0x96, + 0xff,0x2d,0x41,0xed,0x56,0x92,0xa6,0xdc,0x89,0x9e,0x38,0xa9,0x1f,0xb7,0x89,0x6b, + 0x4e,0x70,0x15,0x9a,0x56,0x6c,0x87,0x5f,0x7c,0xf8,0xd8,0xf7,0x20,0xa7,0x24,0x5b, + 0x9c,0x16,0xdb,0xba,0x40,0xf2,0xe4,0xc2,0xb3,0x31,0xee,0xaa,0xc8,0x03,0x22,0x03, + 0x7e,0xfc,0x95,0x0f,0xbf,0x2e,0xf0,0x29,0xd4,0x02,0x88,0x90,0xef,0x60,0xd2,0x22, + 0xa1,0x16,0x49,0xd3,0x94,0xa4,0xf1,0x16,0x6d,0x02,0xa2,0x68,0x94,0x0e,0x14,0x4b, + 0xaf,0x3b,0x96,0xc5,0x33,0xb4,0xf0,0xad,0xa4,0x21,0x34,0x64,0x93,0x9c,0xc8,0xd1, + 0xf6,0x2d,0x53,0xd4,0xb0,0xbc,0xee,0xd4,0x41,0x26,0xa9,0xa3,0x16,0x9b,0x4c,0xd7, + 0x4a,0x9c,0x9b,0xc6,0x20,0x8d,0x4e,0xab,0xdc,0xc1,0xc7,0xec,0x5a,0x08,0xd5,0x44, + 0xd3,0xc9,0xfe,0x6e,0x2a,0x9b,0x83,0x84,0x2b,0x87,0x21,0x9d,0x95,0x14,0x3e,0x8d, + 0x0d,0x29,0xa7,0x9b,0x4c,0x9b,0x01,0x11,0xd1,0x7e,0xaa,0xcb,0x53,0xdc,0xce,0x07, + 0xc8,0xd7,0x42,0x02,0x39,0xfb,0x62,0xe1,0x5f,0x9c,0x58,0x0d,0xc8,0x40,0x91,0x86, + 0x52,0x72,0xaf,0xef,0x1c,0xd1,0x8c,0x89,0x92,0x7f,0x5f,0x6b,0x77,0x3e,0xc7,0x8f, + 0xe7,0x0f,0x40,0x67,0x03,0x6c,0xc5,0x50,0x27,0x22,0xba,0x40,0x3b,0x13,0x80,0xf7, + 0x0c,0x0f,0x38,0xb2,0xae,0xd8,0x30,0xa1,0x7e,0x6b,0x03,0xe0,0xfe,0x6d,0x42,0xbb, + 0xb3,0x91,0x9b,0xdd,0x8d,0xaf,0x83,0xe9,0x28,0xfd,0x76,0xbc,0x99,0x32,0x77,0x68, + 0x57,0xd5,0xe9,0x28,0x6d,0xd7,0xaa,0x8c,0xe2,0xac,0xe4,0x81,0x37,0x66,0x02,0xff, + 0x8a,0xae,0xba,0x4c,0xa3,0x03,0x89,0xab,0xd6,0xfe,0x4e,0x78,0xfa,0x91,0x3d,0x55, + 0xb5,0x2a,0x57,0x57,0x43,0x38,0x67,0x10,0x0c,0xd1,0x89,0xb2,0xb3,0x91,0x6d,0xb9, + 0x9b,0x8f,0x4a,0xff,0x7e,0x36,0x7b,0x1e,0xfa,0xb5,0xb6,0x64,0x43,0xfa,0x09,0x5a, + 0xfa,0xbc,0x69,0x99,0xb2,0xc9,0xea,0xdf,0x4f,0xb9,0x3f,0xf2,0xa2,0x42,0xbb,0x32, + 0xd1,0x54,0xb8,0xbe,0x1d,0x69,0x3e,0xad,0xdd,0xd2,0x75,0xab,0x6d,0xdd,0xf0,0x4f, + 0xb6,0x9b,0xac,0x17,0x47,0x92,0xca,0x37,0x59,0x6d,0x9f,0x2c,0x17,0xb7,0xfb,0xf8, + 0xe2,0x40,0xaa,0x87,0xb4,0x19,0x69,0x99,0xe5,0x0c,0x1f,0xcb,0xe8,0xef,0x7b,0x8b, + 0x3d,0x18,0x58,0xc5,0x86,0x66,0x1f,0x5e,0x73,0xd1,0xf8,0xdd,0x78,0xc6,0x84,0xfd, + 0x81,0xca,0x46,0xe1,0xf1,0x4d,0x36,0xdb,0x0e,0xe0,0xc6,0xf9,0xe9,0xbd,0x56,0x91, + 0x47,0x98,0x90,0x9d,0x8c,0x45,0xea,0x71,0x65,0xba,0x55,0x66,0x3f,0x79,0x4a,0xea, + 0xad,0x00,0x57,0xcb,0x79,0x3e,0x55,0xd6,0x35,0x01,0xfe,0x9f,0x71,0x21,0xeb,0x13, + 0x85,0x41,0x08,0xd4,0xda,0xe3,0x7f,0x02,0x81,0xb7,0x26,0xde,0x14,0x76,0xec,0x74, + 0x8d,0xec,0x5e,0xbe,0xbc,0x1a,0x0f,0xe1,0xf3,0x81,0x49,0xf5,0xbe,0x35,0xf1,0x35, + 0x3d,0xd7,0xdb,0x24,0xa3,0x0d,0xb5,0x9d,0xdd,0xa3,0xcb,0x7f,0xd3,0x63,0x42,0x49, + 0x9e,0xfe,0x81,0x74,0x1e,0xb4,0x5b,0xe4,0x20,0x50,0xf6,0xfd,0xb0,0xed,0xd2,0x1f, + 0xd1,0x21,0x44,0xc9,0x2f,0xb0,0xc7,0xa7,0x26,0xd6,0x5b,0x58,0xa8,0xcb,0xcb,0x42, + 0xbc,0x7f,0xfd,0xc0,0xe9,0x85,0x08,0xf4,0x45,0x1a,0x10,0x7f,0x1a,0x49,0xca,0x32, + 0xc0,0x77,0x0d,0x7a,0x0e,0x06,0xef,0x0f,0xf1,0x13,0xf7,0x11,0x60,0xc2,0xac,0xed, + 0x1c,0xae,0xaa,0x02,0xf3,0xb6,0xf6,0x65,0xa6,0x7e,0x18,0x90,0x14,0x46,0xb6,0x64, + 0x01,0x90,0x48,0x16,0x44,0x7a,0xc7,0x5c,0x06,0x9c,0x47,0xd6,0x7b,0xa1,0x37,0x34, + 0x68,0xff,0x0d,0xc2,0x68,0xee,0xb4,0x68,0xca,0x2c,0x0a,0xfd,0x38,0x1d,0x27,0xdf, + 0x5d,0xae,0x98,0x7c,0xe2,0xfc,0xd6,0x22,0xd6,0x6f,0xc9,0x79,0x92,0x10,0xd8,0x29, + 0x9d,0xdb,0xee,0x9d,0xe8,0x28,0x4c,0xf2,0xa6,0x42,0x1f,0xbb,0xb9,0x55,0x2c,0xf5, + 0x17,0x8e,0xdb,0xa5,0x5f,0xda,0xbc,0xe7,0x71,0xf8,0x61,0x20,0x32,0x69,0xde,0x56, + 0xb5,0xa1,0x2f,0xfc,0xa1,0xed,0x8e,0x10,0x61,0x37,0x78,0xcb,0xdb,0xd9,0xec,0xfb, + 0x67,0x4a,0xf5,0xea,0xad,0xf8,0xb6,0x06,0xa4,0xe6,0xb1,0x14,0x6c,0x56,0x89,0x98, + 0x04,0x53,0xef,0xad,0x2c,0x76,0xd8,0x55,0xae,0xba,0x3e,0xa5,0xe0,0x79,0x43,0x22, + 0x7d,0xeb,0x5a,0xea,0xc7,0x6d,0xc2,0xb8,0xa0,0xe0,0x43,0x30,0xb3,0x5a,0xa0,0x77, + 0x02,0xf8,0x72,0x9f,0xab,0xf0,0x02,0x3e,0xd5,0x95,0x05,0xa7,0x7a,0xea,0x0f,0x91, + 0xc0,0xde,0xdb,0xb5,0x8a,0xcb,0x88,0xa3,0x22,0x05,0xaf,0xd4,0x1f,0x9f,0xf5,0x5c, + 0x8f,0x1a,0x42,0xc2,0x9b,0xcd,0x73,0x20,0xed,0x81,0x77,0x8b,0xb7,0xb7,0x65,0xcc, + 0x4d,0x02,0xe7,0x9e,0x62,0xfe,0x14,0xf6,0x45,0x85,0x16,0x92,0x04,0xf2,0x12,0xaf, + 0x50,0xd0,0x87,0x4a,0x40,0xe6,0xfc,0xa6,0x9e,0x05,0xf5,0x19,0xd1,0x4c,0x39,0x4a, + 0x70,0xe2,0xda,0xd0,0xf6,0x15,0x88,0x47,0x94,0xb1,0x6f,0xff,0x1e,0x68,0xae,0x4f, + 0x57,0x56,0x9d,0x1b,0x5f,0x82,0xc8,0xa4,0xa0,0xbb,0x4d,0x7f,0xfb,0xdb,0xcb,0x3b, + 0x12,0x5e,0xed,0xb3,0xd4,0x19,0x54,0x7e,0xaa,0xc3,0x62,0x69,0x07,0xb3,0xce,0x1f, + 0x4a,0xeb,0x43,0xe8,0x23,0xed,0x64,0x99,0x45,0x0c,0xb7,0xb5,0xec,0x24,0xbd,0x41, + 0xce,0x7e,0x42,0x0b,0x41,0x24,0x3b,0xdc,0x83,0x69,0xe1,0x9d,0x3e,0xe0,0xf9,0xfd, + 0xc1,0x51,0xcf,0xde,0xc9,0x64,0x0b,0xc2,0x2f,0x43,0x6a,0x2e,0x68,0x00,0xcf,0xa1, + 0x8c,0xef,0xed,0xd0,0x96,0x93,0x09,0x01,0x32,0x69,0x57,0x69,0x9a,0xb8,0x79,0xf6, + 0xbe,0x23,0x09,0xd8,0x40,0xda,0x4e,0xca,0xe1,0xc7,0x69,0x75,0x7e,0x29,0x52,0x0f, + 0x1f,0xc4,0x52,0x58,0x68,0xab,0x4b,0xdd,0x8a,0x55,0x68,0x03,0x60,0x07,0x6b,0xb9, + 0xfd,0xba,0xa2,0x08,0x38,0x5b,0xf1,0x89,0xdb,0xe3,0x45,0x3d,0xe3,0x08,0xe0,0x49, + 0xe3,0x3c,0x35,0x07,0xd1,0x62,0xc4,0x60,0xd9,0x4f,0x8f,0x8f,0xcb,0x92,0xcd,0xaa, + 0xc7,0xf0,0x70,0xa1,0xb8,0x20,0x5e,0xbf,0x1a,0x35,0xcc,0x61,0x0c,0xe1,0x72,0xcd, + 0x5d,0x4c,0x71,0x42,0x82,0xc8,0x66,0x39,0x4e,0xcf,0x0a,0x1a,0x0a,0x97,0x78,0x8a, + 0xce,0x78,0x5e,0xcf,0xd6,0x9e,0x55,0xa3,0x2d,0x1f,0xbf,0x3c,0xa3,0x21,0xef,0x6d, + 0x1a,0xeb,0x87,0x51,0xa2,0x78,0x12,0xfa,0x99,0xf9,0xbe,0x2e,0xc6,0x29,0x13,0xae, + 0x2a,0xca,0xcb,0xca,0xaa,0x17,0x0f,0xda,0x37,0x1f,0x68,0xbf,0x2e,0x7e,0x57,0xd2, + 0xdd,0x6f,0x93,0xea,0xd7,0xb3,0xc6,0x8f,0x9c,0xc6,0xc9,0x90,0x20,0x1f,0x3f,0x4f, + 0x7f,0xe3,0x10,0x06,0x92,0xb9,0x71,0xaa,0x9b,0xa8,0x41,0x0e,0x15,0x4b,0x2d,0xc8, + 0x9b,0xa6,0xe7,0x2b,0x67,0xee,0x45,0x85,0x5f,0xe0,0x1a,0x14,0x37,0x60,0xb3,0x4d, + 0xb6,0x45,0xc0,0xaf,0x14,0x05,0x6a,0xb7,0x49,0xff,0x4a,0x80,0xe5,0x4c,0x6e,0x8b, + 0xf6,0xc6,0xda,0x73,0xea,0xcd,0x59,0x6a,0x2f,0x79,0x1a,0x66,0xf9,0x26,0xbf,0xf4, + 0xd2,0x9d,0x69,0x33,0xfe,0x57,0x86,0x8d,0x51,0x3f,0xa9,0xe1,0x81,0x34,0x17,0x29, + 0x68,0x2f,0x03,0x4a,0x27,0x10,0xd6,0x4a,0x1a,0xfd,0x5d,0x07,0xa9,0xb8,0x36,0xef, + 0xee,0x98,0xc6,0x8d,0xed,0x4e,0x54,0xaf,0x88,0x07,0xbb,0xe6,0x06,0x37,0xb6,0x85, + 0x26,0xd9,0x2c,0x0c,0x32,0xaf,0x1d,0xe6,0x09,0xf6,0xa0,0x29,0x37,0xa3,0x92,0x1d, + 0xb9,0x3c,0x91,0x87,0xdd,0x2c,0xb5,0xf1,0xc1,0xbb,0x9e,0xcd,0xbf,0xe5,0x58,0xff, + 0x42,0xa9,0x60,0x25,0xa7,0x4d,0x8e,0x08,0xe4,0x62,0x97,0x4d,0x9e,0xed,0x71,0x53, + 0x9e,0xe9,0x50,0xda,0xf2,0xfe,0xe4,0x4a,0x68,0x05,0xfd,0xa2,0xba,0x33,0xc0,0x5f, + 0xf6,0xad,0xaa,0xbd,0xbe,0xb8,0x1a,0xf9,0xa1,0xbd,0x2e,0xc8,0x51,0xaa,0xab,0x94, + 0xd5,0xe3,0xb3,0x55,0xa4,0xde,0x7d,0x8c,0x6b,0x2d,0x9f,0xb3,0x85,0x8a,0x0c,0x3c, + 0x24,0x50,0x9d,0xd6,0x0c,0xda,0x19,0x0a,0x78,0x7e,0xe5,0xc6,0xf2,0xb4,0xdf,0x06, + 0xa5,0x08,0x06,0xb0,0xc1,0x27,0x7f,0x31,0xfd,0xe7,0x07,0xed,0x88,0x54,0x34,0x16, + 0x1b,0x53,0x47,0xaf,0xbf,0xe7,0xfe,0x1c,0xa2,0xe3,0x1c,0x23,0x6a,0xbc,0x86,0xcf, + 0x1b,0x4a,0xd8,0xc3,0xaa,0xc8,0xe9,0x0a,0x94,0x81,0x56,0x9d,0x5d,0x8a,0x40,0xb6, + 0x70,0xec,0xe4,0xa2,0x57,0x1d,0xf9,0xcb,0x21,0xe5,0xfc,0x38,0x5e,0x33,0xad,0x8e, + 0xd9,0xec,0x3b,0x89,0xb3,0x42,0x35,0xfd,0xec,0xd5,0x97,0x2a,0x8b,0x3c,0x6a,0xda, + 0xa1,0x89,0x8f,0xe7,0x18,0x23,0xf9,0xa2,0xda,0xa0,0xdb,0x51,0xb0,0xd4,0xdc,0xb4, + 0xb3,0x51,0xb7,0xc3,0x62,0xc9,0x4e,0x66,0xe7,0x26,0x76,0xfd,0x11,0x1c,0x00,0xa6, + 0x3b,0x8f,0x99,0x3d,0x10,0x2b,0x9f,0xad,0x6c,0x26,0xaa,0x6b,0x97,0x2a,0xe1,0xce, + 0xd3,0x6f,0x56,0x93,0x46,0x72,0x23,0xf5,0x87,0x89,0xa0,0x61,0x55,0x7b,0xa6,0x5a, + 0xf2,0x91,0xfe,0x32,0x96,0x65,0xb7,0x2b,0xef,0xc9,0xec,0xf6,0x04,0x42,0x52,0x9d, + 0xc2,0x0a,0x29,0xd3,0x98,0xde,0x63,0xc9,0xf9,0x66,0x48,0x62,0xb3,0x92,0xaa,0x6c, + 0x0c,0x1d,0x80,0x5c,0x37,0xd1,0x21,0xad,0x14,0x85,0x8c,0x5a,0x5d,0x96,0x99,0xb1, + 0x26,0x43,0x66,0x56,0x67,0xa4,0x49,0xf1,0xdb,0x49,0xdd,0x23,0xbb,0xf2,0xaa,0x20, + 0x58,0x75,0xf1,0x7b,0xcc,0x4e,0xc2,0x02,0x93,0xb7,0xe6,0xf7,0xd9,0x66,0xc5,0x66, + 0xbb,0x3c,0x2c,0x36,0xe2,0xeb,0x6e,0x38,0xaf,0x95,0x6d,0xfb,0x82,0x96,0x60,0xaf, + 0x27,0x4c,0xd8,0x82,0xab,0x46,0x0a,0x86,0xb3,0xda,0xaf,0x07,0x31,0x2e,0x76,0xc1, + 0x47,0x25,0xeb,0x97,0xcb,0x6a,0xbb,0x38,0x5d,0xaa,0x8f,0x38,0xa4,0x72,0xe8,0xe0, + 0x5e,0x95,0x3b,0x07,0xbd,0x25,0x64,0xe9,0x8b,0xfe,0x6d,0xf7,0x79,0x77,0x88,0xf2, + 0x48,0x7c,0xce,0xa8,0xb6,0xae,0xee,0x6e,0x64,0xfd,0x5a,0xd9,0xf2,0xed,0x1d,0x6c, + 0xee,0x75,0x47,0x1f,0xd9,0xd2,0x49,0xa7,0x68,0xf5,0xee,0xcf,0xe4,0xc9,0x77,0x45, + 0x04,0x3d,0x6f,0xdb,0x57,0xdf,0xee,0xbf,0xe9,0x9e,0x1f,0x97,0x1f,0xfb,0x76,0xf5, + 0xec,0xca,0x77,0x9b,0xa7,0x87,0xb6,0xda,0xf2,0x24,0x0d,0x4c,0xd9,0x95,0x40,0xde, + 0xfd,0xe5,0xc6,0xbf,0x67,0x77,0x21,0x3d,0x0d,0x04,0xc2,0x25,0x40,0xdb,0xec,0x9c, + 0xb0,0xcc,0xd0,0x73,0xae,0x11,0x3d,0xdf,0x4d,0xdf,0x46,0x2d,0xe1,0x67,0x78,0x33, + 0x43,0x4c,0x07,0xf2,0x49,0x92,0x6f,0x32,0xaf,0x10,0x0f,0xe3,0xad,0x9c,0x77,0x18, + 0x67,0x75,0x39,0x67,0xd4,0x42,0xc6,0x4c,0x73,0x85,0xd9,0x46,0xf5,0x87,0x3a,0x4b, + 0x82,0x44,0xa7,0xb3,0x99,0x14,0x09,0x26,0x3f,0x19,0xde,0x40,0xf1,0xf1,0xd9,0x71, + 0xd5,0x7f,0x36,0xff,0x49,0xef,0xf8,0x2e,0x34,0x9b,0x86,0x34,0xcd,0xd3,0xac,0xa5, + 0xdc,0xe9,0xf1,0x9b,0x86,0x34,0x94,0xee,0x7d,0x93,0x9a,0x6a,0xb7,0xda,0xe0,0x9e, + 0x91,0x30,0xa9,0x79,0xfd,0x00,0x83,0xf4,0x69,0x0a,0x5b,0x19,0xf6,0x3c,0x0b,0xe5, + 0x9d,0xf1,0x09,0x88,0x41,0xcb,0x0a,0x64,0xe9,0xa3,0x6b,0x37,0x76,0x88,0x54,0xfa, + 0xc6,0x55,0x54,0x92,0x20,0xdd,0xc9,0x16,0xaa,0x22,0xb8,0xb4,0xe7,0xca,0xfd,0xf6, + 0xf9,0x47,0xd2,0x83,0x16,0xaf,0xbd,0x11,0x0f,0xd6,0x99,0xde,0x24,0x75,0x5b,0x33, + 0x51,0xa9,0xad,0xaa,0x75,0xca,0x05,0xd2,0x9d,0xd9,0x7b,0x73,0x33,0x06,0x71,0x45, + 0x8f,0x11,0x45,0x72,0x56,0x31,0x7f,0x85,0x19,0xe5,0x3c,0x8c,0x1f,0xdb,0xfb,0x52, + 0x84,0x09,0x1a,0x10,0xc5,0xfe,0xd0,0x1d,0x8d,0xdc,0x1d,0x68,0xbc,0x60,0x0b,0xfa, + 0xc0,0x7e,0x69,0x7a,0x16,0xfd,0xd5,0x0e,0x23,0x86,0xc0,0xf3,0x12,0x8e,0xe1,0xfd, + 0xe8,0x3f,0x5c,0xf2,0x59,0x62,0x19,0xc4,0x51,0x5c,0x83,0xf2,0xb2,0x0e,0xff,0xcd, + 0x1c,0xd6,0x25,0x92,0x57,0x5a,0x37,0x5d,0x9b,0xe1,0xf4,0xba,0x8f,0x7c,0x8c,0xf8, + 0xf7,0x2f,0xde,0x76,0x60,0xf4,0x2d,0x4a,0x45,0xda,0x29,0x66,0xfb,0x80,0xde,0xac, + 0x32,0xcb,0xd4,0x59,0x7b,0x76,0x4e,0x81,0xc6,0xa6,0x9c,0x2e,0x64,0x0e,0xb1,0x5e, + 0x06,0xb4,0x16,0x8d,0x0a,0x8f,0xe7,0xa2,0x9a,0xd6,0x25,0x2b,0x59,0x0e,0xdf,0x2c, + 0xd6,0xbc,0x9d,0x3c,0x7f,0x44,0x16,0xa1,0xc4,0x86,0xb6,0x66,0x62,0x05,0xb7,0xf4, + 0x3e,0x17,0x22,0x4a,0x88,0x33,0x38,0xd3,0x45,0xc1,0xd6,0x71,0x33,0xc1,0x5b,0xbd, + 0x0d,0x07,0x59,0x20,0x3b,0x74,0xc0,0x99,0x93,0x9f,0xb1,0x8c,0x8a,0x01,0x5c,0x4b, + 0x54,0x2d,0x59,0xe5,0xcc,0x1c,0x35,0x0b,0x91,0xea,0xb8,0x36,0x36,0x69,0x11,0x8c, + 0x98,0x07,0x77,0x0f,0xef,0xc9,0x04,0xd2,0xba,0x94,0x70,0x58,0xda,0x6a,0x32,0x20, + 0xf6,0x37,0x05,0x99,0x54,0x69,0x8a,0x87,0x6f,0xa1,0xc7,0xb9,0xf2,0x82,0x3b,0xf7, + 0xe6,0x47,0x8a,0x12,0xf6,0xe2,0x5b,0x36,0xf7,0x97,0xbd,0xa8,0x4b,0x11,0x8c,0x9c, + 0x24,0xf8,0x0f,0x72,0xe7,0xd0,0x93,0x32,0x0d,0x8a,0x79,0x50,0xd6,0xc8,0x66,0x4f, + 0xb5,0xed,0x70,0xd5,0x8c,0xab,0x57,0xfe,0x43,0xdd,0xad,0x01,0xc4,0xbe,0xb5,0xa1, + 0xf8,0x12,0x02,0xca,0x68,0x6c,0x06,0x19,0x23,0xbe,0x41,0xae,0xde,0x6c,0x14,0xd8, + 0xed,0x5a,0x21,0xca,0x45,0xbc,0x5b,0xb3,0x33,0x1c,0x7b,0x5a,0x84,0xc3,0x84,0xb6, + 0x76,0x8a,0x6b,0x69,0x7e,0x84,0x4c,0x5d,0xc8,0x8d,0x4e,0x56,0xad,0x8e,0x51,0x65, + 0x9c,0xaa,0x68,0xc3,0x76,0xbe,0x38,0x6e,0xd3,0xcc,0xd9,0xc5,0x70,0x48,0x21,0x15, + 0x39,0x3d,0x32,0xa2,0xec,0x44,0x1c,0xd2,0x3e,0xca,0x99,0x4f,0xb6,0x0d,0xec,0xf8, + 0x22,0x00,0x95,0x8e,0xc7,0xf4,0xfa,0xbc,0xba,0xe2,0xea,0x98,0xa0,0xca,0x66,0x03, + 0x1e,0x7a,0x80,0x6f,0x6e,0x0b,0xe5,0xf4,0x8d,0x73,0x26,0x0b,0xf2,0x0e,0x32,0x54, + 0x0d,0xf8,0xa1,0xcd,0x3b,0xbb,0x4b,0x82,0x16,0x9d,0xb3,0xc4,0x14,0xe0,0x16,0xa9, + 0xec,0x33,0xf9,0x11,0xdd,0xba,0x2d,0xce,0xf3,0xa0,0x3f,0xa7,0x82,0xe3,0x30,0x7d, + 0x88,0x97,0xd3,0x6c,0xaa,0x2d,0x10,0x69,0xb2,0x24,0xd6,0x48,0xbb,0xc3,0xea,0xef, + 0xe9,0x8c,0x3c,0xfa,0xde,0xff,0xf1,0xd3,0x85,0xce,0x8b,0xc4,0x4e,0xbb,0xd3,0x51, + 0x47,0x67,0x14,0x1b,0x12,0x7f,0x8a,0xfa,0x08,0xb0,0x41,0x0a,0x97,0x1b,0x42,0x58, + 0x5e,0xe4,0xe0,0x16,0xaf,0x63,0xd9,0xb4,0x6d,0xd9,0x09,0x85,0x59,0x51,0x85,0x9d, + 0x1b,0x1a,0x51,0xf3,0x0e,0x7c,0x0f,0x91,0x2e,0x7b,0x4a,0x7a,0xbf,0xe0,0xe4,0xf2, + 0xac,0xe3,0xee,0xb3,0xcb,0x1f,0x9c,0xd8,0x23,0x9d,0x50,0xfc,0x44,0x4f,0xee,0xdb, + 0x75,0xfc,0x47,0x17,0xcc,0x5d,0xd1,0xc8,0xf4,0xbb,0xcf,0xef,0xbb,0xfe,0xd9,0x95, + 0x03,0x7d,0xd5,0x88,0x96,0xbc,0x61,0xfc,0x6f,0xed,0xd8,0x5d,0xb0,0x3d,0x6f,0x99, + 0x04,0x15,0xc4,0x47,0xad,0xe7,0x3c,0x11,0x3a,0x93,0x8e,0xe4,0x1b,0xe2,0xb6,0x85, + 0x29,0x50,0x60,0x79,0x7f,0xcc,0x99,0xdf,0xe4,0x6b,0x07,0x53,0x4f,0xc6,0x93,0xd7, + 0x08,0x55,0xda,0xb9,0xd7,0xe5,0x4d,0xc1,0x20,0xfa,0x47,0xcd,0x60,0x54,0x68,0xe4, + 0x08,0xf1,0x64,0x18,0x19,0xb7,0x6b,0x64,0xf4,0x78,0xf6,0xbc,0x11,0xa8,0x1e,0x0d, + 0x9e,0x1b,0x98,0xd7,0x4a,0xd5,0xbb,0x51,0xa3,0x91,0xd6,0x61,0xee,0x23,0x69,0xaf, + 0xd5,0xa6,0xbe,0x5c,0x0d,0xcd,0xd3,0x6d,0xf9,0x70,0x7f,0xb6,0x68,0x55,0x5d,0xe2, + 0xd9,0x82,0x1c,0x59,0xc8,0x92,0x29,0x65,0xf2,0xac,0xb9,0x4e,0xe0,0x5d,0x27,0x3f, + 0x06,0xa8,0x7c,0x3f,0x5c,0x8a,0x1a,0x99,0xcb,0x3c,0x7c,0xa2,0x5d,0x6d,0xba,0x83, + 0x9d,0x38,0x66,0xa8,0xf0,0xdc,0xcf,0xf8,0x5d,0x9a,0x37,0xf1,0x69,0x0f,0xb7,0x9a, + 0x0b,0x4f,0x2c,0x41,0xab,0x93,0x97,0x9f,0x6f,0xc5,0xd6,0xe8,0x35,0xbc,0x27,0x07, + 0x95,0x6c,0xae,0x5e,0xc3,0xdb,0xf5,0x77,0x72,0xcf,0x70,0xdd,0x27,0x7d,0x56,0x2f, + 0x3b,0xc9,0x91,0x12,0xe0,0xf1,0xb1,0x01,0xd3,0x9d,0xbc,0x98,0xdd,0xe4,0x42,0x52, + 0x75,0xba,0x8b,0x1c,0x9d,0xb6,0xf7,0xc6,0xff,0x86,0x3d,0x45,0x36,0x1d,0xfb,0x6f, + 0xf5,0x71,0x91,0x81,0x5d,0x87,0xa1,0xc9,0xb9,0x74,0x2f,0x05,0xa4,0x21,0x3d,0x29, + 0x58,0x39,0xbc,0x77,0xa6,0x68,0xfb,0x20,0x3f,0x75,0x31,0xb3,0x2c,0x3e,0xda,0x38, + 0x9e,0x8c,0x0e,0x93,0xae,0xbf,0x2f,0xa5,0x83,0x9c,0x20,0x48,0xcd,0x7b,0x30,0x9f, + 0x05,0x90,0x93,0x6a,0x42,0x11,0x62,0x87,0x0f,0x79,0xf1,0x2c,0x16,0xcf,0x1d,0xb5, + 0x6d,0x16,0xbe,0x9b,0x95,0xbf,0x20,0x45,0xbf,0x80,0x22,0x4c,0xe7,0xcc,0x98,0x67, + 0x8d,0xb1,0x36,0xf7,0x44,0x6f,0x6c,0xd0,0x01,0x41,0xc5,0xca,0x03,0x6b,0x24,0xf1, + 0x3c,0x26,0x0c,0x8a,0xc7,0xb2,0x9e,0xca,0xae,0xd2,0x53,0x09,0xe3,0xe0,0x16,0xdc, + 0x03,0x47,0xda,0xb4,0xb2,0x80,0xea,0xcc,0x18,0x03,0xa6,0x51,0xe4,0x48,0x4b,0x02, + 0x4a,0x00,0xdc,0xd9,0x8f,0xb4,0xf5,0x75,0x31,0xed,0x07,0xb4,0x38,0xf6,0x2a,0x05, + 0xad,0x74,0x77,0x39,0x48,0xf8,0xb3,0x20,0x55,0x82,0xa1,0x14,0xf5,0xad,0xe5,0xd4, + 0x1d,0x66,0x0a,0x74,0x3a,0x31,0x0b,0x47,0xd6,0x13,0x4e,0x2d,0x4b,0xd7,0xf8,0x70, + 0x26,0x85,0x22,0x08,0x39,0xd2,0x2e,0x14,0x94,0xb0,0xf3,0x48,0x69,0x29,0x3c,0x61, + 0xf9,0x3e,0x45,0xa2,0xa9,0x55,0x1f,0xcc,0x16,0x86,0xbf,0x26,0x67,0x07,0xc0,0x9c, + 0x9a,0xf1,0xe6,0x15,0xc0,0x89,0x0e,0x83,0x6b,0x97,0x74,0xf2,0x0b,0xf7,0xc9,0x45, + 0x89,0x4f,0x84,0xd7,0xcd,0x6f,0x48,0xa8,0x32,0x29,0x18,0x7d,0x41,0xa4,0x55,0x47, + 0x2d,0x9b,0x30,0xc3,0x2e,0x5e,0x17,0x84,0x3f,0xfe,0x99,0xd9,0xb5,0xf0,0xfa,0x79, + 0x0e,0xa7,0x86,0x8b,0x50,0x29,0xec,0x1e,0xd8,0x9a,0x79,0xf1,0xe6,0xf3,0xf1,0x45, + 0xa1,0x9c,0x1a,0xf8,0x72,0xa5,0x48,0x23,0xf6,0x39,0xe7,0x98,0x0c,0x5c,0x19,0xbd, + 0xa4,0xe3,0x58,0x12,0x72,0xdc,0x33,0x9d,0x78,0x89,0xbe,0x5a,0x5d,0xd4,0xed,0x97, + 0xdd,0x06,0xf6,0xb5,0xf1,0x62,0xee,0x04,0x9f,0x66,0xec,0x2f,0x06,0xcc,0x26,0x0a, + 0x21,0x1f,0xa4,0x18,0x33,0x7a,0xc9,0x64,0xda,0x28,0xdb,0x47,0x3b,0xe2,0x09,0x7b, + 0xf3,0x58,0x64,0xa6,0x04,0x24,0xa2,0xdf,0xdd,0x87,0x44,0xd5,0xfc,0x21,0xfb,0x5e, + 0xee,0xb6,0xec,0x62,0xad,0xa2,0xd3,0xfc,0xb2,0xf0,0x7b,0xa6,0xb2,0x3c,0x4d,0xc1, + 0x41,0xfe,0x00,0x3e,0x78,0x66,0x2c,0x24,0x3d,0xd6,0x4e,0xc6,0x07,0x37,0x4b,0xbc, + 0x2c,0x6f,0x2f,0x94,0x4a,0x5b,0x92,0xec,0xb4,0x45,0x1d,0x35,0xc4,0x44,0x42,0x1b, + 0xff,0x76,0x25,0xec,0x0c,0x68,0xf1,0xd9,0x3a,0xa3,0x48,0x24,0x90,0x50,0x5e,0x4b, + 0x1d,0xb6,0xbc,0x40,0xc5,0xa7,0xd6,0x09,0x9a,0x25,0x33,0x16,0x3d,0xf9,0xc8,0x99, + 0xff,0xe4,0x00,0x2f,0x5f,0x4d,0x22,0x97,0x88,0x84,0x28,0xf0,0xa1,0xd4,0x99,0x4b, + 0xc1,0x3a,0xf7,0xc9,0x77,0x90,0x83,0xdc,0x5f,0x4e,0xb3,0xc7,0x4a,0x66,0xba,0xc3, + 0x2e,0xf8,0xe2,0xa6,0x43,0xd8,0xc8,0xd4,0xe6,0x37,0x2d,0xb1,0x58,0xad,0x45,0x62, + 0x73,0xbf,0xe6,0x9a,0xdd,0x40,0x7e,0xe2,0x93,0xda,0xc5,0x21,0xeb,0xbb,0x90,0x24, + 0xe5,0x1e,0x56,0xa3,0xdf,0x41,0x41,0x17,0x9c,0xeb,0xa0,0xae,0xa4,0x08,0x27,0x84, + 0x03,0x0d,0x46,0x32,0x02,0x6e,0xd1,0xe8,0x50,0x49,0x73,0x60,0xaf,0x8c,0xd4,0xd0, + 0x86,0xb4,0x43,0x38,0xd5,0x62,0xb5,0x8e,0x60,0x68,0x85,0xb6,0xf1,0x62,0xab,0x4f, + 0x0b,0xa0,0x27,0x5e,0xfa,0x6f,0x5a,0x8b,0x48,0xb9,0x85,0x81,0x06,0x74,0x03,0xfe, + 0x36,0x69,0xc4,0xa4,0xae,0x09,0x4a,0x35,0x71,0x80,0x3d,0xd8,0x57,0xb3,0x23,0xb2, + 0x14,0x88,0xdb,0x0c,0x05,0x4d,0x35,0xea,0x9e,0x0f,0x21,0xdd,0x7d,0x2d,0x94,0xeb, + 0x66,0x29,0xf5,0xa5,0xce,0x51,0xae,0x46,0x4e,0xec,0x56,0xd9,0xf1,0xba,0x6a,0xd0, + 0xcb,0xf1,0x85,0x9e,0xb2,0x97,0x27,0xed,0x52,0x01,0x51,0xf2,0x69,0xdd,0x1b,0xa9, + 0x15,0x16,0x7d,0xb2,0x50,0x91,0xc3,0xbe,0x47,0x95,0x77,0x3d,0x39,0x4f,0x59,0xf0, + 0xf7,0xe9,0x36,0x82,0x83,0x49,0xc9,0xc6,0x46,0x2f,0x9b,0x2d,0xc1,0x2a,0x4e,0x4f, + 0xe5,0xbd,0xf3,0x68,0x5e,0x0c,0x4d,0xf7,0x40,0xb8,0x7e,0x3a,0xed,0x99,0x4e,0x3a, + 0x63,0xf2,0x9e,0xaa,0x09,0xe9,0x82,0x94,0x21,0xcf,0x5b,0x79,0x5a,0x1c,0x1e,0xb3, + 0xfb,0x2e,0x36,0xa5,0x33,0xb7,0x21,0xf2,0xf6,0xc8,0x26,0xdf,0x99,0x88,0x33,0x47, + 0x49,0x54,0x87,0xf7,0x1c,0x21,0x59,0x9e,0x09,0x1b,0x4b,0xf0,0x83,0x70,0x2f,0x79, + 0x3e,0x96,0x6e,0xf2,0x44,0xbe,0x9f,0x8f,0x5f,0x2c,0xa1,0xa4,0x18,0x19,0xbc,0xee, + 0x7c,0x77,0x31,0x61,0x4d,0xfb,0xfd,0x19,0x17,0x62,0xc2,0xfe,0x3b,0xf1,0x4a,0x85, + 0xce,0x97,0xb7,0x0f,0xd3,0xf8,0x98,0x56,0xaa,0x94,0xbc,0x14,0x77,0x1c,0x91,0xa3, + 0x62,0x00,0x63,0x42,0x5e,0xe9,0xa0,0x7c,0x3e,0xed,0xe8,0x10,0x16,0xaa,0x5c,0x83, + 0xc2,0xd2,0xd2,0xa1,0x59,0xa9,0x57,0x36,0x69,0x76,0x1e,0xf4,0x65,0x63,0xd6,0x65, + 0xce,0xc4,0xe5,0x2d,0x4c,0xe8,0xa4,0xcb,0xb9,0x84,0xde,0xb0,0xa8,0xf2,0x57,0xfd, + 0xaa,0x77,0x10,0x03,0xd0,0x0a,0xfd,0x25,0xd5,0xf0,0xa5,0xb9,0x13,0x3c,0x3b,0xdc, + 0x78,0xb8,0xff,0x26,0x7f,0x66,0xa6,0x51,0x29,0xf2,0x99,0x51,0xfd,0x1b,0xc0,0x65, + 0x69,0xda,0xb4,0x39,0x00,0xc6,0xf2,0x8e,0xcd,0xec,0x0c,0x3b,0x16,0xed,0x61,0x37, + 0xfb,0x41,0x33,0x94,0xca,0x72,0x34,0xcd,0x09,0xf1,0x3b,0x57,0xce,0x10,0x92,0xec, + 0x3f,0x74,0x5f,0x01,0x5f,0x55,0xe9,0x8f,0x08,0x33,0x9f,0x0a,0x83,0xa2,0x9b,0x20, + 0x4f,0x79,0x0e,0xa3,0x82,0x71,0xa2,0x2d,0xb0,0xf7,0x4a,0x0f,0x6a,0xd5,0xb8,0xb7, + 0x12,0x29,0x8d,0x90,0x1d,0x26,0x1b,0xd9,0x91,0x16,0xa7,0xdf,0x8c,0x4d,0xe7,0x71, + 0xa5,0x46,0x73,0x7a,0x4c,0xb4,0x87,0x4a,0x5b,0x18,0x1f,0xae,0x87,0x87,0x78,0x77, + 0xc1,0x41,0xf9,0xa1,0xbc,0x45,0x33,0xd5,0x38,0x27,0x4c,0x57,0xed,0x05,0x3b,0x8b, + 0x02,0x02,0x89,0x71,0x48,0xe2,0x9c,0xa8,0x0c,0x9f,0x91,0x4f,0x21,0xf8,0x6e,0xdc, + 0x37,0x51,0x07,0x3d,0xba,0x77,0xaf,0x48,0xb3,0xf3,0x02,0xa5,0xa4,0x06,0x2d,0x1a, + 0xe2,0x6f,0x31,0x12,0x14,0x92,0x30,0x6b,0x42,0x79,0x90,0x12,0x1d,0xc9,0xf8,0xc1, + 0x07,0x33,0x0a,0xdb,0xe9,0xd4,0x91,0x27,0x3a,0x84,0x4f,0x96,0xd8,0x34,0xe3,0x88, + 0x77,0x36,0xa2,0x27,0x64,0x5b,0xed,0x78,0xf1,0x78,0x24,0x7c,0x1f,0x39,0x7d,0x17, + 0x5a,0xf5,0xad,0x93,0x63,0x70,0x94,0xde,0x1d,0x9a,0x31,0x1a,0xfc,0x88,0xcd,0xf7, + 0xcf,0x2c,0xe3,0x58,0xb6,0xa3,0xd5,0x0a,0x90,0x30,0x6b,0x77,0x7e,0x3c,0x62,0x0c, + 0xc2,0x9b,0x5d,0x87,0x94,0x73,0x10,0xa9,0x87,0xa0,0xad,0x89,0x4b,0xf3,0x6b,0xa0, + 0x25,0x7f,0xc2,0xf8,0xed,0xe8,0x72,0x5e,0x8b,0x06,0x08,0x5b,0x63,0x46,0x1f,0x84, + 0x60,0x97,0x77,0x57,0x83,0x92,0xe4,0x17,0x45,0x05,0x23,0x15,0x4c,0x77,0x92,0xf3, + 0x22,0xa4,0xb2,0x3f,0x30,0x62,0xbd,0x4d,0x0c,0x62,0xb3,0x96,0xcd,0xe3,0x4c,0xbc, + 0x4f,0xf6,0x35,0xee,0x48,0x7e,0xb0,0xa0,0x3f,0x29,0x92,0x39,0x35,0xc9,0x68,0xb6, + 0xac,0x69,0x70,0x52,0xb5,0x45,0x68,0x7d,0xf9,0x72,0xf6,0x05,0xf3,0x88,0xe9,0x8b, + 0x53,0x82,0x62,0xce,0x3d,0xc9,0x5b,0xf3,0x50,0x19,0xfb,0xf5,0x9c,0x03,0xa7,0xef, + 0x38,0xa0,0xc6,0xef,0x62,0xec,0xf8,0x8a,0x8d,0x13,0x72,0x01,0xdc,0xa7,0x4a,0x85, + 0x11,0xe4,0x2b,0xda,0x2b,0x92,0x20,0x72,0x47,0x4e,0xa2,0x19,0xba,0x0e,0xaf,0x1d, + 0xab,0x8b,0xf0,0x25,0x04,0xf2,0x29,0x59,0xb4,0x22,0x60,0xd7,0x6b,0x38,0xbd,0xb0, + 0x74,0xe0,0x96,0x9b,0x92,0x1f,0x60,0x3f,0x54,0x4a,0x3e,0xf6,0xcd,0xcb,0x0d,0xb2, + 0xcb,0x12,0xcd,0x51,0xe9,0xd6,0xc1,0x36,0xc1,0x1f,0x8c,0x34,0x61,0xed,0xf4,0x15, + 0xc0,0xe6,0x2a,0x65,0x0e,0xc0,0x4f,0x06,0x47,0x70,0xc7,0xef,0x36,0x7d,0xbe,0x19, + 0xc6,0xad,0x61,0xec,0x61,0x76,0x3c,0x92,0x19,0x53,0xbf,0x96,0x87,0xc3,0xf6,0x91, + 0x8b,0x05,0xb4,0x6d,0xfc,0x3a,0xbe,0x43,0x98,0xce,0xea,0xbe,0x72,0x4b,0xa3,0xe7, + 0x53,0x88,0x62,0xc9,0x53,0x3b,0x4e,0x45,0x4f,0xad,0x6d,0x57,0x6e,0xa9,0x3b,0xeb, + 0x55,0xb4,0x80,0x00,0x87,0x30,0xbe,0x10,0x40,0x78,0xc2,0xf3,0xf8,0xc3,0x2f,0x34, + 0x76,0x12,0x4d,0x18,0xef,0x23,0xbb,0x5d,0x3c,0x37,0xc6,0xab,0xb4,0xae,0x48,0xd6, + 0x62,0xc3,0x58,0x34,0x13,0x61,0x52,0xb6,0x39,0x8e,0x73,0xb2,0x34,0x55,0x68,0x86, + 0x21,0x5d,0x29,0x15,0x48,0x8e,0xe8,0x8d,0x63,0xbf,0x07,0xef,0x98,0x3f,0xec,0x4d, + 0x52,0x03,0x23,0x33,0x8b,0x57,0x48,0x0e,0xef,0x50,0x8a,0xd5,0x87,0x38,0x73,0x0b, + 0xe3,0x38,0x4b,0x49,0x2c,0x57,0x28,0xb7,0xf8,0x9a,0xd5,0x16,0x6e,0x41,0x6b,0x6a, + 0x29,0x2e,0x43,0x0e,0x0e,0x20,0x69,0xf0,0x13,0x7b,0xcf,0x2e,0x30,0x25,0x34,0x64, + 0xd1,0xca,0x49,0x3e,0xc7,0x0b,0xe9,0x79,0x8e,0x4d,0x77,0xcc,0xbb,0x2c,0x13,0x51, + 0x13,0xd5,0x16,0x0c,0x7e,0xa6,0x5c,0xa7,0x41,0xd1,0xaa,0x86,0x2b,0xec,0x9e,0x5b, + 0x70,0x16,0x7c,0x41,0x44,0xfe,0xca,0x9b,0x38,0xfa,0x91,0xdc,0x60,0xfb,0xf7,0xe2, + 0xf0,0x44,0xcf,0xa7,0x21,0xd4,0x1c,0xb4,0x14,0x58,0x3b,0x68,0xe6,0x6b,0xbc,0xf4, + 0x5c,0x83,0x65,0x9e,0xf7,0x45,0x97,0x61,0x95,0xbe,0x83,0x73,0x73,0x68,0x27,0xcc, + 0x23,0xd3,0xf0,0x09,0xa4,0xd6,0x29,0x70,0x41,0xbc,0x11,0x33,0xda,0x73,0x27,0xac, + 0x86,0x85,0x59,0x86,0xa9,0xce,0x2a,0xb9,0x0e,0x46,0xc7,0x35,0x1c,0xe0,0x49,0x59, + 0x54,0x30,0x24,0xab,0x31,0x7d,0xc0,0x14,0xf3,0x48,0x74,0x32,0xc3,0x7c,0x55,0x1d, + 0x85,0x04,0xb4,0x4d,0x8c,0xb1,0x5a,0x00,0xd4,0x09,0x44,0x9d,0x8f,0xfb,0x70,0x5c, + 0x85,0x3d,0x41,0xb3,0x98,0xd4,0x25,0x44,0xb7,0xc1,0xe3,0x12,0xa1,0xed,0x08,0x73, + 0x6e,0x1a,0x96,0xce,0x28,0x9a,0x64,0x77,0x99,0xa5,0x4c,0x8b,0xda,0x8a,0xd1,0xef, + 0x28,0x82,0x2b,0x9e,0x85,0x07,0x8c,0x32,0x20,0x46,0xe1,0x8a,0x3e,0x1a,0x90,0x4d, + 0xbe,0x3b,0x38,0x1a,0x1c,0xfc,0x8d,0xa6,0x41,0x20,0xc9,0xd8,0x39,0xba,0x03,0x2c, + 0x49,0x8f,0xfc,0xc3,0xdc,0xcf,0x0f,0x97,0x9c,0x57,0x71,0xb6,0xa1,0x4f,0x86,0x3a, + 0xa6,0xf6,0x18,0x0e,0x7b,0xdf,0x79,0x01,0x12,0xc7,0x23,0x3a,0x11,0x58,0xa8,0x44, + 0xba,0xb2,0xe1,0x32,0x2f,0xd0,0x8a,0x97,0x87,0x31,0xf2,0x44,0xe8,0x43,0x62,0xc4, + 0x1d,0x97,0x88,0x00,0x09,0x8e,0x2e,0x4b,0xf3,0xa0,0xc5,0xd3,0x13,0x9a,0x67,0xb2, + 0x63,0x5b,0x56,0xd5,0x4a,0x90,0x28,0x96,0xc7,0xf9,0x99,0x35,0x44,0xc6,0x2e,0x3b, + 0xc4,0x8b,0x9e,0xee,0xec,0x8e,0xf2,0x26,0xfd,0x46,0x9b,0xf6,0xd6,0x38,0x22,0x46, + 0x45,0xe5,0x62,0x9d,0x72,0xf3,0x92,0x47,0x76,0xf3,0x5d,0xef,0x37,0x69,0xcb,0xe3, + 0x2f,0x01,0xf7,0xd9,0xa9,0x14,0x6a,0xb5,0xb3,0xa1,0xb5,0xa3,0x0f,0xcf,0x78,0x9c, + 0x18,0x47,0xa0,0x58,0xa1,0xdd,0xef,0xe8,0x9c,0x27,0x17,0x5d,0xa0,0x62,0x45,0xc9, + 0x8a,0xab,0x82,0x63,0xa8,0xfa,0x50,0xe6,0xb6,0xf4,0x51,0xfc,0x77,0xbc,0xc0,0x1c, + 0xd3,0x90,0x86,0x40,0xf2,0x5b,0x23,0x91,0x61,0x60,0x21,0x85,0xf9,0x85,0x66,0xec, + 0x36,0x1f,0xfd,0x8b,0x7c,0xa3,0xec,0x21,0x05,0x43,0xa9,0x6a,0xec,0x99,0x61,0x8d, + 0xc5,0xd0,0x34,0xa5,0xd2,0x0c,0x4c,0x42,0x59,0x13,0x68,0xc1,0xfe,0x65,0x71,0xf3, + 0xd0,0xf4,0xda,0x22,0x69,0x86,0xeb,0x6a,0xc2,0x86,0xc4,0x4c,0x7f,0x6b,0x9b,0x1d, + 0x84,0xbb,0x00,0x00,0xdd,0xa4,0x9a,0xb4,0x05,0xcb,0x28,0x84,0x52,0x6e,0x50,0xc8, + 0x03,0xeb,0xc3,0xb4,0x27,0xe2,0xaa,0x20,0x49,0xb0,0xef,0xed,0x62,0x16,0xca,0x70, + 0x6b,0xdf,0x72,0xbc,0x39,0xf2,0x5c,0x1c,0x2b,0x0f,0x2b,0x1f,0x3e,0xf2,0xeb,0x5d, + 0xbf,0x31,0xa1,0xb3,0xb7,0x20,0xf3,0xe1,0xdd,0x10,0xcb,0x0f,0x55,0xb7,0xd2,0xa1, + 0x6c,0x01,0x89,0xdb,0xc6,0xef,0x69,0xd2,0x04,0xc5,0xad,0x41,0x50,0xf0,0xdc,0x3a, + 0xa0,0x2e,0xa7,0xf2,0x04,0xb3,0x75,0x65,0x64,0xf3,0x3e,0x05,0x13,0x29,0x75,0x38, + 0x89,0xf9,0x4e,0xd4,0x90,0xb6,0x28,0xa9,0xf9,0x52,0xa6,0x12,0xa0,0xde,0x57,0x24, + 0x65,0xc8,0xe8,0x2b,0x3c,0x89,0xa4,0xe1,0x78,0xbc,0xc5,0xd0,0x0a,0x8b,0x92,0x14, + 0x51,0x25,0x13,0xb0,0x8f,0x1b,0x4a,0xd3,0xab,0x70,0x65,0x21,0xd3,0x65,0xaf,0x90, + 0xdc,0x2e,0x7a,0x6a,0x69,0xd0,0x06,0x66,0xe1,0x39,0xca,0x47,0x5b,0x01,0xc7,0x48, + 0xc7,0x57,0x02,0x47,0xaa,0xdc,0x6d,0xd0,0x8a,0x9d,0xbe,0xb3,0x4c,0x1b,0xe3,0x9e, + 0xd2,0x5c,0x48,0x76,0x9b,0x86,0x4d,0x66,0x24,0x40,0xd1,0x50,0x0a,0xec,0x81,0x46, + 0x16,0x1f,0x3c,0xab,0x03,0xf4,0x8c,0x77,0xd1,0xa9,0x34,0x03,0xcf,0x08,0x67,0x33, + 0xd7,0x46,0xde,0xc8,0xd3,0xb0,0xb1,0x7a,0xc2,0x1f,0x7d,0x2d,0x0d,0xf7,0x1d,0xb6, + 0x52,0x96,0xcc,0x5f,0x40,0x6d,0x02,0x9d,0x64,0x02,0x4f,0x53,0xa4,0x2c,0x2f,0xf2, + 0x0b,0xb4,0x61,0x8d,0x05,0xb2,0x9b,0xb5,0xb2,0xcd,0x0d,0x52,0x44,0x26,0x30,0x8b, + 0xb1,0xed,0x79,0xa7,0x50,0xc9,0xb1,0xdf,0x94,0x79,0xfb,0x09,0x6f,0xbf,0x51,0x3a, + 0x86,0xa5,0x4e,0xcd,0xf8,0x45,0x76,0x83,0x25,0x4e,0x0c,0x11,0x8f,0xbf,0x14,0x35, + 0xa4,0xfd,0x51,0xea,0x82,0xbd,0x8f,0x2a,0xea,0x9b,0x50,0x64,0x0a,0x36,0x76,0x7e, + 0x78,0xdd,0x66,0x64,0xce,0xb5,0xfb,0x23,0xaf,0xb6,0xc0,0x11,0xdf,0x76,0xd0,0x27, + 0xc6,0x86,0xfd,0x64,0x02,0xd0,0x80,0x23,0xab,0xbd,0xf8,0xba,0xa8,0x50,0xfa,0x54, + 0xd3,0x2d,0xba,0x42,0x67,0xa9,0x8b,0xa4,0x61,0x6b,0x73,0x9a,0x02,0x4b,0x20,0x07, + 0xbd,0x4d,0xa5,0xf3,0xe4,0x5b,0xb8,0x6b,0x16,0x9b,0x34,0x95,0xf6,0xcd,0xd6,0xb1, + 0x74,0x37,0xe6,0x4a,0xb3,0x9c,0x3a,0x58,0x13,0x12,0x5a,0xdc,0xd9,0xa1,0xc3,0xf4, + 0x49,0x9b,0x0b,0xbf,0x28,0x24,0x52,0x39,0x1f,0xb8,0x04,0x4e,0x42,0x71,0x23,0x10, + 0xf6,0xb7,0x15,0x34,0x13,0xdb,0xbe,0x38,0xb1,0x61,0xf7,0xca,0x41,0x84,0x91,0x44, + 0x68,0xae,0xb9,0xcf,0xfd,0x6c,0x44,0xc8,0x98,0xe5,0xb1,0x11,0x37,0x70,0x29,0xe2, + 0xe6,0x98,0x62,0x3f,0xce,0x80,0xc2,0x5c,0x6f,0x9e,0x21,0x5c,0x0d,0x0a,0x79,0x29, + 0x5f,0x4a,0xc4,0x35,0xe2,0xba,0x90,0xe4,0x19,0x3e,0xbd,0x08,0xe7,0xdb,0x48,0x2a, + 0x66,0xac,0x04,0xf4,0xd1,0x77,0x76,0x83,0xa2,0x72,0xec,0x7f,0x5f,0xa7,0xb1,0xa7, + 0x3a,0x28,0x47,0x95,0xc1,0x18,0x1c,0x9d,0xf3,0x2c,0xf5,0x09,0x28,0xc6,0xba,0x16, + 0x7f,0xce,0xe9,0x37,0xce,0xb3,0x2b,0xc1,0x74,0x11,0xe3,0x9b,0x20,0x64,0x0e,0x32, + 0x51,0xa6,0x7c,0x42,0x11,0xf4,0x45,0x44,0x1b,0x95,0x5a,0xeb,0x02,0xab,0x49,0xba, + 0xe6,0xb1,0x84,0x17,0x00,0x05,0x94,0x05,0x93,0x68,0x46,0x7a,0xe3,0xfd,0xa1,0x79, + 0xb6,0xbd,0x89,0x21,0x1c,0xe1,0x3d,0x0f,0xc6,0x69,0xcb,0x3b,0x16,0x6a,0x38,0xcf, + 0xa6,0xef,0xdc,0x77,0x2b,0xac,0xc1,0x8d,0x71,0xc2,0x4d,0x4f,0xa5,0xd5,0x7d,0xce, + 0x83,0x6a,0x02,0x91,0xa3,0xb9,0x2f,0xf6,0xcc,0x60,0x1a,0xaa,0xe8,0x5b,0xe6,0x26, + 0x5b,0x0d,0x51,0xc6,0x93,0x78,0x92,0x80,0xd5,0x42,0x34,0x5c,0x4b,0x68,0x3c,0xd7, + 0xd3,0x46,0x91,0x9b,0x7f,0x1d,0x64,0x73,0xed,0xa6,0xec,0xa8,0x9a,0xa5,0xe3,0x19, + 0x7e,0x77,0x7a,0xd3,0x48,0xf2,0x2a,0xf6,0x4a,0xc8,0xb2,0x62,0x73,0xc8,0xa7,0x02, + 0xab,0x46,0x94,0x1b,0x55,0x40,0x7c,0xe9,0x21,0x09,0xa4,0x9c,0x16,0x42,0xf3,0xe8, + 0xfb,0x81,0xb5,0x19,0x7f,0x88,0x57,0x70,0x0e,0x94,0x6d,0x49,0xf4,0xd9,0xe0,0x32, + 0xd6,0xc2,0x69,0x90,0x99,0xf5,0xf8,0x02,0x02,0x98,0xb8,0x7d,0x45,0x1f,0x57,0x49, + 0x0d,0x8e,0x0f,0x8a,0xb6,0xbd,0xed,0x6d,0x17,0x07,0x73,0x3a,0xec,0x00,0x9a,0x9f, + 0x8d,0x6f,0x4e,0x23,0xa2,0x19,0xb1,0x0d,0xe6,0xca,0xb4,0x66,0x8a,0xcf,0x0b,0xc9, + 0x9b,0xeb,0x12,0xf1,0xf4,0x55,0x11,0x35,0x7d,0x00,0x84,0x19,0xb4,0xba,0xa3,0x82, + 0x5d,0x63,0xa2,0xd6,0xc9,0xc6,0xb3,0x95,0x9b,0x5f,0x9c,0x88,0x14,0x69,0x13,0x7b, + 0xda,0x1e,0xe9,0x7e,0x82,0x56,0xda,0xd8,0x26,0x8a,0x8a,0x45,0x07,0x1f,0xc8,0xa0, + 0xc3,0x18,0x20,0x7c,0x8d,0x5f,0xd0,0x16,0xd1,0x4f,0xea,0x30,0x77,0xbb,0x2c,0x73, + 0xcc,0x5d,0xb3,0x1b,0x34,0x74,0x83,0x5d,0xbd,0x5e,0x2a,0xcf,0xbe,0x18,0x96,0x11, + 0x91,0x5b,0xf0,0x80,0x76,0x52,0x16,0xfa,0x22,0x42,0x67,0xac,0x3a,0xc9,0xeb,0x10, + 0xd8,0xf4,0x3e,0xfe,0x5d,0x6d,0x30,0xcc,0xf3,0xea,0x92,0xf3,0xd9,0xdc,0x46,0x2f, + 0x02,0xbc,0xbd,0xf5,0x74,0x46,0xea,0xce,0x3b,0x69,0x54,0xdc,0xc6,0x47,0x38,0xd9, + 0xb8,0x84,0x0b,0x43,0xd4,0xdd,0x80,0x1f,0x28,0xd4,0x68,0x3f,0x34,0xd1,0xbc,0xde, + 0xe2,0x33,0x40,0xde,0x51,0x4c,0x45,0x44,0x0e,0xf0,0xbe,0x0f,0xe9,0x54,0xa4,0xca, + 0x71,0xca,0x9c,0x26,0x0f,0xca,0xdf,0x25,0x3c,0x59,0xe6,0xa9,0x7b,0x7f,0x1a,0x5b, + 0x8e,0x54,0xdf,0x15,0x06,0x0f,0xa3,0x07,0x28,0x05,0x2e,0x4a,0x7a,0x03,0xbb,0x9e, + 0xd8,0x5a,0xf5,0x94,0xad,0xc6,0xab,0x3b,0x0f,0xd7,0x6d,0x5f,0xa4,0x8a,0x0e,0x5d, + 0xba,0x80,0x91,0xa3,0x64,0x58,0x3b,0xe3,0x84,0xde,0x93,0x34,0x16,0xc7,0xcc,0x7d, + 0xbc,0xe7,0x0f,0x9d,0x94,0x12,0xcb,0xdf,0xe0,0xdb,0xec,0x41,0x1d,0x6c,0xf1,0x21, + 0xe8,0xd5,0x84,0x5a,0xc2,0xe7,0x71,0xc8,0x4b,0x66,0x67,0x81,0xb5,0xc7,0xb3,0xbe, + 0x0a,0x0d,0x53,0xfd,0x0f,0x57,0x51,0xe8,0xa9,0x2c,0xcb,0xd3,0x92,0x9d,0x5b,0x63, + 0x7c,0xbd,0x7f,0xf0,0x90,0x24,0x7a,0x09,0x73,0xeb,0x5c,0x0a,0x3f,0x43,0x3b,0x5c, + 0x94,0x1d,0x40,0xaa,0x4a,0xef,0xdc,0xaa,0xa0,0xde,0x6e,0x74,0x21,0x84,0xc0,0xd4, + 0x9e,0x65,0xe0,0x35,0xad,0x43,0x02,0xeb,0xd6,0x2f,0x48,0x5f,0x70,0x93,0xc5,0xe0, + 0x6b,0x5e,0x3e,0xca,0x52,0xcf,0x69,0x56,0xb3,0x40,0x5e,0x55,0x5e,0x8f,0x1b,0x55, + 0xa4,0xe6,0x77,0x7a,0x64,0xb6,0x7f,0x66,0x64,0xb4,0xbf,0x13,0x27,0x75,0x28,0xe9, + 0x44,0xc1,0x7a,0x2a,0xce,0x34,0x0b,0xd1,0xae,0x4e,0xb6,0xe8,0x68,0x93,0x1f,0xa2, + 0x46,0x9c,0xad,0x5a,0xbe,0xb6,0xb1,0x46,0xac,0xe3,0xd5,0x81,0x5c,0xfe,0x79,0x98, + 0x6c,0x61,0x64,0x68,0xe7,0x26,0x53,0xa2,0x99,0x3c,0xf6,0xe6,0x98,0x67,0x62,0x64, + 0xd7,0x3d,0xda,0x2b,0x55,0x24,0x09,0x39,0x7f,0x9a,0x7a,0x78,0xe4,0x90,0x18,0x82, + 0x85,0xdc,0x67,0x99,0x8c,0x27,0x99,0x41,0xbf,0x59,0xa4,0x02,0xc9,0x85,0x8c,0x12, + 0x86,0xd4,0x79,0xf1,0xdc,0x18,0xac,0xc1,0xf2,0xde,0x7e,0x78,0x71,0xde,0xb8,0x3e, + 0x3b,0x10,0xc9,0x56,0x57,0x00,0x26,0x32,0x80,0x27,0xc0,0x7a,0x8c,0x74,0xa3,0x03, + 0x42,0x7b,0x85,0x09,0xb9,0xe7,0x79,0x72,0x8e,0x4d,0xb2,0x13,0xd9,0xa0,0x50,0xbe, + 0x94,0x2a,0x2e,0x1c,0xa8,0x20,0x98,0x3d,0x02,0x5d,0x14,0x64,0x17,0x88,0xfc,0xd9, + 0xb4,0xbe,0xdb,0x01,0xe4,0x7f,0x32,0xed,0xcc,0x68,0xb3,0x5a,0xc9,0xd6,0x66,0x2c, + 0x1a,0xd8,0xda,0x7d,0xcc,0x37,0x28,0x85,0x53,0x39,0x64,0xf0,0x5b,0x5b,0xde,0x24, + 0xbf,0xdd,0xdb,0x56,0xd5,0x66,0xc3,0xe1,0x4a,0xdf,0x56,0xa0,0x07,0xbd,0x9c,0xf2, + 0x62,0xa8,0xa9,0x1a,0x39,0x85,0xc2,0x91,0x6b,0xdd,0x77,0x83,0xa5,0x69,0x65,0x43, + 0x80,0xe9,0x1a,0x0e,0xa6,0x49,0x80,0x84,0x7c,0xa6,0x78,0xf9,0xde,0xcb,0xb1,0xce, + 0x41,0xb2,0xe2,0x29,0xc8,0x0f,0x0b,0x1b,0x74,0xd3,0x2e,0xbb,0x42,0x33,0x5d,0x12, + 0x06,0x74,0x53,0x32,0x2a,0xce,0x13,0x2e,0x87,0x12,0x35,0x94,0x57,0x40,0x16,0x0d, + 0xf3,0x9b,0x7d,0x09,0x29,0x01,0x47,0x1b,0x75,0xc4,0xba,0x56,0x45,0x3a,0xad,0xe1, + 0x30,0x4b,0xa3,0xc5,0x10,0x2e,0x8b,0x5f,0xe1,0x78,0x87,0x4d,0xb9,0x7a,0x88,0x57, + 0xb1,0x46,0x3c,0x2b,0xb6,0x8e,0xe4,0x68,0x88,0xd0,0xc3,0xa9,0x56,0xc2,0xd5,0x74, + 0x4b,0x01,0x61,0x07,0xce,0xb4,0x1a,0x64,0x8f,0xc3,0x26,0x10,0x26,0xc2,0x79,0x1d, + 0x24,0x23,0xf3,0x3b,0x3c,0x1b,0x65,0xd0,0xad,0x06,0xbd,0x74,0xa6,0xf2,0x99,0xbd, + 0x8b,0x2f,0xd8,0x11,0x3b,0x96,0xcc,0x1e,0xd5,0x6f,0x1c,0x5e,0x35,0xc7,0xdc,0x21, + 0xb7,0xd5,0xc3,0x72,0x9a,0x21,0x74,0x93,0x51,0xa0,0x0a,0x7e,0x79,0xe1,0xb0,0xb0, + 0xb9,0x63,0xd9,0xd9,0xf9,0x48,0xe7,0x3c,0xce,0x80,0x0e,0x24,0x1f,0x82,0x4a,0xc3, + 0x97,0x95,0xa1,0x2f,0x8b,0x00,0xe1,0x91,0x29,0x40,0x73,0x7c,0x8a,0xf4,0x75,0xfc, + 0x7d,0x73,0x4c,0x3f,0x2c,0x40,0xd9,0x44,0x4f,0x3f,0x6d,0x8b,0x34,0xfe,0xdd,0x0f, + 0x46,0xd1,0xad,0x26,0x21,0x6e,0xdc,0x9a,0x44,0xbb,0x8d,0x6d,0x98,0x6d,0xcb,0x90, + 0xd1,0x9c,0xff,0xba,0x45,0x62,0x31,0x8b,0x64,0xda,0x87,0xb2,0xf6,0x4f,0x5e,0xdd, + 0xbe,0x83,0x92,0x22,0xc4,0x6f,0xe5,0xb5,0xfe,0x19,0x02,0xf4,0x20,0xff,0x7d,0x9a, + 0xe8,0x30,0xf6,0x1d,0x3e,0x89,0x02,0x0f,0xba,0x71,0x94,0x51,0x6a,0x3c,0x64,0x22, + 0xae,0x4b,0x98,0x8d,0xd8,0xc3,0x0a,0x68,0x80,0x06,0xe9,0xe6,0x1a,0xc1,0x53,0x13, + 0xec,0x66,0x23,0xb2,0xad,0x22,0x82,0x03,0x4b,0xe8,0xe4,0x10,0x18,0xbb,0xf6,0xb8, + 0xbe,0xce,0xd3,0x79,0x72,0xf4,0xde,0x16,0x74,0x4b,0x3e,0x9e,0x6d,0xc6,0xaf,0x51, + 0x1b,0xc4,0x26,0xdd,0x39,0xcf,0xc2,0xcd,0x88,0xc4,0xa4,0x2b,0xe6,0x63,0x66,0x3a, + 0x89,0x91,0xea,0x00,0x59,0x51,0xc6,0x32,0x9e,0xf4,0xd8,0xa3,0xda,0x61,0x82,0x86, + 0xac,0xe0,0x85,0x8e,0x22,0x48,0x24,0x01,0x80,0xe6,0xe8,0xf8,0x57,0x83,0x31,0xc9, + 0xa2,0xbc,0xf6,0x11,0xa1,0xf5,0xfe,0x1d,0x82,0xd5,0x6e,0x12,0xcd,0xd4,0xcd,0xc4, + 0x4f,0x43,0x66,0x6b,0xa0,0x36,0x74,0xfa,0xd3,0x7a,0x19,0x6d,0x95,0xb8,0x40,0x0a, + 0xad,0xf5,0xb3,0x08,0x25,0x1e,0x86,0x38,0x59,0x89,0x6e,0xa5,0x53,0x73,0x3f,0x70, + 0x46,0x1e,0x94,0x3c,0x12,0x3c,0x76,0xc5,0xc9,0xd1,0xdd,0xd4,0xb9,0x58,0xd7,0xfa, + 0x3c,0x1d,0x9c,0x85,0x42,0xa1,0x32,0xe8,0x67,0x0d,0x91,0x8a,0xdf,0x81,0xc0,0x32, + 0xb0,0x1f,0xa0,0xbc,0xa4,0x56,0x9f,0x8b,0xc3,0x96,0x67,0xaf,0x7a,0x3d,0x3b,0x2a, + 0xeb,0x33,0x5b,0x42,0xf8,0x0c,0x2f,0xa7,0x15,0x41,0x5f,0x5a,0x49,0x5a,0xfa,0x26, + 0xd1,0x63,0x70,0x2c,0xd5,0x79,0x59,0xe0,0x41,0x5e,0xad,0x55,0x5a,0x83,0xb5,0xde, + 0x6a,0x58,0xfc,0x35,0x3f,0x32,0xc5,0xd5,0x35,0xb0,0xbe,0xab,0xd1,0x3b,0x4d,0x8b, + 0x24,0xed,0x2b,0xc9,0x25,0x4d,0x63,0x4e,0xfe,0xb2,0xbe,0x7a,0x3d,0x92,0xa8,0x65, + 0x07,0x97,0x3d,0x73,0x65,0xda,0xee,0x3e,0x51,0x97,0xa2,0x07,0x02,0xf9,0x4f,0xa5, + 0xe5,0x12,0x2f,0x56,0xcf,0x81,0xe7,0x70,0x49,0xeb,0x99,0x61,0xa9,0xb9,0x94,0xc6, + 0x11,0x51,0x6b,0xf9,0x6a,0x45,0xde,0xef,0xfc,0x68,0x8a,0x13,0xfe,0x60,0x3b,0x91, + 0xff,0xd7,0xfa,0x99,0xdf,0x08,0x40,0x4f,0x6a,0x3c,0x27,0x2d,0x21,0x4f,0x22,0x9c, + 0x67,0x6c,0x06,0x17,0xb9,0x1f,0xe0,0xc6,0x64,0xca,0x8c,0x4e,0xbc,0x6a,0x5b,0xdc, + 0x56,0x55,0xeb,0x4f,0x42,0x02,0x34,0xa9,0xc8,0x43,0xd0,0x49,0xe6,0xe6,0x12,0x1d, + 0x10,0xc0,0x88,0x6e,0x5e,0xc8,0xad,0xb8,0x00,0xca,0x33,0xbb,0x1d,0x04,0x35,0x6a, + 0x1d,0x11,0xd6,0x76,0x89,0x35,0xe7,0x47,0xc9,0x69,0xef,0xcc,0x8e,0x23,0x94,0x84, + 0x96,0xf8,0xc8,0xc6,0xa4,0x5e,0x7c,0x26,0xf3,0xd2,0x6e,0x70,0xa2,0xce,0xb5,0xd7, + 0xa5,0x1d,0x53,0x54,0x6a,0xad,0xa8,0x94,0x07,0x7b,0x29,0x55,0xf2,0xe8,0xd9,0x8a, + 0x55,0xf1,0x43,0x6e,0xf8,0x0d,0x6d,0xa1,0x1d,0x4c,0xc6,0xb6,0x8e,0xcb,0x71,0xe6, + 0x62,0xdd,0xe1,0x35,0xef,0x02,0xe6,0x55,0x64,0x31,0x62,0x40,0x68,0x6c,0xa0,0x23, + 0x4d,0x3b,0x3b,0x31,0x58,0x0f,0x86,0xed,0x0a,0xd4,0xe3,0xdb,0xb1,0xad,0x0f,0x30, + 0x02,0x6e,0x57,0xfb,0x3d,0xde,0xf1,0xf0,0xa9,0x6d,0x6e,0xf6,0x0b,0xba,0x19,0xd3, + 0x71,0x8d,0xb9,0x7c,0x16,0x3a,0x99,0xfd,0xb4,0xca,0x87,0x83,0xc4,0x0a,0x2d,0xd7, + 0x85,0x59,0xf7,0xf5,0x75,0x50,0xe1,0x43,0x5a,0x24,0xe4,0x43,0x44,0x7c,0xd5,0x4e, + 0x5d,0xd4,0x65,0x73,0x3d,0xa9,0xab,0xdc,0x64,0x31,0x54,0x1d,0x66,0xa5,0xbe,0x1a, + 0xb1,0x0d,0x17,0xe5,0x17,0x9c,0xc0,0xfb,0xcf,0xdd,0x23,0x20,0x13,0xf9,0xb0,0x26, + 0x91,0xed,0x4f,0xbd,0x8c,0x7e,0x72,0xf1,0xf9,0x45,0x76,0x6d,0x9a,0x25,0xf5,0xb3, + 0x0f,0x66,0x4c,0xf6,0x9c,0x8b,0x32,0x4e,0xfb,0x40,0xb2,0x80,0x7a,0xcd,0x24,0xb9, + 0x4b,0x4d,0x93,0x35,0x77,0xff,0x1c,0x99,0xf6,0x66,0x7c,0x6d,0x92,0x82,0xac,0x04, + 0x8d,0xed,0xb7,0x36,0x45,0x7f,0xb7,0x0c,0x16,0x68,0x11,0x8b,0x4d,0xbf,0x92,0xc5, + 0xd0,0x3d,0x64,0xc6,0x30,0x47,0x30,0x56,0xaf,0xc6,0xa2,0x78,0x4a,0xc3,0x4f,0xa5, + 0x1c,0x98,0xf1,0x84,0x9a,0x78,0x02,0xe3,0x33,0x76,0x35,0xb4,0x05,0x0a,0x77,0x9f, + 0xe5,0x02,0x35,0xac,0x36,0xbc,0xd9,0xfd,0xe4,0x2a,0x0b,0x6b,0xd0,0x39,0x08,0x17, + 0xff,0x14,0x69,0xab,0x05,0xb5,0x27,0x5e,0x9a,0xe1,0xd8,0x27,0x75,0xee,0xa6,0xa0, + 0x06,0xd3,0xc7,0x43,0xe6,0x59,0x03,0xe2,0x56,0x43,0xcb,0x92,0xaa,0x7a,0x64,0x4e, + 0xc0,0xf5,0xb1,0xe5,0x6b,0x2b,0x32,0xf8,0x3d,0xc6,0xee,0x56,0xd6,0x50,0xb3,0xf4, + 0x4e,0x2d,0xb6,0xa5,0xd9,0x2e,0xcd,0x30,0xe0,0xc9,0xd4,0x65,0xb6,0xd3,0x54,0x10, + 0x90,0xf9,0xa8,0x21,0x36,0x23,0x1c,0x5f,0x06,0xdd,0x9c,0x5e,0xbf,0xee,0x1e,0x25, + 0x4f,0xcb,0x43,0x2e,0xd5,0xa5,0xea,0x0a,0xd3,0xe0,0x5d,0xaf,0xac,0x67,0x5a,0x06, + 0x4c,0x93,0x91,0xde,0x9a,0x67,0xdc,0xd4,0xf9,0xf4,0x9d,0xfa,0x01,0x3b,0x9b,0xc8, + 0xa2,0x1d,0xa7,0x71,0xa6,0xa3,0xf9,0x4d,0x54,0xfc,0x4f,0x34,0xa5,0x5b,0xad,0xd2, + 0xc9,0xd1,0x74,0x79,0x0c,0xcd,0x29,0xce,0x9e,0xf7,0xf2,0xe8,0x3c,0x65,0x4b,0xb3, + 0x0f,0x80,0x35,0x97,0x1b,0xb7,0xef,0xeb,0x81,0x8c,0x74,0x08,0xc8,0x06,0x92,0x69, + 0xd2,0x4b,0xcd,0x8d,0x32,0xb0,0x4a,0x88,0x7a,0x4a,0xf1,0x69,0x1f,0x98,0xc3,0xec, + 0xe0,0x97,0x10,0xaf,0x2c,0xe6,0xfa,0x84,0x9f,0xce,0x01,0xa7,0x96,0x51,0x89,0xe5, + 0xa5,0xe3,0x48,0xeb,0x55,0xe5,0xe6,0x25,0x03,0x50,0x7e,0x3a,0x07,0xdc,0x55,0x1e, + 0x05,0xd0,0x32,0x56,0xe9,0x87,0x8e,0x4b,0x0a,0xaa,0x18,0xa1,0x82,0xd6,0x7d,0xd2, + 0xcc,0x43,0x89,0x80,0xde,0x6b,0x1b,0x8e,0x31,0x57,0x55,0xde,0xd3,0x86,0x69,0xab, + 0x9a,0x92,0x72,0xd5,0xf6,0xb9,0xa0,0x10,0xb3,0x26,0x73,0x91,0xe3,0xe8,0xd0,0x4c, + 0xfa,0x54,0xce,0x68,0x00,0x34,0xd3,0x4f,0x08,0x09,0x71,0x17,0x46,0xb5,0x8d,0xff, + 0xc2,0x3e,0x9f,0x96,0x1e,0x65,0xba,0xb6,0x59,0xf1,0x14,0xaf,0x95,0x42,0x57,0x9a, + 0xb2,0x44,0x4d,0x60,0xe4,0x37,0x67,0x97,0x29,0xc3,0xd0,0x67,0x9f,0xd1,0x7f,0x24, + 0xcc,0xcd,0xbe,0xaf,0x0f,0x73,0xcc,0x1c,0xe7,0x28,0xd5,0x92,0x4f,0x4a,0x01,0x44, + 0x50,0x92,0xa5,0x13,0x93,0xb6,0x4c,0x71,0x49,0xe1,0x41,0x2d,0xda,0x64,0x91,0x69, + 0xf8,0xe7,0xcd,0x53,0x89,0x5d,0xd1,0xbd,0x6e,0xb1,0x1e,0x68,0x84,0xfa,0x4a,0xec, + 0x25,0x89,0x75,0x88,0xc8,0xbb,0x8d,0x06,0xa9,0x5c,0xe8,0x93,0xbc,0x43,0xc4,0xad, + 0xda,0x10,0x15,0xf4,0xa5,0x82,0xf6,0x1b,0x0b,0xd1,0xdf,0x75,0xf2,0x00,0xe4,0x68, + 0x56,0xc4,0xa1,0x80,0x5d,0xae,0x0b,0x61,0xd8,0x0b,0x11,0xdc,0x1a,0x33,0xb0,0x2e, + 0xfe,0x6a,0x93,0xc4,0xa5,0x20,0x35,0xa9,0xda,0x91,0xf8,0x92,0xb6,0xd0,0xd6,0xa4, + 0x04,0xe9,0xcd,0x33,0x09,0x77,0x5e,0x4d,0xfb,0xc1,0xbb,0x80,0x6a,0xb9,0x79,0xb5, + 0x5b,0xe8,0x9f,0xa1,0x46,0x9e,0x98,0x9e,0xc8,0xb6,0x77,0x05,0x2d,0x78,0xd7,0x7a, + 0x25,0xdd,0xf7,0xe2,0x45,0xf9,0x38,0x53,0x28,0x53,0x9b,0x9c,0x1a,0xc1,0x8d,0x3d, + 0x9e,0x39,0x1b,0xb6,0xd3,0xbf,0xe5,0x94,0x64,0xbf,0x4e,0x13,0xe0,0xa8,0xe2,0xdb, + 0x27,0x57,0x0a,0x87,0xf4,0x3c,0xb0,0x8e,0x2f,0xb3,0x09,0x7e,0x41,0x22,0x7c,0xcc, + 0xc2,0x8d,0xa7,0x1f,0x1b,0x16,0xf2,0x3c,0x3d,0x9f,0x86,0xb9,0xd2,0x24,0x83,0x9f, + 0x03,0x39,0xc2,0x4b,0xde,0x40,0xd5,0x19,0x26,0x1f,0x20,0x56,0x1f,0x64,0xe9,0x47, + 0xeb,0x93,0x0a,0x55,0xfb,0x7a,0xeb,0x93,0x63,0xc9,0xd7,0x5f,0x2b,0xb5,0x8b,0xda, + 0x11,0xe5,0x67,0x3a,0x17,0xd3,0x7c,0x6e,0x3e,0x70,0x8f,0xf7,0x4d,0x0a,0x4b,0x7e, + 0x17,0x28,0xdc,0x64,0x81,0x8f,0x22,0x37,0x04,0xae,0xc5,0xe6,0x0c,0x1d,0xe4,0x51, + 0xd2,0x0f,0x97,0x1d,0xa8,0x65,0x60,0x65,0xe9,0x9f,0xd0,0xc5,0x4f,0xc0,0xb3,0x2d, + 0xf9,0x61,0x35,0x81,0xf8,0x79,0xdb,0xdf,0xcf,0x78,0xce,0x1c,0x97,0x73,0x40,0xb4, + 0xbf,0xe2,0x7b,0xff,0xe6,0x4c,0xe2,0x21,0x04,0x27,0x7a,0xed,0xcc,0x22,0x66,0x06, + 0x67,0xe4,0xb2,0x9b,0x95,0xfc,0xb9,0x47,0x0a,0x70,0x57,0x24,0xb0,0x95,0xd5,0xcf, + 0x78,0x81,0x68,0xfb,0x91,0xad,0xe2,0x20,0x76,0x5f,0xf7,0xd2,0x43,0x9b,0xec,0x2a, + 0x10,0x84,0xb7,0xdf,0xc0,0x4b,0xba,0xe5,0x92,0xb6,0x65,0xb8,0x48,0x8d,0x04,0x89, + 0x14,0x47,0xbb,0x1f,0x9b,0xf5,0x4b,0xb7,0x3b,0xae,0xb6,0xff,0x05,0x51,0xe5,0xc4, + 0x89,0x5e,0xce,0x39,0xa8,0x6c,0x68,0x3e,0xac,0xe4,0x5c,0x80,0x58,0x04,0x94,0x30, + 0xf1,0x8b,0xab,0x87,0xfc,0x10,0x02,0x2e,0x44,0x9e,0x44,0xb8,0x0a,0x7e,0x4d,0xef, + 0xb5,0x1b,0x93,0x71,0x71,0xf7,0x6e,0xa3,0xf1,0xd0,0x90,0xa1,0x48,0x43,0x37,0x59, + 0x32,0x45,0x78,0x06,0x3e,0x84,0x00,0x07,0xbc,0x5f,0x01,0xc8,0xa7,0x65,0xf1,0x02, + 0xa4,0xdc,0x2b,0x8d,0xeb,0x5c,0x56,0x8f,0x5c,0x3f,0xa9,0xe4,0x5f,0x60,0x0e,0x90, + 0x84,0xe8,0x8b,0x87,0x0f,0xdf,0x75,0x08,0x33,0x94,0x8e,0x0b,0x87,0xac,0x0b,0x6a, + 0x97,0x47,0x4e,0xf4,0x7c,0x85,0x93,0x72,0xa1,0xbd,0xec,0x84,0x5c,0xf0,0xb2,0x0f, + 0xa1,0xdc,0x03,0x63,0x42,0x16,0x3b,0x8f,0x91,0x0e,0x9e,0x98,0x27,0xe1,0xcb,0x1c, + 0x23,0xf5,0x66,0x05,0xc6,0xf9,0x00,0xce,0x15,0x47,0xf9,0x39,0x72,0xac,0xae,0xbc, + 0xa5,0x2e,0x92,0x2c,0xbd,0xb5,0x5f,0xa8,0x9d,0x2a,0xd0,0x70,0x1a,0xae,0x62,0xce, + 0x6d,0x57,0x42,0xdd,0xd7,0xec,0x4c,0x3a,0x6c,0x4d,0x61,0xf6,0x6a,0x53,0xa7,0xb1, + 0xee,0xca,0x7b,0xba,0x3c,0x39,0xcf,0xa7,0x18,0x50,0xeb,0x64,0x8e,0x64,0xae,0x72, + 0xa9,0x19,0xa4,0x69,0x09,0x58,0x6e,0x24,0xf2,0x9f,0x3c,0xf3,0x99,0x11,0x5b,0xed, + 0x63,0xe3,0x98,0xa0,0x22,0x17,0xbc,0x78,0xef,0xae,0x36,0x01,0xe9,0x86,0xba,0xe9, + 0xf8,0x87,0x30,0x70,0xc4,0x34,0xeb,0xb8,0x45,0xba,0xe3,0x82,0x70,0xde,0x3d,0xaa, + 0xbe,0x07,0xa3,0xef,0x68,0x90,0xee,0xfe,0x80,0x2f,0xc7,0x6c,0xe2,0x95,0x51,0x5b, + 0xcf,0x01,0x1a,0xcc,0x32,0x51,0x70,0x65,0xa2,0xae,0x3a,0x26,0x41,0x23,0xf3,0x1d, + 0x42,0x8e,0x20,0x95,0xb6,0x19,0x29,0xcc,0x00,0xdb,0xe6,0x69,0xb3,0x99,0x83,0x7e, + 0xd6,0xc1,0x7a,0x31,0xeb,0xee,0xdc,0xec,0x7f,0xaa,0x04,0x54,0x35,0x74,0x2c,0x69, + 0x4c,0x88,0x97,0xcb,0x80,0xab,0x52,0x91,0x71,0xa6,0xf7,0x81,0x18,0x45,0x7b,0x55, + 0xb1,0x6c,0x0d,0xf7,0x78,0x1e,0xc6,0xbb,0xb7,0x4a,0x43,0x9a,0x91,0xe3,0xb2,0x8a, + 0x8e,0x50,0x17,0x00,0x02,0x86,0x6d,0x05,0xb9,0x06,0x9a,0xc8,0xc1,0xe4,0x26,0xae, + 0x5e,0x0f,0x58,0xde,0x83,0xb2,0xc1,0x90,0x9e,0xed,0xe1,0x5e,0x35,0x3e,0x18,0xb0, + 0x36,0xbf,0x57,0xca,0x60,0x07,0x6d,0xe1,0x55,0x9a,0x4c,0xe5,0x2e,0x45,0x3c,0x4e, + 0x58,0x9c,0x4c,0x36,0x6b,0xb1,0x25,0xb5,0xb8,0x1d,0x4d,0xc8,0x62,0x19,0xa3,0x9d, + 0xcc,0x7e,0x42,0x1f,0x17,0xcf,0xb4,0xc4,0x1a,0x5a,0x7e,0x65,0x2d,0xdf,0x93,0xa6, + 0x68,0x13,0x49,0xbf,0x83,0x97,0xde,0x97,0x27,0x20,0xa8,0x47,0x43,0x31,0xfa,0x01, + 0xd3,0xa2,0xe5,0x2f,0x24,0x3b,0x30,0x2c,0x71,0xa7,0x1c,0x9c,0xf2,0xec,0xb7,0x01, + 0x80,0x8d,0xbd,0x72,0x1d,0x68,0x67,0x7e,0x72,0x32,0xa6,0x76,0x6c,0x7a,0x9f,0xa5, + 0xf6,0x38,0x77,0xdd,0x5d,0x03,0x8e,0x9d,0x38,0x8f,0xcd,0x5b,0x02,0x25,0x8f,0x1c, + 0xb9,0xd6,0x23,0x3c,0x27,0xdf,0xe5,0x16,0xf2,0x6d,0xc5,0xf1,0xa3,0x5c,0x0d,0x68, + 0xa5,0x5f,0xcb,0x4e,0xef,0x6b,0xc5,0xb4,0x7a,0xcc,0x17,0x33,0xc7,0x2a,0xca,0xea, + 0x38,0x8f,0x35,0x8a,0x72,0x36,0x3b,0x4b,0x6b,0x6a,0x55,0x91,0xa1,0x93,0x04,0x1f, + 0x4e,0xa5,0xa3,0xc2,0x89,0xc1,0xdc,0xa1,0x9e,0x88,0x14,0x48,0xd7,0xa4,0x97,0x6b, + 0x89,0x1e,0xbd,0x76,0xa1,0x57,0x6d,0x31,0x16,0xd8,0xa3,0x11,0x0a,0xe4,0xcd,0x94, + 0x3b,0x96,0x88,0xde,0xc8,0x01,0xca,0x11,0xf8,0xe7,0xcf,0xe3,0x90,0x2f,0x5e,0xd6, + 0xef,0x54,0xc7,0xa7,0xe1,0x77,0x9f,0x62,0x6b,0xd8,0xdc,0xdc,0xc3,0x51,0xc0,0x81, + 0xf7,0x8d,0xa0,0x80,0xb7,0x96,0x40,0x39,0xb5,0x95,0x6b,0x3f,0xdf,0xf0,0x33,0x37, + 0x82,0xef,0xad,0x51,0x1d,0xcc,0x3c,0x61,0xee,0x68,0x7c,0x2a,0xbc,0x25,0x1c,0x62, + 0x95,0x21,0xe0,0x51,0xde,0x6c,0x6d,0x8f,0x4c,0xfe,0x86,0xe1,0x4c,0x21,0xfc,0x6e, + 0x89,0x5a,0x8e,0x5c,0xda,0xd1,0x5d,0xf5,0xbd,0x93,0x64,0xcd,0x8c,0x92,0xac,0xd9, + 0xec,0x86,0x80,0x23,0x14,0xaf,0xc9,0xbf,0xab,0x9c,0x9f,0x81,0x67,0x7a,0xd0,0xe5, + 0xf9,0x65,0xf1,0x32,0x36,0xb9,0x86,0xbe,0xa4,0xa0,0x13,0xda,0x63,0x85,0xd6,0xa6, + 0xcb,0xbd,0x97,0x43,0x74,0x38,0x02,0x43,0xda,0x3e,0x82,0x4b,0x8b,0x3d,0x08,0xbc, + 0xc3,0xa0,0x96,0x13,0xc9,0xe6,0x60,0x0d,0x45,0x52,0x56,0x89,0x06,0xf9,0x25,0xcf, + 0x9e,0x04,0xc0,0x75,0xb7,0xab,0x6d,0x43,0x8f,0x5e,0xf6,0x63,0xf7,0x65,0x37,0x0e, + 0x2a,0x3b,0x3c,0xe4,0x3f,0x46,0x49,0x3e,0x38,0x62,0x04,0x16,0x1d,0x92,0x83,0xec, + 0xae,0x48,0xa1,0x88,0x2c,0x64,0x0a,0x4c,0xcc,0x66,0xa9,0x82,0x26,0x82,0x14,0x27, + 0xca,0x23,0x16,0x48,0xf8,0x65,0xc4,0xbf,0xac,0x18,0x91,0xe4,0x71,0xbf,0x77,0x5b, + 0x2e,0x01,0x59,0xd0,0xe8,0xb2,0xeb,0x84,0x9f,0xd1,0x53,0x79,0xac,0x38,0xc4,0xd8, + 0x73,0x29,0x38,0x7b,0xc0,0x53,0x76,0x9f,0x25,0xe6,0xb3,0xdb,0x5c,0x39,0xe2,0x1a, + 0xfe,0xa2,0x80,0x91,0xc9,0x00,0x09,0xba,0xbd,0x4a,0x0e,0x85,0xa3,0xda,0x14,0x4b, + 0x26,0x85,0xa7,0x8f,0x00,0x48,0x0e,0x3f,0x14,0x37,0xb1,0xa1,0x73,0x8c,0x68,0x3f, + 0xe3,0xc9,0x5c,0x70,0xca,0xc6,0x99,0xae,0xfc,0xe1,0x0d,0x61,0x64,0x8c,0x0d,0x79, + 0xcb,0xa3,0x75,0xc5,0x40,0x75,0x4e,0x4f,0x02,0x92,0x97,0x24,0x8b,0x1d,0xa1,0x70, + 0x27,0x7e,0x26,0xe5,0x39,0x7d,0xd1,0x4d,0x93,0x43,0x8d,0xb9,0xe4,0x1c,0x86,0x1f, + 0x40,0xc8,0x72,0x44,0x28,0x46,0xc4,0xb4,0x3e,0x71,0x6e,0xcc,0xfc,0x95,0xf7,0xff, + 0x12,0xfc,0x67,0x5c,0xb2,0xb9,0xdd,0xb6,0xaa,0x09,0x97,0xbb,0x8c,0x32,0xcd,0x6f, + 0x5b,0xa6,0xb1,0xcf,0xd8,0x3d,0x09,0x00,0x27,0xbb,0x6f,0xae,0x7d,0xba,0xd6,0x5a, + 0xe2,0xe3,0x17,0x16,0x7d,0xf7,0x37,0x6d,0xf0,0xbb,0x2a,0x44,0xef,0x5b,0x10,0xf3, + 0xa0,0x99,0xa6,0x10,0x2b,0x8b,0xdc,0x6f,0x6f,0x90,0xb5,0x1f,0x8f,0x7a,0xb4,0x46, + 0x45,0x4a,0x19,0xe8,0x29,0xff,0x2e,0x68,0xe3,0xc5,0x24,0x46,0x45,0x62,0xec,0x48, + 0xef,0x17,0xd5,0x93,0x4d,0x2c,0xed,0x26,0x1d,0x85,0xe9,0xc4,0x8a,0x9f,0xfa,0x39, + 0x86,0xd6,0xab,0x3a,0x6b,0x85,0x99,0x38,0xdc,0x70,0x70,0xee,0xf6,0x1a,0xdc,0x3d, + 0x67,0x22,0x04,0x1e,0xc4,0xef,0xba,0x52,0x4d,0x98,0x09,0x89,0x56,0x09,0xd0,0x45, + 0x47,0x78,0x60,0x97,0x8a,0xe8,0x3a,0xa2,0x63,0x30,0x2e,0x06,0x02,0x58,0x19,0x0b, + 0x1f,0x8e,0x47,0x6a,0xab,0x2f,0x63,0x6d,0x43,0x27,0x56,0xb7,0x54,0x11,0x39,0x03, + 0x98,0x19,0xf7,0xac,0xf2,0x48,0x36,0x53,0x2b,0x0f,0xab,0x3f,0x35,0x5d,0x7d,0x1a, + 0x6e,0xd1,0x8e,0x69,0xf5,0xd3,0xdd,0x34,0x66,0x5b,0x2e,0x50,0x94,0x1d,0x07,0xae, + 0xd3,0x94,0xc0,0x4c,0x24,0x49,0x4a,0x51,0x20,0x85,0x59,0xbf,0x3b,0x5e,0x10,0x4b, + 0x2f,0x5c,0x69,0x71,0xa1,0x77,0xd1,0x6e,0x00,0x99,0xfc,0x73,0x51,0x64,0xce,0x14, + 0xa9,0x89,0x43,0xc6,0xec,0xcd,0xd3,0xf3,0x73,0x2d,0x89,0x86,0x17,0x91,0xe1,0x60, + 0xf2,0x30,0x8d,0xe4,0xf1,0x41,0xc3,0x32,0xde,0x4b,0x0c,0x53,0xad,0xd3,0x33,0x30, + 0x83,0x58,0xc5,0x10,0x96,0xf5,0x10,0xd0,0xba,0x0d,0x6e,0xca,0x98,0xf1,0x8d,0xda, + 0x80,0x29,0x85,0x4e,0xfa,0x5b,0x8e,0xfd,0x2b,0x2a,0xd4,0x5d,0x05,0x94,0x0b,0xe1, + 0x8b,0x14,0x6c,0x68,0xe8,0x7d,0x5f,0x03,0xea,0x54,0x0e,0x8e,0x81,0xd2,0xaf,0x5b, + 0x09,0x9b,0x55,0x16,0x75,0x75,0x57,0x74,0x69,0x63,0x32,0xc4,0x68,0x40,0xcf,0x1d, + 0x19,0xc2,0xe5,0x20,0xcf,0xa1,0x69,0xd1,0x35,0xad,0x8d,0xd0,0x5b,0xe7,0x02,0x87, + 0x99,0x2c,0x70,0x2d,0x34,0x0d,0x41,0x06,0x1b,0x0d,0x7e,0xfa,0x12,0x4e,0x82,0x48, + 0xed,0x5f,0x88,0x83,0xcf,0x8d,0x89,0x05,0x8f,0x31,0x8f,0x78,0x22,0x4a,0x9d,0xc5, + 0x17,0x61,0x21,0x69,0x9a,0xf9,0x40,0xa0,0xda,0x6f,0xd2,0xc7,0x23,0xa0,0x1e,0xc0, + 0x33,0x23,0x94,0x83,0x51,0x45,0x46,0xab,0x1a,0x4f,0xec,0xc7,0xe0,0x2d,0x6c,0x2d, + 0x46,0x26,0xe4,0x17,0x19,0x43,0x54,0xf5,0x0f,0xb3,0x21,0x15,0x2c,0x67,0xc9,0x3f, + 0xae,0x7b,0xa8,0x0b,0x25,0xd3,0x19,0xac,0x86,0xcd,0x99,0xe8,0x61,0x17,0x12,0x56, + 0x0d,0xf3,0xed,0x24,0x65,0xad,0x4a,0x64,0x6c,0xad,0x0c,0x5c,0x9d,0xa5,0xae,0x07, + 0xad,0xa9,0x22,0x7e,0x0e,0x6f,0x5e,0x02,0x71,0x6e,0x95,0xf7,0xc4,0x5e,0x6e,0x69, + 0xb9,0x42,0x7a,0x2d,0xa1,0x6e,0x8b,0xb7,0x5d,0xe0,0xd4,0xf7,0x18,0x7b,0xdc,0x7e, + 0xb6,0xd9,0x2f,0xf9,0x0a,0xc3,0xa2,0x02,0x77,0x5e,0x78,0xdb,0xd8,0xb2,0x24,0xc6, + 0x17,0x1d,0x44,0x91,0x74,0xf9,0x29,0x0c,0x7e,0x0a,0x7f,0x5c,0x52,0x68,0x1f,0xc2, + 0x7f,0xc4,0x35,0x9b,0xcf,0x3d,0x26,0x2e,0x15,0xfc,0xa1,0xf3,0x43,0x4f,0x0a,0x63, + 0x45,0x0d,0x9c,0xa0,0xa1,0x71,0x16,0x7b,0x95,0xea,0xe1,0x3a,0x70,0x09,0xcd,0x16, + 0x55,0x78,0x50,0x47,0x0b,0xa8,0xa3,0x74,0x46,0xb8,0x0b,0x20,0xe3,0x84,0xf5,0x17, + 0x2f,0xf0,0x89,0xaa,0x5e,0x80,0x7d,0x9f,0x11,0xe1,0xce,0x9d,0xb8,0xfb,0x5e,0xba, + 0xb7,0x74,0x7f,0xe9,0xc1,0xd2,0xc3,0xa5,0x47,0x4b,0x8f,0x97,0x9e,0xf4,0xee,0xf0, + 0x7e,0xac,0x1c,0xd3,0x33,0xf5,0xbe,0x54,0x5d,0x35,0xc5,0xd7,0x78,0xea,0x82,0xc7, + 0x93,0x0a,0xc1,0xa5,0x00,0x42,0x93,0x98,0xf3,0x8c,0xaf,0xfc,0x6f,0xa1,0xaa,0x1d, + 0x08,0x76,0x96,0x7d,0x94,0x96,0xa3,0x87,0xa1,0x88,0xbc,0x15,0x59,0x67,0x13,0xb6, + 0xbf,0x0c,0x8d,0xb1,0x3d,0x3d,0xd5,0xab,0x06,0x1d,0x5b,0x4f,0xda,0x9f,0x8c,0x23, + 0x6a,0x70,0xd3,0xc0,0x3d,0x6d,0xda,0xc6,0x18,0x62,0x35,0x61,0x4d,0x4e,0x69,0x93, + 0x74,0x31,0xd4,0x79,0xdb,0x74,0x31,0xde,0xa4,0x0c,0xe2,0xba,0xbf,0x0d,0x6f,0x5f, + 0xe3,0x50,0x0f,0x95,0xeb,0xbd,0xe1,0xd9,0x75,0xc0,0xeb,0xc8,0x57,0x75,0xcc,0xe3, + 0x92,0x2e,0xbe,0x14,0xed,0x25,0x4a,0x5e,0x57,0x43,0xab,0xed,0xb1,0x16,0x41,0x73, + 0x72,0x3c,0x11,0x0d,0xe3,0x85,0x18,0x6c,0xed,0xa4,0x94,0xbc,0x7b,0x2b,0x59,0x11, + 0x5b,0x6b,0xe3,0xe5,0xf6,0xd8,0xe2,0xcd,0xae,0xf7,0x59,0x41,0x3e,0x4d,0xdb,0xbd, + 0x8c,0x6c,0x30,0xfc,0x85,0x2d,0x4d,0xfc,0xe2,0x50,0x63,0xd3,0x90,0x38,0x53,0xc9, + 0x06,0xbc,0x2f,0x22,0x04,0x80,0x64,0xe3,0x67,0x31,0x82,0x45,0x73,0x89,0x37,0x6f, + 0x42,0xd8,0x66,0xfb,0x3d,0x9e,0x7c,0xdb,0x44,0xdc,0x01,0xb8,0x2e,0x79,0xee,0x2f, + 0x60,0xc5,0x89,0x40,0x70,0xd8,0x3e,0x6d,0xe8,0x59,0x4e,0x21,0x49,0xa6,0x79,0xd7, + 0xa1,0xa8,0x4f,0xda,0xb5,0x2d,0x88,0x7c,0x81,0xa0,0x03,0xbf,0xbb,0xfe,0x14,0x2e, + 0x14,0x86,0x24,0x8c,0xdf,0x2e,0xfb,0x55,0x2d,0xe9,0x74,0x14,0x2f,0x0c,0x23,0x35, + 0x7e,0x17,0xf1,0x58,0xd5,0x6c,0x8f,0xfa,0xab,0xd7,0x81,0xc9,0xd9,0x31,0xc7,0x2d, + 0x82,0x84,0xda,0xec,0x9e,0x74,0x26,0xdd,0x91,0x5a,0x56,0xec,0xb8,0x17,0x89,0x8b, + 0xc7,0xa2,0x1a,0x32,0x1d,0x3a,0x62,0xd5,0x1e,0x0d,0xed,0x20,0x7a,0x02,0x05,0x11, + 0x17,0x30,0xdd,0xec,0x65,0xc4,0x4c,0x0a,0x56,0x98,0x1c,0x99,0x9b,0x6f,0x87,0xee, + 0x12,0xa2,0xe7,0xb6,0x5c,0xb2,0x9a,0xf3,0x54,0x21,0x54,0xc2,0x4b,0x34,0xf4,0x0d, + 0x26,0x08,0x6b,0x4a,0xaf,0x4b,0xab,0x8a,0x5b,0x01,0x11,0x34,0xf8,0x1b,0x97,0x67, + 0x56,0xb0,0x78,0x3d,0x5f,0xb1,0xfe,0x6d,0x02,0x3c,0x51,0x67,0x80,0x84,0x2e,0xd6, + 0x2e,0x7e,0x42,0x66,0x01,0x2a,0xe6,0x19,0x90,0xd6,0x26,0x83,0x96,0x05,0xbb,0xc6, + 0x57,0x11,0x24,0x6f,0xc1,0x73,0x22,0x7b,0xf3,0x16,0xfb,0x17,0xce,0xa9,0x07,0x51, + 0x26,0xa3,0xb5,0x97,0x6f,0x7f,0x1c,0x81,0x8b,0x13,0xe6,0xa5,0x67,0x7b,0x84,0xf5, + 0xa8,0xc3,0x1a,0xdb,0x1d,0x1e,0x4a,0xb8,0x35,0x7e,0xfe,0xe8,0x7a,0x68,0x21,0xd8, + 0xec,0x7a,0x74,0x22,0x5f,0x4b,0xf8,0x4d,0x81,0xf4,0xe4,0xd4,0xfe,0xa3,0x85,0xcf, + 0xb6,0x28,0xb8,0xf7,0x6b,0xe5,0xd7,0x94,0xd9,0x12,0x6c,0x5d,0x58,0x4c,0xff,0xd0, + 0x1a,0xcb,0xcb,0x59,0x0c,0x64,0x3c,0xf2,0xa3,0x5c,0xd1,0xaf,0xaa,0x4c,0x81,0xab, + 0x49,0xca,0x89,0xcf,0xd5,0x2b,0x38,0x8f,0xa1,0x5f,0xd2,0x3c,0xb6,0xeb,0xc5,0xda, + 0x12,0x5e,0x5d,0x92,0xa5,0xbb,0x2c,0x6d,0xaa,0x38,0x6d,0x3d,0x0a,0xb4,0x67,0xc0, + 0x3f,0x7c,0xaf,0x9c,0x10,0xbf,0x74,0xf5,0xd2,0xba,0xbb,0x1d,0xaa,0x1f,0x98,0x83, + 0x94,0xbe,0x5d,0xa4,0x73,0x6d,0x9e,0x4e,0x43,0xd4,0x70,0x55,0xa9,0x34,0x97,0x72, + 0x9d,0x28,0xc4,0x7a,0x57,0xda,0x39,0x8f,0x87,0x00,0xb6,0xa9,0x69,0x5e,0x1b,0xad, + 0x89,0x56,0xb6,0x4f,0xcd,0xbc,0x5c,0xa1,0x18,0x24,0x95,0xdd,0x78,0x97,0x06,0x0d, + 0x8f,0xdc,0xc8,0x81,0xfd,0xb8,0xfe,0x4b,0x36,0x83,0x16,0x01,0x49,0x2b,0x49,0x1f, + 0x99,0xda,0xb6,0xd5,0xfa,0x60,0xa5,0x40,0xbc,0x0f,0x7f,0xa9,0x2e,0xdd,0xd9,0x27, + 0x8a,0x9b,0x00,0xba,0x4e,0x20,0x40,0x7c,0x4e,0xe3,0x98,0x2b,0xb3,0xad,0xdb,0xa7, + 0x83,0x64,0x5c,0x3c,0xd9,0x27,0x59,0x75,0x3d,0xcb,0x40,0xbd,0xac,0x34,0x61,0xb8, + 0x12,0xba,0x70,0x3a,0xfd,0x5b,0xbb,0x65,0x0c,0xdd,0xa8,0x1c,0x8c,0x93,0x13,0x93, + 0x90,0xd4,0x4f,0x8a,0x0f,0xfc,0x66,0x9e,0x3e,0xb3,0xab,0x08,0x33,0xc9,0xd6,0xca, + 0xcc,0x7f,0xf6,0x8f,0x97,0xa6,0xdb,0xf1,0x67,0xbe,0x99,0xa7,0xc7,0x35,0x24,0x3d, + 0xdc,0xb1,0x51,0x98,0xca,0x21,0x96,0x8f,0xa9,0x0d,0x1e,0x76,0x9b,0xf7,0x21,0xf1, + 0x8b,0xb6,0xf1,0xdb,0xfa,0x4f,0x65,0x95,0xea,0x82,0xdd,0xbc,0x0c,0x82,0x51,0xff, + 0x2d,0x2a,0xdc,0xbf,0xde,0xda,0xca,0x15,0x87,0x58,0x9d,0x7d,0xb6,0x0b,0x49,0xd0, + 0xaf,0x67,0x77,0xfc,0x06,0x7b,0xaf,0x23,0x95,0x39,0x8c,0x1b,0x35,0xb2,0xce,0x93, + 0xbf,0x88,0xcb,0xf8,0xba,0x2d,0xde,0xcc,0xd8,0x1e,0x27,0xc5,0x70,0x4c,0x66,0x15, + 0x39,0x8c,0x73,0x4f,0x20,0x47,0x14,0xc3,0x87,0xbf,0x6f,0x55,0xd0,0x6b,0x86,0x24, + 0x27,0x75,0x8e,0x37,0xc2,0xa5,0x3a,0x1e,0x95,0x1e,0x26,0x57,0xa2,0xf3,0xe1,0xd2, + 0x66,0x41,0xf5,0x3d,0x3a,0x75,0xd2,0x60,0x41,0x86,0x11,0x1a,0xe4,0x62,0xef,0x51, + 0x4c,0xdd,0xb2,0x46,0xc1,0x54,0x2d,0xee,0xf8,0x7c,0x3f,0xb5,0xf9,0x17,0x26,0x87, + 0x1a,0xdd,0xa4,0xd4,0x63,0xd6,0x6f,0xaa,0xc9,0x68,0xde,0xf8,0x9a,0xa4,0x0e,0x31, + 0x3e,0x93,0x65,0xc5,0x36,0x86,0x41,0xff,0x77,0x3a,0x26,0x06,0xd5,0xc9,0xad,0x16, + 0x57,0x50,0x23,0x5f,0x5a,0x7f,0x5b,0x49,0xe9,0xdb,0xfa,0x08,0x49,0x05,0x5c,0xa6, + 0xeb,0x6f,0x09,0xef,0x09,0xa1,0x07,0x34,0x72,0xaa,0x9c,0xcd,0xd6,0x57,0xeb,0xb5, + 0xfa,0xa5,0x0d,0x20,0xeb,0x9f,0x5a,0x0b,0xe9,0xca,0xe3,0x53,0x59,0xda,0x2a,0x56, + 0x76,0xfb,0xff,0xe7,0xde,0xfb,0xd5,0xf5,0xfc,0xd7,0x61,0xd5,0xba,0xc2,0xa6,0x56, + 0x79,0xa5,0x5a,0xc3,0xf5,0x07,0x51,0x4e,0x72,0xd9,0x41,0x4b,0x7c,0x0e,0xae,0xb2, + 0xb8,0x38,0xec,0x56,0x91,0xf2,0x80,0x17,0xfc,0x82,0xe9,0x84,0xee,0x05,0x16,0x96, + 0x7a,0xfd,0xfa,0x6c,0xfc,0x8c,0x2f,0x9d,0xcf,0x21,0x99,0xc8,0xd4,0xa6,0xd0,0x80, + 0x3f,0x85,0xcd,0xaf,0xb4,0x62,0xb5,0xa4,0x9d,0x3f,0xad,0x05,0x92,0xb0,0x9f,0x78, + 0xd4,0x19,0x8b,0xf0,0xcb,0x8b,0x49,0x81,0x34,0x6a,0xda,0xaf,0x14,0x21,0x03,0xd2, + 0xe1,0xce,0xd1,0xe8,0x47,0x17,0xa5,0x99,0xba,0x1c,0x9c,0xb8,0xf2,0x55,0x87,0x06, + 0xad,0x5d,0x1a,0xfb,0xde,0x29,0x1e,0x5d,0xed,0xd2,0x7c,0xb6,0xc5,0xfc,0x9b,0xbe, + 0x02,0xdc,0x84,0x4b,0x21,0xe0,0x87,0xb1,0x9a,0x4c,0x15,0x9c,0x33,0xe6,0x08,0x72, + 0xa4,0xad,0x5d,0x5a,0x9a,0x18,0xb9,0x3a,0xda,0x6e,0x0e,0x9c,0xd0,0x5a,0x65,0xa2, + 0xe2,0xa4,0xd2,0x04,0x1c,0xea,0x03,0x0a,0x42,0xc9,0xb2,0xb0,0xba,0x23,0x33,0xce, + 0x2a,0x3d,0x7a,0x4a,0x03,0xc2,0x73,0xbe,0x78,0x04,0x20,0x93,0xab,0x57,0xe9,0x27, + 0xf5,0x7f,0x42,0x57,0x32,0x9c,0xe2,0x1a,0x3e,0x2d,0xb2,0x74,0xd9,0xa6,0x18,0x1b, + 0x11,0xfc,0xd8,0xc5,0xc2,0x1f,0x16,0xdd,0x02,0x7e,0x6d,0x0f,0xf8,0xae,0x25,0xd5, + 0x5a,0x94,0x2a,0xf9,0xa8,0xa1,0x18,0x4b,0x1a,0xf4,0x74,0x8b,0x9e,0xbd,0x2e,0x1b, + 0x55,0x8d,0x8c,0xbc,0xf8,0xde,0x8c,0x4a,0xb4,0xf7,0x81,0x56,0x10,0xad,0x3a,0x87, + 0x98,0x42,0xb6,0xc6,0xd5,0x68,0x1a,0xe3,0x69,0x1f,0xba,0x2e,0x64,0xa7,0x9c,0x09, + 0x97,0xc5,0x5d,0xb6,0xce,0x5f,0xba,0x1f,0x9d,0x03,0x74,0x7f,0x53,0x39,0x5b,0x57, + 0xa5,0x73,0x05,0xce,0x36,0x53,0x54,0x72,0x97,0x43,0x8e,0xd3,0x5b,0x7c,0xdc,0x8b, + 0x73,0x9d,0x40,0xc1,0xe4,0xfe,0xc2,0x19,0x96,0xa4,0x76,0x68,0x51,0x84,0x8f,0x26, + 0x17,0xb4,0xc8,0x66,0x7b,0xb5,0x39,0x11,0x3a,0x52,0x00,0x98,0xc7,0x20,0x53,0xe8, + 0x40,0xe8,0xe6,0x09,0x12,0x6b,0x1a,0x2e,0xda,0x78,0xf1,0x65,0xad,0x41,0x87,0x44, + 0x2a,0xe4,0x71,0xa4,0xa8,0x21,0xf6,0xb7,0x3e,0x3d,0x3a,0xe1,0x2f,0x48,0xb2,0x81, + 0xae,0xcb,0xef,0x90,0x1f,0x6e,0x67,0x6d,0x27,0xe1,0xb5,0x6f,0xe3,0x63,0xae,0x47, + 0x61,0x0f,0x30,0xdd,0x53,0x71,0xf1,0x8a,0xcd,0x2f,0x26,0xc6,0x14,0x21,0x3e,0xdb, + 0x4d,0x70,0x0e,0x88,0xf1,0x65,0x74,0x69,0x41,0x87,0x8f,0xd4,0x7b,0x28,0x53,0x19, + 0x8d,0xac,0xd8,0x89,0x65,0x61,0x45,0x63,0x05,0x51,0x8d,0x74,0x2a,0x07,0xe0,0xf0, + 0xbf,0x60,0x6c,0x62,0x62,0xe2,0xf7,0x1f,0x05,0x4c,0xf5,0x34,0x0a,0x8b,0x7a,0xe3, + 0xb5,0x0c,0xf6,0x1d,0x10,0x8a,0xb7,0x93,0x95,0x34,0x00,0xcf,0xa0,0xc7,0x8b,0x1a, + 0xd6,0x86,0x25,0x39,0x87,0xd6,0x87,0x8e,0x16,0x6b,0x65,0x3a,0x89,0xf6,0xd5,0x71, + 0x81,0x84,0x0d,0xb0,0x9b,0x5e,0x4d,0xe1,0x7f,0xd2,0x2f,0x00,0xd0,0x6e,0xd6,0xd3, + 0xb1,0x00,0x89,0x58,0x4e,0xf6,0x26,0xf1,0x6d,0x85,0xe4,0xcc,0xed,0x9c,0xdd,0x52, + 0xe4,0xb3,0x20,0x39,0xf4,0x5c,0x4a,0x05,0x55,0xd4,0x1d,0xa5,0x8b,0xca,0xc0,0x29, + 0xdb,0x62,0x6c,0x32,0xfc,0xcd,0x77,0x17,0x16,0xc1,0x57,0x09,0x2e,0x1f,0xba,0x4e, + 0xfb,0xad,0x2a,0xff,0x1b,0x93,0x18,0x77,0x12,0x46,0x4e,0x27,0xc2,0xc8,0x39,0x12, + 0x0b,0x17,0x10,0x0a,0x09,0x69,0x61,0x92,0xcc,0x5b,0xaf,0x63,0x49,0x2d,0x92,0xee, + 0x88,0xf1,0x51,0xfd,0x13,0xa8,0x4c,0x19,0xa2,0xbb,0xd8,0xff,0x30,0x3b,0x53,0x2b, + 0x88,0x35,0xea,0xd9,0xf0,0xda,0xd6,0xc6,0x89,0xed,0x9b,0xd0,0x3d,0x41,0xf1,0xe5, + 0xa3,0x78,0xcf,0x5d,0x79,0x6f,0xd7,0xd6,0xe7,0xf9,0x3d,0x03,0x2a,0xf9,0xe1,0xdc, + 0x52,0x7d,0x27,0xc8,0x38,0xc9,0x96,0x46,0x27,0x4c,0xc1,0x8b,0x54,0x61,0x6e,0x87, + 0xfb,0xe3,0xe8,0xaf,0x05,0x37,0xa9,0x29,0x4c,0xc9,0x2c,0x6c,0x9d,0xf1,0xc6,0xd6, + 0xbc,0x73,0x29,0x3e,0xdd,0x8e,0xa3,0x7b,0x89,0xe9,0x27,0xf2,0x67,0x15,0x22,0x69, + 0x3a,0x57,0xe9,0x79,0x4f,0x0d,0xa2,0x6b,0xc0,0x4b,0x05,0x7b,0xf8,0x4c,0x50,0x03, + 0x39,0x81,0xd4,0x06,0x90,0x11,0x8f,0x2b,0x15,0x99,0xbe,0x53,0xbc,0x9d,0xc5,0xc7, + 0x52,0xfb,0x46,0xa6,0x10,0xe8,0x73,0xe0,0x57,0xe4,0x4f,0xc0,0x61,0x67,0xd2,0x63, + 0x7a,0x30,0x69,0x9d,0x6b,0x07,0x6f,0x40,0xe9,0x14,0x6f,0xa9,0xe4,0xcc,0xb4,0x99, + 0xcd,0x07,0xa7,0x7e,0xf2,0x38,0xb4,0xa7,0xdb,0xc3,0x63,0xbc,0x1b,0xab,0x4f,0xe3, + 0xc0,0x39,0x35,0x79,0x93,0x85,0x3a,0x54,0x48,0xa1,0xfa,0x16,0xa2,0x19,0x22,0xf7, + 0x29,0x0d,0xd5,0x86,0x26,0x4d,0x3a,0x3e,0xc1,0x6a,0x55,0xb6,0x1b,0xb4,0x3f,0x4e, + 0x31,0x35,0x2f,0x2a,0x0c,0xa2,0x5e,0xbc,0xc4,0xe3,0x56,0xa4,0x56,0x34,0xc0,0x92, + 0xbc,0x64,0x29,0x51,0x5d,0xad,0xd2,0x67,0xec,0x8a,0x41,0xc9,0x7f,0xf3,0x95,0xb8, + 0xd1,0xe5,0xa4,0xdc,0x39,0xdb,0xef,0x99,0xd2,0x39,0x38,0xec,0x28,0xed,0x27,0xa3, + 0x82,0xae,0x09,0x96,0x9b,0x5a,0x18,0x02,0x1b,0x65,0xcf,0xf4,0xd9,0xed,0x9c,0x21, + 0x5c,0x4c,0x18,0x59,0xeb,0xd1,0x34,0xde,0xa0,0xcd,0x47,0x25,0xb9,0xa8,0x26,0x85, + 0x78,0xdb,0x2e,0xed,0x7f,0xcb,0x6c,0x09,0x6d,0x15,0xfc,0xf8,0x5a,0x97,0x7e,0x36, + 0xd6,0x9d,0xcb,0x25,0xbc,0x29,0x3c,0x54,0x80,0xf5,0xbe,0xa6,0x9c,0xa7,0xd8,0x3d, + 0x41,0xb2,0xd0,0x18,0x9b,0x6f,0x18,0xd1,0x93,0x62,0x3f,0xe3,0x53,0x4a,0xa2,0x5d, + 0x7b,0xfd,0x46,0x2b,0x8d,0x64,0x38,0xeb,0xba,0xed,0x55,0xf8,0x3a,0x9a,0x83,0x6e, + 0xb1,0xe5,0x9e,0x16,0x95,0xce,0x3a,0xee,0xb5,0xa4,0x0c,0xca,0x50,0xcb,0xc5,0x6c, + 0x4c,0xa8,0x63,0x82,0xbe,0x0a,0x19,0x54,0x67,0xf1,0x74,0x50,0xdf,0x37,0x9c,0xb3, + 0x79,0xef,0x42,0xc5,0x0b,0x7b,0xc5,0xae,0x45,0xa5,0xc9,0xad,0x5d,0xfa,0x88,0xf2, + 0xc9,0x5f,0x64,0xb0,0x69,0x8d,0xe8,0x22,0x43,0x15,0x72,0xbc,0x6c,0xe2,0x30,0xe7, + 0xc5,0xa8,0x93,0x78,0xa2,0x7e,0xc8,0xfe,0xc6,0x76,0x7c,0x28,0x76,0xfc,0xfc,0x20, + 0x9e,0x90,0x8f,0x19,0xb2,0x17,0x2b,0xb8,0x4c,0x77,0xcf,0x8e,0x9c,0x02,0x61,0x74, + 0xed,0xd5,0xce,0x63,0x16,0xd7,0xac,0xf1,0xb8,0x77,0x7a,0xcf,0xfd,0xee,0xf6,0xc1, + 0x60,0xc7,0x2f,0x2f,0xb6,0xc8,0x53,0xff,0x9e,0x7b,0x60,0x49,0xc3,0xfb,0x2b,0xce, + 0x12,0x47,0xb8,0x61,0x39,0xf9,0xd5,0x2b,0xc2,0xfd,0x74,0xd1,0x77,0xdc,0x28,0x5a, + 0xbc,0x38,0xb0,0x5f,0x6b,0xab,0x92,0x95,0x11,0x48,0xe4,0x90,0x01,0xc0,0x9c,0x50, + 0x5c,0xe6,0x82,0x7d,0xa0,0xa9,0xeb,0x55,0xf4,0xb3,0x8a,0x8d,0x3d,0xf8,0x01,0x6a, + 0x13,0x6d,0xc7,0xe7,0xea,0xa5,0x7a,0xc0,0x07,0x67,0xd4,0x90,0xe4,0xbe,0xc1,0x5d, + 0xfd,0xa1,0xad,0x6d,0xf3,0xaa,0x23,0xb2,0x46,0x48,0x02,0x8f,0xc5,0x18,0xfb,0x2c, + 0xdb,0xc3,0x12,0x42,0xbd,0x4f,0x6f,0xc7,0xd7,0xaf,0x30,0x8a,0x04,0xe8,0x98,0x17, + 0x2b,0xab,0xb5,0xc8,0xa4,0x42,0x06,0x83,0x56,0x58,0x9d,0x5e,0x3b,0x9f,0x12,0xf3, + 0x8b,0x66,0xb9,0x41,0xb2,0x2a,0xd7,0xb0,0xaf,0xd2,0xb2,0x3a,0xad,0x7a,0x35,0xee, + 0xed,0xb7,0x26,0xf1,0xc4,0x66,0x17,0x7c,0x98,0x7b,0xdc,0xf6,0x8b,0x93,0x12,0x59, + 0xb1,0x8d,0x4e,0x24,0x22,0x13,0x36,0xc9,0x26,0xfa,0xd9,0x99,0xf5,0xaa,0x49,0x33, + 0x38,0x41,0xc2,0xa1,0x81,0x8c,0x82,0xe2,0xcb,0xf3,0x75,0x37,0x7e,0xdd,0x75,0x77, + 0xa5,0xea,0xb8,0x0d,0xeb,0x58,0x27,0x3e,0x8a,0x60,0x3c,0xb7,0xff,0xd2,0x7d,0x41, + 0xa4,0xe4,0x9e,0x31,0xdd,0xe3,0x83,0xd1,0x7e,0xbb,0xe9,0xc0,0x6d,0xce,0x14,0x42, + 0xc7,0xa2,0xb0,0x92,0xf0,0x37,0x7f,0xec,0x56,0x9c,0x7a,0x91,0x7c,0xfb,0x18,0x7d, + 0xdd,0xda,0xdd,0x9d,0x00,0xf2,0xcc,0xaf,0x71,0x1d,0xdb,0x7a,0xb5,0x43,0x83,0x19, + 0x99,0x15,0xe6,0xf5,0x6b,0xe0,0xd0,0xbf,0xcb,0xd0,0xfb,0x0f,0x13,0x22,0xc1,0x25, + 0x9e,0xa8,0xb1,0x61,0xf2,0xd6,0xa0,0x40,0x7e,0x60,0x4e,0x03,0xa3,0x6b,0x45,0xea, + 0x7b,0xf5,0x5d,0x7c,0x3e,0xcf,0xe9,0xd7,0xdd,0x12,0x1b,0x33,0x15,0x21,0x99,0x7f, + 0x8e,0x8f,0xed,0xe6,0x69,0xce,0xf7,0x21,0x43,0x15,0xe1,0x5a,0x6b,0x81,0xca,0xbc, + 0x87,0x4b,0x52,0xda,0x91,0xbb,0xfe,0x2e,0x9a,0xf5,0x6f,0x96,0xa2,0x8e,0x60,0x52, + 0xeb,0x44,0xcc,0x6b,0x9b,0x74,0xb8,0xec,0x01,0x68,0x5f,0xa2,0x27,0x42,0x7b,0xd7, + 0x7a,0xeb,0x78,0x3b,0xe6,0xef,0x3d,0xd1,0x87,0x1e,0xe5,0xb0,0xbf,0x6b,0x6f,0x8e, + 0xd3,0x99,0x99,0xfc,0xea,0xfe,0x3e,0x0f,0xec,0x5f,0xdc,0x7a,0x56,0xc1,0xe8,0x3a, + 0x7f,0x3b,0xb1,0x53,0x17,0x62,0xb3,0xb4,0xb4,0xb6,0x77,0x43,0x8c,0x6d,0x83,0x4e, + 0x16,0x07,0x26,0xab,0x39,0x25,0x8a,0x8d,0xf1,0x46,0xe6,0x31,0x9f,0xa9,0x99,0xac, + 0x9e,0xe8,0xf7,0xdc,0xb0,0x48,0xf4,0xc9,0x36,0x67,0xaa,0x77,0x56,0x02,0x27,0x02, + 0x58,0x27,0x84,0x27,0x9e,0xf9,0x9d,0xc8,0x19,0xe8,0x53,0x6e,0x2d,0x9f,0x16,0xbb, + 0xce,0x92,0x05,0xa3,0x99,0xf4,0xcb,0xf8,0x9b,0xba,0xd6,0x9a,0x4f,0xbd,0xdc,0x8f, + 0x46,0xfe,0x37,0xb4,0xfa,0xb8,0x1f,0xfe,0xd9,0x37,0xea,0x8e,0xed,0x90,0x7e,0xac, + 0xf2,0x7f,0xd6,0x25,0x89,0x70,0xb6,0x46,0xea,0x44,0x9f,0x39,0x5e,0xe4,0x4a,0xc0, + 0x9d,0x09,0xd3,0xf9,0xa2,0x0d,0x85,0x24,0x9d,0xf8,0x58,0x72,0x21,0xe5,0xa9,0x0a, + 0x7f,0xc4,0x46,0x6e,0x7a,0x66,0x46,0x82,0x88,0xa4,0x48,0x32,0xbd,0x5f,0xe5,0x3e, + 0x27,0x63,0xde,0xde,0x6a,0xc6,0x52,0x39,0x09,0x4a,0x76,0xe7,0x27,0x76,0xeb,0x72, + 0x85,0x97,0xfa,0x62,0x94,0x1a,0xe3,0x0c,0x8d,0xeb,0x02,0x2f,0x37,0x83,0x38,0x52, + 0x70,0x8c,0x58,0x95,0xd6,0xac,0xe4,0x19,0x06,0x8c,0x23,0xef,0x98,0xc2,0xfe,0x72, + 0x3f,0xf6,0x90,0x0e,0xc6,0xef,0xc5,0xfa,0x1d,0xbc,0x2e,0x66,0x2a,0xbd,0x06,0xda, + 0xb4,0xf8,0xd5,0xa1,0x29,0x66,0x0f,0x43,0xe4,0x37,0x31,0x62,0xa2,0xf9,0x4b,0xe3, + 0x27,0x4e,0x36,0x9d,0x0e,0xb6,0x57,0xc8,0xdd,0x89,0x58,0x08,0x7e,0xc9,0xb0,0xce, + 0x96,0x70,0x22,0x71,0x41,0x54,0x9c,0xc9,0x24,0x53,0xc7,0xab,0xe2,0xcb,0x56,0xa0, + 0x2e,0x9d,0x6a,0x3b,0x2e,0x84,0xe1,0xe5,0x3b,0x4f,0x63,0xce,0x9b,0xec,0x54,0xde, + 0x43,0x27,0x2f,0x2e,0xfb,0x98,0xd0,0xdf,0x45,0xa4,0x77,0x7d,0x37,0xeb,0x6e,0xc9, + 0xa9,0x4a,0x11,0x58,0x77,0x58,0xbc,0x42,0x9b,0x4f,0xd3,0xce,0x17,0xe6,0xb6,0x49, + 0xfd,0xd9,0x07,0x4f,0xcc,0x17,0xde,0xe2,0xc9,0xce,0xbf,0x78,0x10,0x64,0x4c,0x2c, + 0xc3,0xf0,0xbe,0xd9,0xb1,0x1f,0xeb,0x6f,0x04,0x6d,0xa4,0xe3,0xb3,0xac,0x1b,0x84, + 0xf4,0xd7,0x1a,0x80,0x09,0x44,0x85,0xef,0xb4,0xa2,0x23,0xe8,0xb9,0x83,0xe8,0xea, + 0xa2,0x8b,0x27,0xfc,0x20,0xe7,0xfc,0x16,0x64,0xb7,0x6b,0x34,0x15,0x2f,0xf8,0x25, + 0xd1,0xc7,0xb9,0xe5,0x9f,0x36,0xe9,0x76,0xaf,0xa0,0xc5,0xbc,0x8c,0x57,0xaa,0xbd, + 0x8e,0xb8,0x3e,0x6c,0xe3,0xd8,0xe3,0x0a,0xca,0x1a,0x85,0xf7,0x92,0xd5,0x55,0xcb, + 0x84,0xe1,0x46,0xe4,0x12,0x47,0x9a,0x61,0xdc,0x7c,0x6c,0xa3,0x07,0xa7,0x17,0x87, + 0x03,0xaa,0xeb,0x89,0x2e,0x7f,0xc2,0xf1,0x09,0x46,0xf9,0x4f,0x27,0xa1,0x5a,0x8d, + 0x87,0xd1,0x37,0x61,0x8d,0x84,0x43,0x99,0x41,0xfa,0x65,0x33,0x93,0x2e,0x3b,0x96, + 0xd3,0x3d,0x31,0x88,0x90,0xd1,0xb2,0xef,0x40,0x2d,0xe5,0x46,0x3a,0xc9,0xda,0x42, + 0x32,0x81,0x33,0xc3,0x34,0x1e,0x8a,0xb2,0x1b,0x33,0x7c,0xed,0x89,0x7a,0xce,0xb9, + 0xc4,0xf1,0xc8,0x26,0xfb,0xf9,0x84,0xc3,0x89,0x0c,0xb7,0xca,0x9d,0xc1,0x75,0x04, + 0x5a,0xe9,0x4a,0xa1,0x5e,0xb7,0x8f,0x4e,0x2a,0xf2,0x79,0xc5,0x8d,0x83,0xca,0x32, + 0x9c,0x88,0xe4,0xbb,0x72,0xd5,0x41,0x1c,0x76,0xaa,0x59,0x84,0x3e,0x0c,0x8c,0xe9, + 0x81,0xbd,0x25,0x43,0x3c,0xf1,0x58,0x0a,0x6c,0xc1,0x5f,0x8f,0xdf,0x4f,0x52,0x66, + 0x7e,0x48,0x4c,0x52,0xe1,0x8d,0x3d,0xe8,0xae,0x54,0x67,0xee,0xab,0x65,0xc0,0xc9, + 0x8d,0xfc,0xe0,0x5a,0xa0,0x4c,0x80,0x57,0x1e,0xd8,0xd2,0x71,0x31,0x9a,0xda,0xdc, + 0xea,0x6c,0x60,0x60,0xc6,0x60,0xc8,0x3b,0x68,0x8f,0xcc,0xf3,0xde,0x67,0xd5,0x92, + 0x58,0x8a,0xae,0xc7,0x91,0x42,0x53,0x4e,0x97,0x2b,0x9b,0x50,0x1f,0xa4,0xc2,0xa3, + 0x6c,0xbf,0x91,0xe7,0x4e,0xb3,0x11,0x68,0xba,0xed,0x51,0xe6,0xbb,0x83,0x2b,0x0b, + 0xe4,0x87,0x66,0x46,0x6c,0xa6,0x44,0xa1,0x66,0xed,0x76,0x1c,0x08,0xa9,0xf9,0x50, + 0x90,0x9d,0x0a,0x41,0x52,0xef,0xc6,0x6e,0xe9,0x38,0x81,0xbc,0xc0,0x21,0x95,0x43, + 0x52,0x77,0x1e,0xfa,0x26,0x7b,0x4e,0xb8,0x93,0x30,0xa9,0x7a,0x90,0x14,0x88,0x14, + 0x1c,0x3c,0x61,0xf8,0xb1,0x1b,0xb2,0xa6,0xf7,0x58,0xa2,0x8b,0xdd,0x27,0x64,0x55, + 0x48,0x3d,0xe3,0xac,0x81,0x81,0x64,0x38,0x45,0xa5,0x11,0x56,0xa4,0x4d,0x8e,0xca, + 0x55,0x58,0xc6,0x3d,0x39,0x3f,0x49,0x2f,0x41,0x85,0x37,0x5f,0xc7,0x0e,0x9b,0xb2, + 0x89,0xb6,0x2c,0xa0,0x08,0xa4,0x1d,0x9b,0xf2,0x9b,0xe3,0xbf,0x37,0xf7,0xe3,0xd2, + 0x22,0x26,0x15,0x33,0x5b,0x47,0x44,0x35,0x8d,0x14,0xab,0x79,0xb6,0x81,0x33,0x6e, + 0x9b,0x93,0x6a,0x39,0x1b,0x3c,0x00,0xc6,0x65,0xb8,0x09,0xdf,0xbb,0xd8,0x8e,0xc7, + 0xdc,0xb6,0x60,0xab,0xb2,0xa2,0x0e,0xbd,0xaa,0x22,0x6d,0x55,0xf9,0x40,0xd7,0x2e, + 0xf3,0xa9,0xa5,0xa5,0x62,0x50,0x3e,0xff,0x1b,0xaa,0xd7,0x5a,0x48,0x13,0x69,0xd5, + 0x8a,0x88,0xa1,0x52,0x9e,0x17,0xfe,0xcc,0x9f,0xcf,0xba,0x57,0x2b,0xc2,0xdf,0x23, + 0x79,0x45,0x90,0xe9,0x78,0x7f,0x22,0x1d,0x56,0xab,0xc0,0xf9,0x80,0xb7,0xad,0xf6, + 0x98,0xd8,0x10,0xae,0x16,0xf0,0x25,0x6e,0xde,0xa5,0x05,0xb4,0xa8,0x2a,0xa2,0xc4, + 0xa0,0xe0,0xc3,0x16,0xa5,0xde,0x35,0x1a,0xb3,0x73,0xfa,0xb9,0xe1,0xe0,0x05,0x0b, + 0xab,0x6a,0xf5,0x03,0xd9,0xd1,0x30,0x28,0xa5,0xf6,0x6c,0x4b,0xb2,0x0c,0x00,0x09, + 0xa1,0x3c,0xd9,0x69,0xb2,0x30,0x65,0xdd,0xb3,0xc7,0x8e,0x29,0x51,0x2e,0x9a,0x2d, + 0x7f,0x90,0x66,0xf1,0x6d,0xc6,0xac,0xe2,0xf3,0x77,0xca,0x9b,0x9d,0xa5,0x7b,0xc7, + 0xa6,0x16,0xee,0x33,0x35,0x8a,0x15,0x47,0xb8,0x3b,0x44,0xbd,0x52,0xbe,0x6e,0x94, + 0x38,0x8e,0x36,0x5e,0x56,0x45,0x70,0x73,0xf0,0x08,0xa1,0x48,0x1f,0x86,0x09,0xc0, + 0xcc,0x25,0xc4,0xb9,0x6a,0x0d,0x37,0x1b,0x28,0x95,0x84,0xe0,0x8f,0xd6,0x2e,0x7d, + 0xe6,0x1a,0x8e,0x94,0x55,0x25,0x5c,0x77,0x68,0x83,0x3a,0x03,0xaa,0x64,0x5a,0x75, + 0x8f,0x3d,0xb1,0x24,0xfc,0xdd,0xb5,0x5b,0xe9,0xe6,0x57,0x60,0xa1,0xc3,0x14,0x86, + 0xd0,0x98,0x96,0x90,0xce,0xaf,0x96,0x36,0xe6,0x91,0xc0,0xfb,0xb4,0x8c,0x0b,0xc4, + 0x0b,0x17,0xab,0x8d,0x04,0xc6,0x82,0xa6,0xc1,0xa5,0x19,0xbe,0xc6,0xd5,0x21,0x1f, + 0x27,0xd3,0xf3,0xf9,0x31,0x4c,0xee,0x82,0xac,0x6b,0xc1,0xa6,0x12,0x37,0xb3,0x32, + 0xf5,0xb0,0xa2,0x18,0x1c,0x70,0x54,0x43,0xc4,0x44,0xc9,0x6c,0x3c,0xa9,0xdf,0xc0, + 0x7f,0x0f,0x4c,0x13,0xea,0x84,0x19,0xb5,0x84,0x2f,0x3c,0x76,0x97,0x16,0x3c,0x55, + 0x32,0xb0,0xfa,0x33,0x46,0xa2,0xe2,0x28,0x82,0x69,0x46,0xe2,0xe6,0x07,0x66,0x31, + 0x38,0x74,0x1f,0xb3,0xe6,0xad,0x46,0x7d,0xdf,0x63,0xbf,0x3b,0xb2,0x0a,0xc3,0xc5, + 0xd0,0x6d,0x23,0xa4,0x0b,0xd4,0x25,0x79,0x57,0xa5,0x69,0x53,0x8e,0x56,0xf2,0x26, + 0x7c,0x3d,0xaf,0x42,0xb8,0x4b,0xfd,0xcf,0xd9,0x1a,0xbb,0x07,0x0b,0xa2,0x8a,0x19, + 0xba,0x10,0x9d,0x5d,0x75,0x7a,0xc2,0xd6,0x28,0x26,0x85,0xf5,0xcc,0x9c,0x64,0x1d, + 0xa6,0x8c,0x71,0x4c,0x47,0x2d,0x78,0x77,0x6c,0xc7,0xbb,0x37,0x23,0xc8,0x5f,0xad, + 0x2f,0x13,0x9e,0x9d,0xf7,0x7c,0xd0,0xc4,0xf0,0x64,0xc2,0x4d,0x69,0x9b,0x3a,0x69, + 0x83,0x2f,0x46,0x0a,0xc9,0xc9,0xfc,0xd3,0xed,0x78,0x90,0x1c,0x84,0x58,0xda,0x25, + 0x15,0x9b,0xdd,0x29,0xdd,0xdc,0x71,0x1b,0x52,0x6d,0x67,0x8c,0x4c,0x2f,0xd7,0xe8, + 0x04,0x9f,0x0e,0x52,0x05,0xcd,0xe9,0xac,0x9a,0xc5,0xb3,0xeb,0x0b,0x54,0x7b,0xa4, + 0x58,0x51,0xbe,0xe4,0x2e,0xe0,0x82,0x28,0x7d,0x50,0x6e,0xb5,0x69,0x01,0x2e,0x3b, + 0x73,0xb3,0xc1,0x55,0x08,0x0d,0x9d,0x77,0x8b,0x4c,0xb2,0x6e,0x85,0xeb,0xae,0xac, + 0x0b,0x1a,0x0b,0x4c,0xe8,0xfb,0x86,0xd5,0x00,0x7b,0x0d,0xa2,0x19,0xfc,0x92,0x9a, + 0xcf,0x74,0x95,0x72,0xa6,0x93,0xa8,0xc9,0x59,0x6c,0x3e,0xe4,0x26,0x9f,0xee,0x91, + 0x19,0x88,0xb7,0xf7,0x35,0x83,0x75,0xe8,0x14,0x70,0x90,0xff,0x50,0x9c,0xe8,0xca, + 0x92,0x7f,0xa0,0xd7,0xa6,0x74,0x7e,0x11,0x42,0x11,0x3f,0xd7,0xb4,0xf2,0x7b,0x71, + 0xac,0x0a,0x8e,0xf5,0x9d,0x2f,0xb1,0x18,0x7e,0x36,0x8b,0x23,0x5c,0x4f,0xb4,0x4d, + 0xf0,0x61,0xff,0xd3,0x02,0x5e,0x94,0x99,0x1c,0xdc,0xfc,0x08,0xfb,0xdd,0xc8,0xfb, + 0x9b,0x18,0x21,0xce,0xca,0x2a,0x0e,0x00,0x2b,0xf6,0x0d,0x69,0x60,0xca,0xd1,0xa9, + 0xf7,0xa9,0x9d,0x2c,0x8c,0xf1,0x20,0x8c,0xcd,0x64,0x43,0x68,0xae,0x22,0xf0,0x2a, + 0xef,0xd9,0x2b,0xc5,0xd1,0xb5,0x31,0x33,0x98,0xbd,0x87,0x03,0x51,0xd4,0x89,0x10, + 0x5d,0x0c,0x84,0x36,0x43,0xfe,0xec,0xdc,0xd8,0x37,0xe9,0x91,0x23,0x8d,0xfe,0x71, + 0xf6,0x54,0x14,0xb7,0x1f,0x98,0xb8,0x28,0xef,0xf3,0xaa,0xef,0xdd,0xd3,0x8b,0xd9, + 0xf6,0x29,0x91,0x5c,0x47,0x18,0xa6,0xa8,0x9b,0xc8,0xfe,0xf6,0xc3,0xa1,0x76,0xcb, + 0x74,0xf4,0x09,0x9a,0x5b,0x30,0x8d,0x83,0xce,0x6e,0xfe,0x62,0x8f,0x20,0xa6,0x3c, + 0xc6,0x8f,0x96,0xaa,0xa6,0x69,0xd6,0x94,0x4e,0x68,0x73,0x51,0xef,0x92,0x41,0xda, + 0x7c,0x21,0x37,0x52,0xfb,0x9a,0x65,0x34,0xed,0xa3,0x52,0xee,0xe2,0x50,0x5d,0x3e, + 0x32,0x98,0x99,0x08,0x41,0xb8,0x1e,0x48,0x1a,0xcb,0xdb,0x4c,0x37,0x83,0x8c,0x38, + 0x9d,0x78,0xe8,0xcd,0xac,0x72,0xf7,0x9d,0x24,0x43,0x69,0x37,0x8a,0x39,0xd3,0xec, + 0x97,0x5a,0x10,0x49,0xe5,0xb5,0x18,0xd5,0xf8,0x7e,0x9d,0x34,0x10,0x34,0x6c,0x2d, + 0xc3,0xc5,0x40,0x20,0x08,0x8f,0xe4,0x02,0xd7,0xa8,0xc3,0x20,0xc5,0x01,0x33,0x90, + 0xc6,0x25,0x27,0x77,0x1e,0x64,0xaf,0x93,0x4f,0xde,0x49,0x14,0x11,0xea,0xbc,0x01, + 0x77,0x88,0xfa,0xfd,0x09,0x23,0x5b,0x0c,0x35,0x73,0x00,0x07,0x0c,0xa0,0xea,0x9f, + 0x89,0xb7,0x53,0x95,0x9c,0x47,0xeb,0x2d,0x73,0x46,0xdd,0xd3,0x90,0x4f,0x7e,0xb0, + 0x58,0x78,0x6a,0xb6,0xc6,0x6b,0x53,0x6c,0xe4,0xec,0xb6,0x1c,0x41,0xdd,0x10,0x80, + 0x21,0x24,0x78,0xa6,0x14,0x24,0x1c,0xf9,0x12,0xa0,0x9f,0x35,0x40,0xc9,0xd7,0x5e, + 0x78,0x7b,0xc0,0x2d,0x76,0xc3,0xea,0xd3,0x42,0x75,0x27,0x37,0x40,0xeb,0x73,0x1e, + 0x04,0xd7,0xef,0x66,0x49,0x55,0x89,0x77,0x10,0xe7,0x47,0xde,0x39,0xbe,0xef,0xcb, + 0x65,0x31,0x77,0xa6,0x79,0x59,0x64,0xb4,0x0c,0xad,0x66,0x31,0x5c,0x75,0x09,0x56, + 0x65,0xd0,0x70,0x2d,0x0f,0x2b,0x0e,0x11,0x1e,0x0a,0x01,0xb4,0x9a,0x20,0xda,0xa4, + 0xfd,0x57,0x41,0x46,0xf3,0x20,0xb5,0xbf,0xbf,0x62,0x4a,0x21,0x8f,0xd7,0xac,0x01, + 0xbd,0xdd,0x92,0x96,0x0f,0x41,0x27,0x0b,0x50,0x6e,0x75,0x9e,0x58,0xab,0x2d,0x5c, + 0x2c,0xd2,0xe3,0xed,0x17,0x27,0x84,0xdd,0xa1,0x2a,0xeb,0x27,0xbc,0x5d,0xf7,0xc4, + 0xb9,0x77,0xac,0x85,0xa0,0x6e,0x9e,0xee,0xc9,0x30,0x98,0x04,0x09,0xa8,0xcd,0x0b, + 0xd3,0x85,0x9d,0xe0,0x0e,0x1d,0x8b,0xd6,0xe6,0xbf,0x96,0xb0,0x18,0x10,0x6f,0x7f, + 0xa1,0xa1,0xee,0x22,0xe4,0x04,0xec,0xf2,0xd4,0x84,0x68,0xf6,0x6e,0xdd,0xa6,0x19, + 0xbd,0xcd,0xdd,0x56,0xb5,0x64,0xf8,0x06,0xd1,0xd9,0x1e,0xce,0xac,0x78,0xf8,0x7d, + 0x00,0x6c,0x9d,0x10,0xdc,0x38,0xb9,0x49,0x0e,0x0a,0x4c,0x3b,0x22,0x53,0xdd,0x2c, + 0x52,0xfe,0xf0,0xca,0x4e,0x95,0x25,0x2e,0x47,0xa7,0x25,0xd3,0x45,0x6a,0xbf,0xb6, + 0x49,0x43,0x29,0xca,0x4f,0xcc,0x6e,0x8a,0x45,0xb8,0xdb,0x56,0x8e,0x84,0x4b,0x17, + 0xca,0xda,0xc8,0xd4,0xf6,0xa4,0xb7,0x4d,0x73,0x33,0x8f,0x53,0x16,0x72,0x41,0x71, + 0x80,0x93,0x0d,0x6a,0xf4,0xb4,0x1c,0xa3,0xbc,0x34,0xc3,0x7c,0xfc,0x4c,0x2b,0xf7, + 0x13,0x09,0x8f,0x32,0xbc,0x06,0xab,0x72,0x68,0x95,0x6d,0xb3,0xd5,0x7b,0x75,0xc3, + 0xf1,0xce,0x72,0xea,0x72,0x42,0xfd,0x68,0xfc,0x73,0xa1,0x16,0xe6,0x60,0xfc,0x66, + 0x11,0xb8,0x10,0x6c,0x2f,0x9a,0x75,0xc3,0x94,0x48,0x68,0x2b,0x11,0x0d,0xb9,0x72, + 0x29,0xf7,0x43,0x73,0xb6,0xd8,0xcc,0xae,0x3c,0x56,0x0d,0x75,0x20,0x57,0x48,0xf8, + 0x76,0x01,0x81,0xd8,0x0f,0x1d,0xf5,0x68,0x6c,0xf7,0x9c,0xd7,0xb3,0xf6,0x5e,0xeb, + 0x8d,0x4c,0xf4,0x15,0xc4,0x7a,0x59,0x6c,0x92,0x25,0xe3,0xce,0x24,0x77,0x7c,0x5d, + 0xdb,0xc3,0x19,0x56,0xac,0x2c,0x94,0x23,0x88,0xed,0xab,0xb3,0x98,0xc8,0xf7,0x8a, + 0x02,0x24,0x20,0x76,0xa2,0x4f,0x02,0x82,0x1c,0xaf,0xcc,0xe4,0xa9,0xc6,0x36,0xaf, + 0xcd,0x42,0x0a,0xd2,0x16,0x37,0x44,0xcd,0x03,0x35,0x1a,0xde,0x3e,0xd4,0x19,0x05, + 0x36,0x5a,0x69,0xde,0x9c,0x0c,0x3a,0x8b,0xb4,0x6e,0x23,0x99,0x9f,0xfc,0xb5,0x00, + 0xc0,0x86,0xfe,0xd7,0x3f,0xb6,0xc9,0xa5,0x19,0xe3,0xc8,0x89,0x90,0xba,0xfe,0x99, + 0xe3,0xf5,0xc5,0xb9,0x62,0xd3,0xdc,0x81,0x47,0xc3,0x55,0xc7,0x2e,0xa5,0x1c,0x65, + 0xb3,0xc3,0x65,0xa8,0x23,0x0d,0x06,0xec,0x84,0x29,0xa2,0xf8,0x69,0x8f,0x09,0x70, + 0x35,0x3c,0xc4,0x80,0xe6,0xd0,0x21,0x59,0xfd,0xb0,0xc1,0xa5,0x6c,0xbd,0xae,0xae, + 0xc3,0x9c,0xa9,0xe4,0x1d,0x23,0x47,0x28,0x9a,0x5e,0x22,0x7a,0x94,0xb2,0xc6,0xa1, + 0x4e,0x54,0x26,0xa0,0xf4,0x59,0xb1,0xb4,0xa8,0x7e,0x82,0xee,0xb0,0x12,0x1f,0x7a, + 0x10,0x5a,0x24,0xa6,0x11,0x53,0x21,0x50,0x60,0x48,0x2e,0xa0,0x33,0xd3,0xa9,0x57, + 0x5c,0xa2,0xe4,0x76,0xe6,0x13,0x1b,0x28,0x14,0x5f,0xd2,0x93,0xa0,0xd9,0xfb,0xb4, + 0x3a,0xf8,0xdc,0xc9,0x29,0x15,0x20,0x5b,0x47,0x8e,0xf8,0x5c,0x76,0x2d,0xb4,0x99, + 0x34,0xe0,0xb8,0xe1,0x6d,0x4c,0x55,0x81,0xda,0xdc,0x24,0x20,0xd2,0xdd,0xb7,0xd4, + 0x93,0xb3,0x1c,0xc9,0xfa,0x04,0x69,0xa7,0xa1,0xce,0x81,0x2f,0xca,0x85,0xd2,0xaa, + 0xe8,0x91,0x5d,0x8b,0xe3,0xb5,0x61,0xa9,0x6a,0x1e,0x5f,0xf4,0x4a,0x8b,0x7e,0x28, + 0x60,0x9b,0x2e,0x6a,0xea,0x86,0xb7,0xab,0x27,0xf9,0x71,0x1a,0x5d,0x98,0x05,0x61, + 0x50,0xe7,0x42,0xb7,0x3a,0x56,0x36,0x32,0xfc,0x47,0x62,0x15,0x35,0x91,0x86,0xde, + 0xee,0x5b,0xee,0x4b,0x67,0xf8,0x28,0xff,0x8c,0x64,0xa8,0x6d,0xc8,0x6b,0x72,0x8c, + 0x3a,0x07,0x1d,0x51,0xc2,0x75,0x75,0x21,0x9d,0x18,0x93,0x5d,0x19,0xcd,0xe2,0x53, + 0x46,0x97,0xd0,0xd6,0xe0,0x5e,0x19,0x80,0xd3,0x3f,0x27,0x2e,0x75,0x7b,0xc6,0x5e, + 0x38,0xec,0x36,0x1c,0x56,0xa1,0x6c,0xa4,0xa4,0xeb,0xd0,0xbe,0xd2,0x85,0x58,0xc1, + 0x44,0xa8,0xf3,0x42,0x71,0x6f,0x74,0xd8,0x5c,0x0a,0x12,0x4c,0x4e,0x7b,0xa5,0xaf, + 0x2e,0xe5,0x57,0x92,0x76,0x8a,0x06,0x7a,0x6a,0xf4,0x21,0x09,0xcc,0x44,0x33,0x9f, + 0x0f,0x71,0xb0,0x04,0xcf,0x00,0xb5,0x08,0x25,0x1c,0xf3,0x5a,0x37,0x5e,0x82,0x43, + 0x3f,0x4a,0x15,0xb3,0xed,0x6d,0xc6,0x66,0xfa,0x75,0xd1,0xba,0x7e,0x26,0xfe,0x8b, + 0xc9,0x40,0x32,0x1c,0x27,0xb4,0x69,0xf0,0xa3,0x22,0xd5,0xc4,0x56,0x22,0x64,0x59, + 0x75,0x91,0xfb,0xd2,0xb4,0x3a,0x24,0x22,0x0a,0x2d,0xd6,0x37,0x8a,0xd2,0xf3,0x14, + 0x18,0x4b,0x07,0x96,0x74,0xbf,0x21,0x59,0x26,0x23,0xcb,0x11,0x82,0xe3,0xf1,0x17, + 0x6f,0x27,0xef,0xa9,0x1a,0xb4,0x97,0x5a,0xe2,0x9b,0x1d,0x0d,0x06,0x80,0x49,0x46, + 0x5b,0x02,0x35,0x69,0xb9,0x54,0xa5,0x05,0xd7,0x3b,0x59,0x25,0x3d,0x7c,0x68,0x48, + 0x9a,0xe1,0x1e,0xfd,0x48,0x31,0x0e,0xb2,0xd2,0xd3,0xe0,0x0b,0xd1,0x4c,0x0d,0xe6, + 0x3e,0xa5,0x13,0xcc,0xc3,0x57,0xe6,0xd4,0x12,0x8a,0x20,0xa8,0x60,0x62,0x93,0x73, + 0x00,0x83,0xa1,0x65,0x66,0x92,0x76,0x67,0x8e,0x8d,0x6b,0x43,0x4d,0x9f,0xf4,0x22, + 0x88,0x3b,0xef,0x14,0x7d,0xb6,0x7a,0xa8,0xd1,0x15,0x8e,0xb2,0x49,0x36,0x83,0x0c, + 0x70,0xc1,0xae,0x1e,0x84,0xad,0x8f,0x5e,0x0b,0xe5,0xd2,0x69,0x5c,0x7f,0x03,0x20, + 0x62,0x18,0xe7,0x2c,0x9f,0xb2,0xbb,0xaa,0x99, }; diff --git a/src/helpers/esp32/WebConfigServer.cpp b/src/helpers/esp32/WebConfigServer.cpp index 141087da..ed017e70 100644 --- a/src/helpers/esp32/WebConfigServer.cpp +++ b/src/helpers/esp32/WebConfigServer.cpp @@ -238,6 +238,12 @@ static inline bool wcIsDeferredReboot(const char* cmd) { return strncmp(cmd, "reboot", 6) == 0; } +static const char* const WC_BOARD_CMDS[] = { + "radio.fem.rxgain", "radio.fem.txgain", "fan", +}; +static const size_t WC_BOARD_CMD_COUNT = sizeof(WC_BOARD_CMDS) / sizeof(WC_BOARD_CMDS[0]); +static_assert(WC_BOARD_CMD_COUNT <= 8, "board command mask must fit uint8_t"); + // Commands the CLI reaches but the portal cannot honestly serve. Rejected at // POST so nothing in the sequence runs, rather than failing halfway with a // reply that does not explain itself. Returns the reason, or NULL if fine. @@ -1007,9 +1013,25 @@ void WebConfigServer::finalizeTeardown() { _admin_pwd_set = false; _session_token[0] = 0; _stats_json[0] = 0; + _board_cmds = 0; + _board_cmds_probed = false; if (_cb) _cb->onWebConfigStopped(); } +void WebConfigServer::probeBoardCommands() { + char command[48], reply[160]; + uint8_t mask = 0; + for (size_t i = 0; i < WC_BOARD_CMD_COUNT; ++i) { + snprintf(command, sizeof(command), "get %s", WC_BOARD_CMDS[i]); + reply[0] = 0; + _cb->execCommand(command, reply); + if (reply[0] == '>') mask |= static_cast(1U << i); + } + WCLock lock(_mux); + _board_cmds = mask; + _board_cmds_probed = true; +} + void WebConfigServer::tick(uint32_t now) { if (_stopping) { uint32_t refs = handlerRefCount(); @@ -1030,6 +1052,8 @@ void WebConfigServer::tick(uint32_t now) { } if (_mode == MODE_OFF) return; + if (!_board_cmds_probed) probeBoardCommands(); + serviceTerminal(now); // A primary ESP-NOW radio and its WiFi station cannot remain on different @@ -1662,7 +1686,7 @@ void WebConfigServer::handleStatus(AsyncWebServerRequest* req) { } const bool has_mqtt = _mqtt_prefs != NULL; - DynamicJsonDocument doc(768); + DynamicJsonDocument doc(896); doc["mode"] = (_mode == MODE_SETUP) ? "setup" : "lan"; doc["auth"] = authed; doc["needs_setup"] = (_wifi_ssid[0] == 0); @@ -1678,6 +1702,25 @@ void WebConfigServer::handleStatus(AsyncWebServerRequest* req) { doc["build_date"] = _build_date; doc["role"] = _role; doc["board"] = _board_name; + uint8_t board_mask = 0; + bool board_probed = false; + { + WCLock lock(_mux); + board_mask = _board_cmds; + board_probed = _board_cmds_probed; + } + if (board_probed) { + char board_cmds[80] = {0}; + size_t used = 0; + for (size_t i = 0; i < WC_BOARD_CMD_COUNT; ++i) { + if ((board_mask & (1U << i)) == 0) continue; + const int written = snprintf(board_cmds + used, sizeof(board_cmds) - used, + "%s%s", used ? "," : "", WC_BOARD_CMDS[i]); + if (written < 0 || static_cast(written) >= sizeof(board_cmds) - used) break; + used += static_cast(written); + } + doc["board_cmds"] = board_cmds; + } doc["uptime_s"] = millis() / 1000; #ifdef WITH_MQTT_BRIDGE doc["runtime_slots"] = has_mqtt ? RUNTIME_MQTT_SLOTS : 0; diff --git a/src/helpers/esp32/WebConfigServer.h b/src/helpers/esp32/WebConfigServer.h index d63821f5..1a9e5dcd 100644 --- a/src/helpers/esp32/WebConfigServer.h +++ b/src/helpers/esp32/WebConfigServer.h @@ -333,6 +333,8 @@ private: volatile uint32_t _stats_wanted_until = 0; uint32_t _stats_built_at = 0; char _stats_json[1024] = {0}; + uint8_t _board_cmds = 0; + bool _board_cmds_probed = false; void createServer(); void registerRoutes(); @@ -342,6 +344,7 @@ private: void detachRoutes(); uint32_t handlerRefCount() const; void drainBatch(uint32_t now); + void probeBoardCommands(); void serviceTerminal(uint32_t now); void closeTerminal(); void serviceSetupWiFiHandoff(uint32_t now); diff --git a/src/helpers/ethernet/ch390/CH390Config.h b/src/helpers/ethernet/ch390/CH390Config.h new file mode 100644 index 00000000..05723067 --- /dev/null +++ b/src/helpers/ethernet/ch390/CH390Config.h @@ -0,0 +1,36 @@ +#pragma once + +#include + +/** + * Bring up the repository's CH390 lwIP interface from the board build flags. + * Shared by the companion transport wrapper and the observer network adapter so + * pin and static-IP behavior cannot drift between the two paths. + */ +static inline bool beginConfiguredCH390(const char* hostname = nullptr) { + ch390_config_t config = CH390_DEFAULT_CONFIG(); + config.spi_miso_gpio = ETH_MISO_PIN; + config.spi_mosi_gpio = ETH_MOSI_PIN; + config.spi_sck_gpio = ETH_SCLK_PIN; + config.spi_cs_gpio = ETH_CS_PIN; + config.int_gpio = ETH_INT_PIN; + if (hostname && hostname[0] != '\0') { + if (!CH390.setHostname(hostname)) { + Serial.printf("Network: invalid Ethernet hostname %s\n", hostname); + } + } + if (!CH390.begin(config)) return false; + +#if defined(ETHERNET_STATIC_IP) && defined(ETHERNET_STATIC_GATEWAY) && defined(ETHERNET_STATIC_SUBNET) + IPAddress ip(ETHERNET_STATIC_IP); + IPAddress gateway(ETHERNET_STATIC_GATEWAY); + IPAddress subnet(ETHERNET_STATIC_SUBNET); + #if defined(ETHERNET_STATIC_DNS) + IPAddress dns(ETHERNET_STATIC_DNS); + CH390.config(ip, gateway, subnet, dns); + #else + CH390.config(ip, gateway, subnet); + #endif +#endif + return true; +} diff --git a/src/helpers/ethernet/ch390/CH390EthernetInterface.cpp b/src/helpers/ethernet/ch390/CH390EthernetInterface.cpp index ba1d3ee8..b7f802e8 100644 --- a/src/helpers/ethernet/ch390/CH390EthernetInterface.cpp +++ b/src/helpers/ethernet/ch390/CH390EthernetInterface.cpp @@ -1,4 +1,5 @@ #include "CH390EthernetInterface.h" +#include "CH390Config.h" void onWiFiEvent(WiFiEvent_t event) { switch(event){ @@ -29,26 +30,12 @@ bool CH390EthernetInterface::begin() { // listen to ethernet events WiFi.onEvent(onWiFiEvent); - // Init CH390 - ch390_config_t config = CH390_DEFAULT_CONFIG(); - config.spi_miso_gpio = ETH_MISO_PIN; - config.spi_mosi_gpio = ETH_MOSI_PIN; - config.spi_sck_gpio = ETH_SCLK_PIN; - config.spi_cs_gpio = ETH_CS_PIN; - config.int_gpio = ETH_INT_PIN; - if (!CH390.begin(config)) { + // Init CH390 using the same board configuration as the observer uplink. + if (!beginConfiguredCH390()) { ETHERNET_DEBUG_PRINTLN("Failed to initialize CH390 hardware."); return false; } - // Setup Static IP if build flags are present - #if defined(ETHERNET_STATIC_IP) && defined(ETHERNET_STATIC_GATEWAY) && defined(ETHERNET_STATIC_SUBNET) - IPAddress ip(ETHERNET_STATIC_IP); - IPAddress gw(ETHERNET_STATIC_GATEWAY); - IPAddress sn(ETHERNET_STATIC_SUBNET); - CH390.config(ip, gw, sn); - #endif - // Start Server server.begin(ETHERNET_TCP_PORT); ETHERNET_DEBUG_PRINTLN("listening on TCP port: %d", ETHERNET_TCP_PORT); diff --git a/src/helpers/ui/RotaryInputGPIO.cpp b/src/helpers/ui/RotaryInputGPIO.cpp index b094fe49..4ed04c98 100644 --- a/src/helpers/ui/RotaryInputGPIO.cpp +++ b/src/helpers/ui/RotaryInputGPIO.cpp @@ -24,11 +24,11 @@ RotaryInputEvent RotaryInputGPIO::poll() { if (!b_prec && b) { // rising edge of A if (a) { ev = RotaryInputEvent::Next; - } else { + } else { ev = RotaryInputEvent::Prev; } } b_prec = b; return ev; -} \ No newline at end of file +} diff --git a/src/helpers/ui/RotaryInputGPIO.h b/src/helpers/ui/RotaryInputGPIO.h index 16b7e46a..a68e01d3 100644 --- a/src/helpers/ui/RotaryInputGPIO.h +++ b/src/helpers/ui/RotaryInputGPIO.h @@ -7,7 +7,7 @@ #define BUTTON_EVENT_DOWN 6 class RotaryInputGPIO: public RotaryInput { - int8_t _pin_a; + int8_t _pin_a; bool _pull_a; int8_t _pin_b; bool _pull_b; diff --git a/test/mocks/Arduino.h b/test/mocks/Arduino.h index 0a8aea49..9c9ddcc3 100644 --- a/test/mocks/Arduino.h +++ b/test/mocks/Arduino.h @@ -3,8 +3,13 @@ #include #include #include +#include #include "Stream.h" +using std::atof; +using std::atoi; +using std::atol; + inline uint32_t g_mock_millis = 0; constexpr uint8_t LOW = 0; diff --git a/test/mocks/CommonRadioPrefs.cpp b/test/mocks/CommonRadioPrefs.cpp new file mode 100644 index 00000000..d749cc1e --- /dev/null +++ b/test/mocks/CommonRadioPrefs.cpp @@ -0,0 +1,32 @@ +#include "helpers/CommonRadioPrefs.h" +#include +#include + +// Native serializer tests instantiate NodePrefs, but the full radio CLI source +// depends on target hardware. These two methods are the only out-of-line vtable +// entries the host-side NodePrefs tests require. +bool CommonRadioPrefs::getByKey(const char* key, char* value, size_t max_len) { + if (strcmp(key, "fem_rxgain") == 0) { + snprintf(value, max_len, "%d", (uint32_t)getFEMRxGain()); + return true; + } + if (strcmp(key, "fem_txgain") == 0) { + snprintf(value, max_len, "%d", (uint32_t)getFEMTxGain()); + return true; + } + return false; +} + +bool CommonRadioPrefs::setByKey(const char* key, const char* value) { + if (strcmp(key, "fem_rxgain") == 0) { + setFEMRxGain(atoi(value)); + markDirty(); + return true; + } + if (strcmp(key, "fem_txgain") == 0) { + setFEMTxGain(atoi(value)); + markDirty(); + return true; + } + return false; +} diff --git a/test/test_mqtt_client_state/test_mqtt_client_state.cpp b/test/test_mqtt_client_state/test_mqtt_client_state.cpp new file mode 100644 index 00000000..1ff2b97f --- /dev/null +++ b/test/test_mqtt_client_state/test_mqtt_client_state.cpp @@ -0,0 +1,118 @@ +#include "helpers/MQTTClientState.h" + +#include + +#include +#include + +namespace { + +const MqttClientState kAllStates[] = { + MqttClientState::Absent, MqttClientState::Configured, + MqttClientState::Starting, MqttClientState::Connected, + MqttClientState::Disconnected, MqttClientState::Stopped, + MqttClientState::Quarantined, +}; + +bool ack(std::vector states) { + return mqttStopMayBeAcknowledged(states.data(), (int)states.size()); +} + +} // namespace + +TEST(MqttClientState, LiveMeansStartedAndNotProvenStopped) { + EXPECT_TRUE(mqttClientStateIsLive(MqttClientState::Starting)); + EXPECT_TRUE(mqttClientStateIsLive(MqttClientState::Connected)); + EXPECT_TRUE(mqttClientStateIsLive(MqttClientState::Disconnected)); + + EXPECT_FALSE(mqttClientStateIsLive(MqttClientState::Absent)); + EXPECT_FALSE(mqttClientStateIsLive(MqttClientState::Configured)); + EXPECT_FALSE(mqttClientStateIsLive(MqttClientState::Stopped)); + // Quarantined is not "live": it is worse. It may own a task and we can never + // find out, which is why it is not simply lumped in with the live states. + EXPECT_FALSE(mqttClientStateIsLive(MqttClientState::Quarantined)); +} + +TEST(MqttClientState, OnlyStartingHasAnAttemptInFlight) { + for (MqttClientState s : kAllStates) { + EXPECT_EQ(s == MqttClientState::Starting, mqttClientStateHasAttemptInFlight(s)) + << mqttClientStateName(s); + } +} + +TEST(MqttClientState, ProvenStoppedIsTheComplementOfLiveAndQuarantined) { + for (MqttClientState s : kAllStates) { + const bool proven = mqttClientStateIsProvenStopped(s); + EXPECT_EQ(!mqttClientStateIsLive(s) && s != MqttClientState::Quarantined, proven) + << mqttClientStateName(s); + } +} + +// The invariant the shutdown contract rests on: the acknowledgement means the +// task destroyed its clients, so it may not be published while any client's +// stop is unproven. +TEST(MqttClientState, StopIsAcknowledgedOnlyWhenEveryClientIsProvenStopped) { + EXPECT_TRUE(ack({})); // no slots configured at all + EXPECT_TRUE(ack({MqttClientState::Absent, MqttClientState::Stopped, + MqttClientState::Configured})); + + // One quarantined client withholds the acknowledgement, whatever the others did. + EXPECT_FALSE(ack({MqttClientState::Quarantined})); + EXPECT_FALSE(ack({MqttClientState::Stopped, MqttClientState::Stopped, + MqttClientState::Quarantined, MqttClientState::Absent})); + EXPECT_FALSE(ack({MqttClientState::Quarantined, MqttClientState::Absent, + MqttClientState::Absent, MqttClientState::Absent, + MqttClientState::Absent, MqttClientState::Absent})); + + // So does a client that is merely still live: teardown did not finish it. + EXPECT_FALSE(ack({MqttClientState::Stopped, MqttClientState::Connected})); + EXPECT_FALSE(ack({MqttClientState::Starting})); + EXPECT_FALSE(ack({MqttClientState::Disconnected})); + + // An empty set is trivially proven; a null array with a nonzero count is a + // caller bug and must never read as proof. + EXPECT_TRUE(mqttStopMayBeAcknowledged(nullptr, 0)); + EXPECT_FALSE(mqttStopMayBeAcknowledged(nullptr, 3)); +} + +// A link transition closes each slot's transport because the route under it +// changed. These two predicates are what decide which clients it may touch. +// +// The distinction from a reconfigure matters: a reconfigure must cancel an +// in-flight attempt, because that attempt would report the OLD endpoint under +// the new configuration. A transition changes no configuration, so the attempt +// is left to resolve — cancelling it would mean an unbounded +// esp_mqtt_client_stop() on the sole MQTT worker during a routine link flap. +TEST(MqttClientState, LinkTransitionOnlyDisconnectsClientsWithNoAttemptInFlight) { + for (MqttClientState s : kAllStates) { + const bool live = mqttClientStateIsLive(s); + const bool disconnected_here = live && !mqttClientStateHasAttemptInFlight(s); + + // Quarantined is never touched: its SDK task was not joined, so it stays + // out of service for the rest of the boot. + if (s == MqttClientState::Quarantined) EXPECT_FALSE(live) << mqttClientStateName(s); + // Nothing that is already proven stopped is worth a disconnect. + if (mqttClientStateIsProvenStopped(s)) EXPECT_FALSE(live) << mqttClientStateName(s); + + EXPECT_EQ(s == MqttClientState::Connected || s == MqttClientState::Disconnected, + disconnected_here) << mqttClientStateName(s); + // Starting is live, and still must not be disconnected here. + if (s == MqttClientState::Starting) { + EXPECT_TRUE(live); + EXPECT_FALSE(disconnected_here); + } + } +} + +TEST(MqttClientState, EveryStateHasAName) { + for (MqttClientState s : kAllStates) { + ASSERT_NE(nullptr, mqttClientStateName(s)); + EXPECT_GT(strlen(mqttClientStateName(s)), 0u); + } + EXPECT_STREQ("quarantined", mqttClientStateName(MqttClientState::Quarantined)); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/test_mqtt_effective_config/test_mqtt_effective_config.cpp b/test/test_mqtt_effective_config/test_mqtt_effective_config.cpp new file mode 100644 index 00000000..70eadb00 --- /dev/null +++ b/test/test_mqtt_effective_config/test_mqtt_effective_config.cpp @@ -0,0 +1,203 @@ +#include "helpers/MQTTEffectiveConfig.h" + +#include + +#include + +namespace { + +const char kPemA[] = "-----BEGIN CERTIFICATE-----A"; +const char kPemB[] = "-----BEGIN CERTIFICATE-----B"; +const char kJwtUser[] = "v1_CC5D3CFD9C4C7B84"; +const char kToken[] = "eyJhbGciOi..."; + +MqttEffectiveConfig build(const char* uri, + MqttAuth auth = MqttAuth::None, + const char* user = nullptr, + const char* pass = nullptr, + MqttTrust trust = MqttTrust::Plaintext, + const char* pem = nullptr, + uint16_t buffer = 896) { + MqttEffectiveConfig c; + mqttBuildEffectiveConfig(uri, auth, user, pass, trust, pem, buffer, 75, &c); + return c; +} + +MqttRecreateDecision decide(const MqttEffectiveConfig& applied, + const MqttEffectiveConfig& desired, + uint16_t allocated = 896) { + return mqttConfigRecreateDecision(applied, desired, allocated); +} + +} // namespace + +TEST(MqttEffectiveConfig, TransportComesFromTheUriScheme) { + EXPECT_EQ(MqttTransport::Tcp, mqttTransportFromUri("mqtt://broker:1883")); + EXPECT_EQ(MqttTransport::Tls, mqttTransportFromUri("mqtts://broker:8883")); + EXPECT_EQ(MqttTransport::Ws, mqttTransportFromUri("ws://broker/mqtt")); + EXPECT_EQ(MqttTransport::Wss, mqttTransportFromUri("wss://broker:443/mqtt")); + EXPECT_EQ(MqttTransport::Unknown, mqttTransportFromUri("broker:1883")); + EXPECT_EQ(MqttTransport::Unknown, mqttTransportFromUri("")); + EXPECT_EQ(MqttTransport::Unknown, mqttTransportFromUri(nullptr)); + + EXPECT_TRUE(mqttTransportIsEncrypted(MqttTransport::Tls)); + EXPECT_TRUE(mqttTransportIsEncrypted(MqttTransport::Wss)); + EXPECT_FALSE(mqttTransportIsEncrypted(MqttTransport::Tcp)); + EXPECT_FALSE(mqttTransportIsEncrypted(MqttTransport::Ws)); +} + +TEST(MqttEffectiveConfig, BuildRejectsUnusableUris) { + MqttEffectiveConfig c; + EXPECT_FALSE(mqttBuildEffectiveConfig("", MqttAuth::None, nullptr, nullptr, + MqttTrust::Plaintext, nullptr, 896, 75, &c)); + EXPECT_FALSE(c.valid); + EXPECT_FALSE(mqttBuildEffectiveConfig(nullptr, MqttAuth::None, nullptr, nullptr, + MqttTrust::Plaintext, nullptr, 896, 75, &c)); + EXPECT_FALSE(mqttBuildEffectiveConfig("broker:1883", MqttAuth::None, nullptr, nullptr, + MqttTrust::Plaintext, nullptr, 896, 75, &c)); + + char too_long[MQTT_EFFECTIVE_URI_MAX + 16]; + memset(too_long, 'x', sizeof(too_long)); + memcpy(too_long, "mqtt://", 7); + too_long[sizeof(too_long) - 1] = '\0'; + EXPECT_FALSE(mqttBuildEffectiveConfig(too_long, MqttAuth::None, nullptr, nullptr, + MqttTrust::Plaintext, nullptr, 896, 75, &c)); +} + +TEST(MqttEffectiveConfig, BuildOwnsItsUriCopy) { + char uri[64]; + strcpy(uri, "mqtt://192.168.50.231:1883"); + MqttEffectiveConfig c = build(uri); + ASSERT_TRUE(c.valid); + + strcpy(uri, "mqtt://other:1883"); // slot.broker_uri is rewritten in place + EXPECT_STREQ("mqtt://192.168.50.231:1883", c.uri); +} + +// An unencrypted transport verifies nothing, whatever certificate material was +// requested. Recording anything else would make a plaintext endpoint look like +// it kept a verified policy. +TEST(MqttEffectiveConfig, TrustIsNormalisedAgainstTheTransport) { + MqttEffectiveConfig plain = build("mqtt://broker:1883", MqttAuth::None, nullptr, nullptr, + MqttTrust::Bundle, kPemA); + EXPECT_EQ(MqttTrust::Plaintext, plain.trust); + EXPECT_EQ(nullptr, plain.pem); + + MqttEffectiveConfig bundle = build("wss://broker:443/mqtt", MqttAuth::Jwt, kJwtUser, kToken, + MqttTrust::Bundle, nullptr); + EXPECT_EQ(MqttTrust::Bundle, bundle.trust); + + MqttEffectiveConfig pem = build("mqtts://broker:8883", MqttAuth::UserPass, "u", "p", + MqttTrust::PemCert, kPemA); + EXPECT_EQ(MqttTrust::PemCert, pem.trust); + EXPECT_EQ(kPemA, pem.pem); + + // Encrypted transport with no usable material is not a verified policy. + MqttEffectiveConfig none = build("mqtts://broker:8883", MqttAuth::None, nullptr, nullptr, + MqttTrust::PemCert, nullptr); + EXPECT_EQ(MqttTrust::Plaintext, none.trust); + EXPECT_EQ(nullptr, none.pem); +} + +// The six F02 transitions from the review, plus the one reproduced on hardware. +// None of them needs a new client: credentials are rewritten unconditionally. +TEST(MqttEffectiveConfig, CredentialAndAuthChangesReuseTheClient) { + const MqttEffectiveConfig jwt = build("wss://broker:443/mqtt", MqttAuth::Jwt, kJwtUser, kToken, + MqttTrust::Bundle, nullptr); + const MqttEffectiveConfig anon = build("wss://broker:443/mqtt", MqttAuth::None, nullptr, nullptr, + MqttTrust::Bundle, nullptr); + const MqttEffectiveConfig userpass = build("wss://broker:443/mqtt", MqttAuth::UserPass, "u", "p", + MqttTrust::Bundle, nullptr); + const MqttEffectiveConfig renewed = build("wss://broker:443/mqtt", MqttAuth::Jwt, kJwtUser, + "eyJhbGciOi...new", MqttTrust::Bundle, nullptr); + + EXPECT_FALSE(decide(jwt, anon).recreate); // JWT -> anonymous + EXPECT_FALSE(decide(userpass, anon).recreate); // user/pass -> anonymous + EXPECT_FALSE(decide(anon, jwt).recreate); // none -> configured + EXPECT_FALSE(decide(userpass, jwt).recreate); // user/pass -> JWT + EXPECT_FALSE(decide(jwt, renewed).recreate); // token renewal + EXPECT_FALSE(decide(jwt, jwt).recreate); // ordinary reconnect + EXPECT_STREQ("reuse", decide(jwt, jwt).reason); +} + +// Host/port/path within one scheme is an endpoint move, not a structural one. +TEST(MqttEffectiveConfig, EndpointMoveWithinOneSchemeReusesTheClient) { + const MqttEffectiveConfig a = build("mqtt://192.168.50.231:1883"); + const MqttEffectiveConfig b = build("mqtt://192.168.50.9:1884"); + EXPECT_FALSE(decide(a, b).recreate); + + const MqttEffectiveConfig wss_a = build("wss://a.example:443/mqtt", MqttAuth::Jwt, kJwtUser, + kToken, MqttTrust::Bundle, nullptr); + const MqttEffectiveConfig wss_b = build("wss://b.example:443/other", MqttAuth::Jwt, kJwtUser, + kToken, MqttTrust::Bundle, nullptr); + EXPECT_FALSE(decide(wss_a, wss_b).recreate); +} + +TEST(MqttEffectiveConfig, TransportChangeForcesRecreate) { + const MqttEffectiveConfig wss = build("wss://broker:443/mqtt", MqttAuth::Jwt, kJwtUser, kToken, + MqttTrust::Bundle, nullptr); + const MqttEffectiveConfig tcp = build("mqtt://192.168.50.231:1883"); + const MqttEffectiveConfig tls = build("mqtts://broker:8883", MqttAuth::UserPass, "u", "p", + MqttTrust::Bundle, nullptr); + const MqttEffectiveConfig ws = build("ws://broker/mqtt"); + + EXPECT_TRUE(decide(wss, tcp).recreate); + EXPECT_STREQ("transport-change", decide(wss, tcp).reason); + EXPECT_TRUE(decide(tcp, wss).recreate); + EXPECT_TRUE(decide(wss, tls).recreate); // both encrypted, still a scheme change + EXPECT_TRUE(decide(tcp, ws).recreate); // both plaintext, still a scheme change +} + +TEST(MqttEffectiveConfig, TrustChangeForcesRecreate) { + const MqttEffectiveConfig bundle = build("mqtts://broker:8883", MqttAuth::None, nullptr, nullptr, + MqttTrust::Bundle, nullptr); + const MqttEffectiveConfig pem_a = build("mqtts://broker:8883", MqttAuth::None, nullptr, nullptr, + MqttTrust::PemCert, kPemA); + const MqttEffectiveConfig pem_b = build("mqtts://broker:8883", MqttAuth::None, nullptr, nullptr, + MqttTrust::PemCert, kPemB); + + EXPECT_TRUE(decide(bundle, pem_a).recreate); + EXPECT_STREQ("trust-change", decide(bundle, pem_a).reason); + EXPECT_TRUE(decide(pem_a, bundle).recreate); + EXPECT_TRUE(decide(pem_a, pem_b).recreate); + EXPECT_STREQ("ca-cert-change", decide(pem_a, pem_b).reason); + EXPECT_FALSE(decide(pem_a, pem_a).recreate); +} + +// IDF 4.4 allocates the MQTT buffers at client init and does not resize them, +// and the wrapper's reassembly buffer is allocated once for the client's life. +TEST(MqttEffectiveConfig, BufferGrowthForcesRecreateButShrinkDoesNot) { + const MqttEffectiveConfig small = build("mqtt://broker:1883", MqttAuth::None, nullptr, nullptr, + MqttTrust::Plaintext, nullptr, 512); + const MqttEffectiveConfig large = build("mqtt://broker:1883", MqttAuth::Jwt, kJwtUser, kToken, + MqttTrust::Plaintext, nullptr, 896); + + EXPECT_TRUE(decide(small, large, /*allocated=*/512).recreate); + EXPECT_STREQ("buffer-growth", decide(small, large, 512).reason); + EXPECT_FALSE(decide(small, large, /*allocated=*/896).recreate) + << "a client that already owns the capacity does not need recreating"; + EXPECT_FALSE(decide(large, small, /*allocated=*/896).recreate); +} + +TEST(MqttEffectiveConfig, FirstApplyAndInvalidDesiredNeverRecreate) { + const MqttEffectiveConfig unset; + const MqttEffectiveConfig wss = build("wss://broker:443/mqtt", MqttAuth::Jwt, kJwtUser, kToken, + MqttTrust::Bundle, nullptr); + EXPECT_FALSE(unset.valid); + EXPECT_FALSE(decide(unset, wss).recreate); + EXPECT_STREQ("first-apply", decide(unset, wss).reason); + + EXPECT_FALSE(decide(wss, unset).recreate); + EXPECT_STREQ("invalid-desired", decide(wss, unset).reason); +} + +// Rule 1: absent is a value that gets written, never an omission. +TEST(MqttEffectiveConfig, AbsentFieldsAreWrittenAsEmptyStrings) { + EXPECT_STREQ("", mqttFieldOrEmpty(nullptr)); + EXPECT_STREQ("alice", mqttFieldOrEmpty("alice")); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/test_mqtt_error_labels/test_mqtt_error_labels.cpp b/test/test_mqtt_error_labels/test_mqtt_error_labels.cpp new file mode 100644 index 00000000..604789bc --- /dev/null +++ b/test/test_mqtt_error_labels/test_mqtt_error_labels.cpp @@ -0,0 +1,78 @@ +#include "helpers/bridges/MQTTErrorLabels.h" + +#include + +#include + +using namespace MQTTErrorLabels; + +namespace { + +bool labelIs(const char* actual, const char* expected) { + return actual != nullptr && strcmp(actual, expected) == 0; +} + +} // namespace + +// F14: these four were the mislabels found in review. 201 is "no AP found" +// (usually a wrong/hidden SSID), not a security mismatch; 202 is an auth +// failure (usually a wrong password), not a rejected auth mode. +TEST(MQTTErrorLabels, WifiReasonsMatchTheSdkMeaning) { + EXPECT_TRUE(labelIs(wifiReason(201), "SSID not found")); + EXPECT_TRUE(labelIs(wifiReason(202), "auth failed (check password)")); + EXPECT_TRUE(labelIs(wifiReason(39), "802.11 timeout")); // was "SSID not found" + EXPECT_TRUE(labelIs(wifiReason(34), "AP saw no acks")); // was "AP state mismatch" +} + +TEST(MQTTErrorLabels, TlsErrorsMatchTheSdkMeaning) { + EXPECT_TRUE(labelIs(tlsError(0x8008), "server closed connection")); // was "connection timeout" + EXPECT_TRUE(labelIs(tlsError(0x8010), "cert chain partly parsed")); // was "mbedTLS error" + EXPECT_TRUE(labelIs(tlsError(0x8006), "connection timeout")); + EXPECT_TRUE(labelIs(tlsError(0x8001), "DNS failed")); + EXPECT_TRUE(labelIs(tlsError(0x801A), "TLS handshake failed")); +} + +// An unknown code must fall through to the caller's raw-number formatting +// rather than borrow a neighbouring code's label. 0x800B is the one the review +// caught: no such esp-tls error exists, but it was labelled "cert verify failed". +TEST(MQTTErrorLabels, UnknownCodesHaveNoLabel) { + EXPECT_EQ(nullptr, tlsError(0x800B)); + EXPECT_EQ(nullptr, tlsError(0)); + EXPECT_EQ(nullptr, tlsError(-1)); + EXPECT_EQ(nullptr, tlsError(0x8099)); + + EXPECT_EQ(nullptr, wifiReason(0)); + EXPECT_EQ(nullptr, wifiReason(61)); // not defined by the installed SDK + EXPECT_EQ(nullptr, wifiReason(88)); + EXPECT_EQ(nullptr, wifiReason(168)); + EXPECT_EQ(nullptr, wifiReason(255)); +} + +TEST(MQTTErrorLabels, ConnackReasonsCoverTheRefusalCodes) { + EXPECT_TRUE(labelIs(connackReason(1), "protocol rejected")); + EXPECT_TRUE(labelIs(connackReason(2), "client id rejected")); + EXPECT_TRUE(labelIs(connackReason(3), "server unavailable")); + EXPECT_TRUE(labelIs(connackReason(4), "bad user/password")); + EXPECT_TRUE(labelIs(connackReason(5), "not authorized")); + EXPECT_EQ(nullptr, connackReason(0)); // accepted: not an error to report + EXPECT_EQ(nullptr, connackReason(6)); +} + +// Labels share a bounded LoRa reply with the rest of the diagnostic line. +TEST(MQTTErrorLabels, LabelsStayShortEnoughForABoundedReply) { + for (int i = 0; i <= 255; i++) { + const char* w = wifiReason((uint8_t)i); + if (w) EXPECT_LE(strlen(w), 30u) << "wifi reason " << i; + const char* c = connackReason((uint8_t)i); + if (c) EXPECT_LE(strlen(c), 30u) << "connack code " << i; + } + for (int32_t e = 0x8000; e <= 0x8040; e++) { + const char* t = tlsError(e); + if (t) EXPECT_LE(strlen(t), 30u) << "tls error " << e; + } +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/test_network_hostname/test_network_hostname.cpp b/test/test_network_hostname/test_network_hostname.cpp new file mode 100644 index 00000000..37814861 --- /dev/null +++ b/test/test_network_hostname/test_network_hostname.cpp @@ -0,0 +1,139 @@ +#include + +#include + +#include "helpers/NetworkHostname.h" + +namespace { + +const uint8_t kStableId[] = {0xab, 0xcd, 0x01}; + +void expectDhcpSafe(const char* hostname) { + ASSERT_NE(nullptr, hostname); + const size_t length = strlen(hostname); + EXPECT_GT(length, 0u); + EXPECT_LE(length, NetworkHostname::kMaxLength); + EXPECT_NE('-', hostname[0]); + EXPECT_NE('-', hostname[length - 1]); + for (size_t i = 0; i < length; ++i) { + const char ch = hostname[i]; + EXPECT_TRUE((ch >= 'a' && ch <= 'z') || + (ch >= '0' && ch <= '9') || ch == '-') + << "invalid byte at " << i; + } +} + +} // namespace + +TEST(NetworkHostname, PrefixesAndLowercasesReadableNodeName) { + char hostname[NetworkHostname::kBufferSize]; + ASSERT_TRUE(NetworkHostname::build(hostname, sizeof(hostname), + "Hill Repeater 2", kStableId, + sizeof(kStableId))); + EXPECT_STREQ("meshcore-hill-repeater-2", hostname); + expectDhcpSafe(hostname); +} + +TEST(NetworkHostname, CollapsesInvalidRunsAndTrimsEdges) { + char hostname[NetworkHostname::kBufferSize]; + ASSERT_TRUE(NetworkHostname::build(hostname, sizeof(hostname), + " Adam's___Hill / Repeater! ", + kStableId, sizeof(kStableId))); + EXPECT_STREQ("meshcore-adam-s-hill-repeater", hostname); + expectDhcpSafe(hostname); +} + +TEST(NetworkHostname, UsesDocumentedFallbackForEmptySanitizedName) { + char hostname[NetworkHostname::kBufferSize]; + ASSERT_TRUE(NetworkHostname::build(hostname, sizeof(hostname), "___ !!!", + kStableId, sizeof(kStableId))); + EXPECT_STREQ("meshcore-node-abcd01", hostname); + expectDhcpSafe(hostname); +} + +TEST(NetworkHostname, RemovesUtf8AndRetainsStableIdentity) { + char hostname[NetworkHostname::kBufferSize]; + ASSERT_TRUE(NetworkHostname::build(hostname, sizeof(hostname), + "M\xC3\xBCnchen", kStableId, + sizeof(kStableId))); + EXPECT_STREQ("meshcore-m-nchen-abcd01", hostname); + expectDhcpSafe(hostname); +} + +TEST(NetworkHostname, MarksCombiningUnicodeAsLossy) { + char hostname[NetworkHostname::kBufferSize]; + ASSERT_TRUE(NetworkHostname::build(hostname, sizeof(hostname), + "Cafe\xCC\x81", kStableId, + sizeof(kStableId))); + EXPECT_STREQ("meshcore-cafe-abcd01", hostname); + expectDhcpSafe(hostname); +} + +TEST(NetworkHostname, UnicodeOnlyNamesUseDistinctIdentityFallbacks) { + const uint8_t other_id[] = {0x12, 0x34, 0x56}; + const char unicode_only[] = "\xE7\xBD\x91\xE6\xA0\xBC\xF0\x9F\x8C\x90"; + char first[NetworkHostname::kBufferSize]; + char second[NetworkHostname::kBufferSize]; + ASSERT_TRUE(NetworkHostname::build(first, sizeof(first), unicode_only, + kStableId, sizeof(kStableId))); + ASSERT_TRUE(NetworkHostname::build(second, sizeof(second), unicode_only, + other_id, sizeof(other_id))); + EXPECT_STREQ("meshcore-node-abcd01", first); + EXPECT_STREQ("meshcore-node-123456", second); + EXPECT_STRNE(first, second); + expectDhcpSafe(first); + expectDhcpSafe(second); +} + +TEST(NetworkHostname, MalformedUtf8CannotReachDhcpHostname) { + char hostname[NetworkHostname::kBufferSize]; + const char malformed[] = {'b', 'a', 'd', static_cast(0xff), + 'n', 'a', 'm', 'e', '\0'}; + ASSERT_TRUE(NetworkHostname::build(hostname, sizeof(hostname), malformed, + kStableId, sizeof(kStableId))); + EXPECT_STREQ("meshcore-bad-name-abcd01", hostname); + expectDhcpSafe(hostname); +} + +TEST(NetworkHostname, KeepsExactBoundaryWithoutIdentitySuffix) { + char hostname[NetworkHostname::kBufferSize]; + ASSERT_TRUE(NetworkHostname::build(hostname, sizeof(hostname), + "abcdefghijklmnopqrstuv", kStableId, + sizeof(kStableId))); + EXPECT_STREQ("meshcore-abcdefghijklmnopqrstuv", hostname); + EXPECT_EQ(NetworkHostname::kMaxLength, strlen(hostname)); +} + +TEST(NetworkHostname, TruncatesReadablePartAndAddsStableIdentitySuffix) { + char hostname[NetworkHostname::kBufferSize]; + ASSERT_TRUE(NetworkHostname::build(hostname, sizeof(hostname), + "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345", + kStableId, sizeof(kStableId))); + EXPECT_STREQ("meshcore-abcdefghijklmno-abcd01", hostname); + EXPECT_EQ(NetworkHostname::kMaxLength, strlen(hostname)); + expectDhcpSafe(hostname); +} + +TEST(NetworkHostname, IdentitySuffixSeparatesOtherwiseCollidingNames) { + const uint8_t other_id[] = {0x12, 0x34, 0x56}; + char first[NetworkHostname::kBufferSize]; + char second[NetworkHostname::kBufferSize]; + ASSERT_TRUE(NetworkHostname::build(first, sizeof(first), + "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345", + kStableId, sizeof(kStableId))); + ASSERT_TRUE(NetworkHostname::build(second, sizeof(second), + "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345", + other_id, sizeof(other_id))); + EXPECT_STRNE(first, second); + EXPECT_STREQ("meshcore-abcdefghijklmno-123456", second); +} + +TEST(NetworkHostname, RejectsMissingOutputBuffer) { + EXPECT_FALSE(NetworkHostname::build(nullptr, 0, "node", kStableId, + sizeof(kStableId))); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/test_network_policy/test_network_policy.cpp b/test/test_network_policy/test_network_policy.cpp new file mode 100644 index 00000000..3558e1e3 --- /dev/null +++ b/test/test_network_policy/test_network_policy.cpp @@ -0,0 +1,202 @@ +#include + +#include "helpers/NetworkPolicy.h" + +TEST(NetworkPolicy, MqttDownDisconnectsSlotsWithoutRequestingImmediateRetry) { + const auto actions = NetworkPolicy::mqttActions(NetworkTransition::Down); + EXPECT_TRUE(actions.disconnect_started_slots); + EXPECT_FALSE(actions.retry_disconnected_slots_now); + EXPECT_FALSE(actions.reset_reconnect_backoff); +} + +TEST(NetworkPolicy, MqttUpRetriesWithoutClearingBrokerCircuitBreaker) { + const auto actions = NetworkPolicy::mqttActions(NetworkTransition::Up); + EXPECT_FALSE(actions.disconnect_started_slots); + EXPECT_TRUE(actions.retry_disconnected_slots_now); + EXPECT_FALSE(actions.reset_reconnect_backoff); +} + +TEST(NetworkPolicy, NoTransitionHasNoMqttSideEffects) { + const auto actions = NetworkPolicy::mqttActions(NetworkTransition::None); + EXPECT_FALSE(actions.disconnect_started_slots); + EXPECT_FALSE(actions.retry_disconnected_slots_now); + EXPECT_FALSE(actions.reset_reconnect_backoff); +} + +TEST(NetworkPolicy, LinkSwitchReconnectsMqttSlotsImmediately) { + const auto actions = NetworkPolicy::mqttActions(NetworkTransition::Switched); + EXPECT_TRUE(actions.disconnect_started_slots); + EXPECT_TRUE(actions.retry_disconnected_slots_now); + EXPECT_TRUE(actions.reset_reconnect_backoff); +} + +TEST(NetworkPolicy, MediumNamesAreStableForTransitionLogs) { + EXPECT_STREQ("none", NetworkPolicy::mediumName(NetworkMedium::None)); + EXPECT_STREQ("ethernet", NetworkPolicy::mediumName(NetworkMedium::Ethernet)); + EXPECT_STREQ("wifi", NetworkPolicy::mediumName(NetworkMedium::WiFi)); +} + +TEST(NetworkPolicy, BootPrefersEthernetAndOtherwiseUsesConfiguredWifi) { + EXPECT_EQ(NetworkMedium::Ethernet, NetworkPolicy::bootSelection(true, true)); + EXPECT_EQ(NetworkMedium::WiFi, NetworkPolicy::bootSelection(false, true)); + EXPECT_EQ(NetworkMedium::None, NetworkPolicy::bootSelection(false, false)); +} + +TEST(NetworkPolicy, EthernetBootProbeUsesFullDeadlineForLinkOrUnknownState) { + EXPECT_TRUE(NetworkPolicy::ethernetBootProbePending( + true, false, false, false, 1500, 8000)); + EXPECT_TRUE(NetworkPolicy::ethernetBootProbePending( + true, false, true, true, 7999, 8000)); + EXPECT_FALSE(NetworkPolicy::ethernetBootProbePending( + true, false, true, true, 8000, 8000)); + EXPECT_FALSE(NetworkPolicy::ethernetBootProbePending( + true, true, true, true, 100, 8000)); + EXPECT_FALSE(NetworkPolicy::ethernetBootProbePending( + false, false, false, false, 100, 8000)); +} + +TEST(NetworkPolicy, EthernetBootProbeStopsEarlyOnKnownCableDown) { + EXPECT_TRUE(NetworkPolicy::ethernetBootProbePending( + true, false, true, false, + NetworkPolicy::kEthernetNoLinkBootGraceMs - 1, 8000)); + EXPECT_FALSE(NetworkPolicy::ethernetBootProbePending( + true, false, true, false, + NetworkPolicy::kEthernetNoLinkBootGraceMs, 8000)); +} + +TEST(NetworkPolicy, EthernetInitRetryUsesBoundedExponentialBackoff) { + EXPECT_EQ(0u, NetworkPolicy::ethernetInitRetryDelayMs(0)); + EXPECT_EQ(5000u, NetworkPolicy::ethernetInitRetryDelayMs(1)); + EXPECT_EQ(10000u, NetworkPolicy::ethernetInitRetryDelayMs(2)); + EXPECT_EQ(300000u, NetworkPolicy::ethernetInitRetryDelayMs(8)); + EXPECT_EQ(300000u, NetworkPolicy::ethernetInitRetryDelayMs(255)); + + EXPECT_FALSE(NetworkPolicy::ethernetInitRetryDue(1, 4999, 0)); + EXPECT_TRUE(NetworkPolicy::ethernetInitRetryDue(1, 5000, 0)); + EXPECT_TRUE(NetworkPolicy::ethernetInitRetryDue(1, 10, 10u - 5000u)); +} + +TEST(NetworkPolicy, EthernetNoIpRecoveryRequiresSustainedCarrier) { + const uint32_t timeout = NetworkPolicy::kEthernetNoIpRecoveryMs; + EXPECT_FALSE(NetworkPolicy::ethernetNoIpRecoveryDue( + true, true, false, timeout, 0)); + EXPECT_FALSE(NetworkPolicy::ethernetNoIpRecoveryDue( + true, true, false, timeout, 1)); + EXPECT_TRUE(NetworkPolicy::ethernetNoIpRecoveryDue( + true, true, false, timeout + 1, 1)); + EXPECT_FALSE(NetworkPolicy::ethernetNoIpRecoveryDue( + true, false, false, timeout + 1, 1)); + EXPECT_FALSE(NetworkPolicy::ethernetNoIpRecoveryDue( + true, true, true, timeout + 1, 1)); + EXPECT_TRUE(NetworkPolicy::ethernetNoIpRecoveryDue( + true, true, false, 100, 100u - timeout)); +} + +TEST(NetworkPolicy, EthernetFailureWaitsForGraceAndConnectedWifi) { + NetworkPolicy::AutomaticSelectionInput input = { + NetworkMedium::Ethernet, false, true, true, false, 0, + NetworkPolicy::kEthernetDownGraceMs - 1}; + EXPECT_EQ(NetworkMedium::Ethernet, NetworkPolicy::automaticSelection(input)); + input.selected_down_ms = NetworkPolicy::kEthernetDownGraceMs; + EXPECT_EQ(NetworkMedium::WiFi, NetworkPolicy::automaticSelection(input)); +} + +TEST(NetworkPolicy, FailbackRequiresStableEthernet) { + NetworkPolicy::AutomaticSelectionInput input = { + NetworkMedium::WiFi, true, true, true, false, + NetworkPolicy::kEthernetFailbackStableMs - 1, 0}; + EXPECT_EQ(NetworkMedium::WiFi, NetworkPolicy::automaticSelection(input)); + input.ethernet_stable_ms = NetworkPolicy::kEthernetFailbackStableMs; + EXPECT_EQ(NetworkMedium::Ethernet, NetworkPolicy::automaticSelection(input)); +} + +TEST(NetworkPolicy, DeadWifiFailsBackToReadyEthernetImmediately) { + const NetworkPolicy::AutomaticSelectionInput input = { + NetworkMedium::WiFi, true, false, true, false, 0, 0}; + EXPECT_EQ(NetworkMedium::Ethernet, NetworkPolicy::automaticSelection(input)); +} + +TEST(NetworkPolicy, SwitchingLockPinsTheCurrentMedium) { + const NetworkPolicy::AutomaticSelectionInput input = { + NetworkMedium::WiFi, true, true, true, true, + NetworkPolicy::kEthernetFailbackStableMs, 0}; + EXPECT_EQ(NetworkMedium::WiFi, NetworkPolicy::automaticSelection(input)); +} + +TEST(NetworkPolicy, DiagnosticsIdentifyEthernetFallbackCause) { + using Reason = NetworkDiagnosticReason; + EXPECT_EQ(Reason::EthernetInitFailed, + NetworkPolicy::automaticDiagnosticReason( + false, false, false, false, NetworkMedium::WiFi, false, 0)); + EXPECT_EQ(Reason::EthernetLinkUnknown, + NetworkPolicy::automaticDiagnosticReason( + true, false, false, false, NetworkMedium::WiFi, false, 0)); + EXPECT_EQ(Reason::EthernetLinkDown, + NetworkPolicy::automaticDiagnosticReason( + true, true, false, false, NetworkMedium::WiFi, false, 0)); + EXPECT_EQ(Reason::EthernetAwaitingIp, + NetworkPolicy::automaticDiagnosticReason( + true, true, true, false, NetworkMedium::WiFi, false, 0)); +} + +TEST(NetworkPolicy, DiagnosticsExplainWhyReadyEthernetHasNotBeenSelected) { + using Reason = NetworkDiagnosticReason; + EXPECT_EQ(Reason::SwitchingLocked, + NetworkPolicy::automaticDiagnosticReason( + true, true, true, true, NetworkMedium::WiFi, true, + NetworkPolicy::kEthernetFailbackStableMs)); + EXPECT_EQ(Reason::EthernetStabilizing, + NetworkPolicy::automaticDiagnosticReason( + true, true, true, true, NetworkMedium::WiFi, false, + NetworkPolicy::kEthernetFailbackStableMs - 1)); + EXPECT_EQ(Reason::EthernetReady, + NetworkPolicy::automaticDiagnosticReason( + true, true, true, true, NetworkMedium::WiFi, false, + NetworkPolicy::kEthernetFailbackStableMs)); + EXPECT_EQ(Reason::EthernetActive, + NetworkPolicy::automaticDiagnosticReason( + true, true, true, true, NetworkMedium::Ethernet, false, 0)); +} + +TEST(NetworkPolicy, NtpIsScheduledOncePerConnectivityEdge) { + EXPECT_TRUE(NetworkPolicy::ntpPendingAfterConnectivitySample( + false, false, false, true)); + EXPECT_FALSE(NetworkPolicy::ntpPendingAfterConnectivitySample( + false, false, true, true)); + EXPECT_TRUE(NetworkPolicy::ntpPendingAfterConnectivitySample( + false, true, true, true)); + EXPECT_FALSE(NetworkPolicy::ntpPendingAfterConnectivitySample( + true, false, false, true)); +} + +TEST(NetworkPolicy, FailedNtpSyncWaitsForThirtySecondRetryBoundary) { + EXPECT_FALSE(NetworkPolicy::ntpRetryDue(false, true, 29999, 0)); + EXPECT_TRUE(NetworkPolicy::ntpRetryDue(false, true, 30000, 0)); + EXPECT_FALSE(NetworkPolicy::ntpRetryDue(true, true, 60000, 0)); + EXPECT_FALSE(NetworkPolicy::ntpRetryDue(false, false, 60000, 0)); + EXPECT_TRUE(NetworkPolicy::ntpRetryDue(false, true, 10, 0xffff8000u)); +} + +TEST(NetworkPolicy, StartOtaUsesReachableSelectedNetworkByDefault) { + EXPECT_TRUE(NetworkPolicy::startOtaUsesSelectedNetwork(false, true)); + EXPECT_FALSE(NetworkPolicy::startOtaUsesSelectedNetwork(false, false)); +} + +TEST(NetworkPolicy, StartOtaForceApOverridesAReachableSelectedNetwork) { + EXPECT_FALSE(NetworkPolicy::startOtaUsesSelectedNetwork(true, true)); + EXPECT_FALSE(NetworkPolicy::startOtaUsesSelectedNetwork(true, false)); +} + +TEST(NetworkPolicy, ManualOtaTimeoutIsUploadSafeAndWrapSafe) { + const uint32_t timeout = NetworkPolicy::kManualOtaSessionTimeoutMs; + EXPECT_FALSE(NetworkPolicy::manualOtaTimeoutDue(timeout - 1, 0, false)); + EXPECT_TRUE(NetworkPolicy::manualOtaTimeoutDue(timeout, 0, false)); + EXPECT_FALSE(NetworkPolicy::manualOtaTimeoutDue(timeout, 0, true)); + EXPECT_TRUE(NetworkPolicy::manualOtaTimeoutDue( + 100, 100 - timeout, false)); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/test_ntp_validation/test_ntp_validation.cpp b/test/test_ntp_validation/test_ntp_validation.cpp new file mode 100644 index 00000000..d2222dd8 --- /dev/null +++ b/test/test_ntp_validation/test_ntp_validation.cpp @@ -0,0 +1,184 @@ +#include "helpers/NtpValidation.h" + +#include + +#include + +using namespace NtpValidation; + +namespace { + +const uint32_t MIN_EPOCH = 1767225600UL; // 2026-01-01, the bridge's floor +const uint32_t MAX_EPOCH = 4102444800UL; // 2100-01-01 +const Nonce NONCE = { 0xA1B2C3D4UL, 0x0F1E2D3CUL }; + +// A well-formed reply to buildRequest(): stratum 2, mode 4, our nonce echoed. +void makeReply(uint8_t out[48], uint32_t unix_epoch = 1789000000UL) { + memset(out, 0, 48); + out[0] = (0 << 6) | (4 << 3) | 4; // LI=0, VN=4, mode=4 (server) + out[1] = 2; // stratum + writeU32(out + 24, NONCE.seconds); // originate = our transmit timestamp + writeU32(out + 28, NONCE.fraction); + writeU32(out + 32, unix_epoch + kUnixEpochOffset); // receive + writeU32(out + 40, unix_epoch + kUnixEpochOffset); // transmit +} + +Result check(const uint8_t* data, size_t len, bool source_matches = true) { + return validate(data, len, source_matches, NONCE, MIN_EPOCH, MAX_EPOCH); +} + +} // namespace + +TEST(NtpValidation, RequestIsAClientPacketCarryingTheNonce) { + uint8_t req[48]; + memset(req, 0xFF, sizeof(req)); + buildRequest(req, NONCE); + + EXPECT_EQ(0u, (req[0] >> 6) & 0x03); // LI = 0, not the library's bogus alarm + EXPECT_EQ(4u, (req[0] >> 3) & 0x07); // version 4 + EXPECT_EQ(3u, req[0] & 0x07); // mode 3 = client + EXPECT_EQ(NONCE.seconds, readU32(req + 40)); + EXPECT_EQ(NONCE.fraction, readU32(req + 44)); +} + +TEST(NtpValidation, ValidReplyIsAccepted) { + uint8_t pkt[48]; + makeReply(pkt, 1789000000UL); + + Result r = check(pkt, sizeof(pkt)); + + EXPECT_EQ(kAccepted, r.reject); + EXPECT_EQ(1789000000UL, r.epoch); +} + +// F07's reproduction: the installed NTPClient accepted a one-byte non-NTP +// datagram and derived epoch 2085978496 from the uninitialised buffer. +TEST(NtpValidation, OneByteNonNtpDatagramIsRejected) { + const uint8_t junk[1] = { 0x00 }; + + Result r = check(junk, sizeof(junk)); + + EXPECT_EQ(kShortPacket, r.reject); + EXPECT_EQ(0u, r.epoch); +} + +TEST(NtpValidation, ShortAndEmptyDatagramsAreRejected) { + uint8_t pkt[48]; + makeReply(pkt); + + for (size_t len = 0; len < 48; len++) { + EXPECT_EQ(kShortPacket, check(pkt, len).reject) << "len " << len; + } + EXPECT_EQ(kShortPacket, check(nullptr, 48).reject); +} + +TEST(NtpValidation, ReplyFromAnotherSourceIsRejected) { + uint8_t pkt[48]; + makeReply(pkt); + + EXPECT_EQ(kWrongSource, check(pkt, sizeof(pkt), /*source_matches=*/false).reject); +} + +// An off-path sender that never saw the query cannot echo the nonce. +TEST(NtpValidation, UnsolicitedReplyIsRejected) { + uint8_t pkt[48]; + makeReply(pkt); + writeU32(pkt + 24, 0); + writeU32(pkt + 28, 0); + + EXPECT_EQ(kOriginMismatch, check(pkt, sizeof(pkt)).reject); + + makeReply(pkt); + writeU32(pkt + 28, NONCE.fraction ^ 1u); // one bit off is still not ours + EXPECT_EQ(kOriginMismatch, check(pkt, sizeof(pkt)).reject); +} + +TEST(NtpValidation, ClientModeAndWrongVersionAreRejected) { + uint8_t pkt[48]; + + makeReply(pkt); + pkt[0] = (0 << 6) | (4 << 3) | 3; // our own request echoed back + EXPECT_EQ(kBadMode, check(pkt, sizeof(pkt)).reject); + + makeReply(pkt); + pkt[0] = (0 << 6) | (5 << 3) | 4; // version 5 does not exist + EXPECT_EQ(kBadVersion, check(pkt, sizeof(pkt)).reject); + + makeReply(pkt); + pkt[0] = (0 << 6) | (3 << 3) | 4; // NTPv3 servers are fine + EXPECT_EQ(kAccepted, check(pkt, sizeof(pkt)).reject); +} + +TEST(NtpValidation, UnsynchronisedServersAreRejected) { + uint8_t pkt[48]; + + makeReply(pkt); + pkt[0] |= (3 << 6); // LI = 3: alarm, clock not set + EXPECT_EQ(kLeapAlarm, check(pkt, sizeof(pkt)).reject); + + makeReply(pkt); + pkt[1] = 0; // stratum 0: kiss-of-death + EXPECT_EQ(kBadStratum, check(pkt, sizeof(pkt)).reject); + + makeReply(pkt); + pkt[1] = 16; // unsynchronised + EXPECT_EQ(kBadStratum, check(pkt, sizeof(pkt)).reject); + + makeReply(pkt); + pkt[1] = 15; // last usable stratum + EXPECT_EQ(kAccepted, check(pkt, sizeof(pkt)).reject); +} + +TEST(NtpValidation, MissingTransmitTimestampIsRejected) { + uint8_t pkt[48]; + makeReply(pkt); + writeU32(pkt + 40, 0); + + EXPECT_EQ(kZeroTransmit, check(pkt, sizeof(pkt)).reject); +} + +// The bridge's floor is the only defence against a stale or rolled-back clock, +// and nothing previously stopped an absurd forward jump. +TEST(NtpValidation, ImplausibleTimesAreRejected) { + uint8_t pkt[48]; + + makeReply(pkt, MIN_EPOCH - 1); + EXPECT_EQ(kEpochTooEarly, check(pkt, sizeof(pkt)).reject); + + makeReply(pkt, MIN_EPOCH); + EXPECT_EQ(kAccepted, check(pkt, sizeof(pkt)).reject); + + makeReply(pkt, MAX_EPOCH + 1); + EXPECT_EQ(kEpochTooLate, check(pkt, sizeof(pkt)).reject); + + makeReply(pkt, MAX_EPOCH); + EXPECT_EQ(kAccepted, check(pkt, sizeof(pkt)).reject); +} + +// Era 1 begins 2036-02-07; a naive subtraction turns those seconds into 1900. +TEST(NtpValidation, Era1TimestampsConvertForward) { + EXPECT_EQ(0u, unixFromNtpSeconds(kUnixEpochOffset)); + EXPECT_EQ(2085978496UL, unixFromNtpSeconds(0)); // 2036-02-07 + EXPECT_GT(unixFromNtpSeconds(1000), unixFromNtpSeconds(0xFFFFFFFFu)); + + uint8_t pkt[48]; + makeReply(pkt); + writeU32(pkt + 40, 1000); // 1000 s into era 1 + Result r = check(pkt, sizeof(pkt)); + EXPECT_EQ(kAccepted, r.reject); + EXPECT_EQ(2085979496UL, r.epoch); +} + +TEST(NtpValidation, EveryRejectionHasAShortReason) { + for (int i = 0; i <= (int)kEpochTooLate; i++) { + const char* reason = rejectReason((Reject)i); + ASSERT_NE(nullptr, reason); + EXPECT_GT(strlen(reason), 0u); + EXPECT_LE(strlen(reason), 20u) << "reject " << i; + } +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/test_radio_watchdog/test_radio_watchdog.cpp b/test/test_radio_watchdog/test_radio_watchdog.cpp new file mode 100644 index 00000000..fea7e720 --- /dev/null +++ b/test/test_radio_watchdog/test_radio_watchdog.cpp @@ -0,0 +1,204 @@ +#include "helpers/RadioWatchdog.h" + +#include + +namespace { + +const uint32_t WATCHDOG_MS = 300000UL; // RADIO_WATCHDOG_MS default: 5 minutes + +// Mirrors Dispatcher::loop(): the radio's three timestamps are sampled every +// pass, and a recovery is acknowledged as soon as it is decided. +struct Radio { + uint32_t last_recv = 0; + uint32_t last_irq = 0; + uint32_t last_tx = 0; +}; + +RadioWatchdogDecision run(RadioWatchdog& w, const Radio& r, uint32_t now, + bool in_recv_mode = true, uint32_t watchdog_ms = WATCHDOG_MS) { + RadioWatchdogDecision d = w.update(now, in_recv_mode, watchdog_ms, + r.last_recv, r.last_irq, r.last_tx); + if (d.recover) w.noteRecovery(); + return d; +} + +} // namespace + +TEST(RadioWatchdog, NoActivitySinceBootNeverTrips) { + RadioWatchdog w; + w.reset(0); + Radio r; // radio has never received, interrupted or transmitted + + for (uint32_t t = 0; t <= 4 * WATCHDOG_MS; t += 10000) { + RadioWatchdogDecision d = run(w, r, t); + EXPECT_FALSE(d.recover) << "tripped at t=" << t; + EXPECT_FALSE(d.measurable); + } +} + +TEST(RadioWatchdog, ContinuousReceiveNeverTrips) { + RadioWatchdog w; + w.reset(0); + Radio r; + + for (uint32_t t = 1000; t <= 3 * WATCHDOG_MS; t += 1000) { + r.last_recv = t; + r.last_irq = t; + RadioWatchdogDecision d = run(w, r, t); + EXPECT_FALSE(d.recover) << "tripped at t=" << t; + EXPECT_LE(d.silent_ms, 1000u); + } +} + +TEST(RadioWatchdog, SilentRadioTripsOncePerInterval) { + RadioWatchdog w; + w.reset(0); + Radio r; + r.last_recv = 1000; + run(w, r, 1000); + + int trips = 0; + uint32_t first_trip = 0; + for (uint32_t t = 2000; t <= 1000000; t += 1000) { + if (run(w, r, t).recover) { + if (trips == 0) first_trip = t; + trips++; + } + } + + EXPECT_EQ(302000u, first_trip); // strictly past the interval, from the last receive + EXPECT_EQ(3, trips); // ~1 M ms / 300 s, never per-loop +} + +// F13: a transmit timestamp from just before the millis() wrap is numerically +// larger than every fresh post-wrap receive. Selecting the largest timestamp +// reported ~24 days of silence and reset a radio that was receiving normally. +TEST(RadioWatchdog, PreWrapTransmitDoesNotSilenceFreshPostWrapReceives) { + const uint32_t WRAP = 0xFFFFFFFFu; + const uint32_t TX_AT = 0x80000000u; // upper half: beats any post-wrap value + + RadioWatchdog w; + w.reset(TX_AT - 60000); + Radio r; + r.last_recv = TX_AT - 60000; + r.last_irq = TX_AT - 60000; + run(w, r, TX_AT - 60000); + + r.last_tx = TX_AT; + run(w, r, TX_AT); + + // Receive steadily right up to the wrap... + for (uint32_t t = TX_AT + 1000; t < WRAP - 1000; t += 1000) { + r.last_recv = t; + r.last_irq = t; + ASSERT_FALSE(run(w, r, t).recover) << "tripped before wrap at t=" << t; + } + + // ...and straight through it. The stale transmit is still the numerically + // largest of the three timestamps for the next ~24 days. + for (uint32_t t = 1000; t < 2 * WATCHDOG_MS; t += 1000) { + r.last_recv = t; + r.last_irq = t; + RadioWatchdogDecision d = run(w, r, t); + ASSERT_FALSE(d.recover) << "tripped after wrap at t=" << t; + ASSERT_LE(d.silent_ms, 1000u); + } +} + +// The wrap must not hide a genuinely silent radio either. +TEST(RadioWatchdog, SilenceAcrossTheWrapIsStillDetected) { + const uint32_t LAST_RX = 0xFFFF0000u; // ~65 s before the wrap + + RadioWatchdog w; + w.reset(LAST_RX - 1000); + Radio r; + r.last_recv = LAST_RX; + r.last_irq = LAST_RX; + run(w, r, LAST_RX); + + bool tripped = false; + uint64_t silent_at_trip = 0; + for (uint32_t step = 1000; step <= WATCHDOG_MS + 5000; step += 1000) { + uint32_t t = LAST_RX + step; // wraps on its own + RadioWatchdogDecision d = run(w, r, t); + if (d.recover) { + tripped = true; + silent_at_trip = d.silent_ms; + break; + } + } + + EXPECT_TRUE(tripped); + EXPECT_GT(silent_at_trip, (uint64_t)WATCHDOG_MS); +} + +// Uptime past 2^32 ms must not alias a long silence back to "recent". +TEST(RadioWatchdog, SilenceBeyondOneMillisCycleKeepsGrowing) { + RadioWatchdog w; + w.reset(0); + Radio r; + r.last_recv = 1000; + run(w, r, 1000); + + // Walk a full cycle in 1-minute steps; the raw timestamp aliases back to its + // starting value, the tracked age does not. + uint64_t last_silent = 0; + for (uint64_t step = 60000; step <= 0x100000000ull + 600000ull; step += 60000) { + uint32_t t = (uint32_t)((1000ull + step) & 0xFFFFFFFFull); + RadioWatchdogDecision d = w.update(t, true, WATCHDOG_MS, r.last_recv, r.last_irq, r.last_tx); + if (d.recover) w.noteRecovery(); + ASSERT_GT(d.silent_ms, last_silent); + last_silent = d.silent_ms; + } + + EXPECT_GT(last_silent, 0x100000000ull); +} + +TEST(RadioWatchdog, DisabledWatchdogAndNonRecvModeNeverTrip) { + RadioWatchdog w; + w.reset(0); + Radio r; + r.last_recv = 1000; + run(w, r, 1000); + + for (uint32_t t = 2000; t <= 1000000; t += 10000) { + EXPECT_FALSE(run(w, r, t, /*in_recv_mode=*/true, /*watchdog_ms=*/0).recover); + EXPECT_FALSE(run(w, r, t, /*in_recv_mode=*/false).recover); + } +} + +// Transmit-only traffic still counts as a live radio. +TEST(RadioWatchdog, TransmitActivityRefreshesSilence) { + RadioWatchdog w; + w.reset(0); + Radio r; + r.last_recv = 1000; + run(w, r, 1000); + + for (uint32_t t = 100000; t <= 900000; t += 100000) { + r.last_tx = t; + EXPECT_FALSE(run(w, r, t).recover) << "tripped at t=" << t; + } +} + +// A blocked mesh loop (e.g. a 30 s NTP probe) collapses several events into one +// observation. That may only shorten measured silence, never lengthen it. +TEST(RadioWatchdog, LoopStallDoesNotManufactureSilence) { + RadioWatchdog w; + w.reset(0); + Radio r; + r.last_recv = 1000; + run(w, r, 1000); + + r.last_recv = 20000; // arrived during the stall + r.last_irq = 20000; + RadioWatchdogDecision d = run(w, r, 31000); + + EXPECT_FALSE(d.recover); + EXPECT_EQ(0u, d.silent_ms); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/test_webconfig_batch/test_webconfig_batch.cpp b/test/test_webconfig_batch/test_webconfig_batch.cpp index f23fc6a9..72d3c710 100644 --- a/test/test_webconfig_batch/test_webconfig_batch.cpp +++ b/test/test_webconfig_batch/test_webconfig_batch.cpp @@ -295,6 +295,7 @@ TEST(WebConfigBatch, CliFailureRepliesAreRecognisedInEveryShapeCommonCLIEmits) { "Err - bad params", // MyMesh setperm "ERR: bad pubkey", // neighbor.remove "Error: IATA code must be exactly 3 letters",// observer setters + "Error: setting not persisted; change rolled back", // observer storage failure "(ERR: clock cannot go backwards)", // clock sync, parenthesised "Unknown command", // top-level fallthrough "unknown config: mqtt.nope", // set fallthrough diff --git a/test/test_webconfig_keys/test_webconfig_keys.cpp b/test/test_webconfig_keys/test_webconfig_keys.cpp index 0984ed9b..73ca5888 100644 --- a/test/test_webconfig_keys/test_webconfig_keys.cpp +++ b/test/test_webconfig_keys/test_webconfig_keys.cpp @@ -15,6 +15,8 @@ TEST(WebConfigKeys, AllowsKnownScalarKeys) { EXPECT_TRUE(wcIsAllowedSetKey("radio.rxps")); EXPECT_TRUE(wcIsAllowedSetKey("powersaving")); EXPECT_TRUE(wcIsAllowedSetKey("repeat")); + EXPECT_TRUE(wcIsAllowedSetKey("radio.fem.rxgain")); // Board::handleCommand(), not CommonCLI + EXPECT_TRUE(wcIsAllowedSetKey("radio.fem.txgain")); EXPECT_TRUE(wcIsAllowedSetKey("wifi.ssid")); EXPECT_TRUE(wcIsAllowedSetKey("espnow.channel")); EXPECT_TRUE(wcIsAllowedSetKey("mqtt.iata")); diff --git a/test/test_wifi_power_save_policy/test_wifi_power_save_policy.cpp b/test/test_wifi_power_save_policy/test_wifi_power_save_policy.cpp new file mode 100644 index 00000000..35eb39f9 --- /dev/null +++ b/test/test_wifi_power_save_policy/test_wifi_power_save_policy.cpp @@ -0,0 +1,68 @@ +#include "helpers/WifiPowerSavePolicy.h" + +#include + +using namespace WifiPowerSavePolicy; + +// F11: the CLI applied stored 0 as MIN_MODEM while the reconnect path applied it +// as NONE, so a node configured for `min` changed behaviour after every +// reconnect and `get wifi.powersave` still reported min. One table, one answer. +TEST(WifiPowerSavePolicy, StoredValuesMapToOneModeEach) { + EXPECT_EQ(kModeMinModem, modeFor(kMin)); + EXPECT_EQ(kModeNone, modeFor(kNone)); + EXPECT_EQ(kModeMaxModem, modeFor(kMax)); +} + +// Stored 0 was the default for nodes set up 2026-01-02..03-28, and they have +// always run with power save off; reading it as `min` would put them to sleep. +TEST(WifiPowerSavePolicy, LegacyDefaultKeepsPowerSaveOff) { + EXPECT_EQ(kModeNone, modeFor(kLegacyDefault)); + EXPECT_STREQ("none", nameFor(kLegacyDefault)); + uint8_t parsed = 0xFF; + ASSERT_TRUE(parseName("min", &parsed)); + EXPECT_NE(kLegacyDefault, parsed); +} + +TEST(WifiPowerSavePolicy, NamesRoundTripWithStoredValues) { + for (uint8_t stored = kNone; stored <= kMaxStoredValue; stored++) { + uint8_t parsed = 0xFF; + ASSERT_TRUE(parseName(nameFor(stored), &parsed)) << "stored " << (int)stored; + EXPECT_EQ(stored, parsed); + EXPECT_EQ(modeFor(stored), modeFor(parsed)); + } +} + +// A byte outside the stored range must read as the product default, not as +// whatever mode happens to sit at that index. +TEST(WifiPowerSavePolicy, OutOfRangeStoredValueReadsAsDefault) { + for (int stored = kMaxStoredValue + 1; stored <= 255; stored++) { + EXPECT_EQ(kModeNone, modeFor((uint8_t)stored)) << "stored " << stored; + EXPECT_STREQ("none", nameFor((uint8_t)stored)); + } +} + +// The setters take the remainder of the command line, so a trailing argument +// must still parse — and a longer word starting with a valid name must not. +TEST(WifiPowerSavePolicy, ParsesCliArgumentsExactly) { + uint8_t stored = 0xFF; + + EXPECT_TRUE(parseName("min", &stored)); + EXPECT_EQ(kMin, stored); + EXPECT_TRUE(parseName("none extra", &stored)); + EXPECT_EQ(kNone, stored); + EXPECT_TRUE(parseName("max ", &stored)); + EXPECT_EQ(kMax, stored); + + stored = 0xFF; + EXPECT_FALSE(parseName("minimum", &stored)); + EXPECT_FALSE(parseName("", &stored)); + EXPECT_FALSE(parseName("off", &stored)); + EXPECT_FALSE(parseName("MIN", &stored)); + EXPECT_FALSE(parseName(nullptr, &stored)); + EXPECT_EQ(0xFF, stored); // rejected input leaves the caller's value alone +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/variants/heltec_v4_r8/platformio.ini b/variants/heltec_v4_r8/platformio.ini index bcf8bbdb..9557283d 100644 --- a/variants/heltec_v4_r8/platformio.ini +++ b/variants/heltec_v4_r8/platformio.ini @@ -17,9 +17,9 @@ build_flags = -D P_LORA_SCLK=9 -D P_LORA_MISO=11 -D P_LORA_MOSI=10 - -D P_LORA_PA_POWER=7 - -D P_LORA_KCT8103L_PA_CSD=2 - -D P_LORA_KCT8103L_PA_CTX=5 + -D P_LORA_PA_POWER=7 ; VFEM_Ctrl - LDO power enable + -D P_LORA_KCT8103L_PA_CSD=2 ; FEM_EN / CSD (HIGH=on) + -D P_LORA_KCT8103L_PA_CTX=5 ; PA_CTX (LOW=RX LNA, HIGH=RX bypass) -D P_LORA_TX_LED=46 -D PIN_USER_BTN=0 -D PIN_VEXT_EN=40 diff --git a/variants/station_g3_esp32/platformio.ini b/variants/station_g3_esp32/platformio.ini index a06819cf..49bf8309 100644 --- a/variants/station_g3_esp32/platformio.ini +++ b/variants/station_g3_esp32/platformio.ini @@ -1,4 +1,7 @@ -[Station_G3_ESP32] +; The motherboard has two RF daughterboard slots on separate GPIOs, mirrored by its +; "LNA P" / "LNA S" jumpers. Slot 1 is [Station_G3_ESP32], slot 2 is [Station_G3_ESP32_r2]; +; the slot pins sit in their own sections so neither set of -D flags shadows the other. +[Station_G3_ESP32_common] extends = esp32_base board = station-g3-esp32 board_build.partitions = default_16MB.csv @@ -11,17 +14,8 @@ build_flags = -D USE_SX1262 -D RADIO_CLASS=CustomSX1262 -D WRAPPER_CLASS=CustomSX1262Wrapper - -D P_LORA_DIO_1=48 - -D P_LORA_NSS=11 - -D P_LORA_RESET=21 - -D P_LORA_BUSY=47 - -D P_LORA_SCLK=12 - -D P_LORA_MISO=14 - -D P_LORA_MOSI=13 -D P_PA1_EN=9 ; PA PL1 Mode: LOW/open selects low level, HIGH/short selects high level. -D P_PA1_EN_ACTIVE=HIGH - -D P_PRIMARY_LNA_EN=10 ; Primary Slot LNA Mode: LOW/open is LNA on, HIGH/short is LNA off. - -D P_PRIMARY_LNA_EN_ACTIVE=LOW -D LORA_TX_POWER=7 ; SX1262 input power to the Station G3 PA; final output depends on PA PL1/PL2 level. -D MAX_LORA_TX_POWER=22 ; -D P_LORA_TX_LED=35 @@ -48,6 +42,48 @@ lib_deps = adafruit/Adafruit SH110X @ ~2.1.13 adafruit/Adafruit GFX Library @ ^1.12.1 +; PA PL1 is one board-level jumper shared by both slots, so P_PA1_EN stays in the base above. +[station_g3_esp32_r1_pins] +build_flags = + -D P_LORA_DIO_1=48 + -D P_LORA_NSS=11 + -D P_LORA_RESET=21 + -D P_LORA_BUSY=47 + -D P_LORA_SCLK=12 + -D P_LORA_MISO=14 + -D P_LORA_MOSI=13 + -D P_PRIMARY_LNA_EN=10 ; Primary Slot LNA Mode: LOW/open is LNA on, HIGH/short is LNA off. + -D P_PRIMARY_LNA_EN_ACTIVE=LOW + +; Slot 2 ("LNA S"). P_PRIMARY_LNA_EN keeps its name because LoRaFEMControl knows only one LNA pin. +[station_g3_esp32_r2_pins] +build_flags = + -D P_LORA_DIO_1=2 + -D P_LORA_NSS=43 + -D P_LORA_RESET=44 + -D P_LORA_BUSY=1 + -D P_LORA_SCLK=39 + -D P_LORA_MISO=41 + -D P_LORA_MOSI=40 + -D P_PRIMARY_LNA_EN=42 ; Secondary Slot LNA Mode, same polarity as the primary slot. + -D P_PRIMARY_LNA_EN_ACTIVE=LOW + +[Station_G3_ESP32] +extends = Station_G3_ESP32_common +build_flags = + ${Station_G3_ESP32_common.build_flags} + ${station_g3_esp32_r1_pins.build_flags} +build_src_filter = ${Station_G3_ESP32_common.build_src_filter} +lib_deps = ${Station_G3_ESP32_common.lib_deps} + +[Station_G3_ESP32_r2] +extends = Station_G3_ESP32_common +build_flags = + ${Station_G3_ESP32_common.build_flags} + ${station_g3_esp32_r2_pins.build_flags} +build_src_filter = ${Station_G3_ESP32_common.build_src_filter} +lib_deps = ${Station_G3_ESP32_common.lib_deps} + [env:Station_G3_ESP32_repeater] extends = Station_G3_ESP32 build_flags = @@ -268,3 +304,124 @@ lib_deps = JChristensen/Timezone paulstoffregen/Time@1.6.1 0neblock/SNMP_Agent + +[env:Station_G3_ESP32_r2_repeater] +extends = Station_G3_ESP32_r2 +build_flags = + ${Station_G3_ESP32_r2.build_flags} + -D ADVERT_NAME='"Station G3 ESP32 Repeater"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D MAX_NEIGHBOURS=50 +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = ${Station_G3_ESP32_r2.build_src_filter} + +<../examples/simple_repeater> +lib_deps = + ${Station_G3_ESP32_r2.lib_deps} + ${esp32_ota.lib_deps} + +[env:Station_G3_ESP32_r2_room_server] +extends = Station_G3_ESP32_r2 +build_src_filter = ${Station_G3_ESP32_r2.build_src_filter} + +<../examples/simple_room_server> +build_flags = + ${Station_G3_ESP32_r2.build_flags} + -D ADVERT_NAME='"Station G3 ESP32 Room"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D ROOM_PASSWORD='"hello"' +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +lib_deps = + ${Station_G3_ESP32_r2.lib_deps} + ${esp32_ota.lib_deps} + +[env:Station_G3_ESP32_r2_repeater_observer_mqtt] +extends = Station_G3_ESP32_r2 +board_build.partitions = default_16MB.csv ; standard 16MB partition table +extra_scripts = + ${esp32_base.extra_scripts} + pre:scripts/generate_cert_bundle.py +board_ssl_cert_source = adafruit-full +board_build.embed_files = src/certs/x509_crt_bundle.bin +build_flags = + ${Station_G3_ESP32_r2.build_flags} + -D ADVERT_NAME='"MQTT Observer"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D MAX_NEIGHBOURS=50 + -D WITH_MQTT_BRIDGE=1 + -D MQTT_MAX_PACKET_SIZE=1024 + -D MQTT_DEBUG=1 +# -D MESH_PACKET_LOGGING=1 +# -D MESH_DEBUG=1 + -D CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y + -D ESP32_CPU_FREQ=160 + -D WITH_SNMP=1 +# -D WIFI_SSID='"ssid"' +# -D WIFI_PWD='"password"' +# -D MQTT_SERVER='"your-mqtt-broker.com"' +# -D MQTT_PORT=1883 +# -D MQTT_USERNAME='"your-username"' +# -D MQTT_PASSWORD='"your-password"' +build_src_filter = ${Station_G3_ESP32_r2.build_src_filter} + + + + + + + + + + + +<../examples/simple_repeater> +lib_deps = + ${Station_G3_ESP32_r2.lib_deps} + ${esp32_ota.lib_deps} + elims/PsychicMqttClient@^0.2.4 + bblanchon/ArduinoJson @ 7.4.3 + arduino-libraries/NTPClient + JChristensen/Timezone + paulstoffregen/Time@1.6.1 + 0neblock/SNMP_Agent + +[env:Station_G3_ESP32_r2_room_server_observer_mqtt] +extends = Station_G3_ESP32_r2 +board_build.partitions = default_16MB.csv ; standard 16MB partition table +extra_scripts = + ${esp32_base.extra_scripts} + pre:scripts/generate_cert_bundle.py +board_ssl_cert_source = adafruit-full +board_build.embed_files = src/certs/x509_crt_bundle.bin +build_flags = + ${Station_G3_ESP32_r2.build_flags} + -D ADVERT_NAME='"Station G3 ESP32 Room Observer"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D ROOM_PASSWORD='"hello"' + -D WITH_MQTT_BRIDGE=1 + -D MAX_NEIGHBOURS=50 + -D MQTT_MAX_PACKET_SIZE=1024 + -D MQTT_DEBUG=1 +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 + -D CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y + -D ESP32_CPU_FREQ=160 + -D WITH_SNMP=1 +build_src_filter = ${Station_G3_ESP32_r2.build_src_filter} + + + + + + + + + + + +<../examples/simple_room_server> +lib_deps = + ${Station_G3_ESP32_r2.lib_deps} + ${esp32_ota.lib_deps} + elims/PsychicMqttClient@^0.2.4 + bblanchon/ArduinoJson @ 7.4.3 + arduino-libraries/NTPClient + JChristensen/Timezone + paulstoffregen/Time@1.6.1 + 0neblock/SNMP_Agent diff --git a/webui/index.html b/webui/index.html index a730665d..49cc2cff 100644 --- a/webui/index.html +++ b/webui/index.html @@ -760,6 +760,11 @@ function boot(){ st.nslots=st.hasMqtt?Math.min(s.active_slots||s.runtime_slots||0,s.runtime_slots||s.active_slots||0):0; if(s.max_cmds>0)CLI_MAX=s.max_cmds; st.fw=s.fw||"";st.build=s.build_date||"";st.role=s.role||"";st.board=s.board||""; + // Board-specific CLI commands this node answered for at startup. Controls + // for anything absent stay hidden: on this board they are not commands. + // The field is ABSENT, not empty, until the node has finished probing, and + // this page reads status once — so latch it only when it is really there. + setBoardCmds(s.board_cmds); $("#h-name").textContent=s.name||"MeshCore"; $("#h-sub").textContent=s.role+" * "+shortVer()+" * "+s.board; var b=$("#h-badge");b.classList.remove("hide"); @@ -1905,7 +1910,6 @@ var CLI_KEYS=[ ["dutycycle","Duty cycle percent (writes airtime factor)",0], ["cad","Listen before transmit",0,"on|off"], ["radio.rxgain","SX126x RX boosted gain",0,"on|off"], - ["radio.fem.rxgain","Front-end module RX gain",0], ["radio.rxps","RX duty-cycle power saving",0,"off|level 1-10|level 1-10 preamble 16|32|rx_us sleep_us"], ["radio.watchdog","Restart the radio if silent this long {0-120 min}",0], ["int.thresh","Interference threshold",0], @@ -1929,6 +1933,8 @@ var CLI_KEYS=[ ["wifi.ssid","WiFi network name",0], ["wifi.pwd","WiFi password",0], ["wifi.powersave","WiFi power-save mode",0,"none|min|max"], + ["link.status","Selected network, IP, signal and uptime",1], + ["link.diag","Ethernet selection and fallback diagnostics",1], ["wifi.status","WiFi connection, IP, RSSI and uptime",1], ["wifi.cli","Browser console",0,"on|off"], ["webui","WiFi settings website",0,"on|off"], @@ -1974,6 +1980,46 @@ var CLI_KEYS=[ ["bridge.format","ESP-NOW bridge wire format",0,"wrapped|raw"], ["bridge.secret","Bridge shared secret",0] ]; +/* Keys that come from Board::handleCommand(), not CommonCLI, so they exist only + on some boards. The node probes its own board at startup and names the ones it + answers in /api/status (board_cmds); the rest are never offered, because on + this board they are not commands at all. `gate` is the probed name — fan.lo + and fan.hi have no getter of their own and ride on `fan`. + [gate, key, description, mode, values] */ +var CLI_BOARD_KEYS=[ + ["radio.fem.rxgain","radio.fem.rxgain","Front-end module RX gain",0,"on|off"], + ["radio.fem.txgain","radio.fem.txgain","Front-end module TX gain",0,"on|off"], + ["fan","fan","Fan mode, temperature and cooldown",0,"on|off|auto"], + ["fan","fan.lo","Fan-off temperature in C {0-100, below fan.hi}",2], + ["fan","fan.hi","Fan-on temperature in C {above fan.lo, max 120}",2] +]; +function boardHas(gate){return st.boardCmds.indexOf(gate)>=0} +// An absent board_cmds means the node has not finished probing its board, which +// it does on the first tick after the routes go live — so in practice the very +// first retry finds it. Retry rather than read absent as "no board commands", +// which would hide working controls for the whole session. Backs off to ~15s +// total: generous against a one-tick gap, and bounded, since a node that never +// answers is one where hiding the controls is the right outcome anyway. +function setBoardCmds(v,tries){ + if(v===undefined||v===null){ + tries=tries||0; + if(tries<10)setTimeout(function(){ + api("/api/status").then(function(s){setBoardCmds(s.board_cmds,tries+1)}) + .catch(function(){}); + },Math.min(300*(tries+1),2000)); + return; + } + st.boardCmds=v.split(",").filter(Boolean); + cli.built=0; // the command table is keyed on this; force a rebuild + applyBoardCmds(); +} +// Board-specific rows in the settings form. Hidden unless the node answered for +// the command at startup, so the form never shows a control that cannot apply. +function applyBoardCmds(){ + $("#sw-fem-rx").classList.toggle("hide",!boardHas("radio.fem.rxgain")); + $("#sw-fem-tx").classList.toggle("hide",!boardHas("radio.fem.txgain")); +} + // Per-slot keys, expanded across the slots this board actually runs. // [field, description, values] var CLI_SLOT=[ @@ -2076,8 +2122,8 @@ function cliKeys(){ var cli={built:-1,tbl:[],hist:[],hix:-1,draft:"",sug:[],sel:-1,busy:false,shown:false,pwd:false}; -// Rebuilt when the slot count changes: `active_slots` decides how many -// mqttN.* keys actually exist on this board. +// Rebuilt when the board's surface changes: `active_slots` decides how many +// mqttN.* keys exist, and board_cmds which of the board-specific keys do. function cliTable(){ var signature=[st.role,st.nslots,st.hasMqtt,st.caps].join(":"); if(cli.built===signature)return cli.tbl; @@ -2116,6 +2162,10 @@ function cliEnum(key){ for(var i=0;i