diff --git a/.github/workflows/run-unit-tests.yml b/.github/workflows/run-unit-tests.yml index 1ee58d8c1..d5c608b61 100644 --- a/.github/workflows/run-unit-tests.yml +++ b/.github/workflows/run-unit-tests.yml @@ -647,9 +647,17 @@ jobs: - name: Verify WiFi OTA startup and WebConfig handoff run: | + python3 -B test/test_esp32_management_password.py -v + python3 -B test/test_companion_admin_password.py -v + python3 -B test/test_management_password_commands.py -v + python3 -B test/test_repeater_password_normalization.py -v + python3 -B test/test_wifi_setup_auth.py -v + python3 -B test/test_lightweight_ota_auth.py -v + python3 -B test/test_esp32_async_web_build_paths.py -v python3 -B test/test_wifi_ota_start.py -v python3 -B test/test_webconfig_ap_start.py -v python3 -B test/test_webconfig_recovery_auth.py -v + python3 -B test/test_webconfig_password_sessions.py -v python3 -B test/test_webconfig_login_throttle.py -v python3 -B test/test_esp32_wifi_scan_fix.py -v python3 -B test/test_esp32_wifi_scan_recipes.py -v diff --git a/arch/esp32/AsyncElegantOTA/src/AsyncElegantOTA.cpp b/arch/esp32/AsyncElegantOTA/src/AsyncElegantOTA.cpp index 225004eea..cddeea543 100644 --- a/arch/esp32/AsyncElegantOTA/src/AsyncElegantOTA.cpp +++ b/arch/esp32/AsyncElegantOTA/src/AsyncElegantOTA.cpp @@ -1,5 +1,8 @@ #include "AsyncElegantOTA.h" #include +#if defined(ESP32) +#include +#endif static std::atomic ota_uploads_enabled{false}; static std::atomic ota_upload_busy{false}; #if defined(ESP32) @@ -19,6 +22,35 @@ void AsyncElegantOtaClass::setID(const char* id){ _id = id; } +bool AsyncElegantOtaClass::authenticateRequest(AsyncWebServerRequest* request, + uint32_t* generation) { +#if defined(ESP32) + if (_managementPassword) { + const char* authorization = request->hasHeader("Authorization") + ? request->getHeader("Authorization")->value().c_str() : nullptr; + const auto result = mesh::esp32::managementPassword::authenticateBasic( + authorization, millis(), generation); + if (result == mesh::esp32::managementPassword::AuthResult::Authorized) return true; + if (result == mesh::esp32::managementPassword::AuthResult::Unavailable) + request->send(503, "text/plain", "saved admin password unavailable"); + else if (result == mesh::esp32::managementPassword::AuthResult::Throttled) + request->send(429, "text/plain", "too many failed logins; wait 30 seconds"); + else { + AsyncWebServerResponse* response = request->beginResponse(401, "text/plain", "admin password required"); + response->addHeader("WWW-Authenticate", "Basic realm=\"MeshCore admin\", charset=\"UTF-8\""); + response->addHeader("Cache-Control", "no-store"); + request->send(response); + } + return false; + } +#endif + if (_authRequired && !request->authenticate(_username.c_str(), _password.c_str())) { + request->requestAuthentication(); + return false; + } + return true; +} + void AsyncElegantOtaClass::begin(AsyncWebServer *server, const char* username, const char* password){ _server = server; setEnabled(true); @@ -34,11 +66,7 @@ void AsyncElegantOtaClass::begin(AsyncWebServer *server, const char* username, c } _server->on("/update/identity", HTTP_GET, [&](AsyncWebServerRequest *request){ - if(_authRequired){ - if(!request->authenticate(_username.c_str(), _password.c_str())){ - return request->requestAuthentication(); - } - } + if (!authenticateRequest(request)) return; #if defined(ESP8266) request->send(200, "application/json", "{\"id\": \""+_id+"\", \"hardware\": \"ESP8266\"}"); #elif defined(ESP32) @@ -47,22 +75,14 @@ void AsyncElegantOtaClass::begin(AsyncWebServer *server, const char* username, c }); _server->on("/update", HTTP_GET, [&](AsyncWebServerRequest *request){ - if(_authRequired){ - if(!request->authenticate(_username.c_str(), _password.c_str())){ - return request->requestAuthentication(); - } - } + if (!authenticateRequest(request)) return; AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", ELEGANT_HTML, ELEGANT_HTML_SIZE); response->addHeader("Content-Encoding", "gzip"); request->send(response); }); _server->on("/update", HTTP_POST, [&](AsyncWebServerRequest *request) { - if(_authRequired){ - if(!request->authenticate(_username.c_str(), _password.c_str())){ - return request->requestAuthentication(); - } - } + if (!authenticateRequest(request)) return; // send() queues a response until the request body has finished. Keep // an earlier upload error even before it has reached the wire. if (request->isSent() || request->getResponse()) return; @@ -85,11 +105,8 @@ void AsyncElegantOtaClass::begin(AsyncWebServer *server, const char* username, c }, [&](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) { //Upload handler chunks in data if (request->isSent() || request->getResponse()) return; - if(_authRequired){ - if(!request->authenticate(_username.c_str(), _password.c_str())){ - return request->requestAuthentication(); - } - } + uint32_t authenticated_generation = 0; + if (!authenticateRequest(request, &authenticated_generation)) return; if (!index) { if (!ota_uploads_enabled.load()) { @@ -114,6 +131,13 @@ void AsyncElegantOtaClass::begin(AsyncWebServer *server, const char* username, c return request->send(400, "text/plain", "MD5 parameter missing"); } +#if defined(ESP32) + if (_managementPassword && !mesh::esp32::managementPassword::beginUpload(authenticated_generation)) { + ota_upload_busy.store(false); + return request->send(409, "text/plain", "password change or OTA upload in progress; retry"); + } +#endif + #if defined(ESP8266) int cmd = (filename == "filesystem") ? U_FS : U_FLASH; Update.runAsync(true); @@ -125,6 +149,9 @@ void AsyncElegantOtaClass::begin(AsyncWebServer *server, const char* username, c if (!Update.begin(UPDATE_SIZE_UNKNOWN, cmd)) { // Start with max available size #endif ota_upload_busy.store(false); +#if defined(ESP32) + if (_managementPassword) mesh::esp32::managementPassword::endUpload(); +#endif return request->send(400, "text/plain", "OTA could not begin"); } // Arduino Update.begin() clears the expected digest. Set it only @@ -132,6 +159,9 @@ void AsyncElegantOtaClass::begin(AsyncWebServer *server, const char* username, c if(!Update.setMD5(request->getParam("MD5", true)->value().c_str())) { Update.abort(); ota_upload_busy.store(false); +#if defined(ESP32) + if (_managementPassword) mesh::esp32::managementPassword::endUpload(); +#endif return request->send(400, "text/plain", "MD5 parameter invalid"); } @@ -146,6 +176,9 @@ void AsyncElegantOtaClass::begin(AsyncWebServer *server, const char* username, c if (!request->_tempObject) { Update.abort(); ota_upload_busy.store(false); +#if defined(ESP32) + if (_managementPassword) mesh::esp32::managementPassword::endUpload(); +#endif return request->send(503, "text/plain", "OTA state allocation failed"); } ota_upload_owner = request; @@ -160,6 +193,9 @@ void AsyncElegantOtaClass::begin(AsyncWebServer *server, const char* username, c Update.abort(); // Release a disconnected, partial upload. } ota_upload_busy.store(false); +#if defined(ESP32) + if (_managementPassword) mesh::esp32::managementPassword::endUpload(); +#endif }); } diff --git a/arch/esp32/AsyncElegantOTA/src/AsyncElegantOTA.h b/arch/esp32/AsyncElegantOTA/src/AsyncElegantOTA.h index f7603201b..e1e06a211 100644 --- a/arch/esp32/AsyncElegantOTA/src/AsyncElegantOTA.h +++ b/arch/esp32/AsyncElegantOTA/src/AsyncElegantOTA.h @@ -36,6 +36,11 @@ class AsyncElegantOtaClass{ // Stop admission atomically with upload ownership. Existing GET // responses may drain while the containing listener is stopped. bool setEnabled(bool enabled); + // Opt in only after the role has published its confirmed runtime + // credential. Legacy migration callers retain their explicit policy. + void useManagementPassword() { _managementPassword = true; } + bool authenticateRequest(AsyncWebServerRequest* request, + uint32_t* generation = nullptr); private: AsyncWebServer *_server; @@ -46,6 +51,7 @@ class AsyncElegantOtaClass{ String _username = ""; String _password = ""; bool _authRequired = false; + bool _managementPassword = false; }; diff --git a/docs/WiFi.md b/docs/WiFi.md index 0accf3cac..2ebb4bd61 100644 --- a/docs/WiFi.md +++ b/docs/WiFi.md @@ -148,19 +148,39 @@ The bootstrap uses ES5 syntax and Promise-based loading, including on Android Most full-size ESP32 MQTT observer builds have the shared WebConfig portal. On a fresh device with no saved SSID: -1. Join the open `MeshCore-Setup-XXXX` access point. +1. Join `MeshCore-Setup-XXXX` with the node's admin password (factory default + `password`). A display's WiFi QR code uses the hotspot's current credential. 2. If the captive page does not open, browse to `http://192.168.4.1/`. 3. Enter WiFi, radio, identity, and MQTT settings. 4. Select **Save & Reboot**. 5. After reboot, check `get wifi.status` and `get mqtt.status`. -First-time provisioning with no saved SSID does not require a portal admin -login. A setup AP opened with a saved SSID, including saved-network recovery, -requires the existing admin password before changing settings. Repeater and -room-server builds also require that password on the normal LAN; deliberately -passwordless images retain their no-password policy. `WEBCONFIG_AP_PASSWORD` -controls access to the WiFi network separately. The portal uses plain HTTP, so -use a trusted network. +ESP32 management uses one saved admin password for WebConfig login, browser +firmware uploads, and setup WiFi. Choose 8–15 printable ASCII characters so the +hotspot can use it for WPA2. Other valid admin passwords (1–15 UTF-8 bytes, +without CR or LF) leave the hotspot open and require an HTTP admin login. +There is no separate setup WiFi password. A protected first-time setup AP with +no saved SSID retains its provisioning flow; recovery with a saved SSID requires +the existing admin login. Deliberately passwordless images retain their local +no-password policy. The portal uses plain HTTP, so use a trusted network. + +Changing the password ends existing browser sessions after the save succeeds. +The submitting page keeps the save result and tries the new password once, +then asks you to sign in if needed. A partial save shows which settings failed +and does not reboot. If the setup hotspot restarts, reconnect with the new +password when it is eligible for WPA2. An unconfirmed password save keeps the +previous runtime password active, but the saved state after reboot may differ; +read the reported error before retrying. + +Credentials for other systems or different permissions remain separate: + +| Credential | Why it does not become the node admin password | +|---|---| +| Router WiFi and MQTT broker login | These are issued by the network or broker, which may serve many devices. | +| Bluetooth pairing PIN | BLE pairing requires its numeric PIN format. | +| Guest and room passwords | Members and guests should not receive node administration access. | +| Channel, bridge, fleet and alert keys | These are shared with peers or recipients and have their own protocol requirements. | +| SNMP community and management-report credentials | Monitoring systems receive these credentials; they should not also receive the node admin password. | Admin login limits apply on both LAN and recovery AP: five failures lock the failing address for 30 seconds after its fifth failure. All addresses also share @@ -442,9 +462,11 @@ of running both. On a WiFi-selected boot, the LoRa layout accepts accepts `min|max` for the saved WiFi setting, while ESP-NOW + BLE requires `min`. Device power saving remains independent of this modem policy. -WiFi companions do not have the repeater/room-server admin CLI password model, -so their LAN WebConfig page is intentionally unauthenticated. Use them only on -a trusted LAN. +ESP32 WiFi Companions also have a saved admin password for LAN WebConfig and +browser OTA, initially `password`. Their `get password` command reports status +without revealing it. The credential is stored in NVS alongside the WiFi +settings and survives a filesystem erase. Use `password ` through +an available administrative connection to change it. The WebConfig **Advanced** card exposes device power saving on WiFi Companion, repeater, and room-server builds. It also exposes RX power saving on radio chips @@ -496,9 +518,12 @@ motatool serve --dir ./motas --tcp :5001 -v The TCP connection supplies `.mota` files for the node to advertise and relay over LoRa; it is not a raw `.bin` uploader. `start ota` continues to provide the -direct browser uploader on HTTP port 80. A FULL role without WebConfig but with -browser OTA support can use the `MeshCore-OTA` access point raised by -`start ota`; its seeder address is `192.168.4.1:5001`. +direct browser uploader on HTTP port 80. Sign in with HTTP Basic username +`admin` and the node's current admin password. A FULL role without WebConfig +but with browser OTA support can use the `MeshCore-OTA` access point raised by +`start ota`; its seeder address is `192.168.4.1:5001`. The runtime OTA hotspot +uses the same WPA2 eligibility rule as setup WiFi. Temporary partition migration +and recovery applications retain their own documented access policy. For browser uploads from an existing 1.17.1.8 ESP32 node, see the [1.17.1.9 WiFi upgrade guide](upgrading_1.17.1.8_to_1.17.1.9.md). @@ -511,6 +536,10 @@ removes the TCP folder. Port 5001 has no login layer, so expose it only on a trusted LAN or temporary setup network. Firmware target and hash checks still apply at the receiving node, along with its configured signature/trust policy. +The HTTP admin login does not protect trusted TCP consoles or delegated remote +CLI access. Those administrative paths can change the node's admin password; +limit them to trusted users and networks. + When the shared seeder is running, `get wifi.status` appends its live state: ```text @@ -840,8 +869,9 @@ Common causes are: - the wrong firmware role or an older compact-CLI build without WebConfig. For a WiFi companion, find its station IP in the router, connect the client to -TCP port 5000, and use the open `MeshCore-Setup-XXXX` AP at -`http://192.168.4.1/` if it cannot join the saved network. Current firmware +TCP port 5000, and use the `MeshCore-Setup-XXXX` AP at +`http://192.168.4.1/` if it cannot join the saved network. The hotspot uses the +admin password when eligible for WPA2, as described above. Current firmware uses standard b/g/n for the setup AP, including ESP-NOW-capable targets. A running LR mesh conflicts with a conventional access point; current firmware refuses that AP startup and defers LR startup while an AP is active. A primary diff --git a/docs/cli_command_availability.md b/docs/cli_command_availability.md index e2f6d9e0b..291b3c35c 100644 --- a/docs/cli_command_availability.md +++ b/docs/cli_command_availability.md @@ -100,7 +100,8 @@ over the normal binary USB, BLE, or TCP connection: | `set freq ` | Local terminal, binary command `0x42`, and authorized LoRa CLI; reboot to apply | | [`get public.key`](cli_commands.md#view-this-nodes-public-key) | Companion text terminal and binary command `0x42`; read-only, no private-key export feature required | | `get prv.key` | Local terminal and binary command `0x42`; requires private key export enabled | -| `get password` | Reports that Companion has no admin password; infrastructure returns its password locally | +| `get password` | ESP32 WiFi Companion reports management-password status without revealing it; other Companions report no admin password; infrastructure returns its password locally | +| `password ` | ESP32 WiFi Companion and infrastructure: change the saved admin password; ESP32 setup WiFi, WebConfig and browser OTA reuse it | | [`get/set lost.reply`](companion_lost_reply.md) | Local Companion CLI and framed command `0x42` when `MESH_ENABLE_LOST_REPLY` is enabled; saved `off`, `no` or `yes` private-message auto response | | `get wifi.pwd`, `get mqttN.password`, `get mqttN.token` | Local terminal and binary command `0x42`; corresponding WiFi/MQTT feature required | | [`board`](cli_commands.md#show-the-hardware-name) | Every Companion text terminal and command `0x42` | diff --git a/docs/cli_commands.md b/docs/cli_commands.md index ba6613828..1cb4d9b95 100644 --- a/docs/cli_commands.md +++ b/docs/cli_commands.md @@ -266,6 +266,12 @@ access point. The reply gives the URL to open and tells you which network to use. `start ota ap` always selects the access point, including when OTA is already running on a LAN address. This is useful with client-isolated networks. +The runtime browser uploader uses HTTP Basic authentication: username `admin`, +password the node's saved admin password. The OTA hotspot reuses that password +for WPA2 when it is 8–15 printable ASCII characters; otherwise it is open and +the HTTP login still applies. Temporary partition migration and recovery apps +retain their documented access policy. + Starting OTA automatically stops WebConfig and reports `WebConfig stopped` in the reply. The existing LAN connection stays up; a setup hotspot is replaced by `MeshCore-OTA`. WebConfig's delayed HTTP cleanup cannot stop OTA's WiFi. @@ -318,15 +324,18 @@ off while a temporary WebConfig session is currently active at that URL. It serves the shared WiFi, radio, flood, loop, and status page and reports its URL. MQTT builds also show the MQTT tab and wizard step; non-MQTT builds remove them entirely. Sign in with the node's admin password. If the node has no saved -WiFi SSID, the command starts the open `MeshCore-Setup-XXXX` captive AP at +WiFi SSID, the command starts the `MeshCore-Setup-XXXX` captive AP at instead. If a saved WiFi network is unavailable and the node falls back to its setup AP, sign in with the existing admin password before changing settings. Joining -that AP does not grant permission to replace the password. First-time setup -without a saved SSID keeps its AP provisioning flow. Images deliberately -configured without an admin password, including passwordless Companions, -retain their local no-password policy; use them only on a trusted network. +that AP does not grant permission to replace the password. The hotspot uses +the same admin password for WPA2 when it is 8–15 printable ASCII characters. +Other valid admin passwords leave the hotspot open and require the HTTP admin +login. Protected first-time setup without a saved SSID keeps its provisioning +flow. ESP32 WiFi Companions also have a saved admin password, initially +`password`. Deliberately passwordless images retain their local no-password +policy; use them only on a trusted network. `start webconfig ap` forces captive-AP mode. It will not interrupt an active MQTT bridge, so run `set mqtt.enabled off` first. Use `stop webconfig` to @@ -352,8 +361,8 @@ paused, rather than starting services from saved intent alone. Every ESP32 build with WebConfig supports the browser command terminal, including WiFi Companion and Full Companion. Companions use their complete USB/TCP terminal on the trusted LAN, including contact import, chat, recipient -selection, and delayed replies. Repeater and Room Server use their local CLI -after admin authentication. +selection, and delayed replies. ESP32 roles require their WebConfig admin +login before browser terminal access; the HTTP login does not protect TCP. To add a Companion contact, run `import meshcore://`, then `list` to confirm it appears. Get the complete card with `card` on the @@ -365,9 +374,10 @@ The saved `wifi.cli` setting defaults to `on`. Use `set wifi.cli off` to disable the **CLI** tab. `get wifi.cli` reports `off`, `on, waiting for WiFi client`, or `on, active`. The saved setting becomes active only in station/LAN mode while the WiFi client -is connected. It is deliberately unavailable on the open setup access point. +is connected. It is deliberately unavailable on the setup access point. The tab displays each reply in the browser, including local diagnostics, -`get password`, private-key and WiFi/MQTT credential reads, and `erase`. +infrastructure `get password`, private-key and WiFi/MQTT credential reads, and +`erase`. ESP32 Companion's `get password` reports status without the secret. Infrastructure `get acl` and raw `log` stream to the requesting browser, with backpressure for slow clients. These maintenance commands retain their LoRa restrictions. `set freq` works both here and through authorized LoRa CLI. @@ -2172,7 +2182,7 @@ Older Companion firmware is not a safe transport for this backup flow. - `password ` **Parameters:** -- `new_password`: New admin password +- `new_password`: New admin password (on ESP32, 1–15 UTF-8 bytes without CR or LF) **Set by build flag:** `ADMIN_PASSWORD` @@ -2180,8 +2190,27 @@ Older Companion firmware is not a safe transport for this backup flow. `get password` returns the current admin password only on a local connection: USB, Ethernet, or the authenticated LAN browser CLI. It is rejected over LoRa. -Companion has no local admin password and reports that explicitly, including -through binary command `0x42`; this command does not report the Bluetooth PIN. +ESP32 WiFi Companion instead reports management-password status without revealing +the secret. Its password is stored in NVS, survives a filesystem erase, and +defaults to `password`. Other Companion builds retain their existing no-admin +response. This command does not report the Bluetooth PIN. + +On ESP32, empty and overlong new passwords are rejected rather than truncated. +Leading spaces are part of the password. For ESP32 setup WiFi protection, choose 8–15 +printable ASCII characters; other accepted passwords use an open hotspot with +an HTTP admin login. WebConfig and runtime browser OTA share this admin +credential (OTA's HTTP Basic username is `admin`). + +A confirmed password change invalidates existing browser sessions. The page +that submitted it keeps a save receipt, tries the new password once, and reads +the same result again after login; it does not resend commands. If another +setting fails, the result remains visible and reboot is withheld. An +unconfirmed password save keeps the previous runtime password active, but the +saved state after reboot may differ; the error reports this uncertainty. + +Trusted TCP consoles and delegated remote CLI remain administrative paths and +can change this password. The HTTP credential does not protect those ports or +replace radio ACL permissions. **Note:** The password setter replies with confirmation. diff --git a/docs/companion_protocol.md b/docs/companion_protocol.md index 63dae7c1c..658226a61 100644 --- a/docs/companion_protocol.md +++ b/docs/companion_protocol.md @@ -305,9 +305,16 @@ Direct USB, BLE, WiFi TCP, and Ethernet clients can also use this command for `stats-core`, `stats-radio`, `stats-radio-diag`, `stats-packets`, `erase`, and `get prv.key` (when private key export is enabled). WiFi/MQTT builds accept `get wifi.pwd`, `get mqttN.password`, and -`get mqttN.token`. `get password` reports that Companion has no admin password; -infrastructure roles return their own admin password on a local CLI connection. -These privileges do not apply to CLI commands relayed over LoRa. +`get mqttN.token`. On ESP32 WiFi Companion, `get password` reports whether the +management password is available without revealing it. `password ` +changes the saved password shared by setup WiFi, WebConfig and browser OTA. +Other Companion builds report that they have no admin password; infrastructure +roles return their own admin password on a local CLI connection. +These direct-client maintenance and secret-read privileges do not apply to +CLI commands relayed over LoRa. +Existing trusted Companion transports and contacts explicitly granted remote +CLI access retain their command privileges. The browser login does not add a +password handshake to those transports. ESP32 WiFi Companion builds expose the official app's `get/set wifi.enabled`, `get/set wifi.ssid`, and `get/set wifi.pwd` controls. Credentials use the shared WiFi store, and enablement is saved in node preferences. WiFi/BLE builds apply diff --git a/docs/companion_radio_full.md b/docs/companion_radio_full.md index d65858ad8..4a7b6b2bd 100644 --- a/docs/companion_radio_full.md +++ b/docs/companion_radio_full.md @@ -405,6 +405,8 @@ get wifi.ssid get wifi.status get wifi.powersave get webui +get password +password my-admin-pass set wifi.ssid MyNetwork set wifi.pwd my-password set wifi.powersave min @@ -416,9 +418,20 @@ stop webconfig ESP32 WiFi Companions with WebConfig, including Full Companion, expose a **CLI** tab at the node's LAN address. It defaults to on; use `get wifi.cli`, `set wifi.cli on`, or `set wifi.cli off`. Older builds that report the browser -terminal as unavailable need a firmware update. The open setup AP does not +terminal as unavailable need a firmware update. The setup AP does not expose this tab. +ESP32 WebConfig and runtime browser OTA share the saved node admin password, +initially `password`; the OTA HTTP Basic username is `admin`. `get password` +reports status without revealing it. The password is stored in NVS and survives +a filesystem erase. New values must be 1–15 UTF-8 bytes without CR or LF. Use +8–15 printable ASCII characters to protect setup WiFi with the same password; +otherwise the hotspot is open and requires an HTTP admin login. The display's +WiFi join QR uses the hotspot's current credential. After a successful change, +the submitting page keeps its save result and tries the new login once; other +browser sessions must sign in again. An unconfirmed save keeps the previous +runtime password active, but the saved state after reboot may differ. + The browser accepts Companion configuration commands, including `get powersaving`, `set usb.logging on|off`, WiFi controls, and MQTT settings. `set mqtt.enabled on|off` controls MQTT without erasing broker settings; `get mqtt.enabled`, `get mqtt.running`, and @@ -716,8 +729,12 @@ stealth remains enabled. Repeating `on` keeps an existing bond. Toggle `off`, then `on`, then reboot to reset first pairing. All flag changes need reboot. The node still sends directed or allowlisted BLE packets; it is not radio silent. -ESP32 ports 5000, 5001, 5002, and WebConfig have no independent login layer. -Expose them only on a trusted LAN or temporary setup network. See +ESP32 TCP ports 5000, 5001, and 5002 remain trusted-network services. The HTTP +admin login protects WebConfig and runtime browser OTA, and does not protect +these ports or delegated remote CLI. Administrative console access can change +the admin password. Expose TCP services only on a trusted LAN or temporary +setup network. Temporary migration/recovery apps retain their documented +access policy. See [WiFi setup](./WiFi.md) for credential setup and reconnect behavior. ## USB Binary and text terminal modes diff --git a/docs/terminal_chat_cli.md b/docs/terminal_chat_cli.md index 028ae9933..9eaac5c97 100644 --- a/docs/terminal_chat_cli.md +++ b/docs/terminal_chat_cli.md @@ -17,7 +17,8 @@ select **CLI**. The browser runs the same commands as the USB terminal and Full Companion's TCP terminal on port 5002, including contact import, contact selection, messages, remote login/commands, and delayed RF replies. Run `help` to list commands compiled into the device. Enable the tab with -`set wifi.cli on`; the open setup AP does not expose it. +`set wifi.cli on` and sign in with the node admin password. The setup AP does +not expose this full terminal. For example, copy the complete `meshcore://...` string from `card` on another Companion, then run these commands on the receiving Companion: @@ -101,7 +102,8 @@ the corresponding feature: | `stats-core`, `stats-radio`, `stats-radio-diag`, `stats-packets` | Runtime diagnostics | | `get public.key` | Read-only node identity public key; Companion returns `> ` followed by 64 uppercase hex characters | | `get prv.key` | Node identity private key; Companion requires private key export enabled in the build | -| `get password` | Infrastructure admin password; Companion reports that it has no admin password | +| `get password` | Infrastructure admin password; ESP32 WiFi Companion reports management-password status without revealing it; other Companions report no admin password | +| `password ` | Change the saved admin password on infrastructure and ESP32 WiFi Companion | | `erase` | Erase stored identity and settings; reboot for a fresh node | | `get wifi.pwd` | Stored WiFi password on WiFi builds | | `get mqttN.password`, `get mqttN.token` | Stored credentials for MQTT slot N | @@ -126,9 +128,12 @@ the binary contacts operations for Companion contacts. Interactive chat commands still use the text terminal or their corresponding binary protocol operations. -The browser CLI requires station/LAN mode and `wifi.cli on`. Infrastructure -uses its admin login; Companion uses the trusted LAN. Configuration forms keep -password fields masked; explicit local CLI getters return their values. +The browser CLI requires station/LAN mode, `wifi.cli on`, and the node admin +login. Configuration forms keep password fields masked; explicit local CLI +getters return their values, except ESP32 WiFi Companion's status-only +`get password`. Existing USB/BLE/TCP clients and explicitly authorized remote +CLI contacts retain their administrative command access. HTTP authentication +does not add a password handshake to the raw TCP services. ## Companion contact and channel TX profiles diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index bea304921..e7f429c67 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -40,6 +40,10 @@ #include #include #include +#if defined(ESP32_PLATFORM) && defined(WIFI_SSID) +#include +#include +#endif #include #if MESH_PACKET_LOGGING #include @@ -3008,6 +3012,23 @@ void MyMesh::begin(bool has_display, bool radio_available, // load persisted prefs const bool prefs_ready = _store->loadPrefs(_prefs, sensors.node_lat, sensors.node_lon); +#if defined(ESP32_PLATFORM) && defined(WIFI_SSID) +#ifdef ADMIN_PASSWORD + const char* management_default = ADMIN_PASSWORD; +#else + const char* management_default = "password"; +#endif + _management_password_ready = mesh::esp32::companionAdminPassword::load( + _management_password, management_default); + if (_management_password_ready) { + _management_password_ready = + mesh::esp32::managementPassword::publish(_management_password); + } + if (!_management_password_ready) { + mesh::usbLoggingPort().println( + "Management password unavailable; use password on USB to repair"); + } +#endif #if defined(RAK_4631) // Only a verified image (or a fresh missing file) may permit GPS-only power. // A failed load never replaces a stored shared policy with an unsafe cut. @@ -3798,6 +3819,39 @@ bool MyMesh::handleLocalControlCommand(const char* command, char* reply, size_t reply_size) { if (!command || !reply || reply_size == 0) return false; while (*command == ' ') command++; +#if defined(ESP32_PLATFORM) && defined(WIFI_SSID) + if (strncmp(command, "password", 8) == 0 + && (command[8] == 0 || command[8] == ' ' || command[8] == '\t')) { + const char* value = command + 8; + // Consume the command separator only. Extra spaces belong to the secret, + // exactly as in infrastructure CLI and browser password forms. + if (*value == ' ' || *value == '\t') ++value; + if (!mesh::esp32::managementPassword::validPassword(value)) { + snprintf(reply, reply_size, + "Error: password must be 1-15 bytes, no line breaks; use 8-15 ASCII for setup WiFi"); + return true; + } + mesh::esp32::managementPassword::ChangeGuard change; + if (!change.acquired()) { + snprintf(reply, reply_size, "Error: OTA upload or password change busy; retry"); + return true; + } + if (!mesh::esp32::companionAdminPassword::save(value)) { + snprintf(reply, reply_size, "Error: password save unconfirmed; reboot may differ"); + return true; + } + memcpy(_management_password, value, strlen(value) + 1); + _management_password_ready = change.publish(_management_password); + if (!_management_password_ready) { + snprintf(reply, reply_size, "Error: password saved; management unavailable, reboot required"); + } else { + // The browser batch recognizes this established success prefix and + // removes the secret before publishing its result. + snprintf(reply, reply_size, "password now: %s", value); + } + return true; + } +#endif if (mesh::powerdiag::handleCommand(command, reply, reply_size, millis())) return true; #if defined(OTA_RAK15002_SD_STORE) && defined(ETHERNET_USE_RAK13800) if (handleRak4631PeripheralCommand(command, reply, reply_size)) return true; @@ -3935,6 +3989,13 @@ bool MyMesh::handleLocalControlCommand(const char* command, char* reply, // Binary Companion callers may supply a shorter buffer. char ota_reply[160] = {0}; bool webconfig_stopped = false; +#if defined(ESP32_PLATFORM) && defined(WIFI_SSID) + if (!_management_password_ready + || !mesh::esp32::managementPassword::publish(_management_password)) { + snprintf(reply, reply_size, "Error: management password unavailable; set password on USB"); + return true; + } +#endif #ifdef WITH_WEBCONFIG if (isWebConfigActiveOrStopping()) { if (!_webconfig->stopForOTA(ota_reply)) { @@ -5034,6 +5095,11 @@ static bool wcCopyValue(char* dest, size_t dest_size, const char* value) { void MyMesh::getNodeSnapshot(WebConfigServer::NodeSnapshot& s) { memset(&s, 0, sizeof(s)); +#if defined(ESP32_PLATFORM) && defined(WIFI_SSID) + if (_management_password_ready) { + wcCopyValue(s.admin_password, sizeof(s.admin_password), _management_password); + } +#endif wcCopyValue(s.name, sizeof(s.name), _prefs.node_name); wcCopyValue(s.bluetooth_name, sizeof(s.bluetooth_name), _prefs.bluetooth_name); @@ -5106,6 +5172,12 @@ void MyMesh::getNodeSnapshot(WebConfigServer::NodeSnapshot& s) { } bool MyMesh::startWebConfig(bool force_ap, char* reply) { +#if defined(ESP32_PLATFORM) && defined(WIFI_SSID) + if (!_management_password_ready) { + strcpy(reply, "Err: management password unavailable; set password on USB"); + return false; + } +#endif #if defined(COMPANION_EXCLUSIVE_WIFI_BLE) if (!isCompanionWiFiEnabled()) { strcpy(reply, @@ -5222,6 +5294,13 @@ void MyMesh::execAdminCommand(char* cmd, char* reply) { void MyMesh::execCommand(char* cmd, char* reply) { reply[0] = 0; +#if defined(ESP32_PLATFORM) && defined(WIFI_SSID) + if (cmd && strncmp(cmd, "password", 8) == 0 + && (cmd[8] == 0 || cmd[8] == ' ' || cmd[8] == '\t')) { + handleLocalControlCommand(cmd, reply, 160); + return; + } +#endif #ifdef WITH_MQTT_BRIDGE if (cmd && strncmp(cmd, "set mqtt.enabled ", 17) == 0) { handleLocalControlCommand(cmd, reply, 160); @@ -10230,7 +10309,12 @@ void MyMesh::handleTerminalCommand(char* command, bool reader_prompt, "Commands:\r\n" " stats-core / stats-radio / stats-radio-diag / stats-packets\r\n" " get prv.key (when private key export is enabled)\r\n" +#if defined(ESP32_PLATFORM) && defined(WIFI_SSID) + " password (shared setup WiFi, WebConfig and WiFi OTA)\r\n" + " get password (management password status)\r\n" +#else " get password (this role has no admin password)\r\n" +#endif " erase (erase stored settings and identity)\r\n" " board\r\n" " version\r\n"); @@ -10514,7 +10598,15 @@ bool MyMesh::handleDirectCommand(const char* command, char* reply, size_t reply_ return true; } if (strcmp(command, "get password") == 0) { +#if defined(ESP32_PLATFORM) && defined(WIFI_SSID) + // Binary Companion and its legacy TCP transports have no admin-login + // handshake. Report status there, never disclose the management secret. + snprintf(reply, reply_size, _management_password_ready + ? "> (management password set; use password to change)" + : "Error: management password unavailable; set password on USB"); +#else snprintf(reply, reply_size, "> (no admin password on Companion)"); +#endif return true; } if (strcmp(command, "get prv.key") == 0) { diff --git a/examples/companion_radio/MyMesh.h b/examples/companion_radio/MyMesh.h index eb8b19a1a..b62b33d5d 100644 --- a/examples/companion_radio/MyMesh.h +++ b/examples/companion_radio/MyMesh.h @@ -246,6 +246,10 @@ public: } #endif +#if defined(ESP32_PLATFORM) && defined(WIFI_SSID) + bool isManagementPasswordReady() const { return _management_password_ready; } +#endif + #ifdef WITH_WEBCONFIG bool startWebConfig(bool force_ap, char* reply); void stopWebConfig(); @@ -794,6 +798,10 @@ private: #endif uint16_t _temp_radio_preamble = 0; CompanionNodePrefs _prefs; +#if defined(ESP32_PLATFORM) && defined(WIFI_SSID) + char _management_password[16] = {}; + bool _management_password_ready = false; +#endif #if COMPANION_FEATURE_NOTIFICATIONS mesh::notify::Controller _notifications{*this, *this}; bool _notification_button_down = false; diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index a976b5278..e78a92dc0 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -306,12 +306,8 @@ static void drawCompanionWiFiSetupPage(DisplayDriver& display) { display.drawTextCentered(display.width() / 2, 37, setup_ssid); char payload[256]; - const char* setup_password = nullptr; -#ifdef WEBCONFIG_AP_PASSWORD - setup_password = WEBCONFIG_AP_PASSWORD; -#endif - if (mesh::ui::buildWiFiSetupQrPayload( - payload, sizeof(payload), setup_ssid, setup_password)) { + if (mesh::ui::buildCurrentWiFiSetupQrPayload( + payload, sizeof(payload), setup_ssid)) { static constexpr int qr_size = 105; const int qr_x = (display.width() - qr_size) / 2; if (display.drawQrCode(payload, qr_x, 55, qr_size)) { diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index ccee74038..6afe4d78c 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -11903,6 +11903,20 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, ClientInfo* sender, char * // same over LoRa and serial. Keep leading whitespace intact until after the // region-load handler because it encodes region hierarchy indentation. char* command_end = command + strlen(command); +#ifdef ESP_PLATFORM + // Password bytes are significant, including spaces and invalid line breaks + // that the ESP32 setter must reject rather than silently remove. + const char* password_command = command; + while (*password_command == ' ') password_command++; + if (strlen(password_command) > 4 && password_command[2] == '|') { + password_command += 3; + } + char command_verb[10]; + strncpy(command_verb, password_command, sizeof(command_verb) - 1); + command_verb[sizeof(command_verb) - 1] = 0; + mesh::cli::normalizeCommandVerb(command_verb); + if (strcmp(command_verb, "password ") != 0) +#endif while (command_end > command && (command_end[-1] == ' ' || command_end[-1] == '\t' || command_end[-1] == '\r' || command_end[-1] == '\n')) { diff --git a/scripts/esp32_async_web_fix.py b/scripts/esp32_async_web_fix.py index 992a7d9ea..89b5c1d36 100644 --- a/scripts/esp32_async_web_fix.py +++ b/scripts/esp32_async_web_fix.py @@ -46,6 +46,11 @@ def replace_async_source(build_env, node): if not destination.exists() or destination.read_text(encoding="ascii") != content: destination.write_text(content, encoding="ascii") build_env.PrependUnique(CPPPATH=[str(include_dir)]) + if source.name == "AsyncElegantOTA.cpp": + # PlatformIO compiles libraries in cloned environments which need not + # inherit the application src include path. The current uploader uses + # the shared runtime management credential header from that directory. + build_env.AppendUnique(CPPPATH=[build_env.subst("$PROJECT_SRC_DIR")]) return build_env.File(str(destination)) diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 50063c257..e9ae3af66 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -1,6 +1,9 @@ #include "Mesh.h" #include #include +#ifdef ESP_PLATFORM +#include +#endif #include "helpers/ota/OtaFormat.h" // request types used by TempRadio relay-pressure tracking //#include #if defined(ENABLE_OTA) @@ -407,6 +410,9 @@ void Mesh::loop() { if (_ota_forwarded[0].valid && !isAnyTempRadioActive()) resetOtaForwardCache(); Dispatcher::loop(); serviceLoopMaintenance(); +#ifdef ESP_PLATFORM + esp32::managementPassword::service(millis()); +#endif #if defined(ENABLE_OTA) && defined(ESP32_PLATFORM) && \ (defined(WIFI_OTA_SEEDER) || defined(WIFI_SSID)) ota::WiFiOtaSeeder::loop(); diff --git a/src/helpers/CommonCLI.cpp b/src/helpers/CommonCLI.cpp index 3d219d2c8..a45bdd133 100644 --- a/src/helpers/CommonCLI.cpp +++ b/src/helpers/CommonCLI.cpp @@ -56,6 +56,7 @@ #define BRIDGE_MAX_BAUD 115200 #endif #ifdef ESP_PLATFORM +#include #include #include #include @@ -3046,6 +3047,11 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re #if defined(ESP_PLATFORM) && defined(ADMIN_PASSWORD) && !defined(WEBCONFIG_DISABLED) } else if (memcmp(command, "start webconfig", 15) == 0 && (command[15] == 0 || command[15] == ' ')) { + if (_prefs->password[0] + && !mesh::esp32::managementPassword::publish(_prefs->password)) { + strcpy(reply, "ERR: management password busy; retry"); + return; + } const bool force_ap = command[15] == ' ' && strcmp(&command[16], "ap") == 0; if (command[15] == ' ' && !force_ap) { strcpy(reply, "ERR: usage start webconfig [ap]"); @@ -3077,6 +3083,12 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re strcpy(reply, "ERR: usage start ota [ap]"); return; } +#ifdef ESP_PLATFORM + if (!mesh::esp32::managementPassword::publish(_prefs->password)) { + strcpy(reply, "ERR: set an admin password first, or wait for the active OTA upload"); + return; + } +#endif #if defined(WITH_ESPNOW_BRIDGE) const bool ota_was_running = _board->isOTAUpdateRunning(); // Keep an outstanding pause if an earlier resume failed. Only a @@ -3250,6 +3262,17 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re } } else if (memcmp(command, "password ", 9) == 0) { // change admin password +#ifdef ESP_PLATFORM + if (!mesh::esp32::managementPassword::validPassword(&command[9])) { + strcpy(reply, "Error: password must be 1-15 bytes, no line breaks; use 8-15 ASCII for setup WiFi"); + return; + } + mesh::esp32::managementPassword::ChangeGuard change; + if (!change.acquired()) { + strcpy(reply, "Error: OTA upload or password change busy; retry"); + return; + } +#endif char previous[sizeof(_prefs->password)]; memcpy(previous, _prefs->password, sizeof(previous)); StrHelper::strncpy(_prefs->password, &command[9], sizeof(_prefs->password)); @@ -3258,6 +3281,12 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re strcpy(reply, "Error: save unconfirmed; reboot may differ"); return; } +#ifdef ESP_PLATFORM + if (!change.publish(_prefs->password)) { + strcpy(reply, "Error: password saved; management unavailable, reboot required"); + return; + } +#endif sprintf(reply, "password now: %s", _prefs->password); // echo back just to let admin know for sure!! } else if (memcmp(command, "clear stats", 11) == 0) { _callbacks->clearStats(); diff --git a/src/helpers/ESP32Board.cpp b/src/helpers/ESP32Board.cpp index 40446149c..fbcc082dd 100644 --- a/src/helpers/ESP32Board.cpp +++ b/src/helpers/ESP32Board.cpp @@ -7,6 +7,7 @@ #include "UsbLogging.h" #include "FileRead.h" #include "UserGpioPinPolicy.h" +#include namespace mesh { namespace esp32_clock { @@ -145,7 +146,13 @@ class LightweightOTAServer { sendResponse(client, code, reason, "text/plain", error, strlen(error)); } - void receiveUpdate(WiFiClient& client, size_t total) { + void receiveUpdate(WiFiClient& client, size_t total, uint32_t auth_generation) { + mesh::esp32::managementPassword::UploadGuard upload(auth_generation); + if (!upload.acquired()) { + static const char busy[] = "password change or OTA upload in progress; retry"; + sendResponse(client, 409, "Conflict", "text/plain", busy, sizeof(busy) - 1); + return; + } if (total == 0) { static const char empty[] = "empty firmware image"; sendResponse(client, 400, "Bad Request", "text/plain", empty, sizeof(empty) - 1); @@ -208,17 +215,43 @@ class LightweightOTAServer { bool post_update = strncmp(line, "POST /update ", 13) == 0; size_t content_length = 0; + char authorization[96] = {}; + bool duplicate_authorization = false, have_authorization = false; do { if (!readLine(client, line, sizeof(line))) return; if (strncasecmp(line, "Content-Length:", 15) == 0) { content_length = static_cast(strtoul(line + 15, nullptr, 10)); + } else if (strncasecmp(line, "Authorization:", 14) == 0) { + if (have_authorization) duplicate_authorization = true; + have_authorization = true; + const char* value = line + 14; + while (*value == ' ' || *value == '\t') ++value; + if (strlen(value) >= sizeof(authorization)) duplicate_authorization = true; + else memcpy(authorization, value, strlen(value) + 1); } } while (line[0]); if (!running) return; + uint32_t generation = 0; + const auto auth = mesh::esp32::managementPassword::authenticateBasic( + duplicate_authorization ? "invalid" : authorization, millis(), &generation); + memset(authorization, 0, sizeof(authorization)); + if (auth != mesh::esp32::managementPassword::AuthResult::Authorized) { + if (auth == mesh::esp32::managementPassword::AuthResult::Unavailable) { + static const char unavailable[] = "saved admin password unavailable"; + sendResponse(client, 503, "Service Unavailable", "text/plain", unavailable, sizeof(unavailable) - 1); + } else if (auth == mesh::esp32::managementPassword::AuthResult::Throttled) { + static const char throttled[] = "too many failed logins; wait 30 seconds"; + sendResponse(client, 429, "Too Many Requests", "text/plain", throttled, sizeof(throttled) - 1); + } else { + client.print("HTTP/1.1 401 Unauthorized\r\nWWW-Authenticate: Basic realm=\"MeshCore admin\", charset=\"UTF-8\"\r\n" + "Content-Length: 0\r\nConnection: close\r\nCache-Control: no-store\r\n\r\n"); + } + return; + } if (get_page) sendPage(client); else if (get_log) sendLog(client); - else if (post_update) receiveUpdate(client, content_length); + else if (post_update) receiveUpdate(client, content_length, generation); else { static const char missing[] = "not found"; sendResponse(client, 404, "Not Found", "text/plain", missing, sizeof(missing) - 1); @@ -276,6 +309,11 @@ static LightweightOTAServer lightweight_ota_server; bool ESP32Board::startOTAUpdate(const char* id, char reply[], bool force_ap) { (void)id; + mesh::esp32::managementPassword::Snapshot credential; + if (!mesh::esp32::managementPassword::snapshot(credential) || !credential.password[0]) { + strcpy(reply, "ERR: saved admin password required for WiFi OTA"); + return false; + } if (ota_server != nullptr && !lightweight_ota_server.isRunning()) { strcpy(reply, "ERR: OTA stopping; retry stop ota first"); return false; @@ -306,7 +344,7 @@ bool ESP32Board::startOTAUpdate(const char* id, char reply[], bool force_ap) { return false; } ota_started_radio = ota_started_radio || WiFi.getMode() == WIFI_OFF; - ota_started_ap = mesh::wifi::startOpenAccessPoint("MeshCore-OTA", ota_started_ap); + ota_started_ap = mesh::wifi::startManagementAccessPoint("MeshCore-OTA", ota_started_ap); if (!ota_started_ap) { inhibit_sleep = ota_server != nullptr; if (!inhibit_sleep) { @@ -332,7 +370,12 @@ bool ESP32Board::startOTAUpdate(const char* id, char reply[], bool force_ap) { ota_server = &lightweight_ota_server; } - const char* network = use_ap ? "Join WiFi MeshCore-OTA" : "Use same WiFi/LAN"; + if (ota_started_ap) mesh::esp32::managementPassword::watchOtaAccessPoint( + this, rotateOTAAccessPoint, credential.generation); + const char* network = !use_ap ? "Use same WiFi/LAN" + : mesh::esp32::managementPassword::apPasswordEligible(credential.password) + ? "Join WiFi MeshCore-OTA (admin password)" + : "Join WiFi MeshCore-OTA (OPEN compatibility; HTTP admin login)"; if (LIGHTWEIGHT_OTA_PORT == 80) { snprintf(reply, 160, "Started: http://%s/update - WiFi on; %s", ip.toString().c_str(), network); } else { @@ -344,6 +387,10 @@ bool ESP32Board::startOTAUpdate(const char* id, char reply[], bool force_ap) { } bool ESP32Board::stopOTAUpdate(char reply[]) { + if (mesh::esp32::managementPassword::uploadActive()) { + strcpy(reply, "ERR: OTA upload active; retry stop ota after it finishes"); + return false; + } if (ota_server == nullptr) { if (ota_started_ap) WiFi.softAPdisconnect(true); ota_started_ap = false; @@ -359,6 +406,7 @@ bool ESP32Board::stopOTAUpdate(char reply[]) { return false; } ota_server = nullptr; + mesh::esp32::managementPassword::forgetOtaAccessPoint(this); if (ota_started_ap) WiFi.softAPdisconnect(true); ota_started_ap = false; mesh::wifi::stopTemporaryAccessPointRadio(ota_started_radio); @@ -385,6 +433,11 @@ bool ESP32Board::stopOTAUpdate(char reply[]) { static AsyncWebServer* async_ota_host = nullptr; bool ESP32Board::startOTAUpdate(const char* id, char reply[], bool force_ap) { + mesh::esp32::managementPassword::Snapshot credential; + if (!mesh::esp32::managementPassword::snapshot(credential) || !credential.password[0]) { + strcpy(reply, "ERR: saved admin password required for WiFi OTA"); + return false; + } if (!mesh::wireless::control().allowWiFiForOTA()) { strcpy(reply, "ERR: wireless change pending; retry start ota"); return false; @@ -409,7 +462,7 @@ bool ESP32Board::startOTAUpdate(const char* id, char reply[], bool force_ap) { return false; } ota_started_radio = ota_started_radio || WiFi.getMode() == WIFI_OFF; - ota_started_ap = mesh::wifi::startOpenAccessPoint("MeshCore-OTA", ota_started_ap); + ota_started_ap = mesh::wifi::startManagementAccessPoint("MeshCore-OTA", ota_started_ap); if (!ota_started_ap) { inhibit_sleep = ota_server != nullptr; if (!inhibit_sleep) { @@ -422,8 +475,11 @@ bool ESP32Board::startOTAUpdate(const char* id, char reply[], bool force_ap) { ip = WiFi.softAPIP(); } - snprintf(reply, 160, "Started: http://%s/update - WiFi on; %s", ip.toString().c_str(), - use_ap ? "Join WiFi MeshCore-OTA" : "Use same WiFi/LAN"); + const char* network = !use_ap ? "Use same WiFi/LAN" + : mesh::esp32::managementPassword::apPasswordEligible(credential.password) + ? "Join WiFi MeshCore-OTA (admin password)" + : "Join WiFi MeshCore-OTA (OPEN compatibility; HTTP admin login)"; + snprintf(reply, 160, "Started: http://%s/update - WiFi on; %s", ip.toString().c_str(), network); MESH_DEBUG_PRINTLN("startOTAUpdate: %s", reply); // Select the requested network even when the HTTP listener already exists. @@ -434,6 +490,8 @@ bool ESP32Board::startOTAUpdate(const char* id, char reply[], bool force_ap) { strcpy(reply, "ERR: OTA server failed; retry start ota"); return false; } + if (ota_started_ap) mesh::esp32::managementPassword::watchOtaAccessPoint( + this, rotateOTAAccessPoint, credential.generation); return true; } @@ -454,11 +512,14 @@ bool ESP32Board::startOTAUpdate(const char* id, char reply[], bool force_ap) { return false; } async_ota_host->on("/", HTTP_GET, [](AsyncWebServerRequest *request) { + if (!AsyncElegantOTA.authenticateRequest(request)) return; request->send(200, "text/html", home_buf); }); async_ota_host->on("/log", HTTP_GET, [](AsyncWebServerRequest *request) { + if (!AsyncElegantOTA.authenticateRequest(request)) return; request->send(SPIFFS, "/packet_log", "text/plain"); }); + AsyncElegantOTA.useManagementPassword(); AsyncElegantOTA.begin(async_ota_host); } ota_server = async_ota_host; @@ -479,10 +540,16 @@ bool ESP32Board::startOTAUpdate(const char* id, char reply[], bool force_ap) { return false; } + if (ota_started_ap) mesh::esp32::managementPassword::watchOtaAccessPoint( + this, rotateOTAAccessPoint, credential.generation); return true; } bool ESP32Board::stopOTAUpdate(char reply[]) { + if (mesh::esp32::managementPassword::uploadActive()) { + strcpy(reply, "ERR: OTA upload active; retry stop ota after it finishes"); + return false; + } if (ota_server == nullptr) { if (ota_started_ap) WiFi.softAPdisconnect(true); ota_started_ap = false; @@ -499,6 +566,7 @@ bool ESP32Board::stopOTAUpdate(char reply[]) { } ota_server->end(); ota_server = nullptr; + mesh::esp32::managementPassword::forgetOtaAccessPoint(this); if (ota_started_ap) WiFi.softAPdisconnect(true); ota_started_ap = false; mesh::wifi::stopTemporaryAccessPointRadio(ota_started_radio); @@ -521,6 +589,26 @@ bool ESP32Board::stopOTAUpdate(char reply[]) { } #endif +#if (defined(LIGHTWEIGHT_WIFI_OTA) && (defined(ADMIN_PASSWORD) || defined(COMPANION_RADIO_FULL))) \ + || (defined(ADMIN_PASSWORD) && !defined(DISABLE_WIFI_OTA)) +bool ESP32Board::rotateOTAAccessPoint(void* context) { + auto* owner = static_cast(context); + if (!owner->ota_server || !owner->ota_started_ap) { + mesh::esp32::managementPassword::forgetOtaAccessPoint(owner); + return true; + } + if (!mesh::wifi::startManagementAccessPoint("MeshCore-OTA", false)) { + // A failed rekey must not leave an AP accepting the previous secret. + WiFi.softAPdisconnect(true); + owner->ota_started_ap = false; + char reply[160]; + owner->stopOTAUpdate(reply); + mesh::esp32::managementPassword::forgetOtaAccessPoint(owner); + } + return true; +} +#endif + // --------------------------------------------------------------------------- // Manifest-driven pull OTA (observer / MQTT-bridge builds only) // diff --git a/src/helpers/ESP32Board.h b/src/helpers/ESP32Board.h index febcfe558..1a2e3690e 100644 --- a/src/helpers/ESP32Board.h +++ b/src/helpers/ESP32Board.h @@ -314,6 +314,7 @@ public: } bool startOTAUpdate(const char* id, char reply[], bool force_ap = false) override; + static bool rotateOTAAccessPoint(void* owner); bool stopOTAUpdate(char reply[]) override; bool isOTAUpdateRunning() const override { return ota_server != nullptr; } bool otaFromManifest(const char* manifest_base, const char* current_ver, bool dry_run, char reply[]) override; diff --git a/src/helpers/WebConfigBatch.h b/src/helpers/WebConfigBatch.h index dd58b1016..c932cda98 100644 --- a/src/helpers/WebConfigBatch.h +++ b/src/helpers/WebConfigBatch.h @@ -46,6 +46,7 @@ static const uint32_t kRebootConfirmMs = 3000; // .cpp:784 first result-read static const uint32_t kSetupWiFiConnectTimeoutMs = 20000; static const uint32_t kSetupHandoffRebootConfirmMs = 1000; static const uint32_t kStopWarnMs = 10000; // .h:95 STOP_WARN_MS +static const uint32_t kReauthReceiptMs = 120000; static const uint32_t kFullSetupApWindowMs = 30UL * 60UL * 1000UL; // The batch lifecycle. A fresh POST moves Idle->Pending; the drainer moves diff --git a/src/helpers/WiFiSetupPortal.cpp b/src/helpers/WiFiSetupPortal.cpp index ca7cb9005..1ddfab581 100644 --- a/src/helpers/WiFiSetupPortal.cpp +++ b/src/helpers/WiFiSetupPortal.cpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace { @@ -41,6 +42,9 @@ struct PortalImpl { uint32_t next_recovery_at = 0; uint32_t recovery_deadline = 0; bool recovery_connecting = false; + uint32_t ap_password_generation = 0; + uint32_t rekey_generation = 0; + uint32_t rekey_at = 0; }; static bool readLine(WiFiClient& client, char* line, size_t capacity) { @@ -223,14 +227,53 @@ static void handleClient(PortalImpl* impl, WiFiClient& client) { bool post_save = strncmp(line, "POST /save ", 11) == 0; bool get_request = strncmp(line, "GET ", 4) == 0; size_t content_length = 0; + char authorization[96] = {}; + bool has_authorization = false; do { if (!readLine(client, line, sizeof(line))) return; if (strncasecmp(line, "Content-Length:", 15) == 0) { content_length = static_cast(strtoul(line + 15, nullptr, 10)); + } else if (strncasecmp(line, "Authorization:", 14) == 0) { + const char* value = line + 14; + while (*value == ' ' || *value == '\t') ++value; + if (has_authorization || strlen(value) >= sizeof(authorization)) { + strcpy(authorization, "invalid"); + } else { + memcpy(authorization, value, strlen(value) + 1); + } + has_authorization = true; } } while (line[0]); + using namespace mesh::esp32::managementPassword; + uint32_t authenticated_generation = 0; + const AuthResult auth = authenticateBasic(authorization, millis(), &authenticated_generation); + memset(authorization, 0, sizeof(authorization)); + if (auth != AuthResult::Authorized) { + if (auth == AuthResult::Throttled) { + sendResponse(client, 429, "Too Many Requests", "text/plain", "Wait 30 seconds before signing in again."); + } else if (auth == AuthResult::Unavailable) { + sendResponse(client, 503, "Service Unavailable", "text/plain", "Set the node admin password on USB, then restart setup WiFi."); + } else { + static const char message[] = "Sign in as admin using the node admin password."; + client.printf("HTTP/1.1 401 Unauthorized\r\nWWW-Authenticate: Basic realm=\"MeshCore\", charset=\"UTF-8\"\r\n" + "Content-Type: text/plain\r\nContent-Length: %u\r\nCache-Control: no-store\r\nConnection: close\r\n\r\n%s", + static_cast(sizeof(message) - 1), message); + } + return; + } + if (post_save) { + // Keep the accepted request bound to the authenticated credential while + // association and persistence run. A concurrent password change retries + // after this operation rather than authorizing a stale request midway. + ChangeGuard request; + Snapshot current; + if (!request.acquired() || !snapshot(current) + || current.generation != authenticated_generation) { + sendResponse(client, 409, "Conflict", "text/plain", "Settings changed or are busy; sign in again and retry."); + return; + } if (content_length == 0 || content_length >= 256) { sendResponse(client, 400, "Bad Request", "text/plain", "Invalid form data."); return; @@ -260,6 +303,25 @@ static void portalTask(void* arg) { PortalImpl* impl = static_cast(arg); while (impl->active && *impl->active) { impl->dns.processNextRequest(); + { + using namespace mesh::esp32::managementPassword; + Snapshot current; + if (snapshot(current) && current.generation != impl->ap_password_generation) { + if (impl->rekey_generation != current.generation) { + impl->rekey_generation = current.generation; + impl->rekey_at = millis(); + } else if (uint32_t(millis() - impl->rekey_at) >= 750U) { + ChangeGuard rekey; + if (rekey.acquired()) { + if (!snapshot(current)) break; + if (!mesh::wifi::startManagementAccessPoint(impl->ap_name, false)) break; + impl->ap_password_generation = current.generation; + impl->rekey_generation = 0; + mesh::usbLoggingPort().println("Setup WiFi updated; reconnect using the admin password"); + } + } + } + } WiFiClient client = impl->server.available(); if (client) { client.setTimeout(5000); @@ -324,6 +386,10 @@ bool WiFiSetupPortal::begin(const char* ap_name, SaveCallback save_callback, voi _impl = impl; } if (impl->task != nullptr) return false; + mesh::esp32::managementPassword::ChangeGuard start; + if (!start.acquired()) return false; + mesh::esp32::managementPassword::Snapshot admin; + if (!mesh::esp32::managementPassword::snapshot(admin) || !admin.password[0]) return false; impl->save_callback = save_callback; impl->callback_context = context; @@ -337,12 +403,14 @@ bool WiFiSetupPortal::begin(const char* ap_name, SaveCallback save_callback, voi impl->ap_name[sizeof(impl->ap_name) - 1] = 0; impl->started_radio = WiFi.getMode() == WIFI_OFF; - if (!mesh::wifi::startOpenAccessPoint(impl->ap_name, false)) { + if (!mesh::wifi::startManagementAccessPoint(impl->ap_name, false)) { WiFi.softAPdisconnect(true); mesh::wifi::stopTemporaryAccessPointRadio(impl->started_radio); impl->started_radio = false; return false; } + impl->ap_password_generation = admin.generation; + impl->rekey_generation = 0; if (!impl->dns.start(53, "*", SETUP_IP)) { WiFi.softAPdisconnect(true); mesh::wifi::stopTemporaryAccessPointRadio(impl->started_radio); diff --git a/src/helpers/WiFiSetupPortal.h b/src/helpers/WiFiSetupPortal.h index dfed50a6d..9c27dcb97 100644 --- a/src/helpers/WiFiSetupPortal.h +++ b/src/helpers/WiFiSetupPortal.h @@ -11,8 +11,9 @@ public: WiFiSetupPortal(); - // Starts an open setup AP and captive HTTP form. The AP remains available - // after a failed association and shuts down shortly after a successful one. + // Starts a setup AP and captive HTTP form using the saved admin password. + // Legacy short passwords retain open WiFi plus authenticated HTTP. The AP + // stays available after a failed association and closes after success. bool begin(const char* ap_name, SaveCallback save_callback, void* context); void stop(); // Retry interval is the steady-state cadence. initial_delay_ms defaults to diff --git a/src/helpers/esp32/CompanionAdminPassword.h b/src/helpers/esp32/CompanionAdminPassword.h new file mode 100644 index 000000000..b67aa49d2 --- /dev/null +++ b/src/helpers/esp32/CompanionAdminPassword.h @@ -0,0 +1,78 @@ +#pragma once + +#if defined(ESP32_PLATFORM) && defined(WIFI_SSID) + +#include +#include +#include + +namespace mesh { namespace esp32 { + +// ESP32 Companion management credentials are separate from the fixed binary +// Companion preferences image. Existing identities, contacts and wire offsets +// do not change when management authentication is added. +namespace companionAdminPassword { +static constexpr size_t CAPACITY = 16; + +inline bool valid(const char* value) { + if (!value) return false; + const size_t length = strnlen(value, CAPACITY); + if (length == 0 || length >= CAPACITY) return false; + for (size_t i = 0; i < length; ++i) { + if (value[i] == '\r' || value[i] == '\n') return false; + } + return true; +} + +inline bool load(char (&out)[CAPACITY], const char* factory_password) { + memset(out, 0, sizeof(out)); + Preferences prefs; + if (!prefs.begin("mesh-admin", false)) return false; + const bool has_password = prefs.isKey("password"); + const bool has_pending = prefs.isKey("pending"); + bool ok = !has_pending || (prefs.getType("pending") == PT_U8 + && prefs.getUChar("pending", 1) == 0); + if (ok && !has_password && !has_pending) { + ok = valid(factory_password); + if (ok) memcpy(out, factory_password, strlen(factory_password) + 1); + } else if (ok && has_password && prefs.getType("password") == PT_STR) { + const size_t count = prefs.getString("password", out, sizeof(out)); + ok = count > 1 && count <= sizeof(out) && out[count - 1] == 0 + && count == strnlen(out, sizeof(out)) + 1 && valid(out); + } else { + ok = false; + } + prefs.end(); + if (!ok) memset(out, 0, sizeof(out)); + return ok; +} + +inline bool save(const char* password) { + if (!valid(password)) return false; + Preferences prefs; + if (!prefs.begin("mesh-admin", false)) return false; + // Each NVS operation commits. An interrupted multi-key change must not + // reopen the web interface using a guessed factory or half-saved password. + bool ok = prefs.putUChar("pending", 1) == 1 + && prefs.getUChar("pending", 0) == 1; + char verified[CAPACITY] = {}; + if (ok) { + const size_t length = strlen(password); + ok = prefs.putString("password", password) == length + && prefs.getType("password") == PT_STR + && prefs.getString("password", verified, sizeof(verified)) == length + 1 + && memcmp(verified, password, length + 1) == 0; + } + if (ok) { + ok = prefs.putUChar("pending", 0) == 1 + && prefs.getUChar("pending", 1) == 0; + } + prefs.end(); + memset(verified, 0, sizeof(verified)); + return ok; +} + +} // namespace companionAdminPassword +} } // namespace mesh::esp32 + +#endif diff --git a/src/helpers/esp32/ManagementPassword.h b/src/helpers/esp32/ManagementPassword.h new file mode 100644 index 000000000..dae5d68a8 --- /dev/null +++ b/src/helpers/esp32/ManagementPassword.h @@ -0,0 +1,261 @@ +#pragma once + +#include +#include +#include + +#if defined(MESH_MANAGEMENT_PASSWORD_HOST_TEST) +#include +#elif defined(ESP_PLATFORM) || defined(ESP32_PLATFORM) +#include +#endif + +namespace mesh { +namespace esp32 { +namespace managementPassword { + +// The wire/prefs field is sixteen bytes, including its terminator. Do not +// silently truncate a new secret or change an existing node's credential. +inline bool validPassword(const char* value) { + if (!value) return false; + size_t n = 0; + while (n < 16 && value[n]) { + if (value[n] == '\r' || value[n] == '\n') return false; + ++n; + } + return n != 0 && n < 16; +} + +inline bool apPasswordEligible(const char* value) { + if (!validPassword(value)) return false; + size_t n = 0; + for (; value[n]; ++n) { + const unsigned char c = static_cast(value[n]); + if (c < 0x20 || c > 0x7e) return false; + } + return n >= 8; +} + +// Exact, bounded HTTP Basic credentials: fixed username admin. +inline bool basicAuthorizationMatches(const char* authorization, const char* password) { + if (!validPassword(password)) return false; + char input[22] = "admin:"; + memcpy(input + 6, password, strlen(password)); + static const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + char expected[35] = "Basic "; + size_t out = 6; + const size_t length = 6 + strlen(password); + for (size_t i = 0; i < length; i += 3) { + const uint32_t bits = (uint32_t(uint8_t(input[i])) << 16) + | (i + 1 < length ? uint32_t(uint8_t(input[i + 1])) << 8 : 0) + | (i + 2 < length ? uint8_t(input[i + 2]) : 0); + expected[out++] = alphabet[bits >> 18]; expected[out++] = alphabet[(bits >> 12) & 63]; + expected[out++] = i + 1 < length ? alphabet[(bits >> 6) & 63] : '='; + expected[out++] = i + 2 < length ? alphabet[bits & 63] : '='; + } + expected[out] = 0; + size_t supplied = 0; + if (authorization) while (supplied < sizeof(expected) && authorization[supplied]) ++supplied; + uint8_t difference = supplied == out ? 0 : 1; + for (size_t i = 0; i < out; ++i) { + unsigned char actual = i < supplied ? static_cast(authorization[i]) : 0; + // HTTP auth scheme names are case-insensitive; the Base64 value is not. + if (i < 5 && actual >= 'a' && actual <= 'z') actual -= 'a' - 'A'; + unsigned char wanted = static_cast(expected[i]); + if (i < 5 && wanted >= 'a' && wanted <= 'z') wanted -= 'a' - 'A'; + difference |= actual ^ wanted; + } + memset(input, 0, sizeof(input)); memset(expected, 0, sizeof(expected)); + return difference == 0; +} + +#if defined(ESP_PLATFORM) || defined(ESP32_PLATFORM) || defined(MESH_MANAGEMENT_PASSWORD_HOST_TEST) +struct Snapshot { + char password[16] = {}; + uint32_t generation = 0; +}; + +namespace detail { +struct State { +#if defined(MESH_MANAGEMENT_PASSWORD_HOST_TEST) + std::mutex mutex; +#else + portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED; +#endif + Snapshot current; + bool changing = false, uploading = false, rotating = false; + uint8_t failures = 0; + uint32_t failure_window = 0; + void* ap_owner = nullptr; + bool (*rotate_ap)(void*) = nullptr; + uint32_t ap_generation = 0, pending_generation = 0, pending_at = 0; +}; +// An inline function's local static is shared across translation units. The +// mirror is published only by the loop owner after a confirmed persistent save; +// HTTP tasks never read a mutable prefs struct or a factory-password macro. +inline State& state() { static State value; return value; } +class Lock { + State& value; +public: + explicit Lock(State& s) : value(s) { +#if defined(MESH_MANAGEMENT_PASSWORD_HOST_TEST) + value.mutex.lock(); +#else + portENTER_CRITICAL(&value.mutex); +#endif + } + ~Lock() { +#if defined(MESH_MANAGEMENT_PASSWORD_HOST_TEST) + value.mutex.unlock(); +#else + portEXIT_CRITICAL(&value.mutex); +#endif + } +}; +inline void assign(State& s, const char* password) { + if (s.current.generation && strcmp(s.current.password, password) == 0) return; + memset(s.current.password, 0, sizeof(s.current.password)); + memcpy(s.current.password, password, strlen(password)); + if (++s.current.generation == 0) ++s.current.generation; + s.failures = 0; +} +} // namespace detail + +inline bool snapshot(Snapshot& out) { + detail::State& s = detail::state(); + detail::Lock lock(s); + out = s.current; + return out.generation != 0; +} +inline bool available() { Snapshot value; return snapshot(value) && value.password[0] != 0; } + +// Boot/load only: retain an explicitly empty legacy credential for services +// whose historical policy is passwordless. OTA still requires available(). +// Never replace an already-published value with a later mutable prefs snapshot. +inline bool initialize(const char* saved_password) { + if (!saved_password || (saved_password[0] && !validPassword(saved_password))) return false; + detail::State& s = detail::state(); detail::Lock lock(s); + if (s.current.generation) return strcmp(s.current.password, saved_password) == 0; + if (s.changing || s.uploading || s.rotating) return false; + detail::assign(s, saved_password); + return true; +} + +inline bool publish(const char* saved_password) { + if (!validPassword(saved_password)) return false; + detail::State& s = detail::state(); + detail::Lock lock(s); + if (strcmp(s.current.password, saved_password) == 0) return true; + if (s.changing || s.uploading || s.rotating) return false; + detail::assign(s, saved_password); + return true; +} + +// Reserve before changing RAM or saving, so a new upload cannot slip between +// an upload-busy check and publication. A failed save simply releases the guard. +class ChangeGuard { + bool held = false; +public: + ChangeGuard() { + detail::State& s = detail::state(); detail::Lock lock(s); + if (!s.changing && !s.uploading && !s.rotating) held = s.changing = true; + } + ChangeGuard(const ChangeGuard&) = delete; + ChangeGuard& operator=(const ChangeGuard&) = delete; + bool acquired() const { return held; } + bool publish(const char* saved_password) { + if (!held || !validPassword(saved_password)) return false; + detail::State& s = detail::state(); detail::Lock lock(s); + detail::assign(s, saved_password); + return true; + } + ~ChangeGuard() { + if (held) { detail::State& s = detail::state(); detail::Lock lock(s); s.changing = false; } + } +}; + +inline bool beginUpload(uint32_t authenticated_generation) { + detail::State& s = detail::state(); detail::Lock lock(s); + if (!authenticated_generation || authenticated_generation != s.current.generation + || s.changing || s.uploading || s.rotating) return false; + s.uploading = true; + return true; +} +inline void endUpload() { + detail::State& s = detail::state(); detail::Lock lock(s); s.uploading = false; +} +inline bool uploadActive() { + detail::State& s = detail::state(); detail::Lock lock(s); return s.uploading; +} +class UploadGuard { + bool held; +public: + explicit UploadGuard(uint32_t generation) : held(beginUpload(generation)) {} + UploadGuard(const UploadGuard&) = delete; + UploadGuard& operator=(const UploadGuard&) = delete; + bool acquired() const { return held; } + ~UploadGuard() { if (held) endUpload(); } +}; + +enum class AuthResult : uint8_t { Authorized, Unauthorized, Unavailable, Throttled }; + +// Compare the bounded Basic value rather than storing decoded credentials. +// The browser's normal HTTP Basic prompt/cache also covers same-origin XHR. +inline AuthResult authenticateBasic(const char* authorization, uint32_t now, + uint32_t* generation = nullptr) { + Snapshot current; + if (!snapshot(current) || !current.password[0]) return AuthResult::Unavailable; + { + detail::State& s = detail::state(); detail::Lock lock(s); + if (uint32_t(now - s.failure_window) >= 30000U) { s.failures = 0; s.failure_window = now; } + if (s.failures >= 5) return AuthResult::Throttled; + } + const bool matches = basicAuthorizationMatches(authorization, current.password); + detail::State& s = detail::state(); detail::Lock lock(s); + if (s.current.generation != current.generation) return AuthResult::Unauthorized; + if (!matches) { + // A browser's first unauthenticated request triggers its login prompt and + // is not a guess. Count only a supplied, rejected Authorization header. + if (authorization && authorization[0]) { + if (!s.failures) s.failure_window = now; + if (s.failures < 5) ++s.failures; + } + return AuthResult::Unauthorized; + } + s.failures = 0; + if (generation) *generation = current.generation; + return AuthResult::Authorized; +} + +inline void watchOtaAccessPoint(void* owner, bool (*rotate)(void*), uint32_t generation) { + detail::State& s = detail::state(); detail::Lock lock(s); + s.ap_owner = owner; s.rotate_ap = rotate; s.ap_generation = generation; s.pending_generation = 0; +} +inline void forgetOtaAccessPoint(void* owner) { + detail::State& s = detail::state(); detail::Lock lock(s); + if (s.ap_owner == owner) { s.ap_owner = nullptr; s.rotate_ap = nullptr; } +} +// Called on the mesh loop. Rekey only this OTA owner's AP after the password +// command's reply has had time to leave; do not race an accepted flash upload. +inline void service(uint32_t now) { + void* owner; bool (*rotate)(void*); uint32_t generation; + { + detail::State& s = detail::state(); detail::Lock lock(s); + if (!s.ap_owner || !s.rotate_ap || s.ap_generation == s.current.generation) return; + if (s.pending_generation != s.current.generation) { + s.pending_generation = s.current.generation; s.pending_at = now; return; + } + if (uint32_t(now - s.pending_at) < 750U || s.changing || s.uploading || s.rotating) return; + s.rotating = true; owner = s.ap_owner; rotate = s.rotate_ap; generation = s.current.generation; + } + const bool done = rotate(owner); + { + detail::State& s = detail::state(); detail::Lock lock(s); + s.rotating = false; + if (done && s.ap_owner == owner && s.current.generation == generation) s.ap_generation = generation; + } +} +#endif +} // namespace managementPassword +} // namespace esp32 +} // namespace mesh diff --git a/src/helpers/esp32/WebConfigHtml.h b/src/helpers/esp32/WebConfigHtml.h index b5a4ab944..488b939f9 100644 --- a/src/helpers/esp32/WebConfigHtml.h +++ b/src/helpers/esp32/WebConfigHtml.h @@ -1,2194 +1,2298 @@ // Auto-generated by scripts/generate_webconfig_html.py from webui/index.html // DO NOT EDIT - edit webui/index.html instead. // Compressed with Google Zopfli 0.4.3 (gzip, 1000 iterations). -// shipped-page-sha256: 6e2d2c2378ddb84f92c5e213278358158d3ecf1eb039914f4246ba002d569c47 +// shipped-page-sha256: 59a76d0c86d87978b73b3db48b9384632bdefdc69f02496e05a273a478908371 #pragma once #include #include -const uint32_t WEBCONFIG_HTML_GZ_LEN = 34316; -const char WEBCONFIG_HTML_ETAG[] = "\"c2a35cb2d2c12262\""; -const char WEBCONFIG_HTML_VERSION[] = "7816a749e5ac22d6"; -const uint16_t WEBCONFIG_HTML_LOADER_LEN = 462; +const uint32_t WEBCONFIG_HTML_GZ_LEN = 35969; +const char WEBCONFIG_HTML_ETAG[] = "\"06006d54de09bac0\""; +const char WEBCONFIG_HTML_VERSION[] = "01b4325be073ed36"; +const uint16_t WEBCONFIG_HTML_LOADER_LEN = 461; const uint16_t WEBCONFIG_HTML_SUCCESS_LEN = 65; const uint8_t WEBCONFIG_HTML_LOADER[] PROGMEM = { - 0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00,0x02,0xff,0x75,0x52,0xc7,0x92,0xdb,0x30, - 0x0c,0xfd,0x15,0x66,0xab,0xe8,0x6e,0x6f,0x5f,0x89,0x4e,0xd1,0xe4,0x94,0xde,0xcf, - 0x34,0x05,0x59,0x9c,0xd0,0x80,0x06,0x82,0xac,0x6d,0xfa,0xf7,0xc4,0x2d,0x3d,0xb8, - 0xa0,0xf7,0x97,0x3c,0xca,0xc8,0xc9,0x6d,0x09,0xaa,0x90,0x45,0x98,0x26,0x0b,0x10, - 0xab,0x5c,0x61,0xb9,0x02,0x31,0xb5,0xe4,0xfd,0xcb,0xad,0x0d,0xed,0x02,0xcc,0xd2, - 0x43,0x53,0x12,0x8b,0x72,0x84,0x02,0x28,0x66,0xaf,0xf1,0x99,0x14,0x26,0x83,0xa5, - 0x77,0xd0,0x5f,0x2b,0x3d,0x8f,0x5e,0xbc,0x0d,0xfd,0xca,0xd9,0x00,0x66,0xbc,0x37, - 0x4d,0xc4,0x4b,0x80,0xe9,0x2b,0xa8,0x8a,0x94,0x18,0xd4,0x17,0x98,0xa5,0x84,0xb9, - 0x9f,0x27,0xc3,0x8d,0x27,0x99,0x51,0x76,0x3b,0x7d,0x49,0x36,0xf3,0x38,0x57,0x7f, - 0xc7,0x1d,0x15,0x10,0x82,0x2f,0xe3,0xa4,0x72,0xec,0x4b,0x99,0x46,0x79,0x8d,0x4e, - 0x3c,0x61,0xa4,0xef,0x97,0x96,0x15,0x9a,0x51,0xbc,0x33,0xa9,0x40,0x36,0xdb,0xda, - 0x53,0xd3,0x78,0xcc,0xa8,0x19,0x3c,0x9d,0x11,0x4b,0x4a,0x28,0x4c,0x21,0x00,0xf7, - 0x9c,0x49,0x8f,0x8e,0x10,0x1a,0x95,0x46,0xba,0x27,0xc6,0x1d,0x1d,0x55,0x20,0x1f, - 0xfd,0x02,0xa8,0x96,0x5f,0x8b,0xbb,0x81,0x5d,0x65,0x46,0xba,0xed,0x5d,0x8d,0xbe, - 0x93,0x8e,0x73,0x10,0x57,0x44,0x7b,0xc3,0xda,0x3f,0x5e,0x9a,0x8b,0xcb,0xf1,0xb9, - 0xbd,0x38,0xbd,0x82,0x33,0xeb,0x26,0x93,0xec,0x7c,0xaf,0xe7,0x1e,0xdf,0x57,0x7e, - 0x8e,0x36,0x5c,0xbb,0xc1,0x46,0x68,0xaf,0xef,0x5b,0x3d,0x90,0x02,0xf0,0x67,0x61, - 0xd6,0xf7,0x3e,0x8f,0x78,0x40,0x5f,0x35,0x83,0xd4,0x8c,0x8a,0x07,0x02,0x37,0x12, - 0xe9,0x78,0x6d,0xaf,0xc4,0x4a,0x5d,0x19,0x63,0x4e,0x47,0x57,0xfa,0x3e,0x90,0xb3, - 0xab,0xb4,0x01,0xc3,0x66,0xb7,0x78,0x9b,0x84,0x75,0x08,0xad,0x14,0x4c,0x8d,0x7a, - 0xce,0x4c,0x1c,0xed,0x09,0x5b,0xac,0x72,0x60,0x95,0x5b,0x1f,0x20,0xdb,0xd3,0x7f, - 0xb5,0x2e,0xd7,0xad,0x45,0xbb,0x00,0x96,0x77,0x1b,0xcb,0xba,0x6f,0x69,0x8c,0x59, - 0x95,0xdc,0xce,0x14,0x67,0xe4,0xea,0x05,0xa0,0x0c,0xa8,0x04,0x8c,0xf4,0x4f,0xbd, - 0x61,0x2f,0x10,0x95,0xbf,0x58,0x5c,0xa0,0x0a,0x56,0x57,0xfa,0xd1,0x07,0xfe,0xdf, - 0xa7,0xdb,0xc5,0xe4,0x44,0xff,0x72,0xf0,0xd5,0x56,0xbd,0xb3,0xd1,0xa8,0x83,0x3a, - 0x86,0x50,0x81,0xfa,0x51,0x77,0x85,0x8b,0xf5,0x65,0xd2,0x1d,0xde,0x3e,0xa1,0x9d, - 0x05,0x50,0x42,0xeb,0x3f,0xff,0x84,0xc8,0xb5,0xda,0xeb,0x42,0x77,0x6f,0xa0,0xde, - 0xc3,0xda,0x21,0xa4,0x18,0x84,0x6f,0x07,0x7b,0xad,0x6e,0x37,0x67,0x6b,0x75,0xa4, - 0x93,0xe1,0x16,0x42,0xdf,0x00,0x67,0x52,0xf6,0x73,0xf8,0x02,0x00,0x00, + 0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00,0x02,0xff,0x75,0x52,0x57,0xb7,0x9b,0x30, + 0x0c,0xfe,0x2b,0xee,0x9d,0x38,0x83,0x70,0xf7,0x00,0xa7,0x83,0xd3,0xa7,0xee,0xfd, + 0x6c,0x8c,0x08,0x3e,0x75,0x2c,0x8e,0x2c,0xc2,0x5d,0xfc,0xf7,0x36,0xab,0xbb,0x7a, + 0xd1,0xde,0x5f,0xf6,0xa8,0x44,0xc3,0xb7,0x0d,0x88,0x9a,0xe7,0x6e,0x9a,0xcd,0x81, + 0xb5,0x30,0xb5,0xa6,0x00,0xac,0x5a,0xae,0xc6,0x97,0x1b,0x9b,0xd7,0x73,0x50,0x0b, + 0x0b,0x5d,0x83,0xc4,0xc2,0xa0,0x67,0xf0,0xac,0x76,0x3a,0x5b,0x72,0xad,0x4a,0x58, + 0x58,0x03,0xe3,0x95,0x32,0xb2,0xde,0xb2,0xd5,0x6e,0x1c,0x8c,0x76,0xa0,0x8e,0x76, + 0xa6,0x19,0x5b,0x76,0x30,0x7d,0x05,0xa1,0xce,0x91,0x40,0x7c,0x81,0x22,0x47,0x5f, + 0xd9,0x59,0x36,0x59,0x7b,0xb2,0x02,0xcb,0xdb,0xe9,0x4b,0xd4,0xa5,0xf5,0x33,0xf1, + 0x77,0xdc,0x41,0x0d,0xce,0xd9,0x26,0xcd,0x82,0x21,0xdb,0xf0,0x34,0xaa,0x5a,0x6f, + 0xd8,0xa2,0x8f,0xe4,0xfd,0x42,0x93,0xf0,0x2a,0x49,0xb7,0x26,0xe1,0x50,0x97,0x1b, + 0x7b,0xae,0x3a,0xeb,0x4b,0xec,0xe2,0xa7,0x05,0x12,0xe7,0xe8,0x99,0xd0,0x39,0xa0, + 0x91,0x51,0xf9,0xc1,0x81,0x87,0x4e,0xe4,0x91,0x1c,0xb1,0x32,0x07,0x07,0x01,0xf8, + 0xa3,0x9d,0x03,0xb6,0xfc,0x6b,0x71,0x13,0xeb,0x65,0x66,0x24,0xfb,0xd1,0x55,0xf2, + 0x9d,0x64,0x5a,0x01,0x9b,0x3a,0xda,0x99,0xb4,0xf6,0xf1,0x42,0x25,0x47,0xc5,0xe9, + 0xc9,0xf1,0x59,0x01,0xc9,0xc5,0x09,0x94,0x27,0xe7,0x3b,0x23,0xf3,0xf8,0x3e,0xd8, + 0x99,0xd7,0xee,0xda,0xc4,0x6b,0xa1,0xbf,0xbe,0xef,0x65,0xcc,0x35,0xf8,0x9f,0x85, + 0x49,0xde,0xdb,0x2a,0xa2,0x18,0xbf,0x4a,0x02,0x6e,0xc9,0x0b,0x8a,0x19,0x6e,0x38, + 0x92,0xe9,0xca,0x1e,0x58,0x73,0x1b,0x94,0x52,0xa7,0xc9,0x95,0xbc,0x77,0x68,0xf4, + 0x32,0x2d,0x26,0x58,0xef,0x96,0x6e,0x92,0x7c,0xeb,0x5c,0xcf,0x35,0x61,0x27,0x9e, + 0x13,0x21,0x45,0x3b,0x4c,0xda,0x87,0x0a,0x48,0x54,0xda,0x3a,0x28,0x77,0xe4,0x5f, + 0xad,0x9b,0x55,0x6b,0x96,0xc6,0x81,0xa6,0xed,0xc6,0xbc,0xea,0xdb,0x28,0xa5,0x96, + 0x25,0x37,0x33,0xa5,0x25,0x9a,0x76,0x0e,0x9e,0x63,0x6c,0xc0,0x47,0xf2,0xa7,0xde, + 0x91,0x65,0x88,0x9a,0x5f,0x2c,0xc6,0x61,0x80,0xe5,0x95,0x7e,0xf4,0x81,0xff,0xf7, + 0x19,0x0e,0x7d,0x76,0x22,0x7f,0x39,0xf8,0x72,0xab,0xd1,0x59,0x92,0x0c,0xbc,0x4c, + 0xc1,0x05,0x10,0x3f,0xea,0x2e,0x71,0xb1,0xba,0x4c,0xbe,0xc5,0xdb,0x27,0xaf,0x0b, + 0x07,0x82,0x71,0xf5,0xe7,0x9f,0x10,0xb9,0x16,0x3b,0x43,0x18,0xee,0xc4,0xe2,0x3d, + 0xac,0x1c,0x8c,0x82,0x80,0xe9,0x36,0xde,0xe9,0x65,0xbf,0x3e,0x5b,0x2f,0x23,0x99, + 0x4d,0x36,0x10,0xfa,0x06,0x14,0x52,0x49,0x45,0xf8,0x02,0x00,0x00, }; const uint8_t WEBCONFIG_HTML_GZ[] PROGMEM = { - 0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00,0x02,0xff,0xac,0x3b,0x67,0x7b,0xa3,0x38, - 0xb7,0xdf,0xfd,0x2b,0x78,0xe3,0x5b,0xe2,0x5d,0xe3,0x01,0x8c,0x4b,0x60,0x33,0xb7, - 0xf7,0xde,0x7b,0x11,0x70,0xb0,0x75,0x43,0x7b,0x24,0xd9,0x4e,0x96,0x67,0xfe,0xfb, - 0x95,0x0e,0xc8,0x20,0x8b,0x64,0x3c,0xef,0x6c,0x1b,0x23,0x21,0x1d,0x9d,0xde,0xc4, - 0xfc,0xf4,0xab,0x3f,0xfc,0x9b,0x3f,0xf8,0xc7,0x7f,0xfb,0xdb,0x3f,0x72,0x8e,0xa2, - 0x2c,0x3e,0xcf,0x7e,0x52,0x3f,0x4e,0x41,0xaa,0xc3,0xf3,0x03,0x54,0x0f,0x6a,0x02, - 0x48,0x26,0x7f,0x4a,0x10,0xc4,0x49,0x8f,0x84,0x71,0x10,0xcf,0x0f,0x27,0x91,0xbb, - 0xfb,0x07,0x3d,0x5d,0x91,0x12,0x9e,0x1f,0xce,0x14,0x2e,0x4d,0xcd,0xc4,0x83,0x93, - 0xd6,0x95,0x80,0x4a,0x2e,0xbb,0xd0,0x4c,0x1c,0x9f,0x33,0x38,0xd3,0x14,0x5c,0x1c, - 0x2c,0x1d,0x5a,0x51,0x41,0x49,0xe1,0xf2,0x94,0x14,0xf0,0xec,0x2f,0x9d,0x92,0xbc, - 0xd2,0xf2,0x54,0x0e,0x13,0x1a,0x90,0x9b,0x53,0xf1,0x9c,0xd6,0x67,0x60,0xea,0x24, - 0x41,0x45,0x01,0x9f,0xff,0x0a,0xf8,0xf1,0x0f,0x6a,0x06,0xce,0x1f,0xd4,0x55,0x4e, - 0x0f,0x3f,0x7d,0xc2,0x69,0xf9,0x9a,0x8b,0x37,0xf5,0x1b,0xb1,0xba,0x16,0xed,0xcc, - 0x75,0x93,0x43,0x34,0xcf,0xc3,0x7c,0x9b,0xef,0x63,0xc7,0x75,0x53,0xc2,0x32,0x39, - 0xce,0x73,0x35,0xa0,0xd5,0x4b,0x34,0xf7,0x49,0xb0,0x5e,0x7b,0x6a,0x58,0x9e,0x44, - 0x34,0xdf,0x6e,0x77,0xeb,0x3d,0x51,0xc3,0x82,0x56,0x10,0xcd,0x21,0x80,0x1d,0x40, - 0x2c,0x01,0x91,0x34,0x8d,0xe6,0x41,0xb2,0xcb,0xe0,0x29,0x76,0x70,0x88,0x00,0x34, - 0xb0,0x5a,0xc1,0xca,0x9e,0xb2,0x0d,0x8e,0x80,0xb1,0x68,0x9e,0x6d,0xc3,0x4d,0xb8, - 0x51,0xc3,0x0b,0x61,0x55,0x34,0x4f,0xf7,0xfb,0x9d,0x4f,0x14,0xac,0xf4,0x48,0x1b, - 0x09,0x1b,0xf2,0x20,0xdf,0x75,0x98,0x28,0x3c,0x07,0xbc,0xf0,0x70,0xb5,0x21,0x0b, - 0x32,0x50,0x53,0xfc,0x48,0xb2,0xfa,0x12,0x79,0x8e,0xdf,0xbc,0x3a,0x6b,0xf9,0x3f, - 0x3b,0x24,0xe4,0xd1,0xdf,0x2e,0x83,0xfd,0x32,0xdc,0x2c,0x57,0xde,0x7e,0x11,0xcf, - 0xbe,0xcc,0x7e,0xb7,0x84,0x8c,0x12,0xe7,0xb1,0x61,0x90,0x03,0xe3,0x6e,0x5a,0x17, - 0x35,0x93,0x0c,0x3d,0x42,0x09,0x51,0x46,0xd8,0xcb,0xa2,0x35,0x18,0xe3,0x7b,0xfe, - 0xc6,0x4f,0x35,0x63,0x90,0x19,0x7e,0x90,0x5c,0x79,0x03,0x5b,0x48,0xf2,0xe0,0xca, - 0x9b,0x7d,0xf2,0xb4,0x27,0xc9,0xc0,0x9b,0x80,0xac,0xc3,0x30,0xb8,0xf2,0x26,0x24, - 0x4f,0x61,0x2e,0x39,0xa9,0xc9,0x0b,0xd6,0x41,0xb6,0x26,0x23,0xf2,0xfc,0x50,0xc2, - 0x0f,0x0c,0x0a,0xd7,0x24,0xdc,0x6e,0xb6,0xef,0x53,0xe8,0x2d,0xd5,0xbf,0xab,0x50, - 0x51,0xf7,0x65,0xf6,0x43,0x9b,0xd4,0xaf,0x2e,0xa7,0x3f,0xd3,0xea,0x10,0x25,0x35, - 0xcb,0x80,0xb9,0x72,0x26,0x2e,0x09,0x3b,0xd0,0x2a,0xf2,0xbe,0xcc,0x94,0xd6,0xb6, - 0xee,0x05,0x92,0x17,0x2a,0x5c,0x01,0xaf,0x42,0xad,0x06,0x97,0x64,0xff,0x77,0xe2, - 0x22,0xf2,0x3d,0xef,0x37,0xbf,0xcc,0x92,0x3a,0x7b,0x6b,0xf3,0xba,0x92,0xe3,0x4d, - 0xf3,0xfa,0xc9,0x5f,0x85,0x1b,0x87,0xbf,0x71,0x01,0xa5,0x7b,0xa2,0x4b,0x97,0x34, - 0x4d,0x01,0x6e,0x37,0xb1,0x7c,0xf8,0x07,0x38,0xd4,0xe0,0xfc,0xd3,0x9f,0x3d,0x2c, - 0xff,0xbe,0x4e,0x6a,0x51,0x2f,0x39,0xa9,0xb8,0xcb,0x81,0xd1,0x3c,0x4e,0x48,0xfa, - 0x72,0x60,0xf5,0xa9,0xca,0xa2,0x33,0x61,0x8f,0x8a,0xa5,0x8b,0x18,0x59,0x8e,0x63, - 0x64,0xe2,0x22,0x6e,0x48,0x96,0x49,0x7c,0x5d,0xb9,0x5b,0xd4,0x65,0xf4,0xe4,0x35, - 0xaf,0xb1,0xd2,0xe5,0xbc,0xa8,0x2f,0xee,0x6b,0x74,0xa4,0x59,0x06,0x95,0xc4,0xdc, - 0x47,0x9c,0x10,0xdf,0xc8,0xdf,0xc9,0x45,0x38,0xbc,0x00,0x3d,0x1c,0x45,0xb4,0xdd, - 0x28,0xe2,0x82,0xf1,0x92,0xd0,0x5e,0x12,0x23,0xc5,0x82,0x49,0x14,0xf3,0x9a,0x95, - 0xd1,0xa9,0x69,0x80,0xa5,0x84,0x43,0x5c,0x80,0x10,0xc0,0x5c,0xde,0x90,0x54,0xf1, - 0x6e,0xe5,0x6d,0xa0,0x1c,0xa1,0x8a,0x02,0x5e,0x68,0x3e,0x06,0x81,0x64,0xbf,0x14, - 0x84,0xc4,0x54,0x1d,0x1a,0xe5,0x94,0x71,0xa1,0x84,0x5a,0x64,0x6d,0xb7,0xc4,0x15, - 0x75,0xa3,0xd8,0x4d,0xda,0x01,0x06,0x6a,0xc1,0x42,0x6e,0x00,0x92,0x01,0x6b,0x33, - 0xca,0x9b,0x82,0xbc,0x45,0x79,0x01,0xaf,0x31,0x29,0xe8,0xa1,0x72,0xa9,0xe4,0x28, - 0x8f,0x52,0xa8,0x04,0xb0,0xf8,0x40,0x9a,0x48,0x9d,0xa0,0xf9,0x13,0xf9,0xea,0x54, - 0x7f,0x2b,0x67,0x2c,0xbe,0x2a,0xe5,0x5c,0xc4,0x9d,0xc0,0x35,0x1f,0x95,0x9a,0xf0, - 0xba,0xa0,0x99,0x83,0x6b,0x50,0x9f,0x24,0xb3,0x6b,0x4e,0x05,0xad,0xab,0x88,0x0b, - 0x9a,0xbe,0xbc,0xc5,0x88,0x67,0xfc,0xb3,0x94,0x44,0x06,0xaf,0xf2,0x3c,0x8d,0x9e, - 0xc3,0xcf,0x87,0x56,0xa1,0x16,0x55,0x75,0x05,0x5f,0x66,0xab,0xa3,0x72,0x60,0x6d, - 0x49,0xab,0xce,0x3d,0x45,0x9e,0x9e,0x73,0x32,0x7a,0x1e,0xd8,0x8e,0x58,0xda,0x8c, - 0xbb,0x1c,0xa9,0x00,0xe4,0x2e,0x48,0x80,0x17,0x46,0x9a,0xab,0x88,0x7b,0x01,0x77, - 0xa2,0xb9,0x4e,0x42,0x51,0xd0,0x86,0x53,0x2e,0x4f,0x49,0x48,0x76,0x00,0xcd,0xd7, - 0x02,0x72,0x11,0x91,0x93,0xa8,0xe3,0x2b,0x72,0xf1,0xe8,0x70,0xdf,0x96,0xf9,0x95, - 0x7f,0xca,0x66,0x9e,0x9a,0x57,0xcd,0x26,0x46,0x32,0x7a,0xe2,0xd1,0xd3,0x93,0xcd, - 0xd0,0xce,0x40,0x17,0x16,0x19,0x1a,0x99,0x15,0x07,0x71,0x6a,0xda,0xd1,0xae,0x79, - 0xbe,0x86,0x7d,0xb6,0xee,0x77,0xcc,0xf7,0x64,0x93,0x7a,0xc8,0x21,0x9a,0xd6,0x55, - 0x3b,0xa0,0x3a,0xa6,0x62,0xdf,0xbc,0x1a,0xb8,0xed,0xaf,0xb8,0x59,0xb2,0xeb,0xdd, - 0xc1,0xe2,0x06,0x77,0x65,0x04,0x33,0x0b,0x77,0x74,0x26,0x36,0xf2,0x71,0x7a,0x62, - 0x5c,0xce,0x34,0x35,0x45,0xfd,0x52,0x00,0xdd,0x63,0xc7,0x26,0x7f,0xb5,0x8e,0x67, - 0x68,0xf1,0x3b,0x4f,0xea,0x75,0x80,0x56,0xbf,0x76,0x4e,0xd4,0x2d,0xeb,0xaa,0x46, - 0xb1,0x2d,0xff,0x0a,0xaa,0xa2,0x5e,0xca,0x68,0x22,0x11,0x23,0x7c,0x79,0x7d,0xa1, - 0xa9,0x8c,0x8e,0x4a,0x78,0x96,0xbe,0x6b,0x94,0x6f,0xe7,0xef,0xf2,0xc5,0xef,0xb2, - 0x7b,0x4d,0x82,0xdc,0x0f,0x35,0xbb,0xc1,0x4b,0xc2,0x4d,0x2a,0xfd,0x5f,0x49,0x68, - 0xd5,0xca,0x30,0xd9,0xeb,0xe8,0x36,0xf4,0x9a,0xc1,0xf9,0x39,0xa8,0x36,0x9a,0xe3, - 0xca,0x90,0x24,0xea,0xca,0x72,0xda,0x0f,0xed,0xc9,0x36,0x24,0x5b,0x12,0xa8,0xf5, - 0x06,0x68,0xf9,0xfe,0x55,0xbb,0x6c,0xdc,0xd6,0x0f,0xb4,0x0f,0xb9,0x5a,0x69,0x88, - 0x68,0x08,0x92,0x70,0xc3,0x23,0xa0,0xf9,0x87,0xef,0xab,0xa6,0x3e,0x2b,0xb4,0x14, - 0x1a,0x7d,0xc6,0xbb,0x87,0x38,0xc9,0x49,0x08,0xad,0x92,0xbe,0x26,0xd1,0x1b,0x1f, - 0x83,0x8a,0x6a,0x69,0x0f,0x6a,0x07,0xad,0x8e,0xc0,0xa8,0x18,0x5b,0xdc,0x7a,0xb5, - 0xb9,0xb5,0x39,0x6f,0xb0,0x39,0xa9,0xa1,0x8e,0x8d,0xa2,0x9c,0xbd,0xd1,0x46,0x13, - 0xbb,0x55,0x5d,0x4d,0xcb,0xc4,0x8e,0x1e,0xef,0xf2,0x59,0x42,0xcc,0xdb,0x1b,0x36, - 0xac,0x91,0x0d,0xb9,0x53,0x90,0x04,0x8a,0x2b,0xbb,0x93,0xa2,0x4e,0x5f,0xc6,0x24, - 0x05,0x93,0x24,0x99,0xb0,0xc2,0x1e,0x94,0xd4,0xfd,0x4a,0xb4,0x63,0x0f,0x84,0x9b, - 0x2d,0xf6,0x8d,0xc2,0x02,0x62,0x41,0xab,0xe6,0x24,0xfe,0x43,0xbc,0x35,0xf0,0xac, - 0x1c,0xdf,0x7f,0x2d,0x47,0x13,0x0d,0xe1,0xfc,0x22,0x19,0x66,0x4c,0x56,0xa7,0x32, - 0x01,0x66,0x4c,0x41,0x49,0x68,0xf1,0x5f,0x4b,0x0e,0x05,0xa4,0xa2,0x9d,0xa1,0xce, - 0x63,0x08,0xd7,0xec,0x57,0x2e,0x06,0xa3,0xd4,0x7b,0xd2,0x43,0x4d,0xb5,0x59,0xfa, - 0x8e,0x47,0x99,0x7d,0x93,0x77,0x42,0xff,0x56,0x9f,0x84,0x7a,0xd5,0x05,0x11,0xc7, - 0xf9,0xf4,0x83,0xf3,0xf9,0x59,0x1d,0x1a,0x39,0x5c,0xb2,0x82,0x3b,0xf4,0x6f,0xfe, - 0xc1,0xf9,0xb9,0xae,0x4b,0xb7,0xae,0xdc,0xbc,0x4e,0x4f,0xdc,0x79,0xe4,0x34,0x83, - 0x0b,0x79,0xe3,0x2e,0x4f,0x59,0x5d,0x14,0x0e,0xad,0x9c,0x94,0x34,0x82,0x9e,0xc1, - 0xe1,0x47,0x00,0xb1,0x70,0x7e,0xf8,0xd4,0xb1,0x2f,0xc2,0x1d,0x3d,0xfd,0xdd,0xa0, - 0x9d,0xf6,0x36,0x86,0x9a,0x78,0x8e,0xfa,0x57,0x05,0xd3,0xce,0xe3,0x94,0xf4,0xf5, - 0x51,0x1e,0xc2,0xd9,0x21,0x59,0x0e,0x3b,0x9c,0x60,0xf3,0x9b,0x4b,0xcc,0x14,0x1a, - 0xc2,0xa0,0x12,0x8b,0x5e,0x66,0xab,0x8c,0x32,0xf1,0xd6,0x1d,0xda,0x0f,0xec,0x43, - 0xbb,0x84,0x56,0xe9,0x60,0xf3,0x72,0xb8,0x2a,0xda,0x81,0xd1,0x2c,0x56,0x7f,0xb8, - 0x02,0x4a,0x39,0x23,0x40,0x6d,0x39,0x95,0x15,0x8f,0x18,0x34,0x40,0xc4,0xa3,0xf2, - 0x50,0x6e,0x4e,0x8b,0x62,0x59,0xd2,0x4a,0xfa,0xb1,0x47,0x5f,0xa5,0x1a,0x4b,0x3f, - 0x67,0x8b,0x05,0x7a,0x84,0xa0,0x8f,0x13,0xdf,0x2e,0x8a,0xb1,0x4e,0xbc,0x23,0x61, - 0xb4,0x99,0x8e,0x24,0x07,0x11,0xff,0x90,0xae,0xbb,0x12,0x18,0x29,0xea,0x8f,0x2d, - 0x2b,0xbc,0x5a,0x96,0x74,0x42,0x33,0x49,0xb5,0x0e,0x49,0xc1,0xd6,0x72,0x12,0x78, - 0xac,0x83,0x52,0x68,0x7b,0x65,0x57,0xe0,0xba,0x0d,0xf8,0x3c,0x80,0x1a,0x52,0x17, - 0xdc,0x24,0x85,0x58,0xb5,0xf7,0x65,0x1c,0x13,0xb9,0x0a,0xc2,0x20,0xf7,0x67,0x6c, - 0x23,0x63,0x47,0x7a,0x6f,0xbc,0x83,0x04,0x57,0x54,0x2f,0xed,0xad,0xcb,0xed,0x45, - 0x8a,0xcf,0x5a,0x58,0x9e,0x69,0xb9,0x96,0x9f,0xb1,0xf4,0x7c,0x66,0xb2,0xac,0xa3, - 0x31,0x83,0xb4,0x66,0x04,0xd3,0x3e,0x79,0x1a,0xb0,0x82,0x76,0x7c,0xc9,0xf9,0xa9, - 0x6c,0x6d,0x57,0x75,0x93,0x69,0xc9,0x95,0xac,0xbe,0xd8,0xd1,0x09,0xd3,0x5f,0xf5, - 0xea,0xf3,0x2a,0xd7,0xf1,0xc4,0xcc,0x0f,0x9b,0xcb,0x68,0xa3,0xcd,0x36,0x2e,0x18, - 0x88,0xf4,0x88,0xc0,0xa4,0x56,0xea,0x0d,0x9d,0x84,0x3f,0x80,0xe8,0xc8,0x1f,0x7e, - 0x94,0x90,0x87,0x77,0xdb,0x00,0xf7,0xf3,0xcb,0x57,0x85,0xa4,0xea,0x1c,0x9a,0xbf, - 0xb9,0x7d,0xe9,0x1d,0xa1,0x9c,0xdd,0x04,0xc4,0x05,0xa0,0xb2,0x93,0xee,0x27,0x95, - 0xe9,0x23,0x64,0xd4,0x21,0x27,0xb1,0xc2,0xc6,0xc7,0x91,0x70,0xb4,0x95,0x76,0x61, - 0x02,0xeb,0x6f,0x29,0x65,0x56,0x92,0x62,0x4a,0xa0,0x56,0xca,0x29,0x0e,0x45,0x7b, - 0x4d,0xdb,0x19,0x14,0x44,0xf9,0xc2,0xb8,0xa3,0x3b,0x0c,0x06,0x03,0x08,0x54,0xa0, - 0x1d,0xf4,0x1e,0x37,0x76,0xbc,0x1c,0xb6,0x93,0x84,0x4b,0x8f,0x23,0x20,0xae,0x55, - 0xa1,0x23,0xde,0xa4,0x82,0x0d,0x61,0x43,0x03,0xc2,0x67,0x6d,0x49,0x96,0x0d,0x22, - 0xd8,0xd3,0x04,0x48,0x5a,0x71,0x10,0x66,0x2a,0x61,0x39,0x25,0x2b,0xf3,0x46,0x0f, - 0xdb,0x01,0x5a,0xf9,0x1b,0x1e,0xf7,0xc7,0xb8,0x70,0x86,0x4a,0xf0,0x31,0x25,0xa7, - 0x28,0x81,0xbc,0x66,0xd0,0x6a,0xc9,0x3d,0x3c,0xc4,0x36,0x12,0x7d,0x80,0x8d,0x51, - 0x7b,0xe5,0x83,0x26,0x6f,0x3f,0x72,0x14,0xa6,0x07,0xc4,0xae,0xc2,0x0d,0x6a,0x1b, - 0xc9,0x80,0x1b,0xcc,0xc6,0xfc,0x8c,0xd2,0x23,0xa4,0x2f,0x90,0xfd,0x78,0xb2,0xd2, - 0x14,0xb4,0xc2,0xe9,0xb5,0x1a,0x7f,0x44,0x2d,0xf0,0x95,0xc2,0xf6,0xe9,0x4e,0x22, - 0xaa,0xab,0x5a,0xd1,0x0a,0x13,0xf3,0x7b,0xd5,0xd7,0xf4,0xb5,0x3d,0x19,0xb6,0xdb, - 0xf8,0xb0,0x28,0x9e,0x8d,0x95,0xdd,0xdf,0xda,0x25,0x92,0xe5,0x89,0xe3,0x49,0xb2, - 0x6f,0xbd,0x11,0x66,0x13,0x63,0x22,0x57,0x1c,0xd2,0xf6,0xeb,0xb5,0x96,0xb5,0x2f, - 0x92,0xcc,0x21,0x49,0x01,0x59,0xab,0xd5,0x76,0xb5,0xd1,0x18,0x65,0x90,0x93,0x53, - 0x21,0xcc,0x63,0xca,0xd6,0x0a,0x3a,0x9a,0xc6,0x2d,0xa6,0x44,0xe8,0x2d,0xd4,0xc1, - 0xb7,0x7c,0x47,0xab,0xbe,0xb7,0xa2,0xd4,0xd1,0xd8,0xd6,0xeb,0xb1,0x13,0x45,0xc1, - 0x9c,0x81,0x09,0x9a,0x92,0xc2,0x45,0x99,0x46,0xfe,0x15,0x81,0x55,0x6d,0x44,0x82, - 0xf7,0x52,0x92,0xfa,0x65,0xe1,0xf8,0x66,0x46,0x32,0xe6,0x19,0x2e,0xd0,0x10,0x81, - 0xb1,0x7b,0x40,0xca,0x65,0x1f,0xc3,0xc4,0x15,0xca,0x81,0x91,0x33,0x24,0x84,0x0d, - 0x26,0x9f,0xd3,0x57,0xc8,0x3a,0x13,0xf3,0x62,0x86,0x6c,0xf1,0xe2,0x3e,0x31,0x1e, - 0x9a,0x09,0x81,0xf7,0x71,0xa3,0x02,0xe3,0xe3,0x64,0x71,0x35,0x68,0xa4,0xef,0xf5, - 0x2a,0xe9,0x48,0xde,0xa5,0x8f,0x38,0xfc,0xd1,0x81,0xea,0xfc,0xc8,0x49,0x0e,0x2e, - 0x61,0x40,0x5c,0xf4,0x3b,0x7d,0x5e,0x2e,0xd3,0x24,0x2d,0x50,0x8c,0xa3,0xef,0x45, - 0x69,0x29,0xb9,0x81,0xb0,0x15,0x3f,0x9a,0x61,0x6a,0xf4,0x4e,0x3a,0xfc,0x1b,0x17, - 0x3f,0x7e,0xb9,0xe2,0x4d,0x1f,0xa7,0xd4,0x64,0x51,0x8b,0xf6,0xfe,0x9a,0xd1,0x6a, - 0xee,0x58,0x55,0x9b,0x7c,0xdf,0x83,0x95,0x07,0x89,0xbb,0xd2,0x8f,0xfd,0xd7,0xa0, - 0x4c,0xd3,0xd3,0xd0,0xa2,0x18,0xcf,0x7b,0x56,0x28,0xdb,0x79,0x96,0xda,0x7f,0x47, - 0x23,0xe5,0x1b,0xfa,0x70,0x21,0x94,0x3d,0x82,0xbf,0xac,0xa5,0x20,0xc4,0x9c,0xd0, - 0x62,0xd9,0x3d,0x4a,0xee,0xa6,0xbf,0xa8,0xd5,0x20,0xd4,0x0b,0xa1,0xe2,0x0e,0xa8, - 0x98,0x56,0x4f,0x83,0xb5,0x32,0x6f,0x41,0x0b,0xe0,0xdf,0x55,0x53,0x84,0x9e,0x51, - 0x53,0xa0,0x86,0x74,0x70,0xa7,0x9d,0xf3,0xc7,0x8a,0x8b,0x16,0x1a,0x5c,0x41,0x4c, - 0xa6,0x39,0x1a,0xdb,0xbb,0xbc,0xeb,0x77,0x2b,0x0b,0xa2,0x61,0xe8,0xf9,0xde,0x3e, - 0x46,0xaf,0xe3,0xed,0x6d,0x8a,0x8c,0x8e,0xe3,0x8e,0xc4,0x2c,0x25,0xd5,0x99,0xf0, - 0xd6,0xce,0x9f,0x36,0xd2,0x5f,0x99,0x24,0xcb,0xc3,0x2a,0x10,0xf7,0x17,0x10,0x03, - 0xcc,0xbb,0x3a,0x34,0x18,0x30,0xcd,0x90,0x6f,0x7a,0x50,0x89,0xd0,0x5d,0xdd,0xe1, - 0xa9,0xe2,0xa1,0x0b,0x58,0xca,0xd9,0x77,0x54,0x44,0x05,0xb9,0x36,0xbb,0x4d,0x98, - 0x1e,0x2e,0x50,0x6e,0x86,0xf7,0x5e,0xd1,0x6a,0xa2,0x7c,0x47,0x09,0x86,0xa0,0xb9, - 0xd4,0xa6,0xa2,0x9d,0x48,0x92,0xb9,0x94,0x46,0x43,0x2a,0x28,0xbe,0xd9,0x03,0x4f, - 0xc7,0xa8,0xaf,0xf5,0xef,0x22,0xb7,0xbf,0x03,0x90,0x39,0xe6,0xf8,0x78,0x15,0x12, - 0x5c,0xd5,0x42,0xff,0xb5,0xca,0xe3,0x5f,0xfc,0xc6,0xc2,0x36,0x53,0x27,0xbc,0x41, - 0x78,0xae,0x1e,0x25,0x7b,0xb8,0xc0,0xce,0x69,0xaf,0xc3,0xe1,0xe6,0x7c,0x1c,0xa4, - 0x65,0x74,0x4e,0x3d,0x67,0x8f,0x2a,0x85,0x60,0x04,0x34,0x13,0x8d,0xcb,0xad,0x1d, - 0x86,0x46,0xeb,0x1d,0xaa,0xd5,0x43,0x1f,0x66,0x05,0x93,0xc0,0x12,0x8c,0x16,0xe1, - 0x00,0x64,0xdc,0x25,0xb4,0xd2,0xef,0x9a,0x70,0x71,0x93,0xb0,0x60,0x6d,0xb0,0x0d, - 0x75,0x71,0xa0,0x72,0xfc,0x81,0xaf,0xf8,0xa4,0xdc,0xe7,0xbf,0x3e,0xba,0xf2,0xcd, - 0xe2,0x9a,0xc5,0x84,0x93,0x05,0xcd,0x8b,0xe9,0x9b,0xb1,0x3b,0x76,0x77,0x53,0xf4, - 0xfd,0x34,0x7b,0x28,0xcb,0x8c,0xf2,0x23,0x98,0x2e,0x8c,0xe2,0xa1,0xd3,0xfd,0xe4, - 0x9d,0x2f,0x9a,0xec,0x2e,0x9d,0xd1,0x90,0x54,0x66,0xa2,0xe4,0x28,0xe5,0x73,0xcb, - 0x0f,0x5d,0xb0,0x69,0x52,0x37,0xde,0xf4,0x8d,0x9d,0x9d,0x51,0xdd,0x55,0x93,0x0c, - 0xde,0x43,0xcf,0x68,0x06,0xa8,0x4a,0x75,0x40,0x6b,0x3a,0xfd,0x6a,0x68,0xd5,0xbb, - 0xd6,0x60,0x5c,0xe3,0x06,0x43,0x91,0xb3,0xfe,0xc8,0xc2,0xa5,0xac,0xed,0x26,0xa0, - 0x5d,0xe4,0x91,0x8a,0x96,0x9d,0xd7,0x67,0x8e,0xcf,0x1d,0x05,0x82,0x30,0x87,0x56, - 0xb9,0xba,0x7c,0x87,0x78,0xaa,0x38,0x90,0x17,0x17,0x2f,0xf0,0x96,0x33,0x52,0x02, - 0x77,0x58,0x2b,0xea,0x76,0xd0,0x22,0x56,0x0b,0x22,0xe0,0x71,0xbd,0xf5,0x32,0x90, - 0xed,0x34,0x49,0x07,0x30,0x86,0xd7,0xac,0xed,0x6d,0x86,0x60,0x74,0x0e,0xcc,0x9e, - 0x11,0x26,0x71,0xf2,0x79,0x54,0xaf,0x4a,0x48,0x2f,0xe7,0xd6,0xd2,0xb0,0x31,0xd3, - 0xee,0xe9,0x6c,0x04,0x37,0x85,0x90,0x77,0x4f,0x54,0xc0,0xb3,0x3f,0xf0,0xfa,0xf8, - 0x7e,0x32,0xec,0x5b,0x7e,0x1a,0x57,0x26,0xed,0xad,0x61,0x8c,0x34,0x85,0xa9,0xc9, - 0xfb,0xef,0x06,0xe5,0x7b,0x68,0xc7,0xfa,0xf9,0x2b,0x5a,0x36,0x35,0x13,0xa4,0xc2, - 0x68,0x55,0x0b,0xb0,0x2b,0x41,0xcb,0x47,0xde,0x95,0xf4,0xec,0x6f,0x9a,0x42,0x98, - 0xba,0x4c,0xde,0x2f,0x08,0x60,0x65,0xeb,0xba,0x22,0x8f,0xe6,0xd9,0x0e,0x3c,0x20, - 0xb1,0x1c,0x64,0xb4,0x8c,0xe6,0xdb,0x6c,0x97,0xee,0x73,0x35,0xc4,0xef,0x01,0x36, - 0x7b,0xb2,0xcd,0x71,0x78,0x60,0x95,0x1c,0xee,0xd2,0x60,0x0b,0x6a,0x88,0x1f,0x47, - 0xe4,0xf9,0x2e,0xd9,0x05,0x6a,0xd8,0x7d,0x1c,0x01,0xeb,0x64,0x1d,0xfa,0xc6,0x7d, - 0xdf,0xdc,0x4b,0x3c,0xf0,0x03,0x83,0x22,0x91,0x4f,0x5c,0x5c,0xcd,0x03,0x2f,0xd8, - 0xaf,0x83,0xa9,0x4b,0xab,0xce,0x6d,0xe5,0xa4,0xa4,0xc5,0x5b,0x64,0x5c,0xf8,0xfd, - 0xc3,0x1f,0xff,0x95,0x7c,0x76,0xff,0x1e,0x0e,0xa7,0x82,0xb0,0xdb,0xfb,0xbf,0x87, - 0xbf,0xa4,0x09,0x74,0x19,0x93,0xa3,0xd6,0x3d,0x0c,0x37,0x82,0x08,0x73,0xac,0xdb, - 0xe6,0x55,0xe3,0xc6,0x54,0x5b,0xf5,0x87,0x9b,0x51,0x06,0x29,0xda,0x61,0x97,0xbd, - 0x5a,0x1a,0x30,0xeb,0xb7,0xef,0xf6,0xe7,0xe3,0xd8,0x38,0x02,0x95,0xcc,0xea,0xbb, - 0xc4,0xc7,0xde,0x49,0x4a,0x20,0x84,0x71,0x58,0xb4,0x9d,0x2c,0xcc,0xfb,0x8e,0x2f, - 0xdd,0x07,0x0e,0xea,0xbe,0xc9,0x4d,0x0b,0xda,0xde,0x7c,0x7e,0xe0,0xf5,0x12,0x74, - 0x8f,0xd9,0xbd,0x15,0xd7,0xd0,0x74,0xb3,0xba,0x0c,0xa6,0xb8,0x7c,0xdf,0xdf,0xfa, - 0x99,0x6d,0x73,0x37,0x52,0x1a,0xf0,0x5d,0xed,0x03,0x33,0xa8,0xa3,0x22,0x2d,0x06, - 0x14,0x8d,0x0a,0x54,0x4f,0x1a,0x77,0x7c,0x88,0x96,0xd5,0x6a,0xb6,0x15,0x84,0xac, - 0xd7,0x6b,0xab,0x0d,0xa6,0x08,0xb0,0x4e,0x37,0x12,0x4d,0x4d,0x31,0xc2,0xda,0x5b, - 0x8d,0x22,0x0b,0xa9,0x89,0x5b,0x62,0x91,0xdf,0x5c,0x12,0xcf,0xd7,0x59,0x48,0x36, - 0x44,0xef,0xad,0x87,0x66,0xb0,0xd6,0x0a,0xf7,0x0d,0x53,0x12,0xfb,0x33,0x11,0x23, - 0xdf,0x89,0xf5,0x77,0x2e,0x7a,0x59,0x7f,0xa5,0xa4,0xde,0x8b,0xfa,0x94,0x1e,0x47, - 0x27,0x7c,0x56,0x5f,0x31,0x8c,0xd3,0xce,0x86,0x81,0x8b,0xdf,0x29,0xa8,0x9b,0x38, - 0x37,0x61,0x40,0x5e,0x22,0xfc,0xd3,0x55,0x13,0xa3,0x9d,0xce,0x2a,0x2d,0xb3,0x8e, - 0x20,0x6c,0x25,0xde,0xbe,0xb2,0xda,0x96,0x9f,0x9d,0x87,0xb1,0x48,0xd1,0xfa,0x17, - 0xc6,0x2e,0x06,0x8d,0x06,0xb8,0x03,0xd8,0xed,0x77,0xc6,0x5b,0x60,0x37,0xfc,0x93, - 0x13,0xe6,0x7e,0xfe,0xc6,0x5b,0x4b,0x6c,0xc6,0x0a,0xa9,0xb9,0x6d,0x6f,0x41,0xab, - 0xcd,0x06,0x4a,0xfd,0x92,0x54,0xe9,0xb1,0x66,0x13,0xed,0xe6,0x6e,0xf1,0xf8,0x62, - 0x65,0xe8,0xf3,0xe8,0xcd,0xfc,0x74,0xb0,0xdb,0xc2,0xef,0xb6,0x89,0x46,0xc9,0x26, - 0x62,0xa9,0xb6,0xcb,0xb9,0x65,0x18,0x9e,0x8f,0x0b,0x4b,0xd2,0xa6,0xdb,0x03,0x7f, - 0xed,0x93,0x51,0xa8,0xb7,0x8d,0xc8,0xbc,0xf0,0x73,0x31,0xfd,0x0d,0xc2,0x9b,0xaf, - 0xa6,0x36,0x1b,0x4c,0x27,0x0f,0xd3,0x77,0x1b,0x86,0xc5,0x27,0x84,0x43,0x41,0x47, - 0x16,0xbe,0xd1,0x16,0x6e,0x29,0x3c,0x3f,0x38,0xc9,0x60,0x7b,0x46,0x16,0xb8,0xf1, - 0x74,0x79,0x3b,0x4f,0x73,0x58,0x4b,0xe7,0x7f,0xa3,0x72,0xfd,0x76,0xe7,0x64,0xca, - 0x4f,0x65,0x2f,0x56,0x3b,0x66,0xaa,0x6e,0xed,0xf6,0xd3,0xf1,0x77,0x3a,0xb1,0x15, - 0x97,0x0d,0x07,0x13,0x4e,0x39,0x98,0x78,0xf6,0x3d,0x85,0x1a,0x3f,0xdc,0xa4,0xe6, - 0x73,0x1f,0x82,0x64,0x4d,0xc6,0x32,0xc1,0xdc,0x13,0x3f,0x63,0xf3,0xe4,0xbf,0x23, - 0x32,0xf5,0x7e,0x27,0x19,0xdb,0x94,0x9e,0xa4,0x7a,0x72,0x9f,0x3c,0x25,0xe4,0x6a, - 0x86,0x4a,0x32,0xdf,0xe1,0xad,0xf5,0x35,0xf9,0x37,0x6b,0x99,0x3e,0xbf,0xe1,0x83, - 0xc0,0xa7,0x6c,0x7b,0x8e,0xab,0x68,0x35,0x71,0xa9,0x35,0x94,0x55,0x43,0xa9,0x6f, - 0x7a,0x61,0xbb,0xf4,0x1f,0x18,0x13,0xcf,0x0c,0x67,0x3c,0xbe,0x6e,0x8f,0x53,0xc2, - 0x40,0xb8,0x1f,0x60,0x63,0x5c,0x99,0x47,0xde,0x48,0x3c,0x08,0x60,0xb4,0x30,0x92, - 0x8c,0x4d,0xe1,0x58,0x17,0x72,0xa1,0x96,0x40,0xf8,0xb4,0xd9,0x6d,0x77,0xa3,0x45, - 0xba,0x49,0xff,0xbe,0xeb,0x39,0xd4,0xad,0xcd,0xfc,0x40,0x33,0xff,0xce,0xa0,0xb4, - 0x35,0xe5,0x64,0xf3,0xdc,0x0e,0x52,0x96,0x8d,0x6a,0x74,0xec,0x68,0x84,0x3c,0xfa, - 0x28,0x1e,0xe1,0x36,0xfb,0x3e,0x22,0xb4,0xee,0x23,0xba,0xc5,0x69,0x5e,0xb6,0x5f, - 0x23,0x4c,0x79,0x48,0xab,0x9a,0xc1,0xac,0xcf,0x4a,0x42,0xad,0x8c,0x22,0xf0,0xf7, - 0x7e,0x6e,0x29,0xb2,0x6e,0x52,0x60,0x8e,0x3f,0x42,0xc5,0x59,0x1d,0x4d,0x62,0xf1, - 0x10,0x33,0x8d,0x55,0x9e,0xcd,0xd8,0x52,0x54,0x5a,0xe4,0xe4,0x29,0xd9,0xa5,0xdb, - 0xf8,0xfe,0x30,0x79,0x6d,0x43,0x21,0x8d,0xfd,0xa1,0xd5,0x72,0x9d,0x1e,0xbb,0xae, - 0x1e,0x46,0x10,0x29,0x27,0x6c,0xee,0xbb,0xbe,0xf3,0x83,0x33,0x5e,0xb2,0xb8,0x41, - 0x63,0xba,0x57,0x67,0x0b,0xdf,0xdc,0x77,0xf9,0x80,0x62,0xfb,0x86,0x7e,0xf5,0x04, - 0xa5,0xb1,0x3d,0x11,0x95,0xd5,0xe0,0x18,0xfc,0x08,0xd2,0x1e,0x21,0x03,0xcc,0x02, - 0x6e,0x04,0x43,0xa7,0x63,0xdf,0xa0,0xdf,0x86,0x88,0x93,0x60,0xb3,0xf6,0xac,0x1c, - 0x7f,0x36,0x99,0x85,0x85,0xd8,0xe5,0xb1,0xa3,0x92,0x85,0xcd,0xea,0x50,0x9b,0x1e, - 0x3a,0x5b,0x27,0xc1,0xfe,0x46,0xef,0x83,0x7c,0x9b,0x84,0x9b,0x58,0xbb,0xdc,0x1c, - 0x3c,0xb2,0xb1,0x41,0x4d,0x59,0xc3,0xc6,0x36,0x87,0xb4,0xa0,0xae,0xa0,0xcd,0x57, - 0x3f,0x15,0x1d,0xf8,0x88,0x1d,0x11,0x3b,0x34,0x07,0x16,0xef,0x07,0xe8,0xce,0x4b, - 0x92,0xb5,0x06,0x67,0xde,0x2d,0x6f,0xba,0x7a,0xe6,0x3a,0x7e,0xaf,0x0a,0x9c,0x99, - 0xd2,0x09,0x47,0x65,0xa0,0xd7,0xf5,0xd2,0x7e,0xfa,0xd4,0x7d,0x52,0x2f,0x1f,0xfa, - 0xbf,0x02,0xa0,0xea,0x0b,0xf9,0xa3,0x46,0xc0,0xe4,0x03,0x3f,0x1f,0xfe,0x9f,0x9d, - 0x27,0xed,0x6e,0x1b,0x47,0xf2,0x7b,0xff,0x8a,0x7a,0xdc,0xf7,0x12,0xfb,0x6d,0x44, - 0x5b,0xb2,0xad,0x1c,0x8e,0xd5,0x2f,0x47,0xdf,0x9d,0x63,0x63,0xcf,0xf5,0x69,0x1f, - 0x44,0x42,0x16,0x26,0x14,0xc1,0x01,0xa0,0xd8,0xea,0x5f,0xbf,0x55,0x05,0x80,0x14, - 0x4d,0x53,0xa1,0xed,0xcc,0xde,0x33,0xdd,0x2d,0x09,0x67,0xa1,0xaa,0x50,0x37,0x0c, - 0xbe,0xc2,0x3f,0x99,0x4c,0x13,0xf0,0x56,0x0f,0x7f,0xe7,0x12,0xfe,0xd7,0xfa,0xfa, - 0x2c,0xe1,0x9a,0xa4,0x63,0xfc,0x27,0x01,0x0a,0xd6,0x9f,0x25,0xc4,0xda,0x09,0x58, - 0x67,0xf4,0x67,0x79,0x96,0x34,0x51,0x8c,0xd8,0x36,0x8a,0x2b,0xc6,0x06,0xd6,0x82, - 0x99,0xa8,0xce,0x12,0x3e,0x45,0x82,0x1b,0x67,0xca,0x64,0x85,0x84,0x0c,0xd7,0x1f, - 0xe3,0xb8,0x6c,0xe3,0x3f,0x0d,0xce,0x4a,0x27,0x71,0xa3,0xee,0xd2,0x61,0xf3,0x03, - 0x5c,0xa1,0x12,0x6e,0x09,0xf9,0x59,0xf2,0xee,0x69,0xfa,0x14,0xf0,0x5f,0x31,0x85, - 0x29,0x1c,0x86,0xff,0x3f,0x4b,0xa7,0xef,0xc6,0xd3,0xf4,0xa8,0xd5,0x31,0x0e,0x1d, - 0xc7,0xe9,0x73,0xc0,0x7f,0xc5,0x18,0x9b,0x78,0xb8,0xef,0x3d,0x4e,0x27,0xef,0xc6, - 0xcf,0xd3,0xf1,0x8d,0xbe,0x71,0xe8,0xe3,0x4d,0x0f,0x10,0x61,0xf8,0x81,0x26,0x39, - 0x64,0x85,0xb0,0xf6,0x2c,0xe1,0x4a,0x63,0x7e,0x64,0x31,0x06,0x95,0xe3,0xef,0x11, - 0x3d,0xa5,0x48,0xea,0x57,0x0e,0x88,0xfa,0xb1,0x9f,0x11,0xba,0xed,0x7a,0x9e,0xcc, - 0x32,0x5d,0x22,0x46,0x1c,0xd2,0xea,0xd1,0x92,0x4d,0x96,0xd3,0x97,0x07,0x38,0x04, - 0x07,0x86,0x0f,0xae,0xcb,0x08,0x5b,0x70,0xa9,0x29,0x50,0x40,0x21,0x09,0x6b,0x70, - 0x4b,0x32,0x43,0x70,0x70,0x18,0x8e,0x66,0x76,0xaf,0xc7,0x73,0xd1,0x6b,0x6b,0x7c, - 0xc6,0xbe,0x31,0xfe,0xe4,0xea,0xbc,0xc4,0x0f,0x4f,0x40,0x97,0xc8,0x9c,0xd9,0xe7, - 0xb3,0x84,0xcd,0x90,0x37,0x7e,0xd0,0xde,0x7e,0xf2,0x9d,0x53,0xae,0xc0,0x71,0xa1, - 0x05,0x46,0x23,0xb0,0x9f,0x55,0x05,0x5c,0xed,0x0a,0xa2,0xcc,0xa1,0x12,0xd6,0x49, - 0x10,0x50,0x19,0x49,0x19,0xa1,0x1c,0x32,0x7e,0xcb,0x91,0x7c,0x27,0x8c,0x12,0x23, - 0xae,0x62,0x3c,0x4b,0x3e,0x54,0xb2,0x84,0xb8,0xf5,0xec,0xd1,0xa5,0x3b,0xfd,0xf7, - 0x97,0x07,0x7e,0xef,0xc8,0x92,0xcc,0x84,0x2b,0xa1,0xa8,0xc1,0x7a,0x3f,0x9b,0x41, - 0xfe,0x32,0x2a,0x34,0xde,0xb5,0x24,0x1e,0x89,0x0f,0xd3,0x46,0x3c,0x05,0xc3,0x19, - 0xef,0x93,0xd9,0xab,0x7c,0xa5,0x4a,0xe0,0x19,0xb8,0xec,0x84,0x98,0x03,0x98,0xf3, - 0xcf,0x92,0x4e,0x60,0xaa,0xe7,0x56,0x07,0x15,0xc3,0x77,0x38,0x99,0xfd,0x40,0xf8, - 0x00,0xb7,0x54,0x16,0x4a,0x9d,0xcb,0xc7,0x16,0x04,0x6f,0x11,0xeb,0x1f,0x61,0xcf, - 0x2d,0x25,0x58,0x24,0x34,0xe8,0x52,0xc2,0xda,0xca,0x1c,0x16,0xda,0x80,0x91,0x2b, - 0xed,0x24,0xbc,0xf9,0xfd,0x17,0x3f,0x61,0x3f,0x7d,0x79,0x50,0x21,0x38,0xd8,0xb7, - 0xe2,0x73,0x31,0x8c,0x23,0xfa,0x79,0xe3,0x34,0x0b,0xa4,0x26,0xa3,0x8d,0xd6,0x89, - 0xe3,0xaa,0x2b,0x3c,0xe1,0xc7,0xb0,0xe7,0xcb,0x03,0xee,0xc7,0x69,0x5c,0xbd,0x11, - 0x48,0x19,0x21,0xf2,0x94,0x6e,0xa6,0x71,0x49,0x71,0xa6,0x57,0x55,0x21,0x1d,0x0e, - 0x43,0x99,0x67,0x24,0x62,0x22,0x0c,0x0f,0xfd,0x6c,0x65,0xcd,0x98,0xe5,0x3a,0x4c, - 0x84,0xda,0x25,0xb2,0x0b,0x72,0xec,0x4a,0xb9,0xed,0x1d,0xa8,0x73,0x76,0x8e,0x76, - 0x2c,0xa8,0x32,0x92,0xb4,0x7d,0x9e,0x10,0x5d,0x6c,0xcd,0xc2,0xb6,0xa4,0xde,0xed, - 0x80,0x90,0x40,0x9f,0xe1,0x67,0xa0,0x7e,0x87,0x0f,0xae,0xd4,0x1f,0x48,0xe8,0x5d, - 0x8c,0x50,0x6a,0x17,0x18,0x3d,0x2b,0xc5,0x88,0x7f,0xcd,0x7e,0x29,0x81,0x28,0xf4, - 0x17,0xf5,0xa3,0x02,0xcb,0xf6,0x76,0x09,0x95,0xae,0xd6,0xd5,0xf7,0xf0,0x8b,0xc3, - 0x89,0xda,0x4a,0x0b,0x6a,0x01,0x1b,0xbd,0x36,0x50,0x2d,0x89,0x88,0xb6,0x90,0xb2, - 0xb2,0xe9,0x77,0x2f,0x05,0x2c,0x8d,0x5c,0x9c,0x25,0xff,0xb2,0x75,0x41,0x70,0xee, - 0x87,0xb5,0xdb,0xdb,0x3f,0x35,0xd2,0xad,0x4d,0x09,0x0b,0x51,0x58,0x99,0x44,0x26, - 0xeb,0xfa,0x1a,0xc9,0x8c,0x99,0x5f,0x95,0x7e,0x87,0xb9,0xd1,0x57,0x56,0x9a,0x97, - 0x07,0x62,0x06,0x4e,0xc3,0x67,0xdc,0x29,0x6c,0x6d,0xf4,0xa5,0x91,0xd6,0xa6,0x8c, - 0x87,0xf6,0xb9,0x38,0x99,0x80,0x08,0x53,0x7c,0x36,0xeb,0xaa,0x71,0x8d,0x05,0x5d, - 0x12,0x22,0xd5,0x56,0xdf,0xe4,0x66,0xc3,0xd1,0xcd,0x86,0xe3,0xd0,0xd0,0x6c,0xc4, - 0x3d,0x57,0x7f,0x8c,0xfb,0x2f,0xd6,0x39,0x82,0x00,0x63,0x78,0xb4,0x52,0x79,0xae, - 0xdd,0x29,0xe3,0xf3,0x9b,0xdc,0xb0,0xb0,0x35,0x52,0x77,0xa1,0x50,0x3a,0x55,0x9b, - 0x64,0xf6,0xc6,0x8b,0xc4,0xe6,0xd6,0x11,0xa6,0x18,0x49,0x4c,0xc5,0x52,0x3a,0x64, - 0xdc,0xcf,0x60,0x35,0x28,0xa4,0xa0,0x28,0xc1,0x48,0x91,0x2d,0x99,0xcc,0xef,0xfe, - 0xed,0xe2,0x02,0xac,0x34,0x68,0x31,0x13,0x26,0xab,0x2e,0x7f,0xe0,0xd9,0xe7,0xb3, - 0x8f,0x2c,0xac,0x50,0xe6,0x6e,0xdf,0xd5,0x5c,0x56,0x85,0xde,0xac,0x64,0xe9,0xbe, - 0x47,0x4e,0x9e,0xc1,0x05,0x6d,0xef,0x99,0x0e,0x9c,0xb4,0xce,0x36,0x8c,0xe4,0xc3, - 0x25,0x38,0x71,0xae,0xb5,0xf3,0x12,0x3a,0x17,0x4e,0x8c,0x58,0xb3,0x1d,0x4d,0x9e, - 0x4e,0xf1,0x39,0x1d,0xac,0xcb,0x42,0x5a,0x4b,0x80,0x83,0x28,0xac,0xa6,0xf7,0x76, - 0xe5,0xa5,0xe4,0x45,0xec,0x92,0x45,0xe5,0x0f,0xe7,0x1f,0x47,0xef,0x3f,0xfc,0x85, - 0x7b,0x4a,0x59,0x04,0x21,0x9e,0xc2,0x2f,0x0b,0x1e,0xd5,0x00,0x54,0x9f,0x99,0x11, - 0xe2,0x40,0x7c,0x11,0xaa,0x20,0x7b,0x06,0x96,0xd2,0xc8,0x27,0x24,0x76,0xe0,0x4f, - 0xe7,0xaf,0xe9,0xe4,0x4a,0x14,0x20,0x1c,0xe0,0x21,0xbd,0x20,0x4e,0x57,0xd2,0x2e, - 0x33,0x84,0x36,0x55,0x9a,0x8e,0xc5,0x42,0xdb,0xac,0x4b,0x1a,0x41,0xee,0x2d,0xe1, - 0x3d,0xb5,0x56,0xe5,0x90,0xa6,0x69,0x1c,0xd0,0xea,0xac,0xae,0xea,0xbe,0x14,0x91, - 0x22,0x3d,0x49,0xa8,0xbc,0x84,0x31,0xb2,0xc2,0x51,0x6e,0x49,0x11,0x9b,0x46,0x95, - 0xf9,0x4d,0xa4,0x33,0x0a,0xc7,0x88,0x05,0x89,0xd0,0xe6,0x30,0x9e,0xc3,0x7b,0x84, - 0xde,0xec,0x7d,0x38,0x29,0xe9,0x4e,0xd8,0x3b,0x3f,0xff,0xe5,0xed,0x7e,0x90,0x77, - 0xed,0x19,0x78,0x8f,0xea,0x5b,0x17,0xac,0xdd,0xe4,0x86,0x44,0xf4,0x52,0x87,0x09, - 0x83,0x17,0xb7,0x3e,0x68,0xcd,0x72,0xf4,0x23,0x88,0x47,0x51,0x29,0x27,0x0a,0x64, - 0x5d,0xbc,0x51,0x8b,0x45,0x94,0x99,0x86,0x02,0xbe,0xa1,0x25,0x6c,0xe5,0x9d,0xe3, - 0xe4,0x36,0x21,0x09,0x56,0x66,0xcd,0xda,0x99,0x60,0xe1,0x78,0x53,0xd1,0xb2,0x56, - 0xa4,0x30,0x9b,0xd1,0x05,0x4e,0xe3,0x61,0x9c,0xe3,0x0c,0x5d,0xf2,0x1a,0x7f,0xe5, - 0x12,0x17,0x09,0x82,0x45,0x97,0x2b,0x4d,0x5a,0x45,0x5f,0x95,0x67,0x09,0x27,0xd6, - 0xd2,0xca,0xf0,0xe7,0x5b,0x6f,0xb6,0xa2,0x96,0x6e,0xa4,0x93,0xae,0x64,0x79,0x8e, - 0x6b,0xee,0x3d,0x0e,0xe7,0x7b,0xbc,0x9f,0xcc,0xa8,0xa1,0x91,0xcd,0x1e,0xfb,0xbb, - 0x68,0xd0,0x51,0x34,0xad,0x61,0x5c,0xde,0x9a,0xf4,0x2a,0x9f,0x88,0xee,0xc8,0x3a, - 0xed,0x0b,0xce,0x0d,0x18,0x41,0x2b,0x64,0x79,0x49,0x86,0xe1,0xf4,0xb8,0xad,0x9f, - 0x18,0xd9,0xbd,0xd8,0x05,0xbb,0x02,0x5f,0x56,0x7b,0x2b,0x5a,0x2b,0x92,0x9f,0x35, - 0xea,0x3a,0xb8,0x6e,0xc1,0x50,0x63,0xcc,0xe9,0xcb,0xcb,0x42,0xd2,0xad,0x8e,0xa7, - 0xde,0x23,0xb9,0x43,0x68,0xc3,0x7d,0x6e,0xa2,0xad,0x6d,0xf0,0xa9,0xd2,0x25,0xb3, - 0xdf,0x25,0xde,0x04,0x98,0x17,0xa2,0xfc,0xcc,0xd2,0x44,0x94,0x40,0x54,0x88,0x57, - 0x36,0x85,0x46,0x3e,0xd4,0xfb,0x8f,0x68,0x2a,0xa3,0xb9,0x5a,0x1a,0x41,0x1a,0x68, - 0x25,0x36,0x30,0x97,0xb0,0xae,0x48,0xd6,0x4d,0x8f,0xf8,0x71,0xae,0xc8,0x9c,0x34, - 0xf6,0x14,0x04,0x4c,0x8f,0x47,0x75,0x03,0x60,0x66,0x0f,0x56,0x6b,0xeb,0x68,0xfc, - 0x52,0x5e,0x8b,0x5c,0x66,0x6a,0x25,0x8a,0x34,0x88,0x0f,0x98,0xa4,0xc7,0x8f,0x1c, - 0x6e,0x60,0xab,0xd3,0x9f,0x7e,0xfe,0x23,0xc2,0x61,0x41,0x97,0xc5,0x26,0xdd,0x41, - 0xfd,0xae,0x08,0x0b,0xec,0x10,0xc5,0xd4,0x01,0x0b,0xbf,0x28,0xad,0x6e,0xb7,0x42, - 0xfc,0x13,0x90,0x86,0x0d,0xa4,0xad,0x50,0x0f,0xa6,0x61,0x0e,0xd2,0x5e,0x21,0x1b, - 0x8f,0x99,0x07,0xf0,0xf3,0x88,0xee,0x95,0xac,0xb8,0x25,0x5c,0xb0,0x26,0x5f,0x3c, - 0x9e,0x1c,0xf2,0x9d,0xee,0xa2,0xfc,0x1d,0x9d,0x7e,0x25,0x5c,0x10,0xfa,0x37,0x0e, - 0x6c,0xf4,0x1a,0xd1,0xc4,0x22,0x48,0xa2,0x1e,0xd8,0x44,0x31,0xcb,0x72,0x2b,0x05, - 0xba,0x0d,0x25,0x8b,0x7e,0x55,0x14,0x2c,0xc1,0xc2,0x8c,0xc7,0x36,0x1e,0x2d,0x85, - 0x3f,0x59,0xc9,0xf8,0x02,0x11,0xdb,0xa0,0x92,0x66,0xa5,0x9c,0x93,0x39,0x14,0x3a, - 0x13,0x05,0xe2,0x12,0x5e,0xd5,0x32,0x5d,0x7c,0x96,0x16,0xe4,0x62,0x41,0x6a,0x8b, - 0xe5,0x5d,0xd0,0x0d,0x4f,0xc0,0x6a,0x8f,0x35,0x65,0xe1,0xef,0x5a,0x95,0x32,0x0f, - 0xfd,0xbc,0x2f,0x8f,0x01,0xa7,0x75,0x3a,0xe0,0x56,0xbe,0x47,0xf0,0x59,0x2c,0x76, - 0x31,0xdf,0x95,0x76,0x34,0xae,0x75,0xd3,0x8e,0xc6,0xb7,0xa1,0x32,0x5e,0x4e,0x1a, - 0xce,0x4c,0xe9,0xd9,0xbe,0x04,0xed,0xcd,0x26,0x52,0x1e,0x8c,0x49,0x55,0x06,0xdd, - 0xea,0x84,0x5b,0x5b,0x6a,0xb7,0xe2,0x52,0xda,0x36,0xdc,0xfd,0xf6,0x63,0xbc,0x6f, - 0xb4,0xd9,0x4f,0x7a,0x6f,0x82,0xd7,0xeb,0x3d,0xc2,0xfb,0x02,0x3e,0x89,0x5c,0xe9, - 0x5b,0x6f,0x59,0x00,0x6d,0x32,0xd0,0xf2,0x67,0x03,0x65,0xd2,0x18,0x28,0xbc,0xf0, - 0x37,0xb1,0x50,0x18,0xf1,0xfe,0xfa,0xc0,0x52,0x0a,0x03,0x6c,0x6d,0x68,0x44,0x8f, - 0x01,0x36,0x4e,0x65,0xc9,0x65,0xb3,0x60,0x68,0x4b,0x72,0x8d,0x48,0x05,0xda,0x14, - 0x3e,0xe2,0x81,0x19,0x8b,0x24,0x98,0xa4,0xf3,0x26,0x0c,0x33,0x8f,0xc7,0xeb,0xda, - 0x32,0x02,0xab,0x3e,0x82,0x63,0x56,0x53,0xe9,0x32,0xcc,0x6e,0x88,0xee,0x9f,0xf5, - 0x44,0xca,0x99,0x8a,0x91,0xcb,0x7c,0x48,0x0d,0x7c,0xee,0x73,0x59,0x04,0x29,0x86, - 0xa4,0xf1,0xe3,0x77,0x10,0xdf,0x54,0xa3,0x6c,0x8d,0x06,0xf9,0x00,0x1e,0xbc,0xf8, - 0x2b,0x54,0xfa,0x4a,0x1a,0xd8,0xcb,0x5f,0xaf,0xf6,0x87,0x89,0x00,0x77,0x1d,0xae, - 0xfd,0xe8,0x79,0xb8,0xf7,0x47,0x87,0x77,0xbb,0xee,0xfe,0x6f,0x0a,0x40,0x21,0x2f, - 0x45,0x11,0xf6,0xff,0x22,0xd8,0xb6,0x98,0x6f,0xc0,0x30,0x96,0x90,0xf0,0xb9,0xb0, - 0xcb,0x53,0xe0,0x52,0xf6,0x80,0x65,0xb3,0x2e,0x3a,0x2c,0xda,0x31,0x07,0xdf,0x4b, - 0x99,0xd7,0x44,0x43,0x72,0x09,0x07,0x54,0xd9,0xf8,0xd8,0x01,0xd5,0x1b,0xc9,0xfc, - 0x7b,0x78,0xb3,0xd4,0xda,0x4a,0xb2,0x89,0x7e,0x23,0x73,0x3d,0x78,0x50,0xf5,0x1c, - 0x32,0x8c,0x9e,0x00,0x55,0x63,0xd8,0xa5,0x77,0x8c,0x9f,0x10,0xd5,0x4b,0x6a,0x92, - 0x23,0xb7,0x2e,0x25,0x28,0x7f,0x9b,0xba,0x0e,0x45,0xf4,0xb8,0x5f,0x55,0xd5,0x4d, - 0x97,0x02,0x7d,0xd9,0x2f,0xa2,0xcc,0x10,0x38,0x99,0x2b,0xa7,0xd9,0x65,0x48,0x5b, - 0x17,0xad,0x73,0x15,0x6a,0xaf,0x74,0xd4,0x71,0x89,0x63,0xcf,0xb7,0xb9,0x11,0x9f, - 0x24,0x07,0xdb,0xbd,0xf4,0x5c,0x88,0x0c,0xc1,0xdb,0xd4,0x5b,0xa4,0xe4,0x58,0x29, - 0xeb,0x7d,0x61,0xa7,0xc1,0x7a,0xef,0x90,0x4d,0x55,0x28,0x44,0x94,0xcd,0x4e,0x7b, - 0xcf,0x58,0xd9,0x20,0x0e,0x59,0x3e,0x07,0x63,0xbc,0xd8,0x00,0x45,0xbd,0x6b,0x19, - 0xb4,0xeb,0x9a,0xbc,0x97,0x57,0x50,0x0d,0x74,0x8d,0x23,0x4f,0xc6,0x96,0x96,0x88, - 0x1c,0x9f,0xdc,0x34,0x46,0x4a,0x79,0x55,0x3b,0xca,0x3b,0x59,0x73,0x7c,0xb2,0xa5, - 0xb1,0x87,0x08,0x73,0xfe,0x8b,0x17,0x66,0x75,0x37,0xc0,0x31,0x9e,0x79,0x4f,0xd0, - 0x7b,0xf9,0x86,0xed,0xe8,0x7e,0x6b,0xb6,0x2d,0xb6,0xc7,0x28,0x4f,0x5e,0x63,0x08, - 0x32,0xca,0xeb,0xbe,0x79,0x21,0xe2,0xd4,0x36,0x99,0xa3,0xb4,0x61,0x29,0x39,0xa2, - 0x28,0x52,0x6b,0xf9,0x73,0x6c,0x60,0xd9,0xb5,0x87,0x9b,0xd0,0x0f,0xe0,0x81,0xbb, - 0xb6,0xda,0xbd,0x43,0x89,0xfa,0xa5,0xb5,0x03,0xea,0xf4,0xb0,0x41,0x50,0x3e,0xac, - 0xd1,0xba,0xba,0xa7,0xa3,0x82,0x8e,0xee,0xa2,0x82,0x8e,0x6a,0x15,0x14,0x96,0xc7, - 0x8e,0x1e,0x1e,0xf8,0x30,0xf7,0x9e,0x6a,0xf0,0x75,0xb4,0x51,0x78,0xd1,0xf6,0x87, - 0x68,0xf7,0xd5,0x3f,0x9c,0x4b,0xfd,0xf8,0x5b,0x1d,0x98,0x5b,0x79,0xf5,0x67,0x7d, - 0xe5,0x5d,0x6a,0x1d,0xf6,0x0d,0xaa,0x6b,0x41,0x82,0x54,0x39,0x2b,0x8b,0x05,0x90, - 0xa4,0x58,0xcf,0x0b,0x94,0x64,0x32,0x0f,0xba,0xfe,0xa0,0x42,0x8a,0x4b,0xd7,0xa8, - 0x7c,0xf8,0xa5,0x5c,0x68,0xe3,0x4b,0xd2,0x44,0xc1,0x7a,0xb1,0x96,0xbe,0xa5,0x76, - 0x4d,0x0c,0xcc,0xe9,0x4a,0x65,0xb8,0x9d,0x21,0x10,0x97,0xac,0x25,0x79,0x12,0x6a, - 0x46,0x23,0xc9,0xfa,0x92,0x39,0xfb,0x8e,0xf5,0xe5,0x67,0x44,0x0c,0xb9,0x3d,0xbf, - 0xbc,0xba,0x78,0x15,0x05,0x7f,0x86,0x13,0x07,0xe3,0x4c,0xe1,0x8f,0xb6,0x59,0xd4, - 0xc5,0x5f,0x73,0x91,0x6b,0x06,0xeb,0x2d,0x70,0x1d,0xa2,0xbe,0xde,0x4b,0x61,0xa4, - 0x75,0x20,0x94,0xa1,0xb2,0x2f,0x06,0xf8,0x09,0xc8,0xf4,0x32,0x25,0x95,0xf2,0xf6, - 0x87,0xf7,0xa4,0x40,0xd8,0xe4,0x64,0x33,0x8b,0xb1,0x06,0x14,0xd3,0x1e,0x24,0x48, - 0x3e,0x5c,0x95,0xd2,0x78,0xa2,0x65,0xe4,0x1a,0x0c,0x67,0x1f,0x9a,0xd8,0x71,0xc6, - 0x06,0x79,0xc3,0x3d,0x3e,0x5b,0xe7,0xe4,0x1f,0xaa,0xc0,0x23,0x81,0x3d,0xa2,0x1f, - 0x43,0x6e,0xcb,0x16,0xc8,0xa0,0x43,0xf8,0x8d,0x56,0x14,0x25,0x4e,0x61,0x6e,0x20, - 0x46,0xcb,0x8a,0x75,0xce,0x68,0x61,0x16,0x82,0x5f,0xff,0x72,0x61,0xc1,0x6a,0x8e, - 0xf0,0xa8,0x4c,0x06,0x75,0x6d,0xd7,0x15,0x23,0x36,0x44,0x83,0x0a,0x6f,0x6a,0x11, - 0x28,0x6a,0xd5,0x04,0x91,0x86,0x23,0x93,0xdf,0xac,0xdf,0x8e,0x47,0xee,0xba,0x81, - 0x48,0x6e,0xeb,0x62,0x6e,0x30,0x52,0x38,0x38,0xa4,0x6e,0x3b,0x2a,0xdf,0x22,0x3e, - 0x06,0xda,0x19,0xcd,0x49,0xc8,0xea,0xb4,0x7a,0x25,0x6b,0x34,0xb4,0x8f,0xc6,0xa2, - 0xc8,0x87,0xc0,0x1a,0xe9,0x53,0xc7,0x25,0x0a,0xed,0xec,0xb7,0xd2,0x07,0x93,0x81, - 0xfa,0xa0,0x23,0xa8,0x6f,0xc8,0xfd,0x77,0x88,0xc6,0x28,0xf6,0x59,0x6a,0xde,0x49, - 0xea,0xb7,0x45,0x7c,0x5c,0xeb,0x93,0xa4,0xb4,0xd5,0x00,0xe9,0x7e,0x3c,0x4c,0xba, - 0xd7,0xca,0x85,0xd7,0x1d,0x71,0x5e,0x24,0xf1,0x22,0xff,0xb8,0x11,0xf9,0x7e,0x57, - 0x78,0x24,0x56,0xd5,0x29,0x87,0xc8,0x3a,0x14,0x08,0x0b,0xf4,0x93,0x20,0xda,0xa5, - 0xe7,0xe2,0x0b,0x53,0xbd,0x8e,0x3c,0x7a,0x3b,0x5e,0xe6,0xec,0x4f,0x3e,0x01,0x0a, - 0x83,0x70,0x47,0x4c,0x4c,0xa0,0xc6,0xaf,0xe3,0x84,0x22,0xcf,0x29,0x18,0xe2,0x0d, - 0xd1,0xe0,0x67,0x5a,0x50,0xa5,0xd3,0xe0,0xeb,0x6b,0x28,0x46,0x61,0x82,0x34,0xbe, - 0x08,0x71,0x68,0x76,0x55,0x50,0xc4,0xd7,0xe1,0xc5,0x60,0xae,0x3d,0x69,0xc5,0x0b, - 0xe5,0x7c,0xad,0x40,0x97,0x2c,0xb4,0xee,0xcc,0x3f,0x6d,0x24,0x52,0x3a,0xf3,0x26, - 0x4f,0x1d,0x05,0x9e,0xba,0x8f,0xe2,0x27,0x84,0x6f,0xaf,0xc7,0xb1,0x5b,0xc4,0xa3, - 0x64,0xe6,0xc2,0xcf,0x40,0x18,0x8f,0x8f,0x2e,0x6f,0xf4,0x64,0x2d,0x78,0x6d,0x6c, - 0xe8,0xd0,0xac,0xb6,0xa2,0xbb,0x65,0xe4,0x4d,0x86,0x98,0x0b,0x3a,0x93,0xd9,0x9d, - 0x6c,0xff,0xdb,0xac,0xf3,0xea,0xfa,0x56,0x97,0x80,0x0d,0xe3,0xfe,0xa4,0x89,0xa8, - 0xaa,0x5d,0xfc,0xed,0xc4,0xdc,0xd2,0x11,0xc3,0xb7,0x06,0xd9,0x2c,0xe1,0x50,0xda, - 0xb3,0x2d,0xd5,0xca,0x36,0xb4,0x3c,0xf6,0xce,0x04,0x16,0x89,0xc9,0x8c,0x2f,0x71, - 0xdf,0x18,0x8e,0x0d,0x26,0x33,0x62,0xe3,0xfe,0x31,0x64,0x7c,0x58,0xa4,0x1a,0x7d, - 0xf4,0x8f,0xca,0x0a,0x5c,0x08,0x93,0x6c,0xfd,0x11,0x04,0xe7,0xcd,0xc1,0xde,0x7b, - 0xcd,0xde,0xfd,0x2e,0x2b,0xed,0xfd,0x56,0xc4,0xe5,0xae,0x01,0x97,0xaf,0xc5,0xd9, - 0xc6,0xd3,0xa3,0x67,0xc7,0xf5,0x4e,0xaf,0x8b,0xb5,0x74,0x5a,0xbb,0xe5,0xe0,0x28, - 0xcf,0x3c,0xce,0x48,0x6f,0xdb,0x1e,0xb6,0x2a,0xa2,0xce,0x12,0x0a,0x69,0xc5,0x54, - 0xf4,0xe8,0x51,0xe1,0x4e,0x6b,0x8b,0x8b,0xf2,0xb1,0xbb,0x55,0x55,0x54,0xf5,0xd0, - 0x80,0xc8,0x7f,0x07,0x30,0x58,0x6c,0xb0,0x1d,0x03,0x75,0x1a,0x16,0xba,0x28,0xf4, - 0xd5,0x10,0xb3,0xae,0x83,0x91,0xe9,0xc9,0xc9,0xd1,0xb4,0x8b,0x91,0x28,0xd0,0xee, - 0x86,0x94,0x95,0xc8,0x5a,0x38,0x99,0x1c,0x77,0x71,0x12,0xdd,0xd7,0xb8,0xc3,0xad, - 0x88,0xa0,0x71,0x6f,0x26,0xf8,0xcc,0x0e,0x1f,0x77,0xbc,0x38,0x3a,0x7a,0x71,0x7c, - 0xfc,0xe2,0xe4,0x04,0xc5,0xa2,0x28,0x73,0xbd,0x8a,0x9f,0x23,0x8e,0x36,0x8e,0x7c, - 0xd8,0x4f,0x9b,0xd8,0xca,0xe1,0xbe,0x51,0xc8,0x8d,0xa4,0xf0,0xa6,0x90,0x02,0xfb, - 0xa4,0xc5,0x4d,0xd9,0x80,0xe9,0x40,0x90,0xfa,0xcc,0x53,0xae,0x25,0x27,0x7b,0x5a, - 0x79,0x23,0x27,0x45,0x81,0xd8,0x58,0x14,0xe2,0x72,0x20,0x42,0xb1,0x3e,0xf0,0xf0, - 0xe9,0xa4,0x8b,0xd1,0xb8,0x56,0x27,0xae,0xd4,0x45,0x63,0x18,0x89,0x6b,0x68,0x66, - 0x08,0xf8,0x22,0xb0,0x2f,0x58,0x38,0x1f,0x16,0x8b,0x97,0x07,0xbe,0xbd,0xd3,0x5f, - 0x62,0x77,0x59,0xf7,0xf6,0x47,0xa2,0x28,0x4b,0x9b,0xcb,0x4a,0x72,0xa1,0x15,0x68, - 0xce,0x7e,0x45,0x6c,0xc4,0x30,0x4b,0x0a,0xaf,0x72,0x7e,0xa0,0x6e,0x65,0x50,0x61, - 0xc5,0x06,0xd6,0xa5,0x53,0x05,0xf0,0x9f,0xb6,0x83,0x4a,0x28,0x83,0xe3,0x82,0xca, - 0x13,0x59,0x26,0x2b,0xc7,0xce,0x89,0x37,0x12,0xe7,0xba,0x24,0xf3,0xaa,0x92,0xd2, - 0xe0,0x52,0x65,0xbd,0xbc,0xd1,0x4e,0x30,0xd0,0x46,0x52,0xd8,0xde,0xc6,0x75,0x90, - 0x52,0x8c,0x77,0x8b,0x1d,0xff,0x58,0x2b,0x23,0x41,0x04,0xbd,0x31,0x10,0xf1,0x93, - 0xe9,0x64,0x7c,0x7c,0x1c,0xb3,0xde,0x16,0xe5,0x90,0xac,0x8a,0xcd,0x28,0x1c,0xa7, - 0x26,0xc8,0xef,0xd4,0xe5,0x3d,0x2d,0x36,0x21,0x81,0x87,0xf5,0x51,0x85,0x57,0x4a, - 0x79,0x48,0x2f,0x39,0x60,0x2f,0x14,0x34,0xed,0xf7,0x11,0xa6,0xd4,0x3e,0x84,0xb3, - 0x81,0xf7,0xba,0x6f,0xcc,0x46,0xda,0x38,0xe8,0x6f,0xd2,0x0e,0x22,0x62,0x3d,0x1a, - 0xb4,0xc1,0x95,0x49,0x12,0x24,0xaf,0x56,0xf0,0x0b,0x10,0xd0,0xdf,0x27,0xb0,0x30, - 0x7a,0xc5,0x46,0x11,0x92,0xc1,0xa8,0x2f,0xc2,0x49,0xe2,0x6d,0xce,0x1b,0x3a,0x91, - 0x39,0x0b,0x57,0x44,0x39,0x36,0x73,0x83,0x74,0x51,0xb6,0xb1,0x45,0x52,0xa0,0xf5, - 0x39,0xa1,0x68,0x24,0x18,0x9a,0x5d,0xa8,0x95,0x72,0x32,0x4f,0xe1,0x6f,0xec,0x3d, - 0x2c,0x75,0x98,0xe3,0xf7,0xd0,0xad,0xb5,0xfa,0xa8,0xc6,0x16,0x4b,0xeb,0xc2,0x24, - 0x7d,0x9a,0xe0,0x77,0xe1,0x94,0x5b,0x37,0xde,0xe6,0xce,0xa8,0x67,0x21,0x5c,0x4c, - 0x6e,0x88,0x72,0xd3,0xa3,0x0a,0x1a,0x26,0x28,0x2f,0xef,0xb0,0xb4,0x2e,0x6f,0x5b, - 0xfa,0x5b,0xc5,0x06,0xbb,0x96,0x28,0xda,0x35,0xb6,0x8e,0xe0,0x89,0x32,0xdf,0xf6, - 0xe7,0xa5,0x8d,0xf9,0x73,0x8e,0xe6,0x91,0xaa,0x58,0xe1,0x10,0xdb,0x8e,0xdf,0x75, - 0x54,0x44,0x6d,0x70,0xc6,0x68,0x6a,0x13,0x3d,0xdc,0x15,0x53,0xfb,0x2f,0x0e,0x01, - 0xfe,0x0f,0x89,0xe9,0x35,0x14,0x46,0xce,0xfa,0x24,0x42,0x62,0xa2,0x55,0x49,0x46, - 0x85,0x83,0x20,0x8d,0xd9,0x2a,0x0e,0xe3,0x51,0xfc,0x84,0x3f,0x99,0xd5,0x99,0x29, - 0x10,0x15,0x8b,0x23,0x4e,0x2d,0xf6,0x31,0xc8,0x8f,0x24,0x22,0x65,0x99,0x6d,0x9e, - 0xc0,0x1c,0x69,0x1f,0xfe,0x36,0xf0,0xf9,0x8f,0xcc,0x2b,0x6f,0x3e,0xc1,0xaa,0xc9, - 0xd7,0xb1,0x9f,0xcf,0xd9,0x0f,0x79,0x8d,0x94,0xdd,0x0a,0x1d,0x09,0xb8,0x32,0x78, - 0x0d,0x58,0xfe,0x84,0x8c,0xda,0xb6,0xcb,0xbb,0x08,0x5a,0x41,0x99,0x5a,0xea,0x5f, - 0xcb,0x9c,0xb9,0x2c,0x94,0x3d,0xf4,0x7a,0x23,0x3d,0xe4,0xaa,0xa1,0x86,0xbd,0x77, - 0x3f,0xff,0xb1,0xff,0xf5,0xab,0x67,0x2e,0x71,0x3a,0x4e,0x8a,0x97,0xef,0x30,0x3d, - 0x3c,0x1c,0xc7,0x94,0xe6,0xc9,0x61,0x48,0x6e,0x4c,0xf0,0x01,0xc5,0x57,0x18,0xe5, - 0x75,0x44,0x12,0xec,0x7d,0x1e,0xbc,0xf3,0xfc,0xaa,0xd9,0xb7,0xde,0xf6,0x69,0xd8, - 0xb4,0xb5,0xe7,0xdd,0xd0,0x70,0x5e,0x19,0x29,0xa8,0x56,0x34,0xd8,0x21,0x5d,0xd5, - 0x13,0x21,0xb0,0x34,0x29,0xe8,0x81,0x93,0x9b,0x7a,0x63,0x36,0xed,0xb4,0x3c,0xed, - 0xb4,0x3c,0xeb,0xb4,0x3c,0xef,0xb4,0x8c,0x0f,0xbb,0x4d,0xe3,0x6e,0xd3,0xa4,0xab, - 0x92,0xbe,0x72,0x39,0xe9,0x8c,0xac,0x37,0xfa,0x4f,0x98,0x99,0x87,0x9f,0xb0,0x17, - 0xac,0xbb,0xe7,0xd5,0xbe,0x61,0x5a,0x6d,0xb7,0xb0,0xd8,0x92,0x02,0xa1,0x96,0x39, - 0xda,0x29,0x36,0xc8,0x91,0xb7,0xbe,0x99,0x25,0xc0,0x60,0xd6,0xfa,0x50,0xc2,0x5c, - 0x38,0x27,0x4d,0x6d,0xcf,0xdc,0x34,0x67,0xc2,0x6e,0xe9,0x4a,0xe7,0xf2,0x41,0xf6, - 0x65,0xb7,0x37,0x94,0x86,0xcc,0x5e,0xf3,0x67,0xdf,0xa8,0x60,0xed,0x51,0x71,0x25, - 0x7f,0x61,0x8b,0x71,0xf7,0x92,0xa3,0x30,0x27,0x2e,0x0d,0xff,0x0a,0xa1,0xa5,0x6f, - 0x1e,0x49,0x71,0x8a,0x97,0x67,0xe8,0xc1,0xc7,0xaf,0x77,0x64,0xdf,0x0b,0xb5,0x92, - 0x54,0x63,0xb5,0x67,0x65,0xa6,0xcb,0xdc,0x0e,0xe3,0x91,0x88,0x5e,0xe7,0x67,0xdf, - 0x28,0xbf,0xc0,0x27,0xe0,0x87,0x75,0x01,0xc6,0x7d,0xc5,0xc7,0x87,0x92,0x2b,0xcf, - 0x98,0x7b,0xbf,0x46,0xe5,0xb5,0x9d,0xff,0x53,0x29,0xfd,0xff,0x94,0x66,0x14,0x3f, - 0x90,0xda,0x6c,0xcc,0x37,0xe0,0x87,0x40,0xa3,0x75,0xc2,0xc4,0x9a,0xef,0x90,0x0a, - 0x22,0x83,0x5d,0x15,0xd2,0xeb,0xe5,0xaa,0x22,0xcb,0x1b,0xc1,0x08,0x9e,0x2e,0x99, - 0xe5,0x6f,0x9a,0x82,0x40,0x36,0xfc,0x2c,0x0f,0x0d,0xa0,0x92,0xc6,0x0f,0xd1,0x1c, - 0x6d,0x22,0x5e,0x81,0x75,0xb2,0xf5,0x81,0xfc,0x2b,0xb4,0x01,0x40,0xb9,0xb4,0x61, - 0x30,0xc8,0xa5,0x0b,0xe1,0x2d,0xef,0x2f,0xda,0x58,0xa8,0x32,0xd7,0xc2,0xe4,0xe9, - 0x20,0x93,0x28,0x06,0xd1,0xfa,0x64,0x59,0xbf,0x47,0x57,0xd3,0xe8,0x95,0x32,0x84, - 0xe4,0xa0,0x31,0x07,0x11,0x48,0x2c,0x1a,0xf5,0x1d,0xb5,0xf7,0x61,0x6f,0x49,0x8e, - 0x58,0x8c,0x72,0xe4,0xa1,0x61,0x9e,0xe6,0x71,0x53,0x31,0xf2,0x57,0xc8,0x65,0x41, - 0xa5,0x64,0xc2,0x0e,0xf3,0x25,0xcc,0x35,0x4f,0xe8,0xc2,0x56,0x9b,0x33,0x5d,0xc3, - 0xa2,0x0f,0x8e,0x93,0xf1,0xa4,0xe1,0xe2,0x00,0xc9,0x5d,0x50,0xe4,0xbe,0x0a,0xcb, - 0x0e,0xfd,0xd6,0x85,0xcd,0xb6,0xdc,0x3a,0x2a,0x67,0xf3,0x46,0xec,0x7c,0xf6,0xe6, - 0xd5,0x5b,0xd8,0xe3,0xea,0x8e,0x32,0x96,0xf2,0x72,0x72,0x6f,0xa5,0xc8,0x67,0x9e, - 0x23,0x94,0xb3,0x37,0xa1,0xea,0x0b,0xa1,0x57,0x5f,0x94,0xdb,0x34,0x9c,0xe7,0x4b, - 0xa7,0x79,0xa9,0xf6,0xe3,0x0c,0x77,0x59,0x24,0xed,0x03,0x72,0x2d,0xca,0x5c,0x5f, - 0x37,0x47,0xcc,0x04,0x19,0xee,0x6b,0x5c,0x60,0x1d,0x16,0xf9,0x3a,0xe4,0xe3,0x69, - 0x03,0x3a,0x51,0x78,0xae,0x35,0xd5,0xa5,0xc0,0xa5,0x50,0x65,0x80,0xf6,0xfc,0xaf, - 0xe3,0xc9,0xf4,0x1a,0x8c,0xcc,0xa4,0xa2,0xbc,0x0f,0xcb,0xb6,0x07,0x01,0xca,0xce, - 0x40,0x6a,0xae,0x69,0x93,0x3b,0x43,0x3c,0x39,0x3c,0xde,0x46,0xf7,0x8f,0x3f,0xbc, - 0x83,0x08,0x77,0x00,0xf8,0x87,0x6b,0x27,0x0d,0x45,0x16,0x17,0x86,0x42,0xdc,0xb2, - 0xcc,0x47,0xa8,0x18,0xd6,0x85,0x84,0xdf,0xdf,0xbf,0xfa,0x06,0x80,0x2f,0xe4,0xea, - 0xbe,0xc0,0x3f,0x1b,0x3f,0x9f,0x6c,0x01,0xff,0x96,0xa3,0x07,0x41,0xfc,0x58,0xce, - 0xc9,0x84,0x33,0x7c,0x92,0xf9,0x3a,0x93,0x21,0xbc,0xc0,0x72,0xf1,0xa7,0x8f,0xe7, - 0xa0,0xf2,0x22,0x8c,0x7e,0xd0,0x31,0x78,0x05,0xbf,0xdd,0xae,0x13,0x6c,0x09,0x81, - 0xc3,0xe7,0xd3,0xe0,0xc7,0x5d,0x57,0x96,0xdf,0x9d,0x25,0x9d,0x63,0xb6,0xf8,0xe8, - 0x96,0x23,0xbd,0x5d,0xbb,0xcd,0x28,0xdb,0x64,0x41,0xa8,0xb3,0xf3,0x18,0x99,0xea, - 0x94,0x7c,0x30,0xf6,0xdb,0x2d,0x47,0x6c,0x54,0xb9,0xd6,0x6b,0x1b,0xbb,0xef,0x7f, - 0x58,0x02,0x97,0x32,0x21,0x14,0xe3,0x19,0x70,0x39,0x58,0x48,0x37,0xe7,0xf4,0xaa, - 0xd5,0xf6,0x99,0x27,0x78,0x4e,0xa4,0x49,0x21,0xbf,0xc8,0xa2,0xc7,0xea,0xe7,0xdd, - 0x79,0x40,0xc7,0x2a,0x41,0x2d,0x39,0x86,0x3d,0x3c,0x2b,0xe5,0x59,0xf9,0x4f,0x0c, - 0xf4,0x46,0xd4,0x90,0x63,0x26,0x7d,0x7d,0x47,0xc9,0xec,0xa8,0xaf,0x0f,0x45,0xf7, - 0x71,0x5f,0xdf,0x49,0x32,0x3b,0x81,0xbd,0xb9,0x28,0x58,0x5b,0xf5,0x6e,0x8d,0xd2, - 0x61,0xda,0xd7,0xf7,0x34,0x99,0x3d,0xed,0xe9,0x23,0x81,0xf8,0xac,0xaf,0xef,0x79, - 0xd2,0x75,0xcc,0x6a,0xac,0x1c,0x22,0x5a,0x0e,0xfb,0x7a,0x57,0xa2,0x5c,0x0b,0x44, - 0xe5,0x3b,0xfe,0x04,0xc7,0xa9,0xeb,0xdb,0xc2,0x87,0x2d,0x96,0xf0,0x0f,0xf8,0xbb, - 0xd2,0xa7,0xb2,0x3d,0x9e,0x74,0xc3,0x00,0xe4,0xbd,0xae,0x90,0x75,0x46,0x0b,0x25, - 0x8b,0xbc,0x29,0x61,0x0f,0xcd,0xbb,0xa8,0x1e,0xa7,0x76,0x08,0x7f,0xe8,0xcd,0x9f, - 0x10,0xb0,0xec,0xf8,0xc7,0x3d,0x78,0x99,0x22,0x5e,0xa6,0x60,0x37,0xab,0xb9,0x2e, - 0x6c,0x2f,0x33,0x4c,0x90,0x1b,0x26,0x71,0xd4,0x70,0x67,0x91,0xf9,0x3e,0xba,0x69, - 0xf1,0xec,0x01,0xd9,0xbd,0xbc,0xef,0xaf,0x26,0x5c,0xa9,0x32,0xc7,0xc9,0x7b,0x98, - 0xa5,0xce,0x8c,0x3e,0x1d,0x60,0x51,0x06,0x04,0x99,0xe8,0x62,0x8e,0x0f,0x0f,0x0f, - 0x6b,0x27,0x93,0xff,0xd7,0x31,0x25,0x7b,0xc3,0x0b,0x85,0x94,0xd5,0xfd,0x41,0xb0, - 0x34,0x7d,0x38,0x14,0xfd,0x06,0x6d,0x83,0x35,0xfe,0xd9,0x33,0xbc,0xa3,0x0e,0x98, - 0x60,0x8d,0xd4,0x94,0x95,0x14,0x51,0x87,0xfd,0xa8,0xcd,0x95,0x30,0xb9,0x8f,0x66, - 0x39,0x23,0x16,0x0b,0x95,0xa5,0x40,0x01,0xf8,0x33,0xf0,0xc6,0xc5,0x88,0xd3,0x0f, - 0x7b,0xd6,0xa9,0xa2,0x88,0x55,0x57,0x96,0x35,0x45,0x2c,0xb2,0xb2,0xfb,0xe9,0xc3, - 0xb4,0x1d,0x03,0x34,0x54,0x6a,0x46,0xe3,0xa9,0xc9,0x4d,0x63,0x6a,0xba,0x95,0x7d, - 0x3b,0xee,0x0f,0x7e,0x73,0x45,0xad,0xe0,0x1c,0x0c,0xec,0x21,0x3d,0x86,0xf9,0x25, - 0x7e,0x42,0x8a,0x28,0x27,0x19,0x5a,0xdc,0x34,0xe8,0x8e,0x6f,0x35,0x81,0x67,0x87, - 0x70,0x46,0xda,0x66,0x40,0xc5,0xce,0x8f,0x85,0xd6,0x79,0x0d,0xd6,0xd2,0x0c,0x74, - 0x97,0x16,0x34,0x2d,0xdd,0x0d,0xdc,0x78,0xfa,0x6c,0x17,0x70,0x4f,0x40,0x16,0x56, - 0xc2,0xd1,0xa3,0x92,0xe3,0x97,0x38,0x9a,0x01,0x1d,0x16,0x8d,0xdf,0x8e,0xb8,0x12, - 0x2c,0xad,0xa8,0x3c,0x9f,0x09,0x05,0x4e,0xa8,0x56,0xc0,0x5f,0x95,0xed,0x0b,0xbd, - 0xfe,0xac,0x2b,0x9f,0x06,0xf1,0xc5,0x42,0xbc,0x56,0x64,0xc6,0xad,0xf0,0xe9,0xc2, - 0xf3,0xaa,0xc5,0x38,0x3c,0x6b,0x7d,0x96,0x46,0x5e,0x8f,0x0b,0x55,0xe2,0x18,0x65, - 0x37,0x50,0xd2,0x9b,0xef,0xb9,0x5e,0xd3,0x9b,0x13,0xa7,0x35,0x6e,0x7c,0x15,0xe2, - 0xb0,0x95,0x30,0xce,0xc6,0xc4,0x1c,0xf3,0xbb,0x5e,0x3b,0xfa,0xcd,0x2f,0xef,0xd2, - 0x01,0x49,0x95,0xc9,0xb3,0x5e,0xce,0xc2,0x78,0x7f,0x80,0x7b,0xc9,0x07,0x1d,0x4c, - 0x3e,0xa4,0x52,0x9b,0x64,0x5d,0xfe,0x0d,0x14,0x0b,0x34,0x9a,0x1e,0xa7,0x10,0x5e, - 0x4d,0x01,0x7e,0x1f,0xc0,0x5e,0x04,0x5b,0x60,0xae,0xbb,0x03,0x17,0xf8,0xeb,0xfe, - 0x30,0x3e,0x0b,0x20,0x0e,0xf2,0xbf,0x18,0xc9,0x2d,0xc0,0xd7,0xa5,0xcd,0x74,0x25, - 0xf3,0x7b,0x63,0x37,0x8d,0x2b,0x74,0x8e,0x70,0xa7,0xfa,0xfd,0x57,0x95,0xcf,0xdb, - 0x39,0x0d,0xbe,0x96,0xd4,0xfa,0xb2,0xcf,0x52,0xc7,0x1a,0x4e,0xde,0x25,0x85,0x88, - 0x83,0x9d,0xb4,0x19,0x20,0xc6,0x26,0x27,0xd3,0x2d,0xb9,0xa5,0xab,0xc6,0x79,0xdb, - 0x91,0x57,0xd5,0x55,0xea,0x87,0xdd,0x39,0x3a,0x45,0x45,0xec,0x2b,0x36,0x7a,0xfc, - 0x97,0xde,0x71,0x3a,0x97,0x14,0x7f,0xc6,0x81,0xe1,0x5b,0xdf,0x48,0xeb,0x8c,0x22, - 0x40,0xce,0xf9,0x73,0x50,0xf2,0xf5,0xad,0x41,0xf2,0x06,0x4a,0x07,0x2c,0x87,0xc7, - 0x0c,0x05,0xd9,0x2f,0x1b,0xc8,0x84,0x31,0x9b,0xd6,0x4b,0xf6,0xa5,0xa0,0xc4,0x9c, - 0xdf,0x43,0x1a,0x38,0x83,0x85,0x24,0xd9,0xe0,0x75,0x0a,0x91,0xab,0x60,0x20,0xf3, - 0xe8,0x23,0xe7,0xb8,0x45,0x85,0x72,0xe9,0x76,0xae,0xec,0xd4,0xdd,0x70,0x25,0xd0, - 0xb0,0xca,0x69,0x7e,0x5a,0x14,0x02,0x47,0x64,0xce,0xef,0xaa,0xc7,0xd9,0xad,0x11, - 0x43,0x49,0x66,0xf4,0x26,0xe0,0x07,0xfe,0x06,0xb4,0x41,0x4d,0xfb,0x2e,0xf2,0x2e, - 0xd6,0xa6,0xf4,0x29,0x26,0xdd,0x84,0xb0,0x08,0x75,0x05,0xcc,0x8d,0xfe,0x2c,0x4d, - 0x08,0x75,0xb1,0xfb,0xe3,0x6b,0x31,0xa5,0x32,0xcd,0x53,0x9f,0x2e,0x42,0x7a,0x8f, - 0xfa,0x0b,0xd7,0x5c,0xbb,0xcd,0xfd,0x0b,0xc3,0xff,0xcb,0xeb,0xc2,0x63,0xf8,0xef, - 0x14,0x54,0xa7,0x12,0x3c,0x85,0xd7,0x9c,0xe2,0x3d,0xfb,0x36,0x05,0xdd,0xff,0xd5, - 0xf5,0xdc,0xf7,0xab,0xbd,0xfe,0xe7,0x94,0x5e,0xf7,0x53,0xb0,0xb7,0xac,0x9a,0xf5, - 0x35,0xef,0xf6,0xd8,0xb6,0xab,0xab,0x89,0xad,0x42,0x75,0xd7,0xfe,0x3d,0x2b,0xa3, - 0x07,0x16,0x46,0x0f,0xbb,0x16,0x1f,0x3d,0x77,0xe1,0x6d,0xea,0xb3,0x74,0x2e,0xa2, - 0xe4,0x62,0x3e,0xe3,0xa7,0x9d,0x54,0x93,0xba,0xae,0x0a,0x2d,0x72,0x7e,0x84,0x45, - 0xb7,0x97,0x25,0xc9,0x08,0x70,0x0a,0xad,0xe5,0x3d,0x38,0x11,0x2e,0x31,0xe0,0x02, - 0xaa,0xfc,0x3b,0x07,0xa7,0xb9,0x16,0xb6,0x36,0x67,0x02,0x06,0x7a,0xc3,0x25,0x5c, - 0x24,0x18,0xde,0x43,0x04,0xeb,0xff,0xa3,0x34,0x4a,0xe7,0x88,0xe9,0x25,0x17,0x47, - 0x1d,0x50,0xa7,0x05,0x5e,0x33,0x8e,0xf4,0xa5,0xfc,0x0f,0xb2,0xef,0x19,0x8f,0x7e, - 0xb5,0x1e,0x23,0xbf,0x17,0xe4,0x80,0xd1,0xa8,0x0c,0x02,0xd8,0xef,0x04,0x3f,0xb7, - 0xb2,0xa8,0x80,0xb3,0x25,0x9b,0x8c,0xa2,0x28,0xc2,0x98,0xda,0x6e,0x44,0xea,0xea, - 0xab,0x87,0xc3,0x1d,0x76,0xbe,0x2b,0xe0,0xaf,0xf2,0x1c,0x8c,0xb8,0x02,0xfe,0xf3, - 0xc5,0x11,0xee,0x57,0x05,0x97,0xfd,0x97,0x39,0xe3,0x77,0xb1,0x2e,0x0a,0xe6,0x76, - 0x1e,0x13,0xb0,0xce,0x93,0xbe,0x11,0xca,0x71,0xa9,0xbb,0x82,0x1d,0xbc,0xed,0xbc, - 0x8d,0x70,0x6c,0xe6,0xb7,0x09,0xa1,0x91,0x1f,0x90,0x86,0xaa,0x85,0x50,0xce,0xf0, - 0x0d,0x80,0xbd,0xbe,0x23,0xac,0x6c,0x2c,0xc0,0x5c,0x44,0xc7,0x89,0x9f,0xe8,0x21, - 0x8f,0x99,0x88,0xee,0xf0,0x00,0x2b,0x9c,0x28,0x8c,0x0a,0xf6,0xc4,0x42,0xa8,0x02, - 0xf0,0xb7,0x5a,0xd4,0xcf,0x79,0x3e,0xd4,0x81,0xc1,0x4f,0x3f,0x02,0x49,0xab,0x75, - 0xb0,0x66,0x94,0x55,0xf3,0x82,0xe9,0x93,0xe9,0x82,0x2c,0x17,0x6d,0xec,0xc3,0xcf, - 0x1b,0xdc,0x36,0x86,0x61,0x73,0xdf,0x6b,0x11,0x9c,0x1d,0xd3,0xb9,0xcf,0xb1,0x03, - 0x1c,0x5b,0x0e,0xa2,0xcc,0xbd,0x79,0x6a,0x61,0xef,0xe3,0xf9,0xa7,0x57,0xef,0x7c, - 0xaa,0xc9,0x87,0xd8,0xf7,0x1f,0x7e,0x98,0x1a,0x8e,0x87,0x39,0xf1,0xbd,0xd9,0xc4, - 0x90,0xd7,0x70,0x0d,0x63,0xf6,0xda,0xc0,0x0c,0x8f,0xbb,0xbe,0x57,0x76,0xf6,0x55, - 0x51,0xc0,0xc5,0x5f,0xfb,0x46,0x04,0x47,0x88,0xb4,0x48,0x64,0x26,0xc6,0xdf,0x20, - 0xcb,0xb6,0x7d,0x83,0x1a,0x0b,0x96,0xc5,0xc1,0xa0,0x37,0x52,0xe7,0x5e,0x1c,0x47, - 0x3f,0x7f,0x70,0xf8,0x22,0xa0,0x24,0xce,0xbb,0x91,0x50,0x9d,0x76,0x32,0x63,0x0f, - 0xa4,0xd5,0xfb,0xc0,0x0a,0xdb,0x90,0x2e,0xc9,0x1d,0xff,0x8f,0xf6,0xfe,0xbd,0xbf, - 0x6d,0x1b,0xd9,0x1f,0xc7,0xff,0xf7,0xa3,0x60,0xb8,0x3d,0x0e,0x59,0x51,0xb2,0x6c, - 0x27,0x69,0x2b,0x85,0xf1,0xcb,0x75,0xd3,0x36,0xa7,0xb9,0x9d,0xd8,0xdd,0xee,0xf9, - 0x38,0xde,0x7c,0x24,0x4b,0xb6,0x55,0xeb,0xb6,0xa2,0x7c,0xc9,0x4a,0xfe,0x3d,0xf6, - 0xdf,0x7b,0x06,0xc3,0x21,0x40,0x50,0xb2,0xb3,0x39,0xfb,0xbd,0xb7,0xaf,0x58,0x24, - 0x38,0x18,0x0c,0x06,0xc0,0x00,0x18,0x0c,0x66,0xee,0xa7,0xd5,0xef,0x4e,0x1e,0xd5, - 0x3b,0xb9,0xea,0x6c,0xf7,0xd9,0xca,0x65,0xe0,0x04,0xb6,0xca,0x74,0x03,0x2d,0x5f, - 0xec,0xb1,0x8c,0x2a,0x0d,0x08,0xc4,0x7b,0xac,0x03,0x47,0x12,0x88,0x95,0x29,0xdc, - 0xc1,0xc5,0x8d,0x2f,0x51,0x7d,0xac,0xbb,0xa1,0x84,0x63,0x64,0xf7,0x8a,0xd2,0x7a, - 0x2c,0x7c,0x58,0x2e,0x6a,0x92,0xc3,0xb7,0x6f,0xde,0xaf,0xb5,0xe3,0x3f,0x7a,0x2f, - 0x9e,0x81,0x1e,0xba,0x4c,0x1b,0xcf,0xa7,0xd5,0xab,0x32,0xd7,0x88,0x7c,0x3a,0x99, - 0x0c,0x09,0x16,0x0b,0xef,0xf3,0x2a,0xce,0x8a,0x0f,0x31,0xc8,0x1e,0xf2,0x58,0x27, - 0x0b,0x15,0x40,0x60,0x26,0x58,0x6f,0x94,0xba,0xce,0x42,0xe0,0x9f,0x40,0x05,0x81, - 0xf4,0xee,0xf0,0xd5,0xdf,0x1e,0xb2,0x31,0x98,0x4b,0x96,0x87,0xd4,0xe7,0xcd,0xe1, - 0xd1,0x77,0x6f,0x7e,0x3a,0x4a,0xde,0xec,0x36,0x76,0x1a,0xcd,0xe4,0x0d,0x82,0xcb, - 0x6c,0x37,0x56,0x98,0xb4,0x55,0xe9,0x01,0xc8,0xb9,0xa7,0xd2,0xfa,0xfb,0xd1,0x01, - 0x6d,0xac,0xb0,0x53,0x7a,0x48,0x1f,0x56,0x3a,0x1b,0x26,0x4f,0x6e,0xe1,0xa4,0x9d, - 0x77,0xfb,0x89,0xd2,0x71,0x9f,0xa0,0xa7,0xfe,0x10,0x60,0x9b,0x32,0x9e,0xeb,0x4c, - 0xcc,0x36,0x0c,0xb9,0x3d,0x77,0xef,0xab,0x64,0x77,0x36,0x1e,0x4d,0xd7,0x4b,0x6c, - 0xb7,0xd1,0x98,0x1c,0x36,0x8e,0xbd,0x42,0xd4,0x86,0x7b,0x77,0x0a,0x52,0x42,0x43, - 0x33,0x54,0x37,0xdc,0x7d,0x7b,0x70,0x76,0x38,0xf3,0xc0,0x3d,0xb8,0xf1,0xed,0xa2, - 0x7b,0xf0,0x55,0xcb,0x70,0xb6,0x8a,0xa7,0xa5,0x35,0xc3,0xcf,0x98,0xa7,0x72,0x41, - 0x4d,0x32,0xdb,0xde,0x18,0x58,0x58,0xf3,0x9d,0xb2,0x1b,0xe8,0xc0,0x59,0x83,0xc0, - 0x33,0xaa,0x75,0xdd,0x1f,0x43,0x1e,0x23,0x41,0x0d,0x39,0xac,0x5b,0x6c,0x8d,0xe0, - 0xe7,0x01,0x60,0xb1,0x05,0xe5,0xd4,0x57,0xef,0x79,0x39,0x6f,0x4c,0x48,0xc5,0xc9, - 0xcb,0x64,0xc6,0x99,0xc4,0xef,0x95,0x78,0x18,0xfc,0xbf,0x86,0x83,0x29,0xd4,0xeb, - 0xdf,0xe7,0x61,0x0a,0xc8,0xff,0xcf,0x77,0x31,0x05,0x22,0xfe,0xaf,0xe4,0x63,0x0a, - 0xe4,0xfc,0x9f,0xef,0x64,0x4a,0x88,0xf8,0x7f,0xbc,0x97,0xa9,0xff,0x27,0xf8,0x91, - 0x52,0x23,0x9f,0xed,0xfa,0xf6,0x6e,0x70,0xc3,0xb7,0x1b,0xc4,0xb7,0x53,0xe1,0xed, - 0x89,0x5d,0xde,0xad,0xf7,0x29,0x65,0xd9,0xb7,0x43,0x9d,0xda,0x1f,0xe6,0x3e,0xf0, - 0xb0,0x6f,0x20,0xfc,0xbd,0xbc,0x91,0xc4,0xe3,0x14,0xc9,0x33,0xa9,0x47,0x1b,0x0f, - 0x5f,0x75,0xc9,0x68,0xbb,0xb9,0xf3,0xa4,0x18,0x52,0xb9,0x41,0x87,0x7f,0xea,0xed, - 0x8e,0x18,0x82,0x23,0xb0,0xb0,0x42,0x93,0x2d,0x5a,0xec,0xab,0xd1,0xea,0xcb,0x43, - 0x63,0xf2,0x9a,0xc3,0xeb,0x8f,0x21,0x30,0x65,0x73,0xbe,0x25,0x0c,0x3b,0xfa,0xb8, - 0x3a,0x0b,0xb7,0x45,0xe1,0x2a,0x25,0x12,0x93,0xe0,0xf8,0xe1,0x87,0xdf,0xae,0xae, - 0xb8,0x43,0x2b,0xdb,0x31,0x19,0x45,0x54,0x5b,0xf0,0x7d,0xf9,0x2d,0xf4,0xde,0xe4, - 0x03,0x33,0x9d,0xef,0x8d,0xf3,0x13,0xb7,0xeb,0x17,0x5f,0x6b,0x17,0x07,0xa7,0xe8, - 0x2b,0x2c,0x97,0xed,0x02,0x5e,0x73,0x72,0x14,0x8b,0xb3,0x54,0x3c,0x5b,0xd8,0xef, - 0x99,0xc4,0x59,0xb5,0xf4,0xc0,0x59,0x5c,0xcc,0x95,0x58,0x1a,0x70,0x76,0xce,0x5c, - 0xc7,0x0c,0x6c,0x51,0x3b,0xe9,0xcc,0x25,0x88,0x51,0x39,0xf0,0x43,0x49,0x31,0x8a, - 0xb6,0xf6,0x82,0xb8,0x61,0x25,0xb8,0xf2,0x3a,0x08,0xc7,0x7d,0x64,0x3e,0xc8,0xe3, - 0xc3,0x9a,0x14,0x37,0x31,0x48,0xc8,0x74,0xa6,0x41,0xf4,0xdb,0x8f,0x31,0xa3,0x7d, - 0x6e,0x22,0x17,0x32,0x2a,0x14,0x36,0xbb,0xac,0xd3,0xf7,0xc2,0x2f,0x35,0x9f,0xf0, - 0x6c,0x19,0xa0,0xfc,0x1e,0xef,0x20,0xeb,0xf3,0x01,0x88,0x5a,0xd1,0x57,0xe2,0x19, - 0x13,0x5c,0x35,0xa2,0xb5,0xc7,0xb5,0xbc,0x29,0x90,0xc6,0xa8,0x97,0xcf,0x2e,0xb2, - 0xca,0xdd,0x0c,0xc1,0xca,0x76,0xe6,0xc1,0xfe,0x96,0x68,0x68,0xf1,0x70,0x0d,0x3e, - 0xf7,0xe7,0x8d,0xfb,0xba,0x06,0xfa,0xd7,0x7d,0x1d,0x43,0x8b,0xb6,0xc3,0xb8,0x96, - 0xe0,0xc8,0x5b,0x3a,0xd5,0x51,0x9e,0xfc,0x8f,0x08,0x8e,0x13,0x96,0x56,0xc9,0xd9, - 0xd4,0x77,0x3b,0xed,0xce,0x97,0x36,0x5d,0x8a,0xbc,0xce,0x1e,0xb2,0x1e,0xb6,0xe8, - 0xd8,0xd0,0x01,0x44,0xd3,0xf1,0x1f,0x7c,0x9d,0x9f,0x86,0xd0,0xe6,0x10,0x67,0x59, - 0xed,0x80,0x31,0xd9,0x83,0xd4,0x27,0xe2,0x4b,0x17,0x37,0xf8,0xf9,0xb5,0x3f,0x9c, - 0x52,0x21,0x17,0xf8,0x15,0xe4,0x5f,0x58,0xc3,0xe2,0x04,0xe9,0x4b,0xab,0x39,0x38, - 0x8b,0x1e,0xe1,0xb1,0xd1,0xbd,0xca,0x3e,0xc7,0x78,0xf8,0x70,0x35,0x8e,0x8e,0x1f, - 0x17,0xf8,0x1e,0x9f,0x80,0xb0,0xe2,0xf5,0x7f,0xbc,0xee,0x7c,0x39,0x99,0x2a,0xcf, - 0xbb,0xd3,0xb5,0xcb,0x92,0x3c,0x4e,0x8f,0xd4,0x5b,0xde,0x2a,0x77,0x89,0x56,0xd4, - 0x1e,0x7c,0xb7,0x3f,0x48,0x44,0x9e,0x40,0x19,0xa8,0x49,0x6b,0x6c,0x9f,0x35,0x9a, - 0x4a,0xb9,0x47,0x4a,0x98,0x13,0xe3,0x60,0x5c,0xbb,0xa6,0xbf,0x60,0xd7,0x72,0x06, - 0xe3,0xaa,0x85,0xa1,0xb7,0x34,0xaf,0x5e,0xc1,0x6f,0x64,0x53,0xf8,0x6b,0xe7,0x9d, - 0xa1,0x2e,0x06,0xd9,0x9f,0x03,0x56,0x4e,0xb4,0xbc,0xc0,0xae,0x61,0x52,0xda,0x59, - 0x13,0x11,0x41,0x27,0xbf,0x22,0xe9,0x4f,0x54,0x4c,0x14,0xe5,0xfa,0xf2,0x66,0xdc, - 0xb0,0x9b,0xf1,0x90,0xdd,0x74,0x53,0x3b,0xce,0xae,0xbc,0x55,0x79,0x55,0x63,0x4a, - 0x64,0x02,0x61,0x28,0x24,0x3b,0x42,0x14,0xbc,0x38,0xea,0x74,0x9f,0x6f,0xd1,0x83, - 0x5e,0xff,0x17,0x9e,0x5a,0x30,0x9b,0x57,0x34,0x12,0x19,0x4c,0x12,0x7a,0x45,0x02, - 0x9a,0x35,0xa3,0x8b,0xed,0x92,0xcd,0xc6,0xfd,0x32,0x3b,0x15,0x18,0xf4,0xe6,0xd1, - 0x20,0xcb,0x1c,0xd4,0xc6,0xa7,0xfc,0x08,0x35,0x1b,0xa0,0x5c,0x8e,0x78,0xc8,0x47, - 0x2b,0xa8,0x0d,0xad,0xaa,0xcc,0xb5,0x3d,0xa1,0xc6,0xab,0x96,0xef,0x46,0x7c,0x4b, - 0xdc,0xca,0x5b,0x15,0x96,0xe0,0xd8,0xd4,0x17,0xf4,0x85,0xdb,0x43,0x13,0xea,0x58, - 0x09,0xb1,0xe2,0xe0,0x3e,0x99,0xe7,0xed,0x1e,0xac,0x21,0x45,0xad,0x34,0x9b,0x43, - 0x37,0xca,0x2b,0x0b,0x7e,0x59,0xbf,0xa8,0x18,0x15,0x14,0x39,0x4b,0x08,0xde,0x58, - 0x38,0x9e,0x4c,0x64,0xe1,0xb8,0x76,0x8c,0x6a,0x00,0x55,0x1d,0x60,0xee,0x76,0x70, - 0x36,0xa1,0x79,0x81,0x8f,0x5d,0x51,0x94,0xed,0xb0,0x9f,0x7c,0x56,0x75,0x3f,0x3b, - 0xfe,0xb6,0x33,0x81,0x30,0xb6,0x9a,0xe8,0xac,0xb3,0xab,0xf2,0x74,0x23,0x61,0x65, - 0xc3,0x17,0x26,0xbb,0xe6,0x64,0x1e,0xba,0x8b,0xa5,0x07,0xf1,0xf1,0x6b,0xa4,0x19, - 0xeb,0x25,0x78,0x9f,0x4a,0x84,0x32,0xfb,0x33,0x6b,0x8f,0xfa,0x6f,0x2b,0x97,0x3d, - 0xca,0x73,0xb9,0x28,0xf3,0x80,0x5e,0xb4,0xc8,0xf2,0xf4,0xad,0x41,0x6d,0x73,0xde, - 0xe3,0xb0,0x85,0xd4,0x89,0x43,0x5c,0x6a,0x97,0x24,0x9a,0x08,0x72,0x56,0x73,0xbe, - 0x95,0x0e,0x67,0x74,0x76,0x67,0x3d,0x45,0xa9,0xd7,0x0e,0xc6,0xca,0xef,0xfb,0x4c, - 0x15,0x38,0x3c,0x2b,0x77,0x15,0x7e,0xac,0x96,0xe8,0x12,0x15,0xd5,0x80,0xf5,0x6f, - 0x39,0x7c,0x9d,0xf4,0x05,0x7f,0xff,0xf5,0x84,0xf6,0x5f,0xe5,0x38,0xcd,0x12,0x27, - 0x43,0x80,0x7d,0x1f,0x93,0x7e,0x64,0x56,0x70,0xd3,0x58,0x9d,0xf7,0x7d,0x67,0xfa, - 0x1c,0x58,0x63,0x32,0xac,0x58,0x64,0x3d,0xf5,0x42,0x3b,0xfe,0xd0,0x76,0xe2,0xfd, - 0xec,0x94,0x03,0xbc,0x9c,0x9d,0xc7,0x44,0xdc,0x70,0x00,0x01,0x38,0x65,0x0f,0x6d, - 0xa2,0xb5,0x25,0x43,0x0c,0x7a,0x3f,0xa0,0xad,0xc7,0x90,0x52,0xe2,0xdc,0xb1,0x27, - 0x66,0x0b,0x3a,0x1e,0xe7,0x03,0xf7,0x41,0x26,0xd6,0xae,0x8d,0xe7,0xdd,0x99,0x08, - 0xbd,0xaa,0xd5,0x5f,0xe5,0xda,0x0f,0x9e,0xdf,0x3b,0xd9,0x65,0xbf,0x97,0x04,0xa7, - 0xea,0x74,0x94,0x9c,0x8f,0xfc,0x21,0x2e,0xd6,0x5f,0x11,0x27,0x30,0xac,0x98,0x9e, - 0x2d,0xfa,0x7a,0x38,0xc7,0x9e,0x5e,0xef,0x5c,0x51,0x7a,0xb1,0x45,0x47,0x1d,0xb8, - 0x22,0x1c,0x81,0xe0,0xb0,0x73,0x86,0x2e,0x45,0x1a,0xb3,0x83,0x0b,0xa8,0xd1,0xfa, - 0x9e,0x7f,0x04,0x05,0xff,0x85,0x5c,0x37,0x00,0x77,0x05,0xd5,0xdf,0x4d,0x6f,0xad, - 0x46,0xbf,0x9a,0x0d,0xb1,0x4e,0x9a,0xcf,0xa7,0xad,0xad,0x2d,0xdc,0x9a,0x68,0xc0, - 0x06,0xb2,0xf1,0xa4,0xb1,0x4d,0x44,0x08,0xb6,0xad,0xc9,0xd0,0x57,0x22,0x56,0x9d, - 0x8b,0x6c,0x3f,0x01,0xe6,0x52,0x65,0x40,0x85,0x4d,0xe1,0xe3,0x8c,0xea,0xcb,0x8b, - 0x3e,0x16,0x4c,0xcc,0x03,0xd5,0x7f,0xfc,0xb7,0x1d,0x44,0xc1,0x78,0x2a,0x18,0x64, - 0xf0,0xe2,0xca,0x76,0x4f,0x03,0xb9,0x29,0x6e,0xe9,0x25,0xfb,0x81,0xc1,0xa4,0x1a, - 0x4c,0x69,0x4a,0xe9,0x53,0x89,0xe8,0x03,0x06,0xe4,0x5e,0x0e,0x5e,0xd6,0xc4,0xd9, - 0x3d,0xb6,0xf4,0xb3,0x3e,0x98,0x49,0x41,0x76,0xd5,0x12,0xea,0xe1,0x9e,0xa0,0x9a, - 0x2b,0x3d,0x41,0xf5,0x10,0x80,0x83,0x9d,0xe3,0x9f,0xf7,0xe7,0x2f,0x87,0x7d,0x7a, - 0xfc,0xf1,0xf3,0xab,0x5e,0xf4,0x58,0x46,0xd7,0xe3,0xb8,0xc1,0x1c,0x7c,0x3d,0x60, - 0xff,0x1f,0x23,0xd4,0x26,0x7a,0x4c,0xab,0xe2,0xc7,0x0f,0x74,0x1d,0x85,0x46,0x25, - 0x77,0x5b,0xea,0x32,0x4a,0x28,0xbf,0x6f,0x70,0xb3,0x36,0x42,0x87,0x37,0x81,0x7a, - 0xa2,0x45,0x8b,0x34,0xc3,0x7d,0xf7,0x89,0x86,0x42,0xe6,0x67,0x95,0x3c,0xfe,0x80, - 0x67,0xd7,0x58,0x01,0xc7,0xea,0xb6,0x4b,0x13,0xe7,0x6a,0xb2,0x15,0xb7,0x22,0xe3, - 0xc8,0x40,0x9f,0xda,0xb0,0xa3,0xec,0x5c,0x09,0xf0,0x7d,0xd7,0xba,0x42,0x28,0x94, - 0xaa,0x4f,0xfd,0x85,0xbb,0x60,0x1b,0x4c,0x57,0x77,0xce,0xb7,0xbe,0x7f,0xb5,0x16, - 0x86,0x38,0xda,0xd3,0xc5,0x40,0x6b,0xd3,0xcb,0x50,0xdb,0xd8,0x6f,0x10,0x90,0xe2, - 0xc5,0x50,0x27,0xd2,0x3a,0x4a,0x5e,0x35,0x09,0x6d,0x0b,0xc5,0x33,0x1f,0x85,0x53, - 0x91,0xd3,0x09,0xbc,0x24,0x84,0x95,0x4d,0x8d,0x2e,0x3c,0x98,0xe2,0xa4,0x35,0xa4, - 0xa8,0x11,0x62,0x69,0xd8,0xde,0x00,0xd7,0x82,0xc3,0x97,0x6f,0x8f,0x5e,0xbd,0x7d, - 0xf9,0x3a,0x0d,0xbf,0x95,0xff,0xcc,0x07,0x40,0xa5,0x0b,0xb2,0x5e,0x6c,0x85,0x61, - 0xc2,0xbe,0x3f,0x7a,0x2d,0xee,0x6d,0x09,0x4c,0x08,0xc9,0xe1,0x5e,0xf1,0x76,0x30, - 0x1c,0xc8,0x0b,0xa9,0x9a,0xde,0x67,0x97,0xcf,0x9e,0xc8,0x7b,0xae,0xbe,0x3d,0x34, - 0xde,0x1a,0x15,0xc5,0x18,0xfe,0x97,0xb3,0xf7,0xf2,0x51,0xd2,0xd8,0x30,0x3a,0xf7, - 0x3e,0x25,0x69,0x59,0xee,0x20,0xd6,0x7a,0xb7,0xca,0xc6,0xf2,0x3c,0x6b,0x35,0x93, - 0xd3,0xb3,0xf3,0xd6,0x18,0xd6,0x21,0x09,0x59,0xc1,0xb5,0x16,0x77,0x49,0x0f,0x57, - 0x35,0x3f,0xd3,0x83,0x71,0xa3,0x9d,0xb5,0x8e,0x4f,0x92,0x31,0xef,0xc9,0x01,0xcd, - 0x9b,0x79,0x3a,0x4e,0x9b,0xe1,0x85,0x56,0xab,0xad,0x05,0xa9,0x19,0x08,0x86,0xd5, - 0x04,0x78,0xb8,0x4b,0x68,0x9a,0x3e,0x42,0x4b,0xf4,0xe7,0xa8,0x3e,0xbf,0x49,0x0e, - 0x7e,0x7e,0x39,0x9d,0x9c,0x5e,0xe0,0xd9,0x44,0xdb,0xc8,0xdf,0xc4,0xf5,0x1c,0xbe, - 0x93,0xec,0xd5,0xba,0x1a,0xa0,0xd7,0x30,0x58,0x3a,0xe8,0x4c,0xc9,0xde,0x82,0x69, - 0x35,0xac,0x12,0x0e,0xd0,0xc5,0x13,0xde,0x86,0xe5,0x99,0xee,0x10,0x46,0xed,0x6a, - 0x6c,0x8e,0x55,0xbe,0x89,0xb2,0x78,0x21,0xc3,0x5d,0x25,0x06,0x56,0xc3,0xb3,0xcf, - 0x46,0xed,0x38,0x99,0x01,0xe0,0xce,0x82,0xb7,0x33,0xec,0xcf,0x66,0xb8,0x20,0x0c, - 0x11,0x39,0x9f,0xd0,0x02,0xa7,0x91,0x0d,0x49,0xec,0x93,0xba,0x33,0xaa,0xc6,0x85, - 0x75,0x2b,0xb2,0xdb,0xf8,0x78,0x45,0x10,0x8d,0xe2,0x05,0x75,0x8a,0x79,0xfa,0x4d, - 0x14,0xfe,0x85,0x93,0xc2,0xb8,0x3d,0x6f,0x90,0xe8,0xa3,0x29,0x1a,0x78,0xd2,0x11, - 0xde,0x0b,0x79,0x85,0xd1,0x12,0xf1,0x16,0x1e,0x70,0xbc,0xb3,0x94,0x3b,0xce,0xd1, - 0xbc,0xf1,0xe9,0x02,0x59,0xf1,0x37,0x45,0xdb,0xe4,0xa9,0x79,0x71,0x51,0xbc,0x98, - 0xfb,0x52,0x4f,0x10,0xdd,0x25,0x3b,0xb8,0xd0,0x6c,0x13,0x87,0xf5,0x9d,0x55,0x5b, - 0x32,0x6b,0x1d,0x9f,0x23,0x01,0xf9,0x78,0x13,0x16,0x6d,0x1d,0x6f,0x3e,0x7f,0x11, - 0x9e,0x6c,0x9d,0x27,0x5a,0xc0,0x69,0x0e,0xbe,0x08,0x37,0xc3,0x56,0xc8,0x07,0xc9, - 0x61,0x12,0x3e,0xa7,0xe7,0xe1,0x9c,0x1e,0x5f,0xd0,0xe3,0x39,0x3d,0x3e,0x0e,0x1f, - 0xe3,0xf1,0x1f,0x57,0x13,0xbc,0xdc,0x1d,0x9f,0x9e,0xdc,0x39,0x8c,0xf1,0xf5,0xfb, - 0x58,0x50,0xc6,0x0b,0x1e,0x3d,0xbc,0x03,0x4d,0xab,0x25,0x3c,0xc3,0x51,0xd2,0xfe, - 0x1c,0x04,0x63,0xa1,0x88,0x0a,0x3a,0x47,0x0a,0x61,0x8c,0xf8,0x6e,0xa4,0x17,0x60, - 0x2c,0xb1,0x21,0x57,0x46,0x25,0x18,0x91,0x72,0x72,0x83,0x57,0xac,0xa9,0x75,0x46, - 0x82,0x3c,0xc5,0x07,0x02,0xdc,0x33,0x9b,0xdf,0x96,0x0d,0x82,0xa2,0xed,0x56,0x13, - 0xb8,0x5f,0x21,0x14,0x01,0x77,0x88,0x17,0x81,0xc9,0x7c,0xf2,0xe4,0x18,0x24,0x4c, - 0x04,0x37,0xad,0x50,0x5b,0xb2,0x0d,0x8e,0x2b,0x73,0xe9,0xee,0x22,0x4c,0x22,0xbf, - 0xa0,0xb8,0x16,0x9a,0xdd,0x86,0x92,0x17,0xe7,0x55,0xe0,0xd8,0x54,0x11,0x5e,0x2d, - 0x7e,0x03,0xc1,0x6c,0xfe,0xd7,0xfe,0x2c,0x12,0x16,0x9f,0xdd,0xa4,0x19,0x20,0x6f, - 0x96,0x4b,0x0c,0xd1,0x51,0xba,0xf5,0xf7,0xe8,0x7a,0xef,0x63,0xaf,0xf6,0xb1,0x91, - 0xff,0x89,0xf6,0x5a,0xfc,0x1b,0xef,0xc5,0x5b,0x8d,0xfe,0x6d,0xff,0x34,0x3a,0xbb, - 0x89,0x85,0x8d,0xe9,0x68,0x6f,0x74,0xbc,0x7d,0xd2,0x8a,0x38,0xff,0xd5,0xf8,0x72, - 0x4c,0x11,0x10,0x48,0x9f,0x47,0xfb,0x22,0xc3,0xfe,0xad,0x3a,0x16,0x21,0x51,0x7d, - 0xf9,0x0d,0xb2,0x93,0x4b,0x4e,0xca,0x1e,0x67,0xb5,0x34,0xa4,0xf4,0xb0,0x1d,0x58, - 0xff,0x6d,0x6d,0x05,0xef,0x8e,0xf6,0x3f,0x1d,0xfc,0xba,0xff,0x16,0xb2,0xf4,0xd3, - 0xd1,0xfe,0x2f,0x29,0x02,0xdc,0x77,0x08,0x70,0x83,0xaf,0x8c,0x30,0x3a,0x4a,0xaa, - 0xc2,0xc7,0x1f,0x04,0x21,0x30,0x75,0x02,0xce,0xcb,0x26,0x8f,0x72,0x68,0x90,0x00, - 0x01,0x9f,0x42,0x6c,0x48,0x57,0x47,0xcd,0xe1,0x93,0x73,0xd8,0xdb,0xcb,0xc0,0xc4, - 0x28,0xac,0xe5,0xef,0xb5,0x30,0x0e,0x5b,0x99,0xc3,0x37,0xe8,0x30,0x22,0x72,0x2d, - 0x9c,0x40,0xf5,0x9e,0x81,0x77,0xf4,0x93,0xd2,0x9f,0xe5,0x72,0x71,0x67,0xfa,0x19, - 0xbd,0x41,0x2a,0x40,0xb1,0x11,0xeb,0x23,0xab,0xfd,0xeb,0xec,0xb2,0x0e,0xa4,0x81, - 0xac,0xc1,0xbb,0xc3,0x80,0x3f,0x64,0xa4,0xe1,0xc0,0x1c,0xf5,0xeb,0x11,0xcc,0x2b, - 0xf6,0xdf,0xbf,0x0a,0x7e,0x79,0x09,0xbf,0xb5,0x1d,0x5c,0xf2,0x62,0xd7,0x6d,0x19, - 0xb1,0x30,0x23,0xbc,0x8c,0x4b,0x3c,0x13,0x6c,0x6e,0xca,0x0a,0x79,0xbf,0x8b,0x66, - 0x3c,0x30,0x3d,0x1d,0xc6,0xe6,0xd2,0x98,0x70,0x0b,0x94,0xd2,0x81,0x6f,0xe9,0x2b, - 0xba,0x00,0x23,0x61,0x63,0xb5,0x61,0x0a,0x28,0x79,0x6c,0x6f,0x54,0x0b,0x0f,0x82, - 0xe8,0x10,0x8e,0x08,0xd2,0xc2,0x2e,0x9f,0xfb,0x52,0xbe,0x6a,0xea,0xe3,0xd8,0xc6, - 0xe2,0x49,0x83,0x3c,0x5b,0x15,0x58,0x40,0x13,0x51,0x3f,0x13,0x23,0x4c,0x8c,0xb1, - 0x27,0xcd,0xed,0x78,0x41,0x1d,0xf8,0x35,0x85,0x32,0x03,0x51,0xf3,0x0b,0xba,0x9a, - 0x47,0x04,0xbf,0x9c,0xcd,0x20,0x81,0x43,0x9a,0x21,0xc3,0x58,0x4b,0x98,0x35,0xfe, - 0xcc,0x88,0x1e,0x70,0x92,0x8a,0x52,0xd4,0x39,0xe6,0xc9,0x65,0xec,0xa1,0xb8,0x1a, - 0x93,0xd1,0x3e,0xdb,0xdb,0xb0,0xb3,0x37,0x3e,0xf9,0xd6,0x53,0x73,0xea,0x93,0x82, - 0x9c,0x5a,0xed,0xae,0x4c,0xf4,0x9f,0x06,0xf5,0x23,0xc2,0xbd,0xb9,0x99,0xd3,0xfe, - 0x28,0x4d,0x11,0x11,0x58,0x78,0xdc,0x4f,0x8b,0xd2,0xfe,0x6c,0xf4,0xe9,0x77,0xb9, - 0x8c,0x42,0x6e,0xc6,0xb0,0x96,0x67,0x81,0xec,0xe9,0xe7,0x35,0xcf,0xd3,0x90,0x82, - 0xc3,0x2a,0x2c,0x35,0xfe,0x34,0xbf,0x78,0x87,0xc6,0x0b,0x6f,0xf8,0x2b,0xbc,0xe8, - 0x5b,0xfc,0xfd,0x13,0xcf,0xc4,0x6f,0x77,0xfc,0x4e,0x27,0xd9,0xdc,0x30,0x9d,0xe2, - 0x50,0xaa,0xd0,0xd6,0xee,0xb9,0x18,0xf5,0xb1,0xe1,0xe9,0xb5,0x42,0x58,0xb8,0x1c, - 0x85,0x89,0x09,0x10,0x98,0xb5,0x16,0xa1,0x88,0xaa,0xfa,0xd1,0xe7,0x29,0xc9,0x0e, - 0xf2,0x4e,0x25,0x66,0x88,0x5b,0xc4,0xe5,0xf0,0x8e,0x11,0xb6,0xfe,0xf3,0xf0,0xdd, - 0xdb,0x46,0xc6,0x53,0x00,0x6c,0x04,0x23,0x2e,0xc4,0x11,0xd8,0xa3,0xcb,0x0f,0xfd, - 0x7f,0x40,0xfa,0x0a,0x3b,0x3a,0xcc,0x8e,0xdf,0xa1,0xb6,0xfb,0x9e,0xa7,0xc9,0xe8, - 0x7b,0x33,0xec,0xa5,0x9f,0x9e,0xce,0x3e,0x4f,0xe7,0x93,0xcd,0x4d,0xf3,0x4b,0xe2, - 0xfa,0x03,0x3b,0x77,0xfc,0x2b,0x5f,0xa3,0x8a,0xab,0x93,0xa3,0x0e,0x70,0xf0,0x80, - 0x3f,0x03,0x93,0x79,0x22,0x48,0x9b,0xed,0xc1,0xf3,0xef,0xdb,0x83,0x5a,0x2d,0xee, - 0x1c,0x0f,0x4e,0xd2,0x37,0xa8,0x6b,0x83,0x8f,0x2c,0x22,0x7e,0x9c,0x71,0xf6,0x28, - 0xfe,0x16,0x37,0x58,0x90,0x79,0xc5,0xc4,0x3d,0xea,0x4c,0xcd,0xb4,0xdd,0x29,0x66, - 0xb2,0x2e,0x2a,0xc2,0xe0,0x78,0x7c,0xbe,0xfd,0x6c,0x2f,0x6c,0x82,0x3b,0x90,0xaa, - 0xf0,0x06,0x32,0x91,0xa9,0x70,0x1b,0x28,0xa9,0xaf,0x50,0x18,0x9a,0x08,0xdf,0x4a, - 0x82,0x01,0xbd,0xec,0xe7,0xbe,0x31,0x02,0x25,0xae,0x60,0xe9,0xf0,0xf8,0x38,0x3f, - 0x68,0x3c,0xc1,0xf6,0x03,0x95,0x78,0xd9,0xb1,0xfb,0x6f,0x7f,0x08,0xb0,0xfe,0xd0, - 0x9a,0xa1,0xcd,0x2c,0x18,0x99,0x65,0x75,0xf2,0x28,0x42,0x12,0x32,0x67,0x9b,0x6f, - 0xf9,0x30,0x37,0x02,0x2c,0x21,0xcc,0xfa,0x9c,0x1c,0xc7,0x4c,0x0e,0xc9,0x60,0xb9, - 0xb7,0x76,0x80,0x25,0x13,0xaf,0x29,0xbc,0x7b,0x71,0xa6,0x31,0x14,0x28,0xd6,0xa7, - 0x07,0x14,0x1e,0xe1,0x5a,0xd4,0x12,0xfc,0xe4,0xf2,0x50,0xab,0xb0,0xe1,0x7a,0xc2, - 0x5b,0x51,0xb3,0x75,0x15,0x43,0x8a,0xb7,0x9a,0x8d,0xa9,0x2a,0xcc,0x34,0xcf,0x3a, - 0x41,0xb8,0x57,0x59,0x06,0x76,0x28,0xaf,0x8d,0x99,0x02,0x90,0xea,0x92,0x79,0x0f, - 0xab,0xe6,0x67,0xbb,0x8a,0xd1,0x3f,0xd5,0x5f,0xdb,0x20,0xf6,0x94,0x6e,0x63,0xdd, - 0xd8,0x0b,0xc2,0xff,0x61,0x6b,0x80,0x70,0xa3,0xf5,0x50,0x9c,0x8d,0xd0,0x34,0x37, - 0x35,0xb0,0x1b,0x06,0x22,0x5e,0xcb,0x69,0x67,0x2f,0x60,0x3a,0x02,0x25,0x9b,0xbd, - 0x46,0x3e,0x63,0x0c,0x07,0xd0,0x56,0xa7,0xe0,0xd5,0x5f,0xc8,0x8f,0xb1,0xf8,0x95, - 0x39,0xb6,0xbd,0x04,0x83,0x63,0x6d,0x64,0x35,0x90,0xb1,0xf9,0xc9,0x97,0x94,0x42, - 0x95,0x39,0x4e,0x8b,0xdd,0x85,0xab,0x90,0xc2,0xa3,0x05,0xf9,0x91,0x28,0x7b,0x1e, - 0x67,0x29,0x36,0x42,0xc2,0x3a,0x0a,0xe8,0x7b,0x4e,0x82,0xc0,0xc6,0xf2,0xeb,0x11, - 0xc1,0xb0,0xd5,0x54,0x28,0xfb,0x76,0xd7,0x03,0x70,0xd4,0xc7,0xb5,0x10,0xa5,0xb3, - 0xcc,0xf5,0xc0,0x4e,0x78,0xc6,0xd8,0xe9,0x5f,0xe1,0x97,0x04,0x6b,0xcc,0x24,0x38, - 0xec,0x95,0xf1,0x3c,0xce,0x86,0x61,0x8e,0x8f,0xcf,0x00,0x89,0x9c,0xf7,0xf5,0xfe, - 0xdb,0x46,0xa8,0x85,0x6b,0x74,0xaa,0x72,0xe1,0x1c,0xab,0x0a,0x05,0x4a,0x34,0x26, - 0x2a,0x3e,0xb3,0x43,0x57,0x29,0x0e,0x2b,0x28,0x88,0x87,0xc4,0xf8,0x6c,0x57,0x48, - 0xc7,0xc3,0x3b,0x60,0x07,0xa8,0xdf,0xec,0xd7,0xa3,0x37,0xd8,0x15,0x4b,0x80,0x8f, - 0xd5,0xde,0xde,0x3d,0x24,0xa4,0x72,0x01,0x8e,0x5c,0xcd,0x63,0xcd,0xfd,0xe2,0x40, - 0xff,0xce,0x91,0xc2,0x6c,0x84,0x80,0x3e,0x4d,0xf3,0x60,0xb8,0x85,0xbf,0x5b,0x72, - 0xf7,0xa3,0x3c,0xc3,0x67,0x00,0xca,0xe6,0xec,0x4c,0x2b,0xcd,0xf8,0xa7,0x8d,0x57, - 0xb3,0x35,0x47,0x02,0x3d,0xb4,0x8b,0xae,0x9a,0x3e,0x7a,0x04,0x20,0x3c,0xb4,0x75, - 0xe0,0x70,0x12,0x88,0x6a,0x13,0x9a,0x6c,0x4e,0x9e,0x10,0x8e,0xc8,0xe4,0x05,0x63, - 0x8c,0x3f,0xcd,0xe5,0xe5,0x93,0xf9,0x86,0x8c,0x9a,0x04,0x43,0x8e,0xd4,0x02,0x80, - 0x04,0xfb,0x24,0x27,0x5a,0xcb,0xe5,0xd3,0x27,0xdb,0xd2,0x8d,0xdd,0x83,0xd0,0x75, - 0x63,0xdc,0x23,0x00,0xbd,0xce,0x16,0x5b,0x4c,0x0f,0xbd,0x7d,0x9a,0xd2,0x2b,0x7f, - 0xf4,0xc4,0x2f,0x01,0x69,0xea,0xa7,0x2c,0x4f,0x26,0xba,0x1d,0x05,0x03,0xc3,0x71, - 0xca,0xa7,0x1c,0x9a,0x11,0x3a,0x52,0x86,0x81,0x38,0xe5,0xd3,0x44,0x92,0x18,0x88, - 0xf3,0x1d,0x92,0xda,0xd0,0x42,0x93,0xd1,0x7b,0x5b,0x66,0x9b,0x34,0xa3,0x9f,0x4e, - 0x77,0x00,0x1d,0xfe,0xa0,0x8f,0x55,0x75,0xd3,0x64,0x64,0x85,0x43,0x5a,0xb4,0xc8, - 0x1e,0x4f,0xf7,0xa8,0x6d,0x94,0x35,0xd8,0xc5,0x50,0xff,0x13,0x81,0x20,0x03,0x0a, - 0x26,0xff,0x96,0x23,0x4d,0x68,0x26,0x5e,0x52,0x39,0x4f,0x33,0x6e,0x35,0x49,0x30, - 0x02,0x19,0xb7,0xc6,0xa8,0x97,0xbd,0x68,0xc6,0x70,0x8b,0xfe,0xe9,0xcd,0xfe,0xdf, - 0xd2,0x22,0x91,0x69,0xa1,0xad,0x92,0xec,0x94,0xda,0xf9,0x4e,0x01,0x29,0xfc,0xfb, - 0x09,0xf2,0xaa,0x9f,0x7f,0xe1,0xd3,0xa1,0x8c,0x7e,0x34,0x89,0xaf,0x3e,0x20,0x8d, - 0x7f,0x39,0x91,0x96,0xde,0x3f,0xd2,0xdb,0x01,0xf0,0x47,0xf2,0x85,0x0b,0x13,0xd9, - 0x21,0x51,0xb0,0x9d,0x31,0x07,0x0c,0x94,0x08,0x04,0xb9,0x43,0x72,0x19,0x38,0x1c, - 0x13,0xdb,0x85,0x15,0x0a,0xb0,0xb3,0xf9,0x16,0x0b,0xd3,0x62,0xdf,0x27,0x09,0x52, - 0xa2,0x91,0xc2,0xdd,0x94,0x91,0x48,0x50,0xec,0xb8,0xdd,0xf5,0xb4,0x07,0x2a,0xd7, - 0x84,0x5b,0x93,0x1e,0x6f,0x9b,0x8d,0x4d,0x42,0xbc,0xe8,0x96,0xc4,0xcb,0xcb,0xa3, - 0xdf,0xdf,0x87,0x8a,0x46,0x65,0xa3,0x80,0xdf,0xd1,0xe2,0xae,0x9c,0x07,0x92,0x2b, - 0xbc,0x93,0xca,0x88,0x3d,0xea,0x6a,0xe1,0x5a,0x5a,0x75,0xe9,0x8a,0xcf,0xea,0x28, - 0x85,0x28,0x10,0x05,0x56,0xe8,0x6d,0x24,0x54,0x89,0x51,0xa8,0xb8,0xee,0xee,0xe2, - 0x96,0xf5,0x5a,0xb5,0x49,0x98,0x1a,0x11,0x22,0x40,0xe9,0x54,0x9e,0xd0,0x9d,0x8e, - 0x4f,0x74,0x96,0x35,0x12,0xc5,0xd9,0xef,0xdc,0xe9,0x26,0x16,0xdf,0xcb,0x0c,0xb4, - 0xec,0x34,0x04,0x70,0xa1,0x31,0x0e,0x90,0x70,0xe7,0xd1,0xde,0x37,0x5b,0x95,0x7e, - 0x43,0x2e,0x95,0x62,0x93,0x22,0xfb,0xa7,0xc5,0xaa,0x0e,0x11,0x5a,0x76,0xc6,0x74, - 0x19,0x09,0xba,0xfd,0x3a,0x07,0x9b,0xfd,0x4c,0xce,0x92,0xda,0xd6,0x5e,0x90,0x5d, - 0xb1,0xef,0x34,0x59,0x4d,0x54,0xda,0x80,0x10,0xa1,0xd1,0x75,0xbc,0x38,0x0e,0xff, - 0x92,0x47,0x18,0x4f,0xe8,0xd1,0x28,0xee,0xf8,0x99,0x63,0x27,0x9c,0xf8,0xcb,0xac, - 0x41,0x8f,0x68,0xc3,0xdf,0xea,0x56,0x45,0x41,0xdf,0x00,0xf3,0x9a,0xae,0xa7,0x9a, - 0x20,0xda,0x96,0x54,0xc0,0x61,0x01,0x61,0x56,0x22,0x6d,0xa3,0x03,0x80,0xbf,0xfe, - 0xce,0x6c,0x44,0xf7,0xb0,0x3f,0xf3,0xcc,0x86,0xef,0x01,0xcf,0x27,0xb9,0xc3,0x6c, - 0x13,0x67,0x7c,0x90,0xf1,0x23,0x47,0xb0,0xa6,0x79,0x71,0xe3,0x6a,0x4a,0xc3,0x99, - 0x4e,0x8b,0x7f,0x24,0xab,0x0e,0xa7,0xf6,0xda,0x9c,0xdc,0x64,0x51,0xc1,0x85,0xd8, - 0x74,0x5e,0x2b,0x3c,0x79,0x4c,0xb5,0x7b,0x49,0xe7,0x9d,0x44,0x65,0x7f,0x8c,0xd1, - 0x97,0x07,0x02,0x4f,0x8a,0x76,0xbc,0xa6,0xb5,0xe7,0xb5,0x77,0x32,0x2a,0x03,0x73, - 0x3e,0x4e,0x0b,0xac,0x78,0x43,0xdd,0x48,0x45,0x84,0x09,0x82,0x2f,0x6a,0xa7,0xa4, - 0x3f,0x6a,0x17,0x10,0xd8,0x8f,0x96,0x1b,0x1d,0x12,0x82,0xb7,0xea,0x32,0x18,0x0c, - 0xb1,0x5f,0xb3,0x4f,0xdc,0xa8,0xda,0x28,0x2e,0xf2,0x49,0xa1,0xa5,0xc4,0xd0,0x9a, - 0x1b,0xc4,0xb0,0x29,0xe3,0x1d,0x5a,0x77,0xc3,0xd7,0x10,0xb8,0x1b,0x7d,0x6f,0x37, - 0xae,0xe3,0x33,0x6b,0xe5,0x9b,0xe8,0xe4,0xcf,0xd6,0x9f,0x77,0x55,0xd8,0x6e,0xc1, - 0x46,0x87,0x33,0xac,0x52,0xe3,0xf1,0x78,0xdb,0x20,0xf5,0x03,0xba,0x73,0xbc,0xd0, - 0x91,0xa9,0x8c,0xf3,0x69,0x25,0x96,0x3d,0x60,0x90,0x96,0xc7,0xa8,0x0c,0xef,0x75, - 0x6d,0x71,0xdb,0x50,0x8d,0x41,0xc8,0x30,0x32,0x0c,0x79,0x81,0xef,0x0b,0xa7,0x8a, - 0xea,0x54,0x63,0xf7,0x87,0x37,0x97,0x12,0xe6,0xfa,0x03,0xed,0xbe,0x85,0x39,0xe5, - 0x82,0x15,0x09,0xd2,0x25,0x38,0x0d,0x7d,0xc2,0x13,0x75,0xca,0x30,0x25,0xc0,0x1a, - 0x00,0x55,0x24,0x3b,0xaa,0x02,0x1c,0x29,0x60,0x43,0x1f,0x5d,0xc6,0x0b,0x1a,0x8c, - 0xd8,0x7c,0x63,0x73,0xf4,0xbf,0xc1,0xcb,0xff,0xcd,0xbb,0xa2,0xb9,0x2c,0x6c,0xc5, - 0x8d,0x39,0xb3,0x3e,0x30,0x1d,0x2a,0x31,0x5a,0x1b,0x94,0x0d,0x14,0x66,0x9f,0x92, - 0x9a,0x97,0x64,0x94,0xcc,0xd2,0x53,0xb3,0xc4,0x48,0xfe,0x81,0x27,0x5a,0x9c,0x41, - 0x05,0xc7,0xf3,0x39,0x1f,0x3a,0xdc,0x20,0x91,0xd6,0x3c,0xdc,0xf2,0xd1,0x28,0xbd, - 0x6c,0x8c,0x98,0xc8,0xad,0xbf,0x13,0x68,0x74,0xbc,0x5d,0xff,0xe1,0x24,0xfe,0xd8, - 0x88,0x3e,0xde,0xd4,0xe2,0x6f,0xb6,0xe2,0xd8,0xa8,0xe4,0xb3,0x34,0xfa,0x47,0x83, - 0x91,0x90,0x14,0x8f,0x8f,0x6b,0xa4,0xd7,0xac,0x6f,0x9f,0xb0,0x76,0x8f,0x00,0xae, - 0xd3,0xec,0x78,0x74,0xbc,0x73,0x72,0x22,0x87,0x86,0x48,0x48,0xe9,0x08,0x62,0x2f, - 0x0c,0x5b,0xa2,0x26,0xb8,0x46,0xdd,0xcd,0xf5,0x60,0xaa,0xf2,0x06,0x5d,0x8b,0x37, - 0xc1,0x4d,0x5a,0xda,0xcd,0xe9,0xb5,0xcd,0x1f,0xdc,0x00,0x24,0x16,0x88,0x7e,0xf8, - 0x44,0x1f,0xcc,0x52,0x41,0x73,0x68,0x74,0x8e,0xca,0x0c,0x48,0xaf,0x84,0x97,0x30, - 0x14,0x95,0x79,0xe4,0xdb,0x1e,0xdd,0x45,0x6c,0x91,0x79,0x96,0x64,0xb7,0xe2,0x25, - 0x58,0xf9,0x28,0xf1,0x13,0x27,0xa6,0xa9,0x89,0x74,0xb0,0x5c,0x96,0x53,0xc7,0x93, - 0x70,0xcf,0x4e,0x73,0xb1,0x76,0xe6,0x8a,0x4e,0xd8,0x06,0xd8,0x0e,0x14,0x8b,0x52, - 0xe8,0xd8,0xff,0x8c,0xc4,0x58,0xb2,0xcf,0x6f,0xfd,0xcf,0xf3,0x5b,0xc9,0xdc,0x39, - 0xf3,0x3f,0x76,0xce,0x24,0xab,0xfa,0xeb,0xf4,0x40,0xe4,0x83,0x20,0x99,0xaf,0x02, - 0x93,0x0f,0x82,0x8e,0xfc,0x51,0x5a,0x7c,0xc1,0x9b,0xcd,0x41,0x86,0x70,0x1c,0x41, - 0x2a,0xa8,0x24,0xf8,0xfc,0x56,0xf7,0x8b,0x7e,0x16,0x24,0x7e,0x5a,0x9f,0x8d,0x1d, - 0xbe,0x69,0x06,0xbc,0x1c,0xf0,0xd0,0xbb,0xea,0x47,0x33,0x21,0xd8,0xf6,0x8b,0x68, - 0xa1,0xb6,0x52,0x7d,0xdc,0xb6,0x8f,0x69,0xcd,0x13,0x99,0x81,0xd8,0x90,0x8f,0x34, - 0x40,0x62,0x86,0x58,0x2e,0xc5,0xf0,0xa7,0x94,0x5d,0x74,0xc7,0x5e,0xbb,0x57,0x22, - 0x12,0xd8,0xe5,0x72,0xfb,0xa9,0x10,0xee,0xfb,0x40,0x5e,0x4b,0x09,0xa0,0x3e,0xad, - 0xa5,0x06,0x00,0x0f,0xa7,0x48,0x10,0xfa,0x54,0x89,0xff,0x30,0xbb,0x5d,0x39,0xc1, - 0x67,0xa2,0xfa,0x04,0xf2,0xbb,0x14,0x7f,0xa2,0x6d,0xa0,0x20,0xf5,0x1c,0x20,0xad, - 0xc9,0xf2,0xc9,0x40,0x68,0x4e,0xdf,0xf3,0xd0,0x9a,0xbc,0x39,0x8c,0xe4,0xb6,0x7d, - 0xf8,0x58,0x35,0xa2,0xd4,0x4f,0x26,0x55,0xe0,0x4a,0x6e,0xbf,0xfc,0x22,0x0c,0xc0, - 0xa7,0x1c,0xc0,0xa5,0x6e,0x7d,0x6e,0x25,0x70,0x05,0x0e,0x3d,0xde,0x92,0x6c,0x2a, - 0xe7,0xf4,0xf6,0x98,0x22,0xbc,0xe1,0x57,0x33,0x0a,0x55,0x97,0xa8,0x1f,0xf1,0x26, - 0xdf,0xdc,0x3b,0x1d,0x16,0x84,0xa6,0x49,0x11,0xce,0x1d,0x1a,0x8f,0xf0,0x9b,0x86, - 0xf9,0xfe,0x49,0xbe,0xa3,0x9b,0x08,0xd1,0x8e,0x4f,0x1d,0xcd,0xf6,0x8f,0x3c,0xc5, - 0xef,0x2c,0xb6,0x1b,0x1a,0x05,0x97,0x04,0xa6,0xd9,0x72,0xde,0xa2,0xdf,0xf9,0xd5, - 0x46,0x20,0xaa,0x0f,0x05,0x90,0x04,0x4f,0x42,0xd9,0xbe,0x26,0x2c,0x68,0x49,0xf1, - 0xa9,0x53,0x07,0x0f,0x0a,0x4b,0x6f,0xd5,0x68,0x59,0x52,0x0b,0x14,0x5e,0xac,0x2f, - 0x33,0xeb,0x0b,0x5e,0xfc,0x62,0x7c,0x57,0x05,0x56,0x06,0xe9,0x1d,0x26,0xbd,0x3a, - 0xef,0xca,0x1e,0x06,0x4e,0xb9,0x9d,0xaa,0xec,0x48,0x40,0x8b,0xd1,0x34,0x97,0x69, - 0x7e,0x96,0x35,0x65,0x29,0x8c,0xd7,0x95,0xf5,0x8e,0xb4,0x96,0x47,0x6f,0xfa,0x51, - 0xfd,0xdc,0xe8,0x67,0xf3,0xae,0xe5,0x8b,0x83,0x18,0xeb,0x3b,0xbf,0x0b,0x02,0xbd, - 0xb1,0x5c,0x7c,0xce,0x93,0x18,0x43,0xf9,0xaa,0xb0,0x47,0xb9,0x82,0x7f,0x32,0x00, - 0x42,0x36,0xdf,0xab,0xb5,0x90,0xd2,0xab,0xc7,0x1d,0xf7,0xee,0x6d,0x09,0xfa,0x93, - 0x7e,0x90,0x63,0x2e,0x19,0xc6,0xb6,0x29,0xc2,0x90,0x56,0x8c,0xfd,0xa1,0x6c,0x6e, - 0x87,0x7a,0x3e,0xaf,0x17,0x89,0x63,0x41,0x89,0x6f,0x9c,0x56,0x1a,0x46,0xfa,0xd5, - 0xac,0xe5,0x1d,0xe4,0xa8,0xcb,0x4b,0x42,0x9e,0x5c,0xaf,0x41,0x5f,0xe0,0x4d,0xa3, - 0x6b,0xfa,0x04,0xe4,0x72,0x1c,0xa5,0x58,0xd3,0x6b,0x07,0xaf,0xc4,0x24,0x3b,0x50, - 0x1b,0x95,0x97,0x3d,0xac,0x6c,0xa3,0x53,0x63,0xa9,0x22,0x47,0x8a,0xf2,0xe6,0x28, - 0xbf,0xd1,0xac,0x59,0xfa,0xae,0x4b,0x8e,0x75,0xac,0x53,0x2a,0x28,0x30,0xe0,0xee, - 0xe1,0xfd,0x8c,0x02,0x4d,0x12,0xab,0x90,0x9b,0x00,0xcd,0xc9,0x95,0xa0,0x31,0x74, - 0x64,0x89,0x25,0xfd,0xe2,0x8d,0xcd,0x4d,0xf7,0xeb,0xb1,0xf5,0xf5,0x04,0xfa,0x81, - 0xcc,0xc8,0x16,0x27,0x19,0x99,0x1e,0xad,0xc5,0xce,0xd2,0x93,0x91,0x6b,0x76,0x4d, - 0x3d,0x01,0x7f,0x72,0xd3,0x27,0x54,0xd3,0x2f,0x5d,0xe1,0xd0,0xcc,0xfa,0xb9,0xd2, - 0x68,0x47,0x76,0x64,0x72,0x58,0x70,0x1f,0x68,0xca,0xc0,0x7e,0x85,0x5d,0xd2,0xc2, - 0x50,0x4e,0x39,0x04,0xaa,0x77,0x88,0x2a,0xa7,0x0f,0xe3,0xe5,0xde,0x1a,0x56,0xb6, - 0xaa,0x18,0xc9,0xed,0xe4,0x14,0x54,0xcd,0xf0,0xaf,0xe2,0xa3,0x42,0xdd,0xcf,0x4d, - 0xd9,0xfe,0xde,0x71,0xc7,0x2d,0x91,0xb6,0xa2,0x2f,0xb0,0x5e,0xeb,0xde,0xe6,0xb9, - 0xdb,0x90,0x1e,0x8b,0x4d,0x5c,0x56,0xe2,0xa1,0x7f,0xb6,0xc6,0x5b,0x21,0xb3,0x81, - 0x2a,0x55,0xeb,0xf2,0xc4,0x98,0x98,0xa5,0xd7,0x05,0x39,0x48,0x74,0xce,0x02,0x57, - 0x9f,0xd6,0xa1,0x46,0xd6,0xa9,0xe8,0x25,0x18,0x88,0x82,0xac,0x01,0xde,0xae,0x3c, - 0x86,0xe4,0x02,0x43,0x53,0xae,0xa8,0xb6,0x80,0xc8,0xbc,0x02,0x8c,0x1f,0x40,0x03, - 0xc6,0x37,0xb3,0xad,0xd7,0xe7,0xd8,0x8d,0xd6,0x17,0xde,0x4f,0x57,0x32,0xe0,0xd4, - 0xc4,0xb0,0x5a,0xc1,0x02,0xa9,0x94,0xc4,0xad,0x5a,0x59,0x2d,0xb7,0x56,0x80,0xe4, - 0x7a,0xa9,0xd8,0x29,0x97,0x05,0x82,0xee,0x62,0xa9,0x85,0x12,0xc2,0x3b,0x02,0x94, - 0xe8,0x13,0x29,0xdf,0xd6,0x34,0x12,0x6e,0x30,0x28,0x9d,0x14,0xd6,0xe7,0x71,0xed, - 0xb2,0xf6,0x58,0x8e,0xdf,0x88,0x40,0x65,0xb0,0x83,0x10,0x64,0x58,0x27,0xd2,0x22, - 0x0d,0x7b,0x6c,0x72,0x98,0x32,0xc0,0xc1,0x04,0x4e,0x9b,0xa3,0x38,0xe1,0x97,0x9f, - 0xb8,0xd1,0x1f,0x9d,0x52,0xda,0xcb,0x7f,0x44,0x0e,0x78,0x22,0xfd,0x40,0x08,0x95, - 0xbe,0x20,0xe4,0xac,0xe4,0xda,0x9a,0xa6,0xb6,0x8a,0x8c,0x85,0x4f,0x92,0x62,0x37, - 0xb9,0x29,0x2e,0x75,0x48,0xf1,0x7b,0x80,0x02,0xba,0x42,0x8a,0x37,0x5f,0x3e,0xbf, - 0xf5,0xd3,0x43,0xd9,0x0d,0xd0,0x87,0x30,0x1c,0x60,0x05,0xbf,0x61,0x29,0x0b,0xa2, - 0x2f,0x3e,0x20,0x91,0x6f,0x6b,0x50,0xb2,0x3d,0x33,0xb9,0x5b,0x41,0x35,0x6e,0xa1, - 0xe4,0x4f,0xb2,0x08,0x95,0x09,0x49,0xa6,0x4f,0xa2,0x8a,0x7d,0xba,0xa7,0x62,0x7a, - 0x20,0xc0,0x9c,0x16,0xd3,0x99,0x4a,0xee,0xfb,0xbb,0x04,0x90,0x27,0x13,0x0c,0xb3, - 0x99,0x73,0xbc,0x48,0xb7,0x37,0x37,0xf9,0xe9,0x79,0xba,0xdd,0xcc,0x8b,0xe2,0x04, - 0x1c,0x41,0xf0,0x6f,0x2d,0x8a,0x14,0x65,0x9a,0x6e,0x3f,0x5b,0x2e,0xad,0xd7,0xdd, - 0x9d,0x78,0x2f,0x0c,0xf2,0x04,0x64,0xc9,0x1f,0x5b,0x6c,0x86,0xe1,0x6f,0xe5,0x41, - 0xc9,0x0c,0xfb,0x1b,0x68,0x71,0x9e,0x3d,0x7d,0xb6,0xf3,0x14,0x87,0x1d,0xc8,0xe4, - 0x7e,0x67,0xc7,0xd8,0x06,0xa4,0x89,0xff,0x5c,0xed,0x36,0xb9,0xc4,0x63,0x6e,0xe6, - 0x26,0x55,0xc2,0xa5,0x72,0x3b,0x49,0x32,0xb5,0x54,0xc2,0xd5,0x28,0x03,0x70,0x22, - 0x37,0x24,0xf3,0x5c,0xe0,0x97,0xcb,0x47,0xfc,0x41,0x57,0x01,0x92,0xae,0x4b,0x8e, - 0x47,0xa5,0xd6,0x31,0x2d,0x32,0x5e,0xd5,0x1a,0x6d,0x7e,0x12,0xe9,0x30,0x66,0x6e, - 0x8f,0x89,0xd3,0x7b,0x52,0xe5,0x71,0xdc,0x12,0xc7,0xf2,0x68,0xdb,0x12,0x85,0x39, - 0x2b,0x89,0x48,0xc1,0xe0,0x32,0xaa,0xd4,0x2c,0x5e,0x2a,0x5a,0x67,0xaf,0x94,0xd8, - 0x6a,0xc6,0x5e,0x39,0xb3,0x5b,0xbf,0x84,0x8a,0xa6,0xf2,0x33,0x72,0x43,0xd9,0x79, - 0xd7,0x36,0xa3,0x3b,0x18,0x78,0xf6,0x73,0x9b,0xd6,0xfe,0x3c,0xc2,0x7d,0xe6,0x07, - 0x37,0x70,0xde,0x38,0xeb,0x1b,0x5a,0xa8,0x34,0x0d,0x66,0x78,0x9e,0x9a,0x0c,0xa9, - 0x3a,0xf7,0x2f,0x06,0xcf,0xbd,0x6d,0x61,0x8e,0xf5,0x2c,0x67,0xf5,0xeb,0x0e,0x82, - 0x0d,0x44,0x2c,0x79,0x7c,0xe7,0xfe,0x6b,0xf2,0x4a,0x56,0x26,0xdb,0x76,0x5b,0xc6, - 0xdd,0x56,0x98,0x40,0x9c,0xe2,0x2f,0x06,0x18,0xd6,0x30,0x6b,0x9a,0x98,0x47,0xdc, - 0xfa,0x96,0x84,0xe9,0x4b,0x59,0x06,0x08,0xbd,0x7c,0x8a,0xd5,0x0c,0xd7,0x8d,0xf9, - 0x3b,0xa6,0x54,0xee,0xd2,0x71,0x39,0x5e,0xe8,0x03,0x1e,0x76,0x06,0x42,0xba,0x8e, - 0xd5,0x34,0x66,0xcd,0x41,0x1d,0x60,0x73,0x93,0x93,0xed,0xc5,0x90,0x8d,0xc3,0x99, - 0x7c,0x90,0xf2,0x2f,0x4d,0x3f,0x3d,0x7b,0xe6,0xe1,0x5e,0x47,0x7f,0x78,0xf6,0x89, - 0xec,0xd2,0x12,0x26,0x25,0x31,0x44,0xdb,0x0d,0x59,0x61,0xbc,0x91,0x0b,0x13,0xb2, - 0x4a,0x82,0x73,0xb9,0x96,0x1f,0x71,0x44,0xbc,0xe8,0xdb,0xe1,0x46,0x86,0x9f,0xd9, - 0xe4,0x48,0x5b,0x30,0x3c,0xb8,0xc2,0x64,0x37,0xca,0xb3,0x6c,0x65,0x56,0xb4,0x01, - 0x13,0x28,0x96,0x4f,0x7e,0xc8,0xdf,0xe7,0x08,0x27,0x68,0x50,0x31,0xf4,0x87,0x9f, - 0xc9,0x8d,0x07,0x72,0x90,0xe7,0x73,0x7c,0xe0,0xf8,0xcc,0xe2,0x75,0x83,0x91,0x87, - 0xaf,0xa9,0x31,0x25,0x74,0x05,0x9d,0xaa,0x01,0x79,0x67,0x78,0x7a,0x35,0x64,0x5f, - 0xc8,0xe0,0x9d,0x1b,0x8d,0x5f,0xc2,0x5c,0x6a,0xe0,0x4b,0x73,0x28,0xc7,0x21,0x68, - 0x1b,0xee,0xae,0xd0,0x5a,0x44,0xc8,0xa8,0x9d,0xa6,0xd0,0xcb,0x93,0x4d,0x9a,0x2e, - 0x0e,0x56,0x99,0xa3,0x4d,0x8f,0xad,0x15,0x15,0xe0,0xd2,0x5c,0x5e,0xde,0x15,0x13, - 0xc8,0xb4,0x41,0xd1,0x29,0x6b,0x61,0x82,0xce,0xd6,0xe8,0xde,0xc8,0x43,0x76,0x26, - 0x0f,0xa7,0x33,0x6f,0x8e,0x30,0x7b,0xbd,0x88,0x1f,0x65,0x63,0x27,0xe2,0x84,0xee, - 0x31,0xa4,0x35,0x32,0x25,0xb6,0x2e,0x36,0x70,0xf3,0xdb,0xc0,0xd6,0x73,0x83,0x9e, - 0x19,0x2a,0xe5,0xcc,0x4a,0x55,0x71,0x80,0x6d,0x30,0x79,0xb6,0x2c,0xa7,0xb2,0x0e, - 0xa6,0x5c,0xe8,0xc5,0x6e,0x91,0xb1,0x60,0x91,0x7d,0x80,0x51,0x6d,0xa6,0xa7,0x6d, - 0xe9,0xeb,0xc4,0xbf,0x7c,0x55,0x23,0xcf,0x7a,0x4f,0x44,0xf6,0x0e,0x92,0xc4,0x76, - 0x30,0x8a,0xe5,0xbe,0xfd,0x86,0x6b,0xe9,0xb5,0x60,0xe3,0x88,0x43,0x3a,0x57,0x41, - 0x87,0x2e,0x7c,0xd4,0xc5,0x6d,0xe7,0x03,0xcc,0x7e,0x24,0xfd,0x6e,0xa3,0x68,0xd4, - 0xcb,0x95,0x6d,0xca,0x9c,0xbe,0x4c,0xed,0x0d,0x40,0x72,0x9d,0xea,0x71,0x13,0xd3, - 0x49,0x95,0x34,0x4b,0x79,0x7f,0x57,0xe0,0x1e,0x1b,0xcb,0x58,0x15,0x19,0x08,0x73, - 0x2a,0x42,0xcc,0xb7,0x51,0xe9,0x84,0xac,0x71,0x86,0x2f,0xf4,0x01,0xed,0x83,0x6f, - 0x9b,0x9b,0xf8,0xe3,0xde,0xf6,0x00,0x0c,0x05,0x85,0x0d,0x79,0xcd,0x06,0xc6,0x9f, - 0x5e,0xe4,0x98,0x65,0x95,0x26,0x55,0x92,0xb5,0xff,0x6a,0xbb,0x49,0x3d,0x7e,0xd4, - 0x4c,0xda,0xb9,0xd7,0xe7,0xd1,0xb9,0x51,0x4e,0xc6,0x4a,0x5d,0x7e,0x7d,0xb5,0x73, - 0xd3,0x42,0x2f,0x7e,0xe5,0x9a,0x09,0xe7,0xb4,0x21,0xd0,0xb2,0x44,0xf7,0x32,0x07, - 0xc6,0xfc,0xe7,0xb8,0x14,0x42,0xf0,0x24,0x59,0x0b,0xe9,0xc7,0x0f,0x5c,0x27,0x74, - 0x65,0x0e,0x78,0x14,0x29,0x35,0x9b,0x9b,0xfa,0xd8,0x10,0x0c,0x5c,0x77,0x3d,0x44, - 0xd5,0x5c,0x54,0xe9,0xec,0xf3,0xf8,0x54,0xa2,0x73,0x8a,0xdd,0x03,0x5b,0x92,0xe8, - 0x12,0x50,0x98,0x89,0x24,0xdd,0x95,0x78,0x5b,0x9a,0x76,0xe7,0xec,0x57,0x48,0x68, - 0xca,0x57,0xd8,0x2a,0x6f,0xc3,0x56,0x39,0x55,0xe3,0x25,0x36,0x5a,0x5e,0xc8,0xea, - 0x83,0x7a,0xfc,0xcf,0x34,0x25,0x67,0xd1,0x37,0xee,0x88,0x48,0x06,0x71,0xbb,0x12, - 0x48,0x46,0x87,0xc0,0xdc,0x31,0xd9,0xef,0x49,0x45,0x0b,0x98,0x21,0x24,0x30,0x13, - 0x5d,0xad,0x82,0x72,0x44,0x4e,0xbb,0x6c,0xd6,0xa0,0x82,0x46,0x76,0xf6,0xee,0x72, - 0xa9,0x92,0x3b,0x8b,0x8d,0xe3,0x50,0x18,0x1c,0x26,0xf6,0x91,0x4a,0x95,0xb9,0xc7, - 0x14,0xd5,0x19,0xdc,0xca,0x68,0xe5,0xa3,0x74,0x7b,0xba,0x7e,0x5c,0x33,0xdf,0x6b, - 0x8f,0x1b,0xf8,0xe6,0xae,0x7c,0xaa,0xc1,0xe4,0x14,0x86,0x21,0xb5,0x45,0x23,0x39, - 0xa3,0xe7,0x45,0xcb,0x72,0xa9,0x6f,0xe3,0xe2,0x45,0x7b,0x9f,0x6f,0x4d,0x5f,0x4c, - 0xc6,0x10,0x20,0x49,0xae,0x58,0xb8,0x4e,0x6d,0x85,0x44,0xbc,0xf0,0xd5,0x00,0xe6, - 0xf0,0xdf,0xd1,0x18,0xf0,0x96,0x10,0x18,0xd6,0xad,0x06,0x2e,0x83,0xc1,0x58,0xd1, - 0x98,0x35,0x01,0x69,0x2e,0xe8,0xe4,0x32,0xd6,0x8e,0xa4,0xa9,0xf6,0xf1,0x1b,0x6a, - 0xc3,0x69,0xde,0x61,0x58,0x5c,0xd9,0x4e,0x7e,0x5b,0xdb,0xb5,0x96,0xa2,0xf4,0x42, - 0x03,0xf7,0x44,0x8e,0x9b,0xc8,0x22,0xec,0x91,0xa3,0xa4,0x04,0x74,0x0a,0xf7,0x3f, - 0x59,0xff,0x67,0xf2,0x7e,0x14,0xd9,0x6d,0x03,0xb2,0xb5,0xd5,0x48,0x45,0xea,0xac, - 0x52,0x06,0x19,0x7c,0x10,0xe2,0x3e,0x7e,0x84,0x23,0xd8,0xcd,0xcd,0xce,0xd9,0x8b, - 0xb4,0xb9,0x17,0xfe,0xff,0xb0,0x9c,0x13,0x83,0x7d,0x5c,0xb3,0xec,0x45,0x14,0x98, - 0x68,0x0b,0x10,0xb5,0xed,0x38,0xde,0xc2,0x06,0xb1,0x16,0xfe,0x47,0xd0,0x43,0x28, - 0xb5,0x80,0x43,0xa9,0x85,0x2d,0xa3,0x1d,0x56,0xb3,0x1f,0xdf,0x9c,0x86,0x2e,0x3a, - 0x79,0xd6,0x34,0xb2,0xb5,0x86,0x51,0xcd,0x9c,0x6f,0x1f,0xb6,0x7d,0x6d,0x91,0x65, - 0x64,0x0e,0x05,0x28,0x20,0xc9,0xe8,0x95,0xa6,0x33,0xfb,0x26,0x5a,0xfc,0xa0,0xe9, - 0xce,0x47,0xac,0x5a,0xc4,0x53,0x02,0x7e,0x35,0x86,0x85,0x2d,0x45,0xdb,0xb7,0x51, - 0x53,0xae,0x41,0x2f,0x51,0x75,0x77,0x5c,0x46,0x25,0x4a,0x05,0x7f,0x83,0x2f,0x1a, - 0x3d,0x17,0x5a,0x34,0x4c,0xf6,0xb0,0xb1,0xbf,0xd6,0x1e,0x57,0x0b,0xd2,0x09,0x6b, - 0x9c,0x26,0x58,0x3b,0xa8,0xaa,0x61,0x62,0xd1,0x44,0x83,0x45,0x47,0x88,0x53,0x5c, - 0x01,0x84,0x27,0x8f,0x26,0xd5,0x5e,0x95,0xf5,0x5e,0x4a,0x97,0x42,0x3c,0x88,0xb2, - 0x89,0x4c,0x72,0xba,0x72,0xf3,0x4b,0x94,0xa9,0x4e,0x75,0x8d,0x8e,0x8c,0x5e,0x3f, - 0x97,0x4a,0x71,0x93,0xd5,0xc3,0xd6,0x52,0x50,0xca,0x94,0xe0,0x72,0x26,0xe4,0x44, - 0xc0,0xe9,0xbd,0xb8,0xdc,0x96,0x99,0x16,0x05,0x64,0xfb,0xa2,0x41,0xfb,0x8d,0x95, - 0x5c,0x60,0x2c,0x06,0xd9,0xab,0x27,0x79,0xc7,0x40,0x84,0x99,0x31,0x04,0x38,0x2f, - 0x9e,0xa0,0x1f,0x6e,0x48,0x6c,0xbe,0x86,0xf1,0xc3,0x98,0x4b,0xd0,0xb4,0xbe,0xdd, - 0xfe,0xb0,0xff,0xd3,0xab,0x77,0x9f,0xde,0x7f,0x78,0x09,0x0b,0xcb,0xc3,0x0a,0x91, - 0x9b,0x0c,0x98,0x71,0xb9,0x72,0xcd,0x94,0x63,0xf8,0x30,0x8d,0x41,0x60,0x3c,0x4a, - 0x07,0x3c,0xf7,0x09,0x4b,0x47,0x2f,0x52,0x55,0x16,0x8c,0xe2,0x56,0x94,0xd7,0xc5, - 0x11,0x54,0x7b,0x21,0xd1,0x1f,0xb6,0x24,0x93,0x28,0x99,0x2c,0xc5,0x3a,0x71,0xc7, - 0xbb,0xa1,0x6b,0x2b,0x25,0x37,0x37,0x8b,0x25,0x95,0xfd,0x5c,0x28,0xca,0xb0,0x87, - 0x88,0x7d,0xb5,0xae,0xaf,0x0c,0xb7,0xbf,0x9e,0xa4,0xda,0x0d,0xd7,0x0f,0x71,0x46, - 0xb3,0x5e,0x5d,0xfe,0x68,0x95,0x10,0x20,0x72,0xa5,0x10,0xc2,0x19,0x9a,0xca,0xaf, - 0xe8,0xef,0x9e,0x82,0xd6,0xfd,0xae,0x9b,0x0f,0x30,0xa7,0xb2,0xff,0xba,0x67,0x45, - 0xd2,0xd9,0x9c,0x37,0x5a,0xab,0x6b,0x65,0xaa,0x16,0x7b,0x36,0x4f,0x7c,0x3a,0x55, - 0xb2,0x38,0xe5,0x70,0x92,0xfd,0xa2,0xa5,0xa8,0xca,0xb1,0x84,0xa0,0x54,0xcc,0x9d, - 0x6b,0x66,0x56,0x9a,0x7c,0x16,0xa2,0xc4,0xb2,0x35,0xa4,0xda,0xb9,0xa4,0x93,0xcb, - 0x5c,0x33,0x9d,0xfe,0xd5,0xb8,0xbe,0x4f,0x1f,0x61,0x0c,0x89,0x29,0xa9,0xbd,0x10, - 0x95,0xc0,0x5b,0x59,0xe9,0xda,0x86,0x38,0x22,0xf2,0x97,0xac,0x72,0xeb,0x39,0x19, - 0x23,0x4e,0xd4,0x66,0x81,0xde,0xca,0x57,0x1f,0x97,0xf6,0xd7,0xe3,0x5a,0x34,0x26, - 0x9d,0xd7,0x5e,0x28,0xbe,0x82,0xc2,0x56,0xfe,0x94,0x95,0x2e,0x7f,0x59,0x6e,0x8a, - 0x16,0xd6,0xb6,0xb0,0xbc,0x51,0x93,0xad,0x34,0x0d,0x4d,0x7d,0x36,0x37,0xc2,0x43, - 0xe3,0xdb,0xa8,0xdf,0xa3,0x75,0xb8,0x19,0x53,0x87,0xaf,0xdf,0x1d,0x91,0xf9,0xf9, - 0xeb,0x97,0x6f,0xd3,0xc5,0x1c,0xe1,0x37,0xc6,0xad,0x27,0xdf,0x25,0x70,0x39,0x30, - 0x23,0x83,0xb0,0xd6,0xee,0xb6,0x3a,0x04,0xc0,0x4d,0xa7,0xc4,0xf8,0xcf,0xa3,0x27, - 0x0e,0xe0,0xd0,0xfa,0xe1,0x29,0xfc,0x0c,0xf4,0x06,0xe4,0xe6,0x09,0x89,0x77,0x86, - 0xad,0xef,0x7f,0x3b,0xfa,0x74,0xf4,0xdf,0xef,0x5f,0x1e,0xa6,0xc7,0xc7,0xcd,0x24, - 0xfc,0xf0,0xf2,0xbf,0xb0,0x12,0x3f,0xde,0xa6,0xa7,0xc3,0xf7,0xef,0xde,0x1e,0xbe, - 0xa4,0xd7,0x9d,0x24,0x3c,0xfa,0x1b,0x4a,0x3e,0xfc,0x85,0xde,0x76,0x93,0x70,0xff, - 0xe0,0x37,0x7a,0x7a,0x82,0xa7,0x9f,0xfe,0xfa,0xf2,0xc3,0x11,0x5e,0x36,0x8e,0x9f, - 0x26,0xe1,0x2f,0x1f,0xde,0x7f,0x02,0x24,0x7d,0x7b,0x66,0xde,0x7e,0x42,0x10,0x1a, - 0x7a,0xfd,0x0e,0xa0,0x6f,0xdf,0xbd,0xfd,0x24,0x05,0x7c,0x9f,0x84,0xef,0xf7,0x8f, - 0x7e,0xa5,0xc7,0x1f,0x80,0xfc,0xc3,0xfe,0xc1,0x4b,0xc6,0xb1,0x0d,0x1a,0xde,0xfc, - 0xfe,0xfa,0xe8,0xd5,0xfb,0x7d,0xc2,0x0a,0x4a,0x40,0xca,0xc1,0xbb,0xb7,0x47,0x1f, - 0xde,0xbd,0xe6,0x57,0x90,0x32,0xeb,0x73,0xcd,0x7a,0xfc,0xbe,0x5b,0x7a,0x7f,0xe2, - 0xbc,0x03,0x21,0xa8,0xfa,0xb0,0xff,0xc7,0xa7,0x83,0xdf,0x0f,0x8f,0xde,0xbd,0x09, - 0x4f,0x4e,0x8a,0x6a,0xbf,0xdd,0x7f,0xf3,0xf2,0xa7,0xbc,0xe7,0xc1,0x05,0x09,0xfa, - 0x65,0x44,0x76,0x7b,0x68,0x47,0xe5,0x4a,0x85,0x1c,0xe5,0xa6,0x9a,0x1e,0x6f,0xd3, - 0xb1,0x69,0x51,0x56,0xac,0x18,0x8f,0xe9,0x1b,0xba,0x18,0x07,0x85,0x3b,0xc0,0xb0, - 0x88,0xe2,0x93,0x74,0x7a,0xdc,0x3c,0x71,0xc6,0xc1,0x19,0x2f,0xd0,0x11,0x39,0xe4, - 0x32,0xa2,0x0e,0x26,0x03,0x61,0x2e,0xbb,0x35,0x4e,0x2b,0xac,0x08,0x19,0xa2,0x81, - 0x2f,0x23,0x59,0x04,0xce,0x59,0xde,0x2c,0x97,0xfc,0x8b,0xf3,0x4a,0x3d,0xfa,0x6e, - 0xde,0xfe,0x8c,0xff,0x14,0xc6,0x38,0x16,0xd5,0x8f,0xa2,0x81,0x44,0xa1,0x69,0x33, - 0x99,0x5c,0xca,0xb9,0x1d,0xf6,0xf2,0xe8,0x77,0xe8,0x70,0x49,0xd5,0xfc,0x87,0x05, - 0x9e,0x52,0x87,0x2c,0xf4,0x2a,0x94,0x24,0x63,0x9a,0x76,0xf8,0x22,0xf7,0xdf,0x8f, - 0x9b,0xb0,0x9d,0xac,0x7d,0x23,0xf7,0xae,0x01,0x18,0xc7,0x63,0xb3,0x36,0x7c,0x35, - 0xe6,0xf7,0x04,0x4b,0x38,0x95,0x6c,0x94,0xe0,0x72,0x88,0x26,0x15,0xe5,0x20,0xb2, - 0x16,0xdc,0xf4,0x40,0xcd,0x71,0xea,0xf8,0x79,0x73,0xb9,0x1c,0xbf,0x80,0xd5,0xd5, - 0x02,0x54,0x99,0x25,0x97,0xa9,0xe6,0xdd,0x06,0x55,0x70,0x99,0x46,0xdb,0xcf,0x9f, - 0x8f,0x65,0x5d,0x2f,0x0c,0x98,0x5c,0xee,0xd1,0xb7,0x56,0xce,0xa5,0xbb,0x72,0x7b, - 0x1c,0x81,0xd1,0x11,0x81,0xb0,0x14,0xe4,0x27,0x70,0xd1,0x80,0x0b,0x17,0x99,0xdd, - 0x6d,0xfb,0xab,0x7c,0x30,0xbc,0x96,0xd3,0x7b,0xf8,0x26,0x20,0x8b,0x7f,0xf7,0x92, - 0xea,0xf6,0x33,0xde,0xf0,0x49,0xd6,0x4d,0x22,0x70,0x10,0xc7,0x80,0x6d,0x4c,0xaf, - 0xb2,0x8b,0x68,0xa0,0x84,0x52,0x7e,0xb9,0x52,0x9a,0x94,0xc4,0x4a,0x96,0x6f,0x00, - 0x7f,0x9d,0x8f,0x86,0xd1,0x20,0x39,0x4b,0xc8,0x30,0x20,0x61,0x27,0x00,0x09,0x69, - 0x04,0xf5,0xce,0xea,0x63,0xc7,0xc1,0x6d,0x90,0x9d,0xd5,0x1f,0xd7,0xce,0x6a,0x8f, - 0xd5,0xb3,0xed,0xe3,0x1a,0xff,0xd6,0x1e,0x57,0xfa,0x4d,0x7f,0x5c,0xa3,0x5f,0x80, - 0x3b,0xee,0xfb,0x1f,0xd7,0x06,0xd8,0x6d,0x31,0x9e,0x07,0xbb,0xe0,0xf6,0x9d,0x01, - 0xa2,0xe8,0x88,0x48,0xdd,0x73,0x48,0xa4,0x14,0xfa,0x44,0xbf,0x20,0x8a,0x1d,0xab, - 0x3c,0x6e,0x3d,0x7e,0x1c,0xeb,0x8b,0x7b,0xdb,0xd9,0xda,0xe7,0x1a,0x5e,0x48,0x2f, - 0x85,0xa9,0x46,0x3f,0x4b,0x75,0x04,0xd3,0xcd,0x5e,0x67,0xf4,0x2a,0x7b,0xb8,0xd6, - 0xea,0x1d,0xfb,0x72,0xbd,0x7b,0xfa,0x29,0xfc,0xce,0x70,0xed,0x43,0x51,0x85,0xe3, - 0x8d,0x06,0x35,0x31,0x34,0x30,0x1e,0xf6,0xf2,0x84,0x80,0x1e,0xb6,0xf1,0xa0,0x3e, - 0xa3,0x84,0xe1,0xee,0x4d,0xe1,0x95,0xcd,0x64,0xba,0xa2,0xb6,0x13,0x6f,0xe8,0x0d, - 0x55,0x99,0xa2,0xda,0x00,0x76,0x3f,0xd8,0x6f,0x55,0x63,0x09,0x36,0xce,0x22,0x45, - 0x49,0x85,0xcf,0x89,0xdb,0xcc,0x2d,0xe5,0xb0,0x07,0xd3,0x01,0x19,0xeb,0xbc,0x74, - 0x0e,0xc7,0x97,0xca,0x20,0x2c,0x00,0x84,0x47,0x2d,0x8c,0x11,0x0e,0x5f,0xa2,0x6e, - 0xda,0x18,0xf3,0xbf,0x80,0xa8,0x70,0x8c,0xec,0xa2,0xb2,0xfd,0x25,0x21,0xc3,0xd5, - 0xc8,0xf5,0xc5,0xc6,0x40,0x7e,0xe7,0xfa,0xe3,0x62,0x70,0x4a,0xc1,0x9b,0x3e,0xd3, - 0x84,0xcc,0x74,0x18,0x7d,0xb6,0x89,0x77,0x55,0x38,0xc7,0x92,0xd8,0x56,0x8d,0xc0, - 0x8a,0xb2,0x08,0x3f,0x6a,0x79,0xdc,0x27,0xa3,0xeb,0xee,0xdc,0x48,0xbe,0xac,0x2d, - 0xb1,0xa9,0x38,0x5d,0x6d,0xbb,0x18,0xf3,0x98,0xe6,0x70,0x11,0x2e,0xe4,0xf7,0x9a, - 0xd7,0x94,0x10,0xf0,0xe2,0xf1,0x1a,0xdc,0xcf,0x91,0xe4,0xe1,0xb5,0xd4,0x49,0xb5, - 0xdf,0xe5,0x7d,0xf5,0x8e,0xbb,0xb7,0xfb,0x26,0x0d,0xa5,0xb9,0xab,0x77,0x4e,0xf9, - 0x76,0x61,0x90,0x5e,0xe8,0x8a,0x6d,0x85,0x0d,0xfc,0x56,0x7c,0xbc,0x2d,0x53,0x25, - 0x5d,0x65,0x45,0x86,0x42,0xeb,0x49,0x22,0x48,0xd4,0x01,0xf4,0x4d,0xc4,0x9f,0x35, - 0xb7,0x58,0x73,0xdb,0x85,0xee,0x0b,0x08,0xd4,0x77,0x85,0x23,0xa4,0xeb,0xe8,0xaa, - 0x26,0xfc,0xb4,0x4b,0xcb,0xf4,0xae,0x1e,0x85,0x16,0xf2,0x53,0xa7,0x18,0x7c,0xe5, - 0x92,0x68,0x9e,0x89,0x63,0x4c,0xcd,0xcd,0xc2,0xec,0x00,0xdd,0x23,0xf5,0x8b,0x47, - 0x4d,0x4c,0xcf,0x31,0x53,0x2a,0x9e,0x62,0xfc,0x73,0x96,0x7b,0x8e,0xfc,0xdf,0x23, - 0xc9,0x6f,0x3a,0x4d,0xd8,0x52,0xe1,0xbf,0x17,0x4a,0xbb,0x69,0x27,0x0a,0x5b,0xe5, - 0xb9,0x44,0xc8,0xa0,0xf0,0xf1,0x0e,0x23,0xcf,0xa4,0x68,0xfa,0x10,0xd3,0x9f,0xd5, - 0xfb,0x4c,0xab,0xc1,0x9c,0xfd,0x17,0x57,0x72,0x95,0x58,0x3c,0xe0,0x85,0x69,0x0f, - 0xb3,0x04,0xb7,0xd3,0xc2,0x9a,0xfd,0xbf,0xbe,0x3d,0x88,0xf0,0xa2,0x49,0x62,0x99, - 0x73,0x57,0x36,0x49,0xd1,0x1a,0x22,0x9d,0x42,0xa0,0xd7,0xee,0x0a,0x15,0x7d,0x99, - 0x69,0x8e,0xb1,0x8f,0x58,0x3f,0xac,0xec,0xd6,0x17,0xf9,0x61,0x1e,0x15,0xe2,0x68, - 0xee,0xf0,0xee,0x0f,0x1b,0x97,0x65,0xd6,0x79,0x43,0xa6,0x47,0x08,0x17,0x93,0x0c, - 0xbe,0x98,0x38,0x81,0x7b,0x3a,0xbd,0x3b,0x3d,0xfd,0x02,0x73,0x0e,0xef,0xf9,0xd6, - 0x2b,0x77,0x19,0x96,0x3d,0xc2,0x3c,0xae,0xf4,0xf9,0x5e,0x0f,0xe8,0x37,0xa8,0xab, - 0xe3,0xf6,0xc7,0x6d,0xeb,0x06,0x61,0xe5,0xf2,0x93,0xb0,0xd5,0xca,0xe8,0xc0,0x20, - 0xf2,0xd5,0x34,0xe5,0x3b,0x23,0x31,0xcd,0x4a,0xa5,0x84,0xa2,0x00,0xe2,0x51,0x35, - 0x8e,0x53,0x3e,0xf8,0x0b,0x5f,0x98,0xdf,0x46,0xa3,0x61,0x53,0x45,0x15,0x46,0x16, - 0x5b,0xaa,0x52,0x3d,0x45,0x6a,0xd3,0xa3,0xf4,0x19,0x7f,0xae,0xc9,0xe6,0x21,0x47, - 0x8f,0x01,0x4c,0xc0,0x20,0x10,0xe6,0x9e,0xa0,0xf6,0x82,0x59,0x30,0x0b,0x74,0x71, - 0x52,0x11,0x57,0x8b,0x51,0x09,0xab,0xa8,0xbe,0x5c,0x29,0xe0,0x36,0xa0,0x45,0x01, - 0xe5,0x35,0x53,0xc8,0x5b,0xa7,0x30,0x51,0xc3,0x71,0x3c,0xee,0x9f,0x9e,0x92,0x8f, - 0xc3,0xfc,0x4b,0x18,0x57,0x64,0xcb,0x37,0x5a,0xf8,0x4e,0x52,0x02,0x3f,0xbf,0x6b, - 0x4a,0x75,0x0e,0x2d,0xc0,0x79,0x7c,0xaf,0x8f,0xd5,0xb9,0xcc,0xc6,0xad,0x28,0xe5, - 0x90,0xdf,0xb9,0x4b,0xae,0x2c,0x68,0x32,0xa3,0x6f,0x12,0xe1,0x01,0x45,0x98,0xf7, - 0x66,0x00,0x9a,0xf9,0x0a,0xa3,0x46,0x96,0x02,0x24,0x47,0x99,0xee,0x98,0x80,0x7f, - 0x99,0xc1,0xfd,0xfb,0x87,0xd7,0x95,0x78,0x79,0xe7,0x58,0x50,0x72,0x44,0xaf,0xc1, - 0xbc,0x3f,0x9a,0xd2,0xc1,0x2d,0x95,0x53,0xb8,0x62,0xce,0x5a,0xc1,0x82,0xcc,0xcd, - 0xef,0x82,0x85,0xf1,0x2d,0x89,0x07,0x92,0x96,0xf8,0x61,0xae,0xde,0x55,0x16,0x20, - 0x3b,0x52,0x8b,0xa7,0xff,0xf9,0xc7,0x51,0x60,0xa5,0xe6,0xf7,0xc7,0x83,0xba,0x15, - 0xa9,0x83,0x5a,0x62,0x8b,0x38,0x1a,0xf0,0xbd,0x56,0x20,0xae,0x58,0x0e,0x6e,0x38, - 0x0b,0x47,0xe2,0x9e,0xe5,0x77,0x80,0x7a,0xb3,0x23,0x05,0xfc,0x03,0x16,0xca,0x91, - 0xd0,0xaa,0xd2,0x1f,0xff,0x3a,0x2d,0x22,0xd5,0x15,0xa2,0x22,0xb2,0x64,0x3c,0xa8, - 0x0c,0xad,0x9e,0x2d,0x4d,0xd7,0x7d,0x39,0xf4,0x67,0x27,0xc1,0x53,0xd9,0xd5,0x19, - 0x1f,0xe7,0xa7,0xae,0x97,0xe6,0x48,0x6c,0x23,0x13,0x34,0x36,0x6f,0x1e,0xdb,0xf7, - 0x88,0x12,0x50,0x65,0x04,0x04,0xa6,0x32,0x96,0x13,0x94,0x71,0x9a,0x4b,0x6a,0xbe, - 0x8b,0x9f,0x9a,0xcf,0x2a,0x1c,0xf6,0xf2,0x87,0x56,0x04,0xe0,0x3d,0xfc,0x6b,0x30, - 0x5c,0x4b,0xf6,0x9a,0x85,0x1b,0xb5,0x37,0x9d,0x69,0xae,0xa5,0x60,0x08,0x42,0x22, - 0xe3,0x4b,0x55,0x16,0xfa,0x81,0x52,0xa8,0x41,0xb1,0xa9,0xd5,0x34,0x29,0x28,0xd9, - 0xc8,0xc7,0xce,0x7a,0xf0,0x1c,0xaa,0x0a,0x85,0xe8,0x42,0x7c,0xd4,0x34,0x1c,0xfc, - 0x64,0xee,0xf6,0x7e,0x72,0xde,0x2d,0xfd,0x2f,0x66,0xf6,0x6a,0x51,0x9d,0x1e,0xe5, - 0xdb,0xee,0x3b,0xd7,0x1a,0x54,0x58,0x52,0x31,0x81,0x9d,0xc9,0x34,0x71,0x53,0xbd, - 0x4a,0xc1,0x96,0x20,0xac,0x9d,0x71,0x17,0xba,0x89,0x6f,0x56,0x9f,0xbc,0x4a,0x01, - 0xc7,0x67,0x62,0x02,0xb8,0xfe,0x78,0x44,0xf4,0x57,0xf7,0x9c,0x8f,0x24,0x23,0x4f, - 0x7d,0xba,0xb9,0x19,0x8d,0x52,0x24,0xac,0x5f,0x41,0x4a,0xb7,0x33,0xd7,0x28,0x37, - 0x8e,0xed,0xf3,0xcc,0xc4,0x3a,0xb7,0xf4,0xcf,0x06,0x79,0xca,0xad,0x3a,0x13,0xe5, - 0x0f,0x09,0xdf,0xbe,0x8c,0x57,0xa9,0xf9,0xa7,0xc4,0x4a,0x1d,0x9d,0xf8,0xe0,0xad, - 0x5a,0xa9,0x36,0x3c,0x0e,0xab,0x16,0x4a,0x0e,0xa6,0x84,0xc1,0xda,0xa2,0xc0,0x5c, - 0xc3,0x49,0xbe,0x36,0x5e,0xc5,0xc8,0x6e,0xc1,0xc7,0x9c,0x90,0x3d,0x2f,0x85,0x8e, - 0x1f,0x74,0xdb,0x83,0x13,0x88,0x16,0x8f,0x5b,0x96,0x39,0x5d,0x57,0x58,0x90,0x47, - 0xdd,0xb4,0xab,0x14,0x52,0x06,0x55,0xdd,0xb4,0xe8,0x04,0x38,0x65,0x10,0xec,0x41, - 0x13,0xac,0x54,0xcd,0x0b,0x98,0x95,0xab,0x88,0x2c,0xb1,0xd5,0xbd,0x77,0x35,0xff, - 0xf5,0xeb,0x43,0x6b,0xb9,0x8e,0xd2,0x89,0x85,0x6b,0x96,0xa6,0xa5,0xbb,0xc8,0x64, - 0x33,0xf1,0xf3,0x84,0x9c,0x5b,0x25,0xd0,0x1c,0x8d,0x32,0x52,0x7e,0x57,0x1b,0x60, - 0x08,0xe5,0xf8,0xe0,0xf0,0x0a,0x13,0x52,0xba,0xde,0x18,0x03,0x10,0x31,0xfe,0xa9, - 0x39,0x86,0x70,0x47,0x3d,0x4a,0x8a,0x42,0x50,0x9c,0x4a,0x46,0x21,0xed,0x2d,0xa9, - 0xfb,0x9c,0x9a,0xf1,0xf7,0x96,0x84,0x62,0x48,0xe8,0xe8,0xd8,0x12,0x7a,0xa5,0x70, - 0x72,0x89,0x46,0xe0,0x9b,0xd7,0xed,0x53,0x67,0x13,0x01,0xf2,0xdb,0x1b,0x15,0xc4, - 0x18,0xbf,0x8d,0x71,0x83,0x62,0xb5,0x8d,0x7b,0x07,0x17,0x58,0x84,0x46,0xa7,0xee, - 0xca,0x94,0x74,0xd0,0x86,0x53,0x59,0x04,0x8c,0xb3,0x4e,0x42,0x9c,0x65,0x4a,0xd1, - 0xf6,0x50,0x6c,0xb0,0x32,0xbe,0x5a,0x77,0x9e,0x41,0xb0,0x59,0x6a,0xe6,0x44,0x32, - 0xa2,0x1b,0xa5,0x5b,0x3a,0x3a,0x45,0x5f,0xd7,0x89,0xf7,0x34,0xe7,0x71,0xe7,0x44, - 0x15,0x87,0x7b,0xcd,0xd6,0x76,0xdc,0xda,0x91,0xfe,0xd7,0xf5,0x33,0x76,0xed,0x8c, - 0x5d,0x3f,0xa3,0x5a,0x51,0xa1,0xcb,0x74,0x97,0xcb,0x4e,0x83,0x43,0x41,0xf5,0x71, - 0xea,0x84,0xde,0xd9,0x47,0x76,0x54,0xb7,0xda,0x08,0xda,0xd4,0x8f,0x8e,0xcf,0xed, - 0xb3,0x75,0x69,0x26,0xf2,0x32,0x90,0x12,0x48,0xcb,0x80,0x19,0x2f,0x8b,0x86,0x45, - 0x9b,0x9b,0xfc,0xd3,0x30,0xc6,0x67,0xb0,0x84,0x8d,0x9c,0x20,0x72,0x63,0xe1,0x5c, - 0xf1,0x61,0x7a,0xe3,0xa5,0xbb,0x97,0xfa,0xca,0x5f,0xdd,0xdb,0xd6,0xee,0x47,0xff, - 0x6a,0xb5,0x0d,0x10,0x13,0xe1,0x42,0x99,0x28,0x5f,0x41,0xb7,0xdd,0x7e,0x02,0x28, - 0x27,0x1f,0xb4,0xc1,0xc4,0x19,0xb4,0x95,0x2b,0x5e,0xc8,0xe1,0xc0,0x5b,0xd9,0x75, - 0xce,0x27,0xc6,0x49,0x52,0xac,0xda,0x4f,0x62,0x90,0x71,0x26,0xa8,0xfe,0xf8,0xda, - 0x82,0x81,0x12,0xf9,0xaf,0x75,0xc4,0xc1,0x8e,0x23,0x4a,0x4e,0x23,0x36,0xd4,0x03, - 0x80,0x1a,0x98,0x25,0x84,0xc2,0xf7,0x01,0x30,0x85,0x17,0x49,0x04,0x01,0xb8,0x1a, - 0xd2,0x76,0x2f,0x69,0xe2,0x7f,0x42,0x90,0x70,0x21,0x89,0x54,0x06,0xf7,0x10,0xee, - 0xf3,0x50,0x92,0x3a,0x1e,0x4a,0x7c,0xc2,0xf4,0x54,0x9d,0x37,0x9d,0xf1,0x69,0x97, - 0x15,0xf5,0x09,0xa7,0x69,0xcd,0x19,0xa3,0xed,0x53,0x12,0x1a,0x62,0xfb,0x7d,0x7b, - 0x17,0xa5,0xae,0x47,0xcf,0x28,0xa8,0x25,0x00,0xf9,0x20,0x6b,0x33,0xff,0x68,0xd1, - 0x64,0x57,0x09,0x26,0x44,0x26,0x5a,0x55,0xdc,0x3e,0x9e,0xf5,0x4d,0xbc,0xf4,0xc2, - 0xea,0xa4,0xb2,0x5a,0x3c,0xbf,0x99,0xe6,0x8e,0xec,0xec,0x1c,0xaa,0xa2,0xc0,0x51, - 0x33,0x14,0xef,0x85,0x2d,0x88,0x22,0x7e,0x24,0x6b,0x58,0xa0,0xcd,0x05,0xa2,0xcf, - 0x98,0x1f,0x84,0x72,0xe9,0x12,0xa9,0xe9,0x14,0x0f,0x6b,0x4d,0xe5,0xf6,0x7a,0x4e, - 0xde,0x5b,0xa5,0x70,0x7f,0xcc,0x0e,0xc6,0xe4,0xf8,0x2c,0x20,0xad,0x5b,0x1f,0x3d, - 0x5a,0x8c,0x4b,0xd5,0xff,0x8c,0x71,0x4b,0x0b,0x57,0x03,0x4e,0x8d,0x7c,0x4a,0xb9, - 0x04,0x97,0x54,0x4f,0x39,0xa2,0xf1,0x3e,0x8c,0x28,0x34,0x43,0x4a,0xa6,0xa2,0xd4, - 0x93,0x13,0x22,0x77,0x7c,0x49,0xa1,0x5f,0x7c,0x59,0xe1,0x7f,0xf7,0xa5,0x85,0xff, - 0xd9,0x97,0x17,0x02,0x22,0xf2,0x0e,0x05,0xc3,0xab,0x68,0xda,0xe9,0xc1,0x7a,0xf6, - 0x3d,0x3f,0xa3,0x6b,0x39,0xd4,0x9b,0x85,0x8d,0x81,0x43,0xed,0xaa,0x5d,0xe6,0x89, - 0x21,0x34,0xcf,0xd9,0xbc,0x68,0xa1,0x69,0x8f,0x5b,0x43,0x72,0x3a,0x2c,0xb6,0x27, - 0x1f,0x97,0x8d,0x2e,0xf3,0x31,0xe7,0x65,0xc9,0xa0,0x37,0xec,0x67,0x49,0x87,0xa6, - 0x7b,0x69,0x03,0xe3,0xcd,0x66,0xce,0x26,0xe2,0x04,0x92,0xe2,0x0f,0xfb,0xee,0x62, - 0xd0,0x94,0xfe,0xf2,0xab,0xa0,0x15,0xbf,0x43,0x68,0x9a,0x2f,0xea,0x57,0x5c,0xa2, - 0xd3,0xaf,0x38,0x65,0x8f,0x07,0x49,0x2f,0xa1,0xfa,0x07,0x72,0xe2,0xde,0xe1,0x42, - 0x6e,0x3a,0x59,0x40,0x0e,0x28,0xb8,0x7b,0x19,0x35,0xf0,0x24,0xc8,0xaf,0x12,0x73, - 0xae,0xc2,0xff,0x11,0xaf,0x5f,0xec,0x08,0xac,0x62,0xe3,0x3c,0x23,0xd3,0xc8,0x8d, - 0xb2,0x0d,0xee,0xd6,0x8c,0x59,0xb2,0x67,0xc6,0x14,0x86,0xe2,0xf8,0x14,0x56,0x58, - 0xbf,0x7f,0x78,0x45,0xb3,0xdd,0x64,0x4c,0xab,0x08,0x33,0xcc,0x92,0x85,0x98,0xab, - 0xb5,0x20,0xa2,0x9a,0x77,0x2b,0xbd,0xe3,0x32,0xf4,0x23,0x1d,0x9c,0x86,0x3d,0x3a, - 0xfc,0xd4,0x81,0x2e,0x0b,0x4f,0x5a,0x42,0xb0,0x1d,0xdb,0xa2,0xca,0x6d,0xaf,0x3f, - 0xb2,0x99,0xfd,0x3c,0xba,0xbd,0xe6,0xba,0x4b,0x40,0x56,0x45,0x39,0xbc,0xb1,0xe9, - 0xf1,0x1e,0x8f,0x09,0x64,0x14,0xcf,0x9f,0xac,0x2f,0xd1,0xef,0x24,0xb5,0x6d,0xbf, - 0x9b,0x48,0xb9,0xdf,0xd9,0xe5,0xda,0xd5,0xe5,0xfe,0xb8,0xbe,0x5f,0xf0,0x38,0xa1, - 0x3c,0x59,0xda,0xe4,0x9b,0x5d,0x12,0x7e,0x30,0xff,0xcc,0xfc,0x04,0x35,0xe2,0xc5, - 0xa5,0xc2,0x03,0xd5,0x3c,0x57,0xd6,0x5d,0xc2,0xd5,0xf5,0xbb,0xdf,0xb6,0x06,0x66, - 0x89,0x33,0x10,0x57,0x27,0x72,0x5b,0x07,0x27,0x9b,0x5c,0x4a,0xad,0x66,0xde,0x4f, - 0x61,0xf6,0x4b,0x0e,0x81,0xb5,0x1e,0xd8,0x1e,0x0d,0x78,0x32,0xe7,0x71,0xac,0xb5, - 0x03,0x44,0xbe,0x8e,0x31,0x9f,0x69,0xb1,0xa4,0x9f,0xf3,0xb4,0xd8,0xb5,0x27,0x54, - 0x58,0x2e,0xcb,0x3c,0xa7,0xa9,0x0c,0x63,0x69,0x86,0x2d,0x23,0x07,0x3c,0x72,0x63, - 0x8b,0x09,0x7a,0x41,0x53,0xb6,0x77,0x2b,0xdc,0xdc,0x3f,0x36,0x46,0x15,0x81,0xa5, - 0x74,0x35,0x65,0x8a,0x0e,0x43,0xcc,0x18,0xdd,0xd5,0x39,0xad,0x7d,0xdf,0xfd,0x16, - 0xb6,0xf2,0x82,0x0b,0xd7,0xf0,0x7f,0x87,0x44,0x89,0x26,0xb3,0x78,0xef,0xb8,0x95, - 0x9c,0xec,0x7d,0xcc,0xbe,0xdd,0x1a,0x90,0xf6,0x4a,0xc4,0x72,0xe1,0x93,0xf6,0xa6, - 0x33,0x1b,0xaf,0xb3,0x28,0xb6,0x2a,0xc2,0x34,0xc8,0xf6,0x22,0x9a,0x39,0x9d,0x94, - 0x5b,0x45,0x4c,0x27,0x4c,0x0b,0x85,0x81,0x18,0x12,0x47,0x59,0xac,0xf3,0x65,0x50, - 0x47,0x2a,0xc6,0x38,0x6f,0x2a,0x43,0xeb,0x48,0x7a,0xa6,0x2b,0xac,0x0d,0xdb,0xf8, - 0x9d,0x59,0xa6,0x42,0x7a,0xdf,0x84,0xa8,0xc8,0xa7,0x0c,0xbb,0xd1,0x3d,0x41,0x6f, - 0xb7,0x7e,0x09,0xcd,0xa1,0x11,0xf5,0x6b,0xd1,0xe8,0x84,0xe0,0xa1,0xa2,0x7d,0xbe, - 0xc4,0xd6,0x9c,0x19,0x1f,0x8e,0x83,0x29,0x5d,0xdb,0x38,0xca,0xe3,0x3f,0xd3,0x11, - 0x63,0xbf,0xe7,0xde,0xa8,0x20,0xbb,0x25,0x0a,0xbb,0x2a,0xa1,0xa3,0x59,0x94,0x49, - 0xc0,0x8d,0x20,0xa3,0x08,0x31,0xd7,0xc6,0xfa,0x25,0xb8,0xc1,0x46,0x84,0x43,0xb4, - 0x18,0x76,0x64,0x0d,0x78,0xe4,0x14,0x11,0x68,0xdc,0x88,0x4e,0xc9,0x22,0x2d,0x98, - 0xd0,0x6e,0x6c,0x0a,0x3d,0x89,0x39,0x33,0xeb,0xcc,0x73,0xaf,0xa4,0x09,0x95,0x2b, - 0x81,0x74,0xf1,0x94,0x17,0xc2,0xb7,0x40,0x56,0xf0,0xd1,0x21,0x1e,0x04,0x4a,0xf8, - 0x18,0x5a,0x0c,0xc0,0x67,0xd2,0x85,0x06,0xab,0xfe,0x31,0xcf,0xae,0x48,0x03,0xf4, - 0x43,0xec,0xa5,0x19,0x02,0xbb,0x39,0x0b,0xa2,0x3f,0x86,0x98,0x4e,0x38,0x5a,0x6c, - 0xd0,0x21,0xff,0x38,0x09,0x57,0x99,0xec,0x7d,0x19,0xa9,0xc6,0xc5,0x1e,0xf4,0x00, - 0x0a,0xbf,0x03,0x4a,0xa0,0xdf,0x42,0xeb,0x09,0x14,0x5c,0x7c,0x39,0x25,0x90,0x36, - 0x83,0xef,0xe5,0xce,0x79,0x23,0x78,0x35,0xcf,0x94,0xc9,0x14,0x82,0xea,0xf4,0x33, - 0xe5,0x86,0xc4,0x31,0x68,0x1b,0xc1,0x1f,0xc4,0x2a,0xbe,0xb3,0x43,0xb8,0x24,0x73, - 0x62,0xa8,0x9c,0x40,0xd1,0xd4,0x36,0x37,0x69,0x30,0x42,0x30,0xf1,0x68,0x33,0x5c, - 0x65,0x04,0xad,0x85,0x4a,0x28,0x1f,0xae,0xc0,0xc3,0xc8,0xe4,0xde,0x90,0x8f,0x0e, - 0xbb,0x85,0xcb,0x8d,0xc9,0x3c,0x93,0xa6,0x14,0xbc,0x1d,0xe6,0xb6,0x04,0xef,0xad, - 0x77,0x32,0x72,0x17,0x0f,0x8c,0xda,0xcc,0xc9,0x86,0x59,0x89,0xad,0x68,0xeb,0xbd, - 0xd0,0x6b,0x45,0xa1,0xe9,0xf8,0xdd,0x6f,0x27,0x41,0x5d,0xba,0x1d,0xbb,0x22,0xf2, - 0x5b,0xc3,0x43,0x21,0x2c,0x5b,0x89,0x22,0x3c,0x94,0x4a,0xae,0x82,0x48,0x74,0x08, - 0x25,0x26,0xf1,0x90,0x78,0x01,0x7d,0xd3,0xcc,0x59,0x42,0xdb,0x0b,0xd7,0x43,0xc5, - 0x44,0xf2,0xa3,0xb0,0xed,0x3a,0x9c,0x9c,0xcd,0xcd,0xbd,0x8e,0x07,0x6f,0x77,0x64, - 0x56,0x7f,0xf0,0x16,0xa6,0xf9,0xa4,0x32,0x07,0x26,0xd7,0xe7,0x3b,0xcd,0x87,0xcf, - 0xc4,0xb5,0x6d,0x59,0x00,0x3c,0x7c,0x26,0xf6,0x17,0xd3,0xe5,0x8a,0x2f,0xc4,0xad, - 0x22,0x1d,0xb7,0x05,0xec,0x97,0x46,0xce,0x95,0xb2,0xe0,0x46,0x22,0x6d,0x41,0x71, - 0xd3,0xed,0xf6,0xf9,0xfc,0xdb,0x4c,0xc6,0xac,0xe9,0xc9,0x36,0x1e,0x74,0x9d,0x49, - 0xaf,0x29,0xfd,0xcb,0xf7,0x80,0xcc,0x15,0xee,0x15,0x97,0x81,0xcc,0x47,0xa3,0x48, - 0x70,0xce,0x58,0xad,0xa9,0x1b,0x70,0x8f,0x52,0x81,0xb4,0x5c,0x0a,0x58,0x9f,0x4b, - 0xf7,0x69,0xd0,0xc3,0xf5,0x32,0x8d,0xb8,0xee,0xac,0x70,0x1c,0xa0,0x88,0x04,0xf3, - 0xda,0x3b,0x39,0xea,0x9a,0xe0,0x51,0x54,0x68,0xbc,0x1d,0x7a,0xe3,0x7f,0xe5,0x52, - 0x11,0xf3,0xcb,0xbe,0x9d,0x7f,0x2c,0x77,0x5c,0xf8,0xfe,0x5b,0x92,0xbf,0x74,0x6f, - 0xf4,0x31,0x3b,0xd3,0xc7,0xd3,0xd9,0x89,0x9a,0x2b,0x79,0x77,0x62,0x2c,0xa4,0x5c, - 0x0a,0x5b,0x3c,0x9b,0x32,0x7c,0x93,0x62,0x66,0xb7,0x3a,0x00,0x70,0xef,0xd6,0x27, - 0x16,0x26,0x61,0x81,0xa2,0x8a,0xfd,0xdb,0xf8,0x5a,0x1e,0x3f,0xbe,0x67,0xed,0x69, - 0xa4,0x19,0xf6,0x5c,0xc8,0x96,0x8d,0xdb,0xb2,0x87,0x7b,0xd8,0x65,0x2b,0x31,0xab, - 0xe8,0xdd,0xa6,0x0b,0xe2,0x56,0xab,0x99,0x74,0x6f,0x5a,0xdb,0x49,0x76,0xd6,0xda, - 0x49,0x4e,0x67,0xad,0xdd,0xbb,0x92,0x21,0x6e,0x7b,0x43,0x99,0x5f,0x10,0x77,0x8c, - 0xfc,0x27,0x6b,0x7d,0x53,0x28,0xf1,0x3c,0x18,0xff,0x4f,0xbe,0x56,0xa4,0x97,0x52, - 0xfc,0xfb,0x24,0x95,0xde,0x1f,0x5d,0xe1,0xa1,0xce,0x31,0x5d,0x37,0x2c,0xe9,0x82, - 0xac,0xbd,0x5b,0xb9,0x75,0x6f,0x62,0xe4,0x07,0x45,0x9a,0x92,0x4d,0x1c,0x3d,0x63, - 0x51,0x56,0x65,0x54,0x9e,0x0a,0x0e,0xb3,0x40,0x8a,0x04,0x87,0x2b,0xa2,0x23,0x81, - 0xf1,0x15,0x59,0xd4,0x9d,0x2a,0xb1,0xa6,0x69,0x9e,0xa7,0xf2,0x33,0xed,0x42,0xab, - 0x45,0xfe,0x57,0xa2,0xac,0x76,0xe0,0x2b,0x53,0xd0,0xcf,0xbc,0x45,0xa5,0xd9,0x9a, - 0xb7,0xb0,0xb9,0xd4,0xdc,0xa8,0xe2,0xf2,0x81,0x71,0x98,0x4c,0x75,0x54,0xae,0x03, - 0x6c,0xbd,0x5f,0x7f,0x55,0x10,0xc8,0xce,0x8b,0x41,0xc3,0xf8,0x2b,0x4f,0x3f,0x22, - 0xb1,0xfa,0x42,0xa3,0x38,0xe7,0x1b,0x3c,0xc8,0x6c,0x6a,0xfc,0x71,0xc6,0x5e,0x5c, - 0x6f,0x2b,0xc6,0x06,0x80,0x93,0x5b,0xb0,0xb4,0xcb,0x87,0x42,0xc7,0xf9,0x85,0x0b, - 0x63,0x63,0x62,0x1c,0xf7,0xe0,0xc7,0x84,0x7b,0x4f,0x4c,0xed,0x7c,0xdc,0x58,0xf5, - 0x33,0x05,0x38,0x68,0x9b,0xaf,0xde,0x89,0xcc,0x1f,0xa5,0xd6,0xf9,0xcb,0x3c,0xbf, - 0xbb,0x6d,0x25,0x81,0x0e,0x29,0x2a,0x36,0xb1,0x52,0xe9,0x39,0x12,0xfd,0x44,0x86, - 0xd5,0xb2,0x24,0xac,0xf6,0x57,0x2c,0x25,0xaa,0xbf,0xe2,0xa4,0x84,0x9d,0xd2,0xb4, - 0x58,0xef,0x83,0x69,0xf0,0xe1,0x80,0x4a,0x70,0xcd,0x8d,0x47,0xf3,0xdf,0xa7,0xe4, - 0xe1,0x9e,0x4f,0x87,0xed,0x18,0x29,0xd9,0xd6,0xf7,0xcf,0x68,0xc3,0x9f,0x5c,0x38, - 0xa9,0xff,0xc1,0xa9,0x5b,0xbb,0xcf,0xe8,0xd3,0xc8,0xfd,0x44,0x89,0x5b,0xcf,0x9a, - 0x85,0xb9,0x6a,0xef,0x45,0x73,0xaf,0x57,0x0b,0x7b,0x50,0x40,0x5e,0xd4,0x42,0x78, - 0x13,0x8d,0x2e,0x90,0x42,0x8f,0x48,0x19,0xd5,0x42,0x1c,0x16,0xf3,0x5f,0x27,0xba, - 0xd7,0x00,0xd5,0x1c,0x24,0xdd,0x04,0x44,0x55,0x58,0x42,0xd2,0x67,0xb2,0xc8,0x7c, - 0x21,0xf6,0x22,0x03,0x18,0x90,0xe0,0xb9,0x4b,0xcf,0xf4,0x10,0x65,0x7b,0x8f,0x61, - 0x77,0x89,0x27,0x63,0xf2,0x51,0x32,0x15,0xb5,0x0a,0xb2,0x1b,0x62,0x61,0xb7,0x01, - 0xad,0x8b,0xf2,0x67,0x70,0xbe,0x88,0x5b,0x97,0x82,0xa9,0xaf,0xc4,0x31,0x5b,0xa4, - 0x50,0xc9,0x6e,0xd3,0x8d,0x8d,0x66,0xe1,0xa2,0x83,0x74,0x07,0x45,0xbc,0x90,0x0b, - 0x5e,0x82,0xc5,0xf9,0x58,0x2e,0xae,0x79,0x67,0x61,0xd5,0xf2,0xfc,0x98,0x05,0xd5, - 0x21,0x0b,0xa8,0x68,0x5f,0x11,0x64,0x3a,0x34,0xe7,0xaa,0x43,0x82,0xf8,0xfe,0x80, - 0x87,0xb4,0x31,0x04,0x24,0xac,0x7c,0x42,0x5d,0xea,0xad,0xcd,0x13,0xca,0xf4,0xdd, - 0x4d,0xad,0x6b,0x7a,0x59,0x83,0x82,0xfb,0x7d,0xc2,0x2c,0xd2,0xc7,0x2d,0xbd,0x9d, - 0x27,0xb2,0xb3,0xa7,0xe6,0xcb,0x9c,0x40,0x0f,0x1b,0xdc,0xe0,0xe1,0xef,0x53,0x52, - 0x7e,0x85,0x89,0x74,0xc8,0xc6,0x15,0xbf,0x7f,0xca,0xe2,0xb8,0x26,0x10,0x3f,0x76, - 0xe6,0x60,0x1a,0xa6,0x3b,0x7c,0xed,0xe2,0xf9,0xd3,0xe8,0x1a,0x98,0xc1,0x7a,0x8c, - 0x8d,0x9f,0x07,0xb7,0x38,0x34,0xdc,0x89,0x93,0xf0,0xaf,0xa1,0x66,0xf8,0x19,0x65, - 0x07,0x44,0x05,0x66,0xc8,0x6e,0x12,0xfe,0xf6,0x23,0x9c,0xd8,0x43,0x51,0x8a,0xae, - 0xe7,0xd3,0x89,0x74,0x43,0xa6,0xe6,0x46,0xe4,0x85,0x00,0x07,0x94,0x13,0x58,0xb9, - 0x78,0xe0,0xec,0x11,0x93,0x3f,0x9a,0x4c,0x84,0xbc,0x28,0xf7,0x2d,0x45,0x33,0x0c, - 0x78,0x50,0x84,0x49,0xd6,0x18,0xd3,0x6b,0x12,0xf6,0x7e,0x1c,0x15,0x20,0xaf,0x21, - 0xad,0x83,0x0f,0x87,0x87,0xaf,0x08,0x60,0x86,0xbd,0x12,0x7f,0x07,0x7d,0x87,0x6f, - 0x3f,0xb0,0xa3,0xfd,0x6c,0x3c,0x53,0xe0,0xfd,0xc1,0x8c,0x78,0x11,0x1c,0xfd,0xad, - 0x60,0x0f,0x36,0x82,0xc2,0x1f,0x0f,0xec,0x83,0x05,0x36,0x03,0x99,0x3e,0xa4,0x99, - 0xb3,0x33,0x86,0x04,0x4c,0xff,0xf4,0x3a,0xa1,0x13,0x4a,0x2e,0x18,0x39,0xf0,0xe8, - 0x81,0x1e,0x31,0x68,0x86,0xf6,0x2e,0xd8,0x4b,0xae,0x37,0x81,0x63,0xeb,0x48,0xd1, - 0x7c,0xa2,0x4a,0x63,0xc0,0x07,0x5b,0x84,0x8b,0xc1,0x4d,0x92,0x66,0x82,0xfd,0x1d, - 0xba,0x57,0x29,0x57,0x8f,0x13,0x9d,0x6c,0x92,0xa6,0xf9,0x8e,0xfe,0x16,0x40,0x27, - 0x75,0xd5,0xa7,0x3c,0xf3,0xdb,0x4f,0xfc,0x8c,0x8f,0x91,0xe5,0xbc,0x5f,0x9a,0xed, - 0xbf,0x8e,0x8e,0x0a,0x50,0x12,0xf6,0x02,0xdc,0x0a,0x0b,0xf6,0xd3,0x36,0x57,0xd9, - 0xcf,0xdb,0x3c,0x6d,0x83,0x02,0xe8,0xd5,0x7b,0xfa,0x3a,0x98,0xe2,0x64,0xa5,0x4e, - 0xa2,0x95,0x6c,0xf1,0xb9,0x3c,0x88,0x63,0xee,0x05,0xe8,0x55,0x71,0xdb,0x4e,0x95, - 0xa6,0x96,0x26,0x47,0x96,0x6c,0x0a,0x93,0x43,0x5e,0x39,0xf1,0x53,0x9d,0x3b,0x63, - 0x9c,0xd8,0x48,0xe2,0x76,0x19,0x88,0x33,0x17,0x50,0x82,0xcc,0x73,0x93,0x60,0x16, - 0xe6,0xc3,0x34,0x2b,0x7c,0x50,0xb7,0x75,0x9c,0xca,0x32,0xcd,0x1e,0x67,0xd9,0x50, - 0x0e,0x0f,0xf7,0xf0,0xe4,0xd8,0xbe,0xdf,0x0a,0xb2,0xb3,0x34,0xba,0x25,0xc3,0x4b, - 0xb9,0x60,0x12,0xd3,0x0d,0x13,0x47,0xf6,0x5e,0x5e,0xb3,0xe4,0x65,0xa1,0xeb,0x06, - 0x2c,0x96,0xc0,0xa8,0x98,0x19,0x2a,0xe2,0x2c,0x8b,0x0d,0x4c,0xf0,0x78,0x83,0x2d, - 0x0f,0xa5,0x0c,0xb1,0x91,0x85,0xca,0x28,0x2a,0x5b,0xca,0xc6,0xb6,0xa9,0xac,0xc0, - 0xc7,0xb1,0x63,0x1d,0x68,0x44,0x0e,0x07,0x5e,0xcd,0x88,0xec,0xc9,0xa5,0x21,0x7a, - 0xb9,0xbc,0x25,0x77,0xe9,0x56,0x0d,0xc8,0xb7,0x0c,0x7d,0x47,0xf7,0x9a,0x5c,0x72, - 0x0f,0x63,0x08,0xbc,0xe2,0xaf,0x7a,0x7f,0xac,0xa8,0xa7,0x98,0x25,0x02,0x7c,0x2c, - 0xf1,0x2f,0x0c,0xf5,0x62,0x37,0x29,0x53,0x8f,0x6b,0x71,0x3e,0x18,0x0e,0x91,0xc3, - 0xc0,0x51,0x3b,0x88,0xc5,0xa5,0x9b,0x22,0xf6,0xff,0x48,0x36,0xf4,0x3b,0x15,0xab, - 0x9d,0x39,0xb7,0x01,0x5a,0x90,0x26,0x62,0x8b,0x57,0x04,0xf4,0x11,0x67,0x27,0x0f, - 0x59,0x4f,0x73,0xf7,0xec,0x90,0xf7,0xca,0x4e,0x83,0x9f,0xaf,0x79,0x89,0xd5,0x91, - 0xbe,0xf0,0x02,0xb3,0x75,0xa7,0x91,0x5d,0x0c,0x68,0xa3,0x6e,0x65,0x33,0x7d,0x12, - 0x72,0x81,0x96,0x12,0xd2,0x3d,0x7a,0xd3,0x59,0x2a,0x21,0xda,0x8c,0x62,0xe9,0x3d, - 0x84,0xee,0xf0,0x43,0x07,0x19,0xe0,0xbe,0x96,0x9c,0xa8,0x5f,0xd3,0xe2,0x10,0x83, - 0xf7,0x0f,0x72,0xcd,0x82,0x75,0xc3,0xd3,0x67,0xed,0x0d,0x24,0xde,0xd0,0x6b,0x7a, - 0xf3,0x2d,0x10,0xb4,0xf1,0x6a,0xc2,0x15,0xa7,0x17,0xfc,0xce,0x98,0xcf,0x29,0xeb, - 0x79,0x9f,0x67,0x14,0x6a,0xf1,0x70,0x87,0x8e,0x40,0xcf,0x1b,0x19,0xd9,0x04,0x44, - 0x00,0x4b,0xf0,0x8f,0x12,0x78,0xee,0x84,0x52,0x6a,0x1e,0xd1,0xc9,0xde,0x4d,0x72, - 0x61,0x86,0x05,0x11,0x29,0x15,0x7a,0xbe,0xe3,0x9a,0x9d,0x8f,0xd3,0x3c,0xf8,0x4b, - 0x83,0xe3,0x7f,0x98,0xd3,0x21,0xae,0x55,0x32,0xba,0x95,0x8f,0x9d,0x5b,0xef,0x23, - 0xe3,0x05,0x40,0x9a,0x8e,0xc6,0xf1,0x62,0x74,0x5b,0xc3,0x56,0x6a,0x34,0xae,0xa7, - 0xdb,0x77,0x1b,0xa0,0x6b,0x4e,0xd7,0x00,0x0e,0xb9,0xff,0x33,0xd9,0xa3,0x29,0x94, - 0x5e,0x3d,0x4e,0x28,0xc2,0xbb,0xe6,0x0f,0x62,0x2a,0x12,0x53,0x0d,0x73,0x0f,0x9d, - 0xc6,0xbb,0x5a,0x58,0xaf,0x77,0x4e,0x4f,0xc3,0xfc,0x06,0x17,0x04,0xcd,0x5f,0x76, - 0xba,0xdf,0xf5,0xfa,0x3f,0x84,0x6d,0x94,0x42,0x91,0xd4,0x99,0x93,0xe9,0x4e,0xdb, - 0xbc,0xfd,0x27,0x3a,0x45,0x1a,0xf2,0x44,0x14,0x22,0xa9,0xdb,0x87,0x2a,0xe5,0x3d, - 0x6a,0xc0,0xeb,0x46,0x50,0xed,0xaf,0x5f,0xaf,0x93,0xfc,0xf6,0xcb,0x6d,0x3a,0xd8, - 0xb2,0x19,0x55,0xdf,0x8e,0xbf,0x8d,0x6e,0xea,0x4f,0xe2,0xda,0x4e,0xf2,0x39,0xbd, - 0xa8,0x3f,0xa9,0x47,0xd7,0x75,0xd4,0x75,0x0b,0xb5,0xc6,0x2f,0x3e,0x02,0xa4,0x49, - 0x7c,0xd8,0x33,0x85,0x1f,0x4d,0xa2,0xdb,0xe4,0x73,0xdc,0x3a,0x6f,0x90,0xda,0x41, - 0xde,0x78,0x35,0xa9,0x1c,0x89,0xf8,0x19,0xa3,0x75,0x28,0xbc,0xb1,0x39,0x05,0x82, - 0x49,0x54,0xa4,0x21,0x05,0xe6,0xc6,0x95,0x05,0xec,0x13,0x46,0xf5,0xab,0x01,0x55, - 0x84,0x1a,0x7d,0x9f,0xc2,0x78,0xa3,0x72,0xd4,0x37,0xc2,0x1c,0x0d,0x8f,0x7f,0x22, - 0xfa,0xd8,0xa1,0xfc,0x24,0xb9,0xa9,0xef,0x24,0xdb,0xae,0x1f,0x36,0xbe,0x19,0xfd, - 0x5b,0xff,0x33,0x87,0xa8,0x89,0xcc,0xfe,0xa2,0x30,0x5c,0x33,0xef,0x9b,0x9b,0xd5, - 0x81,0x61,0x15,0xbe,0xad,0x0e,0x19,0xa0,0x63,0x9c,0xe5,0xd6,0x3f,0x9d,0xbe,0x9e, - 0x8c,0x48,0x30,0x20,0xc9,0xca,0xbd,0xa4,0xd3,0xc7,0x2d,0x51,0xda,0x8a,0x39,0x4b, - 0x77,0x4a,0x63,0x24,0xb1,0xfc,0xba,0x67,0xa5,0xac,0x3c,0xa5,0x90,0xc5,0x4a,0x29, - 0x50,0xc9,0x33,0x2d,0xd7,0x68,0xa7,0xcd,0xfe,0x00,0x20,0xf2,0xdd,0xf8,0xc6,0x6a, - 0x8b,0x81,0x2f,0x45,0xb4,0x64,0xa9,0x60,0x3b,0xaf,0xef,0x3d,0xf5,0x4c,0x20,0x7f, - 0x00,0xc5,0xd3,0x05,0x70,0xd4,0xf9,0x35,0xcc,0xe3,0x03,0x42,0x3b,0xc6,0x37,0xae, - 0xfd,0x1b,0x09,0x67,0x9b,0x9b,0x67,0x0d,0xc8,0x06,0xa0,0x7b,0x0b,0xa5,0x6f,0x6c, - 0xbf,0x60,0xae,0xc9,0xd0,0xb7,0x7f,0xec,0xa3,0x17,0xf6,0x23,0xc6,0x98,0xc0,0x06, - 0x14,0x4d,0x78,0x38,0x60,0x3d,0x36,0x50,0x70,0xea,0xea,0x68,0x2d,0xfc,0xb9,0x2a, - 0x96,0xad,0x5c,0x63,0x4a,0x8a,0xa0,0xb7,0xa2,0x8e,0x60,0xea,0xf9,0xe0,0xaf,0x2a, - 0x5b,0xff,0x16,0x18,0xe9,0xea,0x45,0xe2,0x73,0xd6,0x8f,0xa3,0xab,0x6a,0x90,0x2f, - 0xc6,0xc9,0xb9,0xaa,0x91,0x56,0xf5,0xca,0x55,0x31,0x54,0xab,0x60,0xef,0x92,0xed, - 0xa7,0xd4,0xd1,0x79,0xb7,0xc2,0x1d,0x86,0x51,0xdb,0xc2,0x9a,0x9b,0x89,0x3f,0xa1, - 0x17,0xb9,0x4d,0xba,0x3e,0xd4,0x9c,0x0d,0xb7,0x96,0xeb,0x5c,0xa9,0x2f,0x67,0xfa, - 0x97,0xb3,0xd6,0xcf,0xe9,0x84,0xb0,0x96,0x2e,0x2f,0x9b,0x25,0xfb,0x2d,0x35,0xb1, - 0xbf,0x34,0x48,0x78,0xad,0xe6,0x8c,0x36,0x8b,0x7b,0x93,0xd9,0x29,0xe9,0x60,0x1e, - 0x8e,0xb7,0xec,0xa3,0x4b,0xcb,0xb0,0x98,0x48,0xce,0xd3,0xaa,0xeb,0xd4,0xbd,0xca, - 0x3e,0x2b,0x07,0xfd,0x1c,0xba,0x3e,0x93,0x0b,0x14,0xb2,0xa8,0x22,0x89,0x58,0xef, - 0x90,0x48,0x6c,0x9d,0xf2,0xde,0x1d,0x43,0xa3,0x47,0xfb,0xb7,0xd6,0x36,0xc5,0xef, - 0x77,0x57,0x1d,0xd9,0x74,0x30,0x2e,0x5f,0x73,0x6b,0xb3,0x25,0x4c,0x51,0xe3,0x3d, - 0xd9,0x2d,0x22,0x01,0x86,0x08,0xf4,0x93,0x6e,0x87,0xad,0x22,0x31,0x4c,0xb8,0x86, - 0xa5,0x0b,0x30,0x1d,0xa8,0xf4,0x68,0x65,0x6c,0xd4,0x03,0xe3,0x94,0x9e,0x5f,0xd4, - 0x9f,0x3e,0xdd,0x7b,0xd2,0x32,0x8f,0xcf,0xbe,0xdb,0xdb,0x95,0xc7,0xef,0xbe,0xdf, - 0xdb,0x69,0x6d,0xb7,0x09,0x70,0x52,0x75,0xff,0xe5,0x09,0x6b,0x1f,0x27,0xb5,0x54, - 0x2e,0xe9,0x49,0x4d,0xc5,0x3b,0x4d,0x6b,0x30,0xa6,0x49,0xa6,0xde,0xc5,0x9e,0xea, - 0xb2,0xcd,0x2b,0x86,0xd6,0x2e,0xc2,0xee,0x4b,0x54,0x7e,0x9e,0x16,0x5a,0xdb,0x48, - 0xe8,0x42,0xad,0xdd,0x9f,0x71,0x84,0xc1,0xab,0x8c,0x53,0xcc,0x7a,0xa2,0x85,0xad, - 0xff,0x6e,0x6d,0xf0,0xed,0x2e,0xd6,0x57,0x04,0x86,0x7d,0xcb,0x39,0xcf,0x94,0xf4, - 0x01,0xc5,0x8f,0xf7,0x42,0x5e,0x93,0xd2,0x8c,0x8b,0xf5,0xa5,0xbc,0x50,0x99,0x71, - 0x88,0x2c,0xca,0xbf,0xc7,0xba,0x22,0x5c,0x47,0xe6,0xd9,0xb0,0x7f,0xdb,0xe6,0xf6, - 0xa9,0x0f,0x30,0x8f,0x65,0x2d,0x4a,0xa8,0x63,0x8b,0x9d,0x53,0xb3,0xfd,0x74,0x7a, - 0xcb,0x57,0x4f,0x6a,0xa1,0x20,0x0e,0x2d,0xc6,0x6a,0xdb,0x5c,0xcd,0x86,0xc2,0xf8, - 0xb2,0x5b,0x36,0xed,0x65,0xba,0x9e,0x41,0x53,0x11,0xbc,0x6f,0x16,0x72,0x7f,0x56, - 0xd7,0x26,0x84,0xbe,0x8f,0xc5,0x28,0xc4,0xee,0xea,0xd5,0x42,0x49,0x69,0xf5,0x3b, - 0x0b,0xcb,0xa6,0xa6,0x6b,0x61,0x38,0xa6,0xf8,0x66,0x28,0x4d,0x0e,0x0a,0xc5,0xaa, - 0xc2,0x2c,0xe7,0x0b,0xb4,0x63,0x8d,0xe3,0x34,0x66,0xc3,0x2a,0x5a,0x45,0x50,0x4e, - 0xdf,0x3a,0x55,0x01,0xbb,0xbc,0x4f,0xae,0x77,0xf8,0x47,0x0f,0x26,0xfa,0xfd,0x31, - 0x9d,0xc6,0x73,0xa9,0x8c,0xa0,0xa2,0x24,0xd4,0x9e,0xe0,0x8e,0x4d,0x51,0x27,0xae, - 0x97,0x3b,0xfb,0x0b,0x3a,0xaa,0xe5,0xde,0x8a,0xca,0x78,0xf8,0x00,0x67,0x6c,0xeb, - 0x47,0x38,0xd3,0x27,0x7b,0x30,0x7e,0x76,0x76,0x61,0x63,0xbd,0x81,0xbc,0xfe,0x42, - 0x2c,0x72,0xca,0xd5,0x2a,0xa2,0x39,0xbf,0xdf,0x65,0x6a,0x10,0xeb,0xbd,0x6c,0x31, - 0x3b,0x2b,0x3e,0x4b,0x02,0x05,0xfb,0x91,0x3d,0x09,0x8f,0xee,0x31,0xb3,0x33,0x2e, - 0x5f,0x9d,0xcd,0x32,0x40,0x38,0x88,0xb5,0x1b,0xd7,0x90,0x04,0x13,0xa6,0xbd,0x70, - 0xf3,0x2f,0x08,0xf6,0xbb,0xf3,0xdd,0x93,0x36,0x07,0x3f,0x06,0x40,0x36,0x82,0x4a, - 0xe4,0x05,0x2e,0xd2,0x86,0x5e,0x99,0x7b,0x04,0xa0,0xb1,0x3c,0x01,0x60,0xca,0x65, - 0xac,0x9c,0x4b,0x6f,0xf1,0x86,0xee,0xf6,0xe7,0xf1,0xf3,0x69,0x3e,0x04,0xcb,0x1b, - 0xcb,0x42,0x24,0xee,0xd0,0x58,0xc3,0x3e,0x29,0xef,0x73,0xc1,0x19,0x0d,0x7c,0x5c, - 0x52,0x9b,0xd2,0x70,0xf6,0x77,0x49,0xf7,0x8f,0x98,0xff,0xd9,0x86,0x7f,0x78,0x25, - 0x30,0xd0,0x24,0xc0,0x97,0x90,0x5f,0xd6,0xdc,0xaf,0x71,0x0f,0x25,0x17,0x33,0x78, - 0xc1,0x45,0x4d,0xb6,0xc8,0x4d,0x04,0x5f,0xf5,0xd2,0xaa,0xe5,0x4f,0x1e,0x68,0x96, - 0x23,0x9d,0x54,0xae,0x65,0xf0,0x68,0x81,0x90,0x4c,0x17,0x8c,0x29,0x63,0x5d,0xbd, - 0x9a,0xe6,0xcf,0x72,0x14,0x87,0x67,0x5b,0x0e,0x31,0x79,0xab,0x5d,0xdd,0x9b,0xa6, - 0x59,0xe9,0x44,0x0b,0x65,0x02,0x9f,0x1c,0x91,0x89,0xb7,0xfe,0xfb,0x3d,0x6e,0x69, - 0x16,0xf5,0x85,0xef,0xb8,0x1d,0xe7,0x83,0x0b,0x8e,0x49,0xce,0x4f,0xea,0x21,0x0c, - 0x9e,0x28,0xbb,0xb0,0x7c,0xc9,0x5a,0xb9,0x34,0xb0,0xe1,0x2b,0x1d,0xff,0xa4,0x80, - 0x94,0xf2,0x68,0xc2,0xa0,0x5e,0x67,0x50,0xda,0x39,0xb9,0x41,0x1d,0x1b,0x5c,0xa5, - 0xef,0x91,0xe5,0xd3,0x5f,0x20,0xee,0x77,0xaf,0xaf,0xb9,0x55,0x13,0xcb,0x9d,0xe4, - 0xc1,0xb5,0x12,0xe8,0x2f,0xae,0x93,0xe4,0x93,0x1a,0x79,0xdd,0xff,0x6b,0x4f,0x84, - 0x68,0x06,0xf1,0xce,0x83,0xee,0xd9,0xdd,0x38,0x5b,0xa2,0x98,0xc1,0xd5,0xd2,0xc9, - 0x3a,0xa1,0xe1,0x50,0x3f,0x1b,0x6b,0x86,0x92,0x83,0x27,0xc9,0x31,0xc4,0xd6,0xf1, - 0x6c,0x9e,0xc6,0x49,0x2e,0x5f,0xee,0x65,0xb9,0x10,0x66,0xa4,0xa3,0x7a,0x4d,0x2f, - 0xc8,0x93,0x0f,0x66,0xfc,0x68,0x68,0xf5,0xdd,0x9d,0xef,0x9e,0x7d,0x8f,0x43,0x70, - 0xfe,0x2a,0x6e,0xd2,0xe5,0x19,0xee,0xbb,0x77,0x37,0x37,0xad,0xa3,0x98,0x1c,0x03, - 0x86,0x88,0x3c,0x96,0x9d,0xbd,0xb9,0xd6,0xc9,0xd5,0xb7,0x75,0x78,0x55,0x72,0x7a, - 0xe1,0xba,0x0b,0x55,0xe2,0xf0,0xe1,0x4b,0xeb,0x2d,0xc2,0xcc,0xda,0xaf,0x14,0xb7, - 0xbf,0x1d,0x2f,0x65,0xe9,0xf1,0xc6,0x02,0xa7,0xbd,0xbf,0x1f,0xee,0x6f,0x1d,0x74, - 0xc6,0x9d,0x5e,0x27,0x88,0xc8,0x14,0x69,0x84,0x86,0x66,0xf5,0x60,0x72,0xd6,0x0a, - 0x7f,0xd8,0x6e,0x36,0x9e,0xee,0x3c,0x0d,0xe9,0x48,0x3d,0x7c,0xb6,0xd3,0xc0,0x53, - 0x86,0xe4,0xef,0x42,0x3a,0x59,0x0f,0x9f,0x86,0x77,0x09,0xe3,0xd8,0xbf,0x82,0x0e, - 0x02,0x2b,0xb5,0x8e,0x64,0x7a,0xda,0xf8,0xbe,0xd9,0x34,0x99,0x76,0x9e,0x36,0x4d, - 0x9e,0xed,0xe6,0xaa,0x4c,0x41,0xf4,0xb6,0x03,0xa3,0xea,0x9b,0xbc,0xc8,0x67,0x8d, - 0xa7,0xdf,0xad,0x2a,0xf2,0xfb,0x8a,0xdc,0x6f,0x20,0x87,0xb5,0xe0,0x66,0x9e,0x75, - 0x7b,0x47,0x72,0xfe,0xb0,0xaa,0xdc,0x56,0x70,0xb8,0x9f,0x04,0x7f,0xec,0x9b,0xbc, - 0x3b,0xbb,0x8d,0x6d,0xbf,0xa6,0xdf,0x6b,0xb1,0x5e,0xe6,0xff,0x7a,0xfd,0xd3,0xfa, - 0x9c,0x6e,0xb1,0x3f,0xce,0x3a,0xff,0x1c,0x0c,0xbf,0xa4,0xac,0x97,0xbf,0x6f,0xfd, - 0xfe,0x9b,0xcb,0x9c,0xef,0x9f,0xfd,0xd0,0x78,0xb6,0xfd,0xfd,0x03,0x73,0xfe,0xd4, - 0x9f,0x92,0xa7,0x67,0x8c,0x20,0xcd,0x2d,0xad,0xe9,0x34,0xcc,0x76,0x89,0xd2,0x83, - 0x7f,0xf6,0xb1,0xbe,0xf8,0xd0,0x9f,0x5e,0x75,0x21,0x4c,0x7c,0x02,0x9e,0xec,0xee, - 0xac,0xed,0x10,0x4c,0x40,0xf0,0x64,0x77,0xf7,0xcd,0xaf,0xff,0x0c,0xa2,0xd7,0x13, - 0x28,0x9d,0x3f,0x90,0xed,0x98,0xc1,0x80,0xf4,0xc6,0x33,0x2a,0x7b,0x3d,0x11,0x8a, - 0x41,0xcb,0x77,0x73,0xaf,0x67,0xc0,0xdb,0x3e,0xdd,0x6e,0x18,0x62,0xa3,0x9b,0xb9, - 0x7c,0x5b,0x4f,0xf6,0x5b,0x8c,0xae,0xff,0xd5,0xef,0x50,0x3e,0xe9,0x50,0xdf,0x35, - 0x76,0xbf,0x5b,0xcf,0x30,0x37,0x9b,0x52,0xeb,0xe4,0x5f,0x5f,0x2c,0xdf,0x17,0xbf, - 0x3a,0xef,0x0c,0xa9,0xc6,0x5a,0x4b,0x2f,0x9f,0xf6,0xe4,0x67,0x5e,0xbe,0xef,0x9f, - 0x7d,0xbf,0xbe,0x9a,0x6e,0xbe,0x43,0x98,0x84,0xfd,0xd3,0xb0,0xe7,0x4b,0x7a,0xd5, - 0x5f,0x07,0xfd,0x39,0xf4,0xf2,0xa5,0x2a,0xee,0x34,0x1b,0xcc,0x99,0xf5,0xbd,0x5f, - 0xf2,0xfa,0x7d,0x52,0xf2,0xaf,0x66,0xf1,0xc6,0x89,0x75,0x92,0xee,0xfa,0x4d,0x5c, - 0x14,0x6e,0xc2,0xd7,0xf8,0x08,0xb7,0x16,0x76,0x62,0xda,0xc4,0x5b,0x1e,0xb6,0x98, - 0x1b,0x63,0x86,0x9b,0xa1,0x8f,0x9f,0x9a,0x3b,0x71,0xad,0xc0,0x54,0x21,0x4d,0xf9, - 0x17,0xc4,0x04,0x4c,0x13,0xde,0xf1,0xd3,0x68,0x86,0xbc,0xd8,0xea,0x20,0x5a,0x44, - 0xd7,0xdd,0xe0,0x88,0xf6,0xb7,0x63,0x19,0x2f,0x41,0xe1,0xdb,0xb5,0x5e,0xcb,0xee, - 0xa8,0x9e,0xe4,0xde,0xa8,0x64,0x66,0xba,0x3d,0x1e,0x9c,0x90,0xe7,0x14,0x79,0xfd, - 0x4c,0xaf,0x4e,0x19,0x65,0xaf,0xc0,0x65,0xa6,0xfc,0x84,0xed,0x40,0x99,0x27,0x01, - 0x8d,0x1f,0xdd,0x10,0xfc,0xf8,0x47,0xce,0x22,0x4d,0x83,0xaf,0x77,0xe1,0x96,0x95, - 0x76,0xf0,0xc1,0x63,0xdc,0xcd,0x3f,0xd9,0xf4,0xe9,0xe7,0x01,0x7b,0xd4,0xcb,0xa7, - 0x7c,0xdb,0x9d,0x66,0x82,0x78,0xb1,0xae,0x33,0x4e,0xda,0x05,0x15,0xde,0x3a,0x3c, - 0x77,0x17,0x58,0x87,0xf7,0x87,0x6a,0xd7,0x3c,0xeb,0x9f,0xe3,0xdb,0xe6,0x45,0x7f, - 0x38,0x1c,0x4c,0xdb,0x96,0xe7,0x0b,0x46,0xc0,0x77,0x9c,0xd9,0xdf,0xd9,0x43,0xfc, - 0x6c,0x6e,0xac,0x76,0xb4,0x09,0x22,0xe3,0xd8,0x60,0x1b,0xa8,0x53,0x0d,0xcf,0x97, - 0xc7,0xc0,0xf6,0xe0,0x31,0xc7,0x4e,0x0e,0xbc,0xe9,0x75,0xb2,0x8b,0x36,0x8e,0x9d, - 0x1c,0x66,0xdb,0x8e,0x3d,0x78,0x96,0x5d,0x81,0x92,0xdd,0x74,0xbe,0xf8,0x0d,0x7f, - 0x35,0xac,0x6e,0x6e,0xff,0x6b,0x23,0x00,0x4b,0x3d,0x27,0x09,0xa8,0x0b,0xd3,0x0b, - 0x7f,0xa0,0x71,0x56,0x76,0x2b,0xce,0x5f,0xf4,0xf6,0xac,0x84,0xc9,0xdc,0xdc,0x34, - 0xbf,0xe2,0xa5,0x92,0x23,0xe5,0x6e,0x68,0x4b,0xd5,0x41,0x80,0xb3,0x6f,0x0a,0x0f, - 0x0c,0x45,0x08,0x08,0x1b,0xe0,0xa8,0xcd,0x6c,0x2b,0x4f,0xd9,0xf0,0x30,0xf6,0x7b, - 0x90,0x7c,0x46,0x2f,0x8a,0x4b,0xdd,0x48,0x3e,0x64,0x67,0x71,0xa9,0x2f,0xc9,0x87, - 0xd3,0x19,0xef,0x6f,0x51,0xc2,0x46,0xcd,0x10,0xfe,0x1c,0x67,0x93,0x01,0x8e,0x72, - 0xfa,0xd9,0xf8,0xf1,0xdc,0xb4,0x71,0xd0,0x91,0x9e,0xd0,0x19,0x4a,0xb7,0x8e,0x79, - 0xe3,0x0b,0xde,0xac,0xf7,0x10,0xef,0xf7,0x55,0xf4,0x2e,0xf1,0x28,0x53,0xe1,0x42, - 0x5f,0xbc,0xd1,0x2a,0x43,0x13,0xee,0x2f,0xcc,0xed,0x6b,0xf1,0xee,0x87,0x5f,0x69, - 0xb8,0x78,0xc1,0x5f,0xdd,0xde,0x2d,0x06,0xa5,0x26,0xe6,0x81,0xd3,0x2b,0x8f,0x6b, - 0xd7,0x27,0x6d,0x93,0xc3,0xed,0x7d,0x77,0x0f,0x37,0x67,0x94,0xfb,0xe6,0x8c,0xc5, - 0x96,0x29,0xff,0x92,0x95,0xe3,0xb4,0x30,0x70,0xdc,0x58,0x67,0xe1,0xc8,0xa5,0x79, - 0x2e,0x75,0x4d,0xbf,0xce,0xbe,0x3c,0xa3,0xef,0x89,0x57,0x20,0xfd,0x33,0x9a,0x3f, - 0x8a,0xc3,0x17,0xd8,0xdd,0xab,0x41,0xa0,0x77,0x28,0xa3,0x5b,0x94,0xd5,0x07,0x36, - 0x7a,0xe4,0xa3,0x9b,0x70,0x3f,0x4c,0xbe,0x29,0x6e,0xb5,0xf5,0xa3,0x41,0xfd,0xb5, - 0x06,0x90,0x82,0xe6,0x61,0x36,0x90,0xea,0x89,0xf4,0xab,0xed,0x16,0x1f,0x09,0x2a, - 0xe5,0x95,0x23,0xbb,0xdb,0x55,0xec,0xae,0xd4,0xde,0x30,0x6f,0x44,0x5a,0x95,0x42, - 0x58,0x08,0x2d,0x4e,0x8c,0x8c,0xf6,0x57,0x13,0x2e,0x65,0xc5,0xd5,0x14,0x96,0xc7, - 0xf8,0x2f,0x93,0x68,0x2c,0xde,0x61,0x0a,0x83,0x0d,0x44,0x59,0xa2,0xf0,0x47,0xf1, - 0x18,0x8a,0x70,0x78,0x1f,0x4d,0x76,0x92,0xdd,0xe4,0x49,0x85,0xc5,0x21,0x26,0x09, - 0x91,0x88,0x70,0x84,0xb5,0xda,0xe4,0x70,0x80,0x3e,0x3d,0x8e,0x73,0x83,0x8f,0xa9, - 0xc2,0xfa,0x36,0x90,0x83,0xe7,0x0c,0x28,0x36,0x89,0x4c,0x04,0x8a,0xa8,0x08,0xd4, - 0x61,0x34,0xf7,0xd8,0x24,0xa2,0xec,0x5d,0xbd,0xeb,0x65,0xc7,0x97,0xb5,0x1c,0xcc, - 0x8c,0x52,0xb5,0x93,0x36,0x31,0xc7,0x65,0x80,0xc9,0x5b,0x18,0x72,0x69,0x13,0x8a, - 0x14,0x69,0x86,0x3a,0xea,0x0f,0xdf,0xde,0xf2,0x92,0x8e,0x47,0xed,0xc9,0x17,0x6f, - 0x1f,0xc9,0x67,0xb0,0x54,0xe1,0x49,0xcc,0xce,0xb9,0xe0,0x09,0x77,0xd0,0xbf,0xa1, - 0x6d,0xa4,0x18,0x26,0x64,0xa7,0xb3,0x09,0x8e,0x8d,0x27,0x64,0x1f,0x50,0x6e,0x16, - 0xf8,0x64,0xe2,0xde,0x16,0xad,0x90,0xbb,0xdc,0x70,0xbb,0xe5,0x5c,0x87,0x39,0x58, - 0xa4,0x4d,0x6a,0x84,0x48,0xee,0x7f,0x48,0x3b,0xb3,0x8d,0x53,0x46,0x7c,0xb5,0xf1, - 0xb9,0x97,0x3c,0xbf,0xfd,0xb7,0x9b,0x93,0xdb,0xf2,0xcf,0x16,0xdb,0x46,0xf6,0xde, - 0x33,0x81,0xc5,0xd6,0x24,0x0d,0xd2,0xec,0x95,0x83,0xf3,0x65,0x1d,0x12,0x47,0xfb, - 0x80,0x48,0xbf,0xab,0xc3,0x34,0xea,0xad,0x07,0xa1,0x19,0xec,0x61,0xad,0xf5,0xfd, - 0x54,0xfa,0x16,0xe7,0xdc,0xa6,0x96,0x8d,0xd8,0x6e,0xeb,0x49,0x45,0xb7,0xa0,0x4f, - 0x51,0xf5,0xa0,0x60,0x04,0x4f,0xaa,0x3a,0x45,0x55,0x26,0x6e,0xf5,0x6a,0xbf,0x1b, - 0x7e,0x65,0xc5,0x97,0xac,0xb8,0xc7,0xd9,0x6b,0x7d,0x6c,0x2c,0xd9,0x47,0xce,0xc7, - 0x46,0x6c,0xbc,0x68,0x00,0x22,0xae,0x0e,0x27,0xf9,0xb0,0x80,0x97,0xeb,0xb1,0xbb, - 0x4e,0xd3,0x2b,0xf8,0xee,0xfa,0x4d,0x7f,0x50,0x13,0x3c,0xe0,0xf6,0xc1,0xc6,0x83, - 0xae,0x1f,0x6c,0xac,0xbf,0x7f,0x20,0x40,0x55,0x37,0x10,0xfc,0x5e,0x50,0xdd,0x88, - 0xd3,0xc9,0xf4,0xdd,0xd5,0xdc,0xb5,0xa5,0x25,0x9f,0x4f,0x9d,0xe1,0x56,0xff,0x76, - 0x40,0xd2,0x67,0x84,0x8d,0xfa,0xa4,0x87,0xad,0xec,0xbb,0xc3,0xa3,0x70,0xe5,0x6d, - 0xec,0xcd,0xcd,0x59,0x83,0x4e,0xe5,0x88,0x3c,0xca,0x58,0xc7,0x4b,0xc9,0x40,0x96, - 0x01,0xda,0x1b,0x0a,0x31,0xb9,0xf6,0x8f,0xe5,0xd9,0xe3,0xf8,0x8a,0x2b,0x12,0x62, - 0xdb,0x7f,0x30,0xb9,0x1a,0xf6,0x68,0x39,0x3a,0xeb,0xa3,0xa9,0x8b,0x8b,0x77,0xf5, - 0x80,0xbc,0x21,0xf0,0x5d,0xc6,0x30,0x2e,0x1b,0xfa,0x9f,0x21,0x30,0x88,0x6e,0xbc, - 0x4a,0xf7,0x97,0xf6,0xac,0x5e,0xd5,0x8a,0xf2,0x56,0x97,0xa6,0xb6,0x90,0xb8,0xee, - 0x05,0xce,0x10,0xa2,0x23,0x23,0x73,0xbd,0x42,0x1e,0xe6,0xd7,0x8d,0x0e,0xaf,0xa6, - 0xc4,0x42,0x9d,0xe0,0xf5,0xc4,0x20,0x25,0x3a,0xc2,0x1c,0x8c,0x76,0x64,0xa9,0x1b, - 0xe3,0x41,0x3f,0x59,0x21,0x5d,0x80,0x5c,0xcb,0xe2,0x8d,0x03,0x3b,0xd7,0x2a,0x7c, - 0xec,0x3f,0x9a,0xe6,0xc5,0x1c,0x92,0xeb,0x55,0xa1,0x33,0x50,0x54,0x8c,0x21,0x82, - 0xf9,0xe6,0x69,0x8c,0x53,0x03,0xcc,0x97,0xa7,0x39,0xfc,0xbe,0x03,0x98,0x05,0xbd, - 0x09,0x38,0x29,0xcb,0x7c,0x64,0xab,0x8c,0x32,0xed,0xcc,0x37,0xe2,0x26,0x02,0x61, - 0xcf,0xe0,0xcd,0x39,0xe9,0xe9,0x5c,0xd8,0x56,0x78,0xfa,0x18,0x71,0xd4,0x68,0x82, - 0x32,0xa6,0x77,0x55,0x36,0x86,0x70,0xb6,0x5c,0x0b,0xc9,0x94,0x50,0xf7,0x37,0xd7, - 0x31,0x12,0xd4,0x1e,0x90,0x1a,0x02,0x18,0xc4,0x64,0x55,0x0e,0xb8,0xc2,0xa4,0xe7, - 0x1c,0x9a,0xe8,0xec,0x5b,0x4a,0x0d,0x23,0xaa,0x16,0xef,0x54,0x0a,0x87,0x11,0x72, - 0x59,0xf2,0xbe,0x18,0xd2,0x26,0xdc,0x71,0xcf,0x8e,0xe7,0xdc,0xb6,0x28,0x51,0x2e, - 0x27,0x05,0xca,0xbd,0xa8,0x67,0x07,0x1e,0xde,0x0b,0xbf,0xe5,0xff,0xb0,0x4b,0x8a, - 0x68,0xe1,0x94,0x53,0x0f,0x62,0xb4,0xb7,0xb9,0xf0,0x91,0xde,0x80,0x8d,0x2b,0x32, - 0xf1,0x02,0xa6,0xa4,0x0e,0x67,0x82,0xe0,0x90,0xbe,0xfe,0xf6,0xdd,0x1f,0xb0,0xed, - 0x64,0xd2,0x72,0x9d,0x36,0xfc,0xc3,0x9b,0x27,0x1c,0x37,0x72,0xff,0x2b,0xe9,0xbc, - 0xe3,0x1a,0xe8,0x2d,0x27,0x82,0x8a,0x40,0x3c,0x68,0x90,0xb3,0x9c,0xab,0xc1,0xcc, - 0x10,0x93,0x17,0xdf,0xab,0x58,0xee,0x18,0x2a,0xde,0xd2,0x58,0x34,0x3e,0x1f,0x2b, - 0x81,0xe4,0xc8,0x09,0x9e,0xa4,0x72,0x1d,0x84,0xa7,0x92,0x48,0x66,0x53,0x5e,0x73, - 0xde,0xaf,0x4b,0x58,0x17,0xb1,0x63,0x76,0x1a,0xc7,0x40,0x34,0xbd,0xcb,0x1b,0xec, - 0x83,0xd9,0xe0,0xd8,0xeb,0x13,0xf8,0xc1,0xc0,0xe3,0xb4,0xdf,0x0b,0x1c,0x9e,0x47, - 0xb3,0xe9,0xde,0x6c,0xda,0x20,0x53,0xec,0x7a,0x60,0x8e,0x75,0x67,0xa7,0xd6,0x6a, - 0x41,0xce,0x65,0xc1,0x69,0xe2,0x9e,0x54,0x84,0x8d,0x6c,0x1d,0x3c,0xca,0xab,0xf9, - 0x2d,0xf1,0x86,0xad,0xb7,0xa7,0xe4,0xa8,0x3d,0x4c,0x28,0x0d,0xd8,0xd9,0xd0,0x9a, - 0x81,0x7c,0xf1,0xc1,0xd7,0xdd,0xcb,0xc3,0x7d,0xb9,0x2c,0x89,0x90,0x98,0x31,0x97, - 0x86,0x72,0x98,0x94,0xa0,0xf6,0x42,0x8e,0x56,0xef,0x0c,0x04,0x29,0x55,0xd7,0xe5, - 0xc2,0x17,0xb1,0xaa,0x26,0xac,0x6c,0x44,0x1e,0x26,0x95,0x3c,0x52,0x07,0x73,0x8a, - 0xc5,0xce,0xf8,0xae,0x2b,0x7e,0x33,0xa5,0x23,0x1c,0xbb,0xcb,0x67,0x6d,0x73,0x2f, - 0xdd,0xa5,0x90,0x71,0xbd,0xa2,0x08,0x09,0x49,0x94,0xe3,0x20,0x17,0x9a,0x1e,0x06, - 0x49,0x75,0xf3,0x63,0xf9,0xff,0x3b,0xe8,0x16,0xb7,0xf8,0xb1,0xc6,0x8d,0x4f,0x73, - 0x54,0x78,0xee,0xcf,0x7c,0x5c,0x92,0x9c,0x47,0x8f,0x8f,0x4d,0x8d,0x28,0x31,0xc0, - 0x5a,0x26,0x4c,0x90,0x96,0x9b,0x0d,0x6f,0xef,0xec,0xd1,0x5b,0x06,0x25,0x7c,0x1f, - 0x6b,0xed,0xed,0x1d,0x08,0x2d,0xba,0x30,0xd2,0x42,0xaa,0x14,0xd8,0x1f,0x69,0x79, - 0xfd,0x11,0x4e,0xb4,0xfd,0xf2,0x38,0x59,0xca,0xeb,0x8f,0xec,0xe2,0xcc,0x97,0x04, - 0x89,0x0f,0x72,0xa3,0x3b,0x95,0x92,0xc4,0x77,0xb0,0x19,0x0f,0x5e,0x79,0xf6,0x47, - 0x29,0x75,0x6a,0x26,0x06,0xf1,0x50,0xc9,0x04,0xb0,0xd1,0x37,0x40,0x93,0xa9,0x15, - 0xb3,0x86,0x3d,0x87,0x39,0xb1,0x48,0x7a,0xbe,0x4d,0x8b,0xce,0xb3,0x8f,0xb6,0xfe, - 0x1e,0x91,0x58,0xc3,0x92,0xcb,0x48,0x97,0x8f,0xb9,0x78,0xf9,0x66,0x99,0x77,0xcd, - 0x6f,0x96,0xd4,0x43,0xbe,0x59,0xf2,0x08,0xfa,0x66,0x39,0xbf,0xfd,0x66,0x49,0x34, - 0x7e,0x94,0x2e,0x21,0x2f,0xd4,0xba,0xf2,0xc8,0x8d,0x23,0xcf,0xcc,0x1e,0x7e,0xf6, - 0x16,0x8c,0x77,0xb1,0x34,0x11,0xd7,0x8f,0xe9,0x16,0xc6,0x5a,0x3e,0x95,0xb2,0x30, - 0xe1,0x2f,0x8e,0x27,0x8c,0xd0,0x5a,0xe5,0xf3,0x34,0xe7,0xa8,0xe2,0x68,0x16,0x93, - 0xd1,0x5f,0xd6,0x69,0xf1,0x7e,0x98,0x56,0x5b,0xba,0x43,0x92,0xd9,0xb0,0x14,0xc3, - 0xfe,0x51,0xf5,0x79,0xbf,0x94,0xc9,0x1e,0xf2,0xdc,0x7b,0x45,0xef,0x87,0x7d,0xf4, - 0x60,0x22,0x11,0xba,0x37,0x7b,0xfe,0x0b,0x30,0xf2,0xa0,0xaf,0xdc,0x8e,0xad,0x1b, - 0x4a,0x52,0xb0,0x4a,0xb8,0xcd,0x4d,0x6f,0xcb,0xc2,0xda,0xb3,0xfb,0x0b,0x04,0x93, - 0x26,0x13,0xfc,0x74,0xcc,0x05,0x61,0x51,0xf6,0x49,0x99,0x3b,0x71,0x50,0xe7,0x65, - 0x57,0x16,0x60,0x61,0x32,0x35,0xfe,0x13,0xd0,0x7d,0xea,0xbf,0x1f,0xe6,0x9e,0x74, - 0x33,0x8b,0xaa,0x95,0x4e,0x9a,0x68,0xa7,0x60,0xfb,0x66,0x5a,0x43,0x96,0x01,0xa8, - 0x85,0x4a,0x81,0x85,0xbf,0x24,0xca,0x72,0x0e,0xc8,0x1b,0xc2,0x6f,0xec,0xd7,0xff, - 0x57,0xa7,0xfe,0xcf,0x93,0xc5,0xee,0x5d,0xee,0x9a,0x4f,0x5b,0xe7,0x41,0x62,0x25, - 0xa4,0x9d,0xc1,0xbd,0x1c,0x63,0x13,0x45,0x30,0x6c,0xb7,0x8e,0xdd,0x0a,0x3d,0x92, - 0xec,0x12,0x75,0x69,0x70,0x4a,0x13,0x63,0xc4,0xf7,0x72,0xa8,0x02,0x16,0xf9,0x6b, - 0x10,0xcb,0xca,0xb1,0x9b,0x0a,0x88,0xf1,0x65,0x97,0x74,0xd9,0x39,0x62,0xda,0xb5, - 0x81,0xdb,0xdd,0xb2,0x97,0x3a,0xe7,0x73,0xba,0xde,0x15,0x17,0x7b,0x84,0xa2,0xcb, - 0x27,0xf2,0x95,0xa5,0x58,0x78,0x04,0x4e,0x21,0x91,0x7b,0x1d,0xa5,0xb4,0x1d,0xaf, - 0x57,0x0b,0xb3,0x40,0x30,0x7a,0x89,0xa4,0xd8,0x12,0x88,0xd7,0xa9,0x05,0x08,0x28, - 0x79,0x21,0x72,0x29,0xe2,0x5a,0x88,0x4a,0x4c,0xf6,0x11,0x92,0xd3,0xf6,0xe1,0x52, - 0xb8,0xec,0x80,0xc9,0x62,0x7f,0x3a,0x37,0x9e,0x5b,0x54,0x3b,0xcf,0xfe,0x8e,0xb1, - 0x7a,0x23,0xf7,0xd4,0x78,0x67,0x97,0x56,0x0c,0xe0,0xb8,0xb5,0x62,0xd7,0x3b,0xea, - 0xdc,0x0a,0x9e,0x47,0xce,0x24,0xc2,0x80,0xa0,0xe1,0xa9,0x13,0xae,0x1e,0xd8,0x77, - 0x07,0xb4,0x27,0xfd,0xbe,0xd1,0x43,0x66,0xc1,0xc7,0xd0,0xa8,0x05,0x8d,0x83,0x8c, - 0x47,0x1f,0x43,0xf2,0xf9,0x61,0xf9,0x7f,0xe1,0xae,0x0f,0x4e,0xee,0x36,0x81,0x8b, - 0x5d,0x63,0x10,0x76,0x00,0xb0,0xdb,0x98,0x4c,0xbc,0x1b,0x5e,0x4d,0x39,0x8c,0x63, - 0x82,0x5c,0x96,0x2b,0x11,0x14,0x26,0x1f,0x89,0xc1,0x8c,0x58,0x62,0x83,0x70,0x0d, - 0xd4,0x27,0x0f,0x7b,0xe3,0x29,0x5c,0x87,0x58,0x4e,0x3b,0xe8,0x9c,0xa2,0x2e,0xfe, - 0xb9,0x74,0x2b,0x04,0xc9,0xe4,0xf8,0xe8,0x51,0x2b,0x9b,0x75,0x3d,0x6d,0xd5,0xb6, - 0x4a,0x1c,0x28,0x22,0x34,0x03,0x7b,0xfb,0x42,0x5d,0x33,0x71,0xa8,0x12,0xe0,0x29, - 0x9b,0xd3,0x55,0x1f,0x30,0xd8,0xad,0x8a,0x38,0xb9,0x61,0x5f,0x60,0x8d,0xd0,0x22, - 0xc0,0x72,0x43,0xe5,0x7a,0x9c,0xf2,0xe7,0x91,0x5b,0x9d,0x47,0x6c,0x77,0x53,0xb7, - 0xe2,0xbe,0x49,0xf4,0x78,0x8c,0x4a,0x44,0xfd,0xba,0x11,0xca,0x70,0xde,0x75,0x2f, - 0xd9,0x0f,0xde,0xb2,0x0f,0x27,0xf6,0x0f,0x28,0xe8,0xd5,0xf4,0x8e,0xee,0x3b,0x95, - 0x5d,0x05,0xaa,0x47,0x94,0xea,0x7e,0xaa,0xfe,0x85,0x1e,0xcb,0x7a,0x5b,0xc5,0x3c, - 0xf9,0xe1,0x0e,0x1f,0xff,0x7b,0xbd,0x0c,0x09,0xf7,0xab,0x5d,0x0c,0x69,0x07,0xe2, - 0xee,0x26,0xf8,0x2a,0xbc,0xbe,0x04,0xd9,0x64,0x32,0x5e,0xeb,0xfa,0x45,0x56,0x7f, - 0x66,0xdd,0x21,0x8b,0x42,0xd9,0x66,0xa4,0xeb,0xe4,0x8c,0xe3,0x9d,0x29,0x72,0x33, - 0xe6,0x5e,0x84,0xb2,0x0b,0xb2,0xea,0x0a,0xf2,0xed,0x8c,0xa0,0x61,0x5e,0x39,0x7e, - 0x79,0x02,0xac,0xa4,0x73,0x87,0x3d,0xd0,0xf4,0xb2,0x3d,0x41,0x23,0x70,0x5a,0x21, - 0xab,0x6a,0x04,0xb4,0x81,0x13,0x80,0x3b,0x20,0xe1,0x7c,0xcf,0x16,0x29,0x6c,0x04, - 0xea,0x3e,0xa8,0xa2,0x7c,0x95,0x3a,0xa6,0xe8,0xde,0xa0,0x87,0x07,0x6a,0x3c,0xf6, - 0x26,0xdf,0x61,0x47,0x4a,0x32,0x69,0x6b,0x6b,0xb8,0x5e,0x85,0xaa,0xe9,0x6c,0x04, - 0xdc,0x67,0xa0,0x9b,0xe3,0x56,0x17,0xaf,0x42,0xd4,0xec,0x8f,0x51,0x5f,0x10,0x80, - 0xed,0xf8,0x63,0xca,0x7e,0x36,0x60,0xa1,0x94,0xf9,0x6d,0x7d,0xbf,0x87,0x1f,0xda, - 0x6a,0x55,0xb6,0xb0,0x23,0x44,0xca,0xfa,0xfd,0x52,0x06,0x1d,0x4c,0xac,0x09,0x32, - 0x1f,0x3f,0x0d,0xc6,0x9f,0x46,0xd9,0x5e,0x7e,0xb9,0x2c,0xda,0x4e,0xf8,0xf1,0xb4, - 0x0f,0x7f,0x39,0x2e,0x8c,0xb9,0xc0,0x1c,0xb7,0x76,0x9b,0xf6,0x45,0x26,0x71,0x6a, - 0x96,0xaf,0xa7,0x44,0xa0,0x47,0xa1,0x49,0x66,0x51,0x64,0xf8,0x8d,0xb6,0xda,0x0b, - 0xf3,0xb3,0x78,0xc7,0x3b,0x2b,0x17,0x42,0x5a,0x2c,0x4f,0x71,0xe5,0x0d,0xde,0x2a, - 0xbf,0x50,0xf6,0x58,0xbd,0x21,0x49,0x07,0x79,0x46,0xec,0x56,0x29,0xce,0xd1,0x9b, - 0x68,0x8e,0x21,0x35,0x01,0x44,0x1d,0xbb,0x0c,0x5c,0xe5,0xe3,0x68,0x9d,0xcb,0x0a, - 0xa9,0x94,0x18,0xbd,0x92,0x28,0x52,0xd0,0xb2,0x32,0xcb,0x22,0x1b,0xbe,0x93,0x13, - 0xa5,0x25,0x81,0x9b,0xae,0x61,0x3f,0xc1,0x70,0x95,0x89,0x48,0x04,0xa2,0xe1,0x41, - 0x9d,0xbf,0x96,0xc4,0x22,0xa7,0x2d,0x97,0xa6,0x70,0xbd,0xed,0x6e,0xe7,0x42,0x09, - 0xc8,0xe3,0xf9,0x6b,0xe6,0x9d,0xc8,0x14,0xab,0xe1,0xd4,0x82,0x25,0xdf,0xd1,0x28, - 0x1e,0x37,0x03,0x2e,0xdd,0xe4,0x3a,0x25,0xc9,0x96,0x93,0xc4,0x26,0xe5,0x86,0x2e, - 0x30,0x0d,0x2f,0xe6,0xf3,0x69,0x6b,0x6b,0x0b,0xfb,0x8c,0x69,0x2d,0xdc,0x0a,0xdb, - 0x26,0xb3,0x53,0x1c,0xe0,0xf2,0xe4,0x0b,0x68,0x43,0xe5,0x1d,0x25,0xaf,0xbc,0x3e, - 0x25,0xe7,0xbe,0x15,0xb8,0xc2,0xd0,0x41,0x15,0xfe,0x25,0xf4,0x50,0x61,0xfc,0x28, - 0x1e,0x9b,0x0f,0x6b,0x94,0x95,0x12,0xa2,0x51,0x98,0xbe,0x5c,0xee,0x36,0xdb,0x56, - 0x46,0xbe,0xdb,0x5a,0x0e,0x93,0x68,0xf2,0xcc,0x1d,0x47,0x0a,0x76,0xcf,0x1c,0xd7, - 0xeb,0xf7,0xe2,0x80,0x07,0x89,0x31,0x54,0x13,0x12,0xed,0x2d,0x7d,0xba,0xb9,0xa9, - 0x3d,0x01,0x18,0xce,0xfa,0xe8,0x7d,0x96,0x6f,0x84,0xab,0x0c,0x83,0xe0,0x14,0x33, - 0x7b,0x9f,0x02,0x11,0xd4,0xd9,0x0c,0xb7,0x52,0x9b,0xcb,0x13,0xdc,0xe4,0xb2,0xec, - 0xa0,0x01,0x66,0xa4,0xe4,0x9b,0x9a,0xa0,0x1a,0xc6,0x31,0x28,0x2e,0xca,0xae,0xbc, - 0x78,0x2b,0x34,0x35,0x2b,0xb0,0x6c,0xf8,0xf5,0xb2,0xf7,0x57,0x52,0x05,0x8a,0x7d, - 0xd6,0x09,0x4c,0x2b,0x6d,0x85,0x2f,0x3e,0x70,0x89,0xcf,0xb7,0x3a,0x70,0x63,0x11, - 0xfe,0xf7,0xe4,0x0a,0x27,0xc2,0x72,0xdf,0x2b,0x98,0xe7,0x03,0x54,0xee,0x02,0x27, - 0x2c,0x4a,0xf2,0xa5,0xc6,0xc1,0xeb,0x57,0x14,0x10,0x32,0xdd,0x79,0xd2,0xd6,0x77, - 0x04,0x64,0xfc,0x91,0x4c,0x2b,0x8f,0x43,0x13,0x45,0xe4,0x67,0x08,0x95,0x1b,0x0a, - 0x46,0x85,0xd7,0x0c,0x95,0xe0,0xb8,0x88,0x21,0xdf,0x3e,0xc3,0xd7,0x1f,0xe9,0x97, - 0x27,0x9f,0x0b,0x3c,0x30,0xdc,0x60,0x7c,0x36,0x31,0x40,0xa7,0x74,0x4d,0x87,0x34, - 0x24,0xe8,0x09,0x2c,0xfe,0x65,0x65,0xc4,0xe9,0x41,0xf4,0xfb,0xd1,0x41,0x6c,0x00, - 0xd9,0x23,0x41,0xc8,0xc2,0x98,0xe0,0x04,0x60,0xc1,0xb6,0xf7,0x75,0xe9,0x39,0x77, - 0x06,0xd4,0x6c,0x17,0x2c,0xa4,0xd6,0x7d,0xe7,0x40,0x3e,0x32,0xe0,0x08,0xbd,0x9e, - 0xfc,0x40,0x84,0xbf,0xe2,0xfe,0x3c,0x53,0xf8,0xfe,0xf0,0xc3,0xfe,0x9b,0x80,0x7d, - 0x4d,0x90,0x23,0x87,0x21,0xd9,0xed,0x66,0xf3,0xa0,0xcb,0x54,0x72,0x1e,0x8d,0xbe, - 0x85,0x6c,0x6f,0x79,0xfb,0x76,0xd1,0x17,0xe7,0x79,0x6c,0x60,0x92,0xf0,0x72,0x96, - 0x7d,0x02,0x30,0x46,0xf0,0xd5,0xcd,0x28,0x63,0x8d,0xea,0xf2,0xd3,0x0c,0xeb,0x0e, - 0x5a,0x85,0xc8,0x37,0xcc,0x4f,0x8b,0x67,0x4f,0x70,0xb9,0xff,0x96,0xae,0x5d,0xcc, - 0xea,0x58,0x54,0x49,0x95,0xb0,0x0b,0x38,0x45,0xa6,0x59,0xc3,0x2e,0x7e,0x3f,0xbb, - 0x2c,0x72,0x72,0x08,0x31,0x76,0x35,0x28,0x0b,0xd9,0x11,0xcc,0x19,0xae,0xfb,0x59, - 0x29,0x3f,0x7e,0xa6,0x7d,0xca,0x7c,0x60,0xfc,0x73,0x58,0x45,0x9b,0x4f,0x41,0xc4, - 0xea,0x32,0x66,0x9b,0x16,0x66,0x94,0xd6,0xd2,0x12,0x18,0x72,0xd0,0x09,0x8d,0xf2, - 0xc6,0xe8,0xb0,0xd4,0x7f,0x9c,0x05,0xfb,0x07,0xaf,0x03,0xfa,0x30,0xc8,0xa8,0x0f, - 0x64,0x7e,0x55,0x82,0x05,0xfc,0x39,0x7d,0x2f,0x35,0xea,0xf4,0x40,0xce,0x9c,0x71, - 0x10,0x97,0xc6,0x81,0x49,0xa0,0x99,0x28,0x88,0xd8,0xd5,0x03,0xb6,0x31,0x36,0x68, - 0x03,0xd6,0x7c,0x93,0x8b,0xc9,0xd4,0xcf,0x62,0xf1,0x80,0xa7,0x18,0x59,0x38,0xc0, - 0xbb,0xbe,0xc9,0x4f,0xd1,0x64,0xcc,0x0e,0x1c,0x79,0x8f,0x30,0xff,0xf0,0x0b,0x99, - 0x9f,0x74,0x46,0x85,0xeb,0xb8,0xcc,0xec,0xde,0xf8,0x40,0x14,0xc7,0xa1,0x09,0x79, - 0x1f,0x9b,0x09,0xb1,0x3c,0x06,0x83,0xdc,0xc5,0x0f,0x5c,0xdd,0x49,0x27,0xb4,0xa3, - 0xb5,0x31,0x4e,0x1e,0x8f,0xfd,0x99,0x70,0x9d,0x33,0x60,0x8c,0xce,0xfa,0xc4,0x70, - 0xfc,0xe8,0xf7,0x20,0x62,0x67,0x19,0xbc,0xfd,0x48,0x02,0xf1,0xac,0x11,0xdb,0xb9, - 0x18,0x35,0x17,0xf7,0xbe,0x3f,0x93,0xb7,0x3a,0xa9,0xd7,0x2b,0xcb,0xe0,0xd2,0x89, - 0x34,0xfa,0xb5,0x4a,0xa1,0x6e,0x98,0x90,0x2f,0x90,0x24,0x30,0xde,0x1f,0xbc,0x4c, - 0xf5,0xde,0xa0,0x73,0x8e,0x9c,0x2f,0x6f,0xe7,0x6c,0x13,0x2d,0x15,0xa1,0xd4,0xf1, - 0x24,0xc3,0xb4,0x2c,0xe5,0x0c,0x27,0x04,0xf5,0xd3,0xd5,0x68,0x2a,0x4e,0xdc,0xf2, - 0xca,0xe3,0x43,0xa6,0x61,0xed,0x0a,0x57,0xc6,0x9a,0x8b,0xd8,0x66,0x1a,0x9a,0x7e, - 0xad,0x5c,0xe7,0xe2,0x5d,0x9e,0x18,0x89,0xad,0x4b,0xdf,0xdc,0xe4,0xb6,0xf3,0x99, - 0xc6,0xc6,0x4f,0x29,0x57,0x01,0xd3,0x9f,0x41,0x6b,0x40,0x74,0xf1,0xe9,0x26,0xa3, - 0xf2,0xa9,0xcb,0xbb,0xed,0x38,0xa3,0xd5,0xfe,0x20,0x23,0x62,0x68,0x0e,0x0a,0xe0, - 0xfb,0x05,0xf2,0x1c,0xc0,0xe6,0x9b,0x0b,0x48,0xcb,0x43,0x6e,0xec,0x4e,0x8f,0xc7, - 0xa8,0x24,0x2f,0x06,0xe0,0xd2,0xed,0x9d,0x03,0x9a,0x19,0xd0,0x3f,0xc8,0xfe,0xbf, - 0x02,0x36,0x58,0xb0,0xd6,0x48,0xf2,0x10,0xf0,0xf9,0x34,0x03,0x1c,0xb5,0x2d,0x29, - 0xb3,0xe1,0xae,0x82,0x29,0xff,0xe5,0xfd,0x61,0x09,0xe4,0xec,0x4c,0x61,0x38,0x54, - 0xb7,0x03,0x45,0x10,0x74,0x6c,0xe9,0x09,0x45,0xea,0x8e,0xf9,0x54,0x03,0x59,0x36, - 0x19,0xf9,0xf9,0x50,0x02,0x20,0xb8,0x57,0x4e,0x59,0x5a,0xa8,0xcd,0x1e,0xc0,0xd0, - 0x1a,0xb7,0x10,0xd1,0xe4,0xfb,0xab,0x33,0xdf,0x1a,0x82,0x50,0xcd,0xa7,0x83,0x74, - 0xcc,0x5c,0xe7,0xe3,0x2e,0x80,0x9e,0x0e,0xaf,0x7a,0x7d,0xce,0x8a,0x95,0xe3,0x80, - 0xca,0x45,0xa2,0x00,0x67,0x5e,0x6e,0xde,0x9e,0x90,0xfc,0xe2,0xd7,0x41,0xc6,0xed, - 0x86,0x86,0xb9,0x76,0x51,0x78,0xf9,0xa6,0x98,0xcc,0x32,0x2f,0x9f,0xb4,0xb7,0x4b, - 0x6a,0x1f,0xd0,0xc4,0x36,0x33,0xa8,0xed,0xa9,0x80,0x93,0xeb,0x26,0x9d,0x35,0x0a, - 0xc2,0x72,0x37,0x87,0x69,0x9d,0x97,0xe4,0x37,0x55,0xb2,0x88,0x7c,0xa8,0x84,0x96, - 0x86,0xfa,0x69,0x90,0xf9,0xf0,0x4a,0x8f,0xe3,0xbd,0xd7,0xa6,0xc8,0x77,0x57,0xea, - 0x90,0xe5,0x66,0x14,0xa9,0xab,0xa0,0x0b,0x79,0x58,0xce,0xd0,0xea,0x93,0x91,0xfc, - 0xd4,0x59,0x35,0x53,0xa7,0x25,0x42,0x9e,0xc2,0xfb,0xb5,0xba,0x8c,0xcf,0xa5,0x68, - 0x18,0xef,0x7c,0xf2,0xd4,0x2b,0xb0,0x4d,0x22,0xf5,0x63,0xec,0x85,0x69,0x76,0xb1, - 0xc8,0xb5,0x5d,0xd1,0x2a,0xb9,0x3e,0x22,0x21,0x59,0xc1,0x17,0x93,0xf1,0x12,0x0c, - 0xbb,0x4b,0xd8,0x4f,0xa3,0x38,0x9a,0x2d,0x79,0xb1,0x65,0x74,0x7a,0xfc,0x42,0x18, - 0x8c,0xca,0x4c,0x40,0xed,0xa3,0x9a,0x60,0x81,0xbd,0x61,0x3d,0x7f,0x2b,0x6a,0xa4, - 0x00,0x32,0x88,0x59,0x40,0xc9,0x5c,0x55,0x46,0x11,0x71,0xd4,0x10,0x4b,0x7a,0xe5, - 0x33,0xcf,0x90,0xfa,0x1d,0xa9,0x4d,0x74,0xd6,0xe1,0xb7,0xc0,0x7c,0x98,0x8c,0xcb, - 0xab,0x0b,0xd9,0xef,0x9a,0xdc,0x93,0x79,0xc7,0x78,0x78,0x67,0xf2,0xf1,0xcb,0x9a, - 0x36,0xde,0xcb,0xf6,0x67,0x66,0x4a,0x35,0xa6,0xa1,0x3c,0x8a,0xc0,0xc5,0xec,0x22, - 0xd6,0x9c,0x12,0xc7,0x9c,0x47,0xd9,0xcd,0x98,0x16,0x6f,0x3c,0xae,0x19,0x8a,0x4b, - 0xb5,0xb0,0x88,0xba,0x42,0xb6,0x6a,0x8a,0xa1,0x8b,0xa6,0x3f,0x75,0xda,0xf1,0x1d, - 0x2b,0x53,0x59,0xd5,0xea,0x91,0x2a,0xe0,0xd2,0x5a,0xab,0xc0,0x83,0x05,0x96,0xfb, - 0xbd,0x65,0xb7,0x3f,0xef,0x94,0x3a,0x11,0x8b,0x79,0xda,0x50,0x1b,0x76,0xa8,0xc0, - 0x67,0xb6,0x1b,0x83,0x88,0x9c,0x61,0xaf,0xf7,0xdf,0x56,0xe6,0x09,0x3a,0xd3,0x55, - 0xd9,0xd8,0xff,0xf2,0x4d,0xae,0x09,0xdc,0x7f,0x9f,0xe7,0x9f,0x4c,0xdd,0x22,0x91, - 0x60,0x67,0x35,0x60,0xc2,0x18,0x9e,0xb9,0x05,0xb9,0xe8,0xf9,0x64,0x76,0xbf,0x5c, - 0x09,0x91,0x18,0xad,0xfd,0x8c,0x87,0xb9,0x8a,0x58,0x93,0x8f,0xc7,0xb9,0x25,0xa3, - 0x35,0x13,0xc9,0x03,0x21,0xf0,0xe2,0x6a,0x4e,0x92,0xbb,0x12,0x24,0x88,0xb2,0xce, - 0x08,0xdd,0x19,0xc4,0x0a,0x26,0x69,0xfe,0x7c,0x56,0x7b,0x49,0xbf,0xa5,0xf9,0x31, - 0xa8,0xd7,0x55,0x7f,0x42,0x3d,0x42,0xdd,0x4b,0x87,0x27,0x1b,0x27,0xc5,0x12,0xfd, - 0xb7,0x97,0xff,0x6d,0x56,0xe8,0x72,0xdf,0x1c,0x3b,0x04,0x84,0x82,0x05,0x4e,0x8e, - 0x8c,0x33,0x26,0x09,0xcd,0x29,0x41,0xb7,0x7f,0x01,0x41,0x45,0x0e,0xc6,0x9a,0x09, - 0xb6,0x6d,0x24,0x4d,0x3f,0x2f,0xc5,0xc7,0xdb,0xf2,0x6a,0x3c,0xc3,0xc8,0x61,0xa2, - 0x14,0x11,0x0b,0x27,0xf4,0x4a,0xf3,0x4a,0x6d,0xd3,0x15,0x7f,0x6a,0x84,0x01,0x95, - 0x58,0x62,0x7c,0x9b,0x3b,0xb8,0x4b,0x72,0x33,0x0d,0x3c,0xf2,0x5a,0xcf,0x5f,0x75, - 0xcb,0xef,0x62,0x96,0xa0,0x05,0xb4,0x65,0x30,0x18,0x03,0xf9,0x12,0xc8,0x17,0x90, - 0x9c,0xab,0x88,0x83,0x68,0xbb,0xce,0xae,0x03,0x51,0xaa,0x83,0xe4,0x2a,0xeb,0x56, - 0x90,0xf8,0xfb,0xe1,0x8f,0x86,0xc9,0x5f,0x4d,0x24,0xf0,0x5b,0x84,0x02,0xef,0x97, - 0x10,0x69,0x0e,0x73,0xad,0x13,0x7e,0x49,0xc7,0xe4,0xa5,0xf3,0x5a,0x80,0x97,0xc1, - 0xfc,0xaa,0xa7,0x1f,0x69,0x56,0xd3,0x8f,0x78,0x39,0x77,0xbe,0x9a,0x0b,0x4c,0xa4, - 0x7f,0xa5,0xc5,0xad,0x25,0xe2,0xcc,0x87,0x80,0x3f,0x6c,0x1b,0x69,0x76,0x3a,0xcc, - 0x57,0x3e,0xc6,0xbd,0x92,0xb3,0x5c,0x47,0x5f,0xb2,0xf2,0x64,0x79,0xa6,0xe9,0xec, - 0x9a,0x90,0xeb,0x4a,0x48,0x2f,0xbb,0x22,0x83,0xf6,0xbd,0x60,0x81,0x1b,0xdc,0xa5, - 0x7d,0x8b,0xd0,0x07,0x33,0x4a,0xad,0x32,0x3f,0x0b,0x5e,0x7b,0xc5,0x2a,0x6b,0xf1, - 0x3e,0xad,0x59,0xbd,0x05,0xb8,0xe0,0xa1,0x54,0xda,0x6a,0xe2,0xe7,0x0a,0xb7,0xc6, - 0x39,0xf8,0x01,0xec,0xf6,0xf3,0xcf,0x73,0xf4,0x6d,0xb5,0x0e,0xc0,0x37,0x36,0x0c, - 0x90,0x6f,0x1d,0x8c,0x50,0x75,0x6a,0x77,0xd6,0xa1,0x48,0x04,0xda,0x6b,0xae,0xe6, - 0x9f,0x4f,0x3f,0x9f,0x0e,0xb9,0xbb,0xe0,0x39,0xe0,0x17,0xe2,0xcb,0x29,0xf1,0x27, - 0xba,0xa1,0x25,0x1d,0x78,0xe3,0x64,0xd6,0xe6,0x3c,0xed,0xf4,0x84,0xa1,0x7d,0x8c, - 0x02,0x76,0x57,0x13,0xcc,0x21,0x45,0x33,0xb8,0xb9,0xe6,0x8e,0x66,0x66,0xba,0xb0, - 0xa8,0x30,0xbc,0xe2,0xb1,0x79,0x15,0x24,0xd5,0xdf,0xb6,0x77,0x9e,0xdd,0xc2,0x7f, - 0x5d,0x00,0xc9,0x93,0x91,0x0e,0x99,0x3f,0xac,0xca,0x35,0xcd,0x90,0x07,0xc0,0x44, - 0x70,0x5d,0x88,0xb4,0x96,0x19,0xda,0xad,0x87,0x98,0xf9,0x87,0xc1,0x36,0x3c,0x2e, - 0x59,0x8f,0x24,0xc3,0x3a,0x23,0x5a,0x9a,0x6c,0x3f,0x5b,0xee,0xee,0x2c,0xe1,0x9a, - 0xef,0x0a,0x6b,0xc0,0x21,0xa6,0x5f,0x3c,0xd8,0x05,0xdd,0x90,0x32,0xa2,0x37,0x39, - 0x2f,0x49,0x42,0xfe,0x08,0x43,0x85,0x20,0x83,0x1c,0x1a,0x8b,0x70,0xa6,0xae,0x18, - 0x2c,0x9a,0xf5,0xed,0x9d,0x26,0x79,0x43,0xd4,0x96,0xc2,0xca,0x11,0x4a,0x11,0x32, - 0xba,0x03,0x16,0x56,0x5c,0x9c,0xf5,0x67,0x14,0xd4,0x30,0x30,0xa9,0x70,0xa3,0xaf, - 0x2d,0x73,0x7e,0xda,0xe0,0x43,0xd1,0xc6,0x40,0x14,0x1c,0xd4,0x52,0xbf,0x1c,0x04, - 0x9c,0x18,0xe4,0x89,0xd6,0x90,0xd2,0x6e,0x75,0xdb,0xeb,0x63,0xd0,0x09,0x53,0xe8, - 0x11,0x62,0x28,0xeb,0x6b,0x77,0xd0,0xcf,0x47,0xf2,0x59,0xda,0x8e,0x08,0xde,0x51, - 0x52,0x8d,0x6f,0xc0,0xc6,0x4a,0x68,0x9e,0xb0,0x0d,0x90,0x6c,0x28,0x32,0x17,0x81, - 0x6c,0x33,0xd1,0x2f,0x27,0xc6,0x87,0x3e,0x5d,0x7c,0xa6,0x3e,0x70,0x76,0x36,0x38, - 0xf5,0x1a,0x73,0x84,0xd9,0x72,0xd0,0x00,0x9e,0x8c,0x37,0x5c,0x00,0xc3,0xa6,0xf9, - 0x37,0xde,0x3d,0x61,0xc7,0x50,0x70,0x65,0x38,0x84,0x46,0x8d,0x24,0x6f,0x63,0x32, - 0x1e,0x12,0x59,0xfb,0x94,0x12,0x50,0x4a,0x9d,0x52,0x02,0x52,0x21,0xcc,0xcd,0x71, - 0x5e,0x96,0x79,0xc5,0xc8,0x7e,0xd9,0x62,0xe9,0x6b,0x5e,0xde,0x70,0xba,0xcb,0x55, - 0xb4,0xdb,0x15,0x75,0xf0,0xa8,0x19,0xa4,0x34,0x25,0x69,0xd7,0xe6,0x1d,0x78,0xc3, - 0xc7,0xc4,0xbe,0x1a,0xab,0x30,0x61,0x0f,0x3d,0x5b,0x89,0x67,0xd4,0xc1,0xf0,0x64, - 0x47,0x98,0xfc,0x0e,0xe0,0x29,0x33,0xf2,0xd9,0x93,0x3b,0x0f,0x50,0x0a,0x15,0x78, - 0xf3,0xb2,0x3e,0xc3,0xd5,0x98,0x55,0x17,0x3d,0xc9,0xc2,0xb0,0xd4,0x70,0x79,0xba, - 0x29,0xb4,0x9c,0x1f,0x69,0x53,0xf8,0x9f,0x9b,0xa3,0x6d,0x45,0x15,0x93,0xc3,0x75, - 0x86,0xc4,0x69,0xc8,0x02,0x5c,0x01,0xfc,0xcc,0xf3,0xbe,0x25,0x56,0x2f,0xb0,0xfe, - 0xd2,0xd1,0x06,0xf6,0x0d,0xe0,0x75,0x62,0x49,0x13,0xce,0x0c,0xab,0x35,0x1c,0x7e, - 0xcf,0x06,0xc0,0x27,0xab,0x57,0xac,0x81,0x09,0x3c,0x9f,0x8f,0xde,0x23,0x81,0xf3, - 0x07,0x94,0x00,0x72,0x96,0xdb,0xcb,0xa2,0x2b,0xb1,0x5d,0x46,0x83,0x35,0x63,0x89, - 0x58,0xaf,0xd0,0x4b,0x40,0x2a,0xcb,0x20,0x5a,0x06,0x5d,0x0c,0x00,0xf4,0x2e,0xb3, - 0x7e,0x34,0xee,0x66,0x24,0xe7,0xf9,0x55,0xdf,0x32,0x7e,0x42,0xee,0x5f,0x28,0x41, - 0x57,0xb7,0xda,0xad,0x7a,0xa7,0x0d,0xee,0x81,0x74,0x75,0x62,0x66,0xcd,0xb2,0xfb, - 0x3f,0x1d,0x04,0xf6,0x07,0x06,0xb7,0xce,0x51,0x12,0xc7,0x66,0xd0,0x9e,0xb8,0xd4, - 0xe8,0x4e,0x60,0xdc,0x32,0xf5,0xbb,0xec,0x94,0xfa,0x0a,0x95,0xef,0xc1,0xfa,0xcc, - 0x09,0x66,0x27,0x6d,0x29,0x89,0x9f,0x4b,0xea,0x2b,0x9c,0x97,0xd5,0xcc,0xb9,0xe6, - 0x35,0x3c,0x94,0x7b,0xf2,0x45,0x14,0x90,0x57,0xef,0x93,0x80,0x62,0x43,0x74,0xcc, - 0xc9,0x16,0xfb,0x79,0x95,0xe9,0x45,0x32,0xe7,0xaa,0x0d,0x3a,0xd7,0x42,0x36,0x73, - 0x83,0x5f,0xe3,0x2c,0x9d,0x61,0x9c,0x91,0x77,0x1f,0x5b,0xd7,0xe1,0x66,0x1f,0x67, - 0xd4,0x33,0xde,0x1e,0xe6,0x7e,0x13,0x93,0xe0,0x1c,0x8d,0x7c,0x03,0xf1,0xc0,0x93, - 0x25,0xea,0x90,0xf3,0xc4,0xac,0x91,0x01,0x2a,0x08,0x84,0x7b,0x42,0xbc,0x73,0x5a, - 0x88,0xe2,0x99,0x76,0x56,0x11,0x7a,0x94,0x4b,0x4e,0xcc,0xcf,0xd4,0x40,0x64,0x2c, - 0x43,0xc6,0x36,0xc6,0xc1,0xb6,0x37,0xd0,0xf9,0xf4,0x0a,0x70,0xe5,0x43,0xbd,0x2e, - 0x36,0xd0,0x3e,0x34,0xad,0x5c,0x44,0x81,0x22,0x2b,0x17,0x79,0xf3,0x20,0xdd,0xad, - 0xf3,0x4f,0xac,0x91,0xf5,0xa7,0x1b,0x3b,0xc7,0x39,0xcf,0x4f,0xbc,0x7b,0x27,0x30, - 0xef,0xbb,0x94,0xd4,0xc0,0xfa,0x68,0xaa,0x0b,0x27,0xaa,0x3b,0x5b,0x73,0x70,0xaa, - 0xd5,0x3c,0x3a,0xbe,0x40,0xf2,0x92,0xf8,0xb1,0xec,0x62,0x3f,0xc9,0x98,0xc4,0xe0, - 0x8b,0x37,0xe6,0xd4,0xeb,0x38,0xff,0x08,0xe7,0x3f,0x44,0xdb,0xcd,0x80,0xae,0xd7, - 0xb1,0x0b,0x7e,0xa8,0x2c,0xc9,0x61,0xe0,0x4c,0xd9,0x12,0x7b,0x34,0x31,0xa6,0xd9, - 0x15,0x7b,0x30,0x22,0x26,0x5e,0xf0,0xf9,0xa7,0xa1,0x08,0xe3,0x5d,0xbe,0x48,0xb3, - 0x38,0x66,0x76,0x89,0x6b,0x9e,0x47,0xe2,0x8f,0x57,0x4e,0x19,0xe9,0x92,0xe4,0xcc, - 0x49,0x67,0x2a,0x35,0x83,0x41,0x36,0xcf,0x9a,0xe5,0x2a,0x43,0x0e,0x64,0xe7,0x70, - 0xc0,0x01,0x49,0x0c,0x37,0x9f,0xf6,0xa0,0x03,0xed,0x3c,0x59,0xb0,0x45,0x5d,0x6f, - 0x30,0xe9,0x21,0x87,0xf9,0x6e,0x4a,0x37,0x0a,0x9f,0xea,0x6a,0xe6,0xaa,0xcb,0xf7, - 0x86,0xcc,0x2d,0xf6,0x64,0xab,0x7a,0x42,0xbb,0x8e,0x62,0xd7,0xc6,0x7a,0x96,0x6b, - 0x1c,0xa5,0x11,0xa3,0x73,0x5e,0xca,0x27,0x07,0xdc,0x6c,0xbd,0xc8,0x2e,0x6a,0xd0, - 0xb3,0xb8,0x88,0x3f,0x86,0x93,0xe6,0x3b,0x47,0xa5,0x61,0xed,0x88,0x93,0x99,0xe7, - 0x54,0x9b,0x30,0x99,0x65,0x95,0x89,0x2b,0x1a,0xad,0x73,0xc3,0x93,0x62,0x36,0xc9, - 0xf9,0x6e,0x42,0x8d,0x23,0x3d,0x38,0xc3,0x42,0x72,0x65,0xbe,0x5b,0xaf,0xa4,0x5c, - 0x7d,0x3f,0xb9,0x16,0xa2,0xb1,0xd4,0xab,0xce,0x2c,0x73,0xa1,0xb1,0x14,0x91,0x19, - 0x83,0xb5,0xfe,0xd0,0x5b,0xc9,0x8c,0x28,0xb6,0x2c,0x58,0x89,0xf4,0x8c,0x64,0xc2, - 0x69,0xea,0x2a,0x5a,0xe6,0x55,0xb4,0xe8,0x44,0xc3,0xeb,0x81,0xcc,0xde,0xac,0x98, - 0x02,0x14,0x81,0x33,0x29,0x1f,0x4a,0x2f,0x10,0x6c,0xf9,0x17,0xac,0xca,0xeb,0xcf, - 0x74,0x6d,0xa6,0x39,0x9d,0x33,0x04,0xa1,0x00,0x25,0xdb,0xa7,0x10,0x73,0x6e,0xf5, - 0xc8,0x9c,0x86,0xf0,0x39,0xce,0xaa,0xf1,0xa3,0xb8,0x6c,0x7a,0xde,0x2a,0xa2,0x0a, - 0x92,0x76,0xea,0xbb,0xbb,0xcf,0xcc,0x72,0xc1,0x25,0x8b,0x27,0x40,0x9d,0xfb,0x8a, - 0xad,0x88,0x7f,0x90,0xe0,0x64,0x13,0x13,0x4f,0xdb,0xe0,0x33,0x57,0x26,0xb9,0xb5, - 0x9e,0x4f,0x89,0xb4,0xa3,0xf7,0x81,0x0c,0xdd,0x88,0xa6,0x1c,0xe3,0xe2,0x26,0x83, - 0x7e,0x21,0x2e,0x43,0xcb,0xf4,0x61,0x5c,0x6c,0x23,0x1f,0x2b,0x5b,0x25,0xac,0x4c, - 0xde,0x8b,0x49,0x70,0xff,0x93,0x95,0xa1,0x74,0xbb,0xe3,0xd5,0xdf,0x82,0x3c,0x01, - 0x23,0x73,0x66,0x04,0xa5,0x03,0xd7,0x00,0xf7,0xb2,0x3e,0x0b,0xc0,0xa3,0x83,0xc0, - 0xbc,0x14,0xab,0xa7,0x05,0xd6,0xd2,0xb4,0x18,0xdc,0x2e,0x56,0x29,0xd9,0x78,0xc4, - 0x3a,0x91,0xb7,0x6f,0xde,0xe3,0x28,0x89,0xf7,0x24,0x72,0xb8,0xae,0x56,0xe5,0x5e, - 0xcb,0x70,0xa6,0x06,0x79,0x39,0xb9,0x1a,0x93,0x62,0x40,0xb2,0x6b,0x82,0x43,0x9b, - 0x28,0xb9,0x78,0x3c,0xe1,0x57,0xd5,0x42,0x2e,0x4e,0x81,0x6a,0x4c,0xb3,0xcb,0x32, - 0x24,0x49,0x85,0xba,0x58,0x9c,0xa0,0x71,0x1c,0xac,0xbc,0xfc,0x99,0x33,0x17,0xdd, - 0x3c,0x92,0xee,0x02,0x1b,0xc1,0xa8,0xb0,0x22,0x27,0x8d,0x55,0x93,0x0d,0xe9,0xf4, - 0xfd,0x37,0xb4,0x04,0xbb,0x1a,0xe9,0x4a,0xb6,0x8b,0x19,0x99,0x6c,0xcf,0x18,0x30, - 0x73,0xb3,0x51,0xcb,0x8a,0x22,0x4f,0xbe,0x83,0xdb,0x2c,0xa6,0x56,0x54,0x97,0xe6, - 0x1e,0xa5,0x07,0xb4,0x98,0xd5,0xcb,0x6c,0x82,0xd1,0x31,0xf2,0xc7,0x75,0x77,0x36, - 0xe8,0x9d,0xf7,0xad,0xc9,0xe9,0x10,0xb2,0x02,0x7d,0x5e,0x64,0x9a,0xf9,0xbc,0x2a, - 0x57,0x86,0x1e,0x70,0xca,0xfd,0x48,0x65,0x41,0x5f,0xb2,0xf0,0x42,0x74,0x20,0x82, - 0x64,0x76,0x0b,0x1b,0x5f,0x27,0x67,0xb7,0x73,0xc5,0xc7,0xac,0x06,0x36,0x33,0x65, - 0x52,0x22,0xe4,0x21,0x2f,0x03,0x6c,0x60,0xd9,0xe8,0x28,0x34,0xb1,0x42,0xd2,0x1c, - 0x38,0x69,0xa8,0x02,0x52,0x13,0x1c,0x30,0x2c,0xb3,0x47,0xb4,0xff,0xd1,0xab,0x13, - 0x42,0xf1,0x0d,0x3a,0x66,0x20,0x1f,0x89,0xea,0x9b,0x59,0x87,0x0c,0xe0,0x97,0x90, - 0xd0,0x6e,0xad,0xfb,0xb0,0x14,0x9c,0x17,0xa5,0x48,0x3f,0xca,0x93,0x9b,0x8e,0x4e, - 0xeb,0xc7,0x77,0xfb,0x1f,0x7e,0x2a,0x34,0x5b,0x12,0x3c,0xa8,0x3f,0xd2,0x4d,0x75, - 0x55,0xd2,0xcf,0x33,0x72,0x2b,0x8e,0x6a,0xd2,0x52,0xf3,0x6a,0x48,0x5e,0xed,0xd7, - 0xec,0xb4,0x39,0xef,0xdc,0x47,0x37,0x5f,0x89,0xee,0x68,0x05,0xba,0xb3,0x8e,0xf1, - 0x32,0xcb,0x99,0x3a,0x63,0x31,0x5e,0xa4,0xa3,0xc8,0xfe,0x8c,0xe7,0x05,0x31,0x56, - 0x9c,0x0c,0x8d,0x7e,0x50,0xb3,0xb3,0xe2,0xa9,0x84,0x03,0xeb,0x36,0x83,0xa6,0x0e, - 0x00,0x07,0x09,0x64,0xc7,0x01,0x6f,0xc2,0x9b,0xcd,0x04,0x7d,0x9f,0xb6,0x89,0x04, - 0x7f,0x31,0x80,0x04,0xd9,0x71,0x91,0x20,0x31,0x47,0x32,0xae,0xc0,0xd1,0xe9,0xd2, - 0xa9,0xb4,0x29,0x2c,0x09,0xb0,0x0a,0x0f,0xb0,0xb1,0x67,0x2c,0x8e,0x77,0x12,0x9e, - 0x0d,0x7e,0xed,0x64,0x11,0x2d,0x85,0xd5,0x66,0x09,0xfb,0x0f,0xfe,0x70,0x30,0x82, - 0xf5,0x26,0x9f,0x7a,0xbd,0x3b,0x33,0x10,0x2f,0x52,0xdb,0x22,0x09,0xe2,0xee,0xc7, - 0x1c,0x0e,0x3e,0xa5,0xe7,0xd4,0xad,0xe3,0x45,0xee,0x92,0xe0,0x0a,0x19,0xcf,0xc8, - 0xf2,0x8f,0x3d,0x13,0xf0,0x0d,0x16,0x7c,0x64,0xa0,0x14,0x7f,0x25,0x9c,0x2b,0x80, - 0xf9,0xe5,0x39,0xfc,0x36,0x57,0x79,0x9a,0xf4,0xa2,0x5a,0x5c,0x55,0x86,0xb5,0x70, - 0x48,0xc9,0x0c,0xf9,0x9f,0x4e,0xf1,0x62,0xa8,0xaa,0x6d,0xfb,0x61,0xa5,0xd5,0x3a, - 0x23,0xc9,0x7d,0x81,0x47,0x08,0xd9,0xf1,0x6d,0x94,0x67,0x48,0x76,0xd8,0x08,0xcb, - 0xb6,0x76,0xb4,0x19,0x93,0x5e,0xdb,0x37,0x60,0xc4,0x5a,0xf3,0x47,0xf4,0x80,0x7e, - 0x67,0xcc,0xee,0xd3,0x06,0x0d,0x52,0xe7,0xcf,0xe1,0x3b,0x25,0xb0,0xfe,0xdb,0xda, - 0x92,0x53,0x86,0xd1,0x08,0x5d,0x46,0xe6,0xe6,0x41,0x46,0xc2,0xb6,0x4f,0x47,0x93, - 0xbc,0x6a,0x68,0x07,0xec,0x9d,0x95,0x7d,0x4b,0xf0,0x99,0xc0,0x06,0x3b,0x22,0xd7, - 0x1a,0x96,0x9c,0x46,0xbb,0x1f,0xf5,0x1e,0xda,0x6d,0x5a,0x04,0x3e,0x4b,0x3f,0x7a, - 0xc3,0xe9,0x63,0x48,0x01,0xe9,0x04,0xf4,0x03,0x4c,0x97,0x66,0xb7,0xb0,0x99,0xb9, - 0xb5,0x63,0xfd,0xdf,0x88,0x91,0x12,0x7f,0x8f,0xf9,0xef,0xea,0xb8,0x9b,0xda,0x97, - 0xfc,0x81,0x1b,0x4b,0x39,0xf3,0x95,0x24,0xcd,0xcb,0x24,0xcd,0x99,0xa4,0x39,0x48, - 0x9a,0x57,0x92,0xc4,0xdf,0xe3,0xf9,0x97,0x93,0x34,0x17,0x92,0x1c,0x9b,0x98,0xc3, - 0xd7,0xef,0x8e,0x58,0x0c,0xc9,0x3d,0x90,0xc4,0x3c,0xe8,0xca,0xc0,0x2c,0x32,0x90, - 0x7c,0x7a,0x95,0x41,0x91,0x9c,0x2f,0xa1,0x2f,0xb0,0xcf,0xe4,0x0d,0xb4,0x6c,0xb4, - 0x78,0xe6,0x95,0x6f,0xf4,0xc6,0x4a,0x8a,0xa7,0x4f,0x77,0x9f,0xb6,0x83,0x26,0xed, - 0x0e,0xb2,0x00,0xf1,0x7d,0x03,0xf7,0xa4,0x05,0xc9,0x33,0xc6,0x91,0xc8,0xa3,0xa2, - 0xd3,0xdd,0xb7,0x3e,0x8a,0x05,0x04,0xf0,0x93,0x14,0xe0,0xdf,0x20,0xca,0x57,0x0e, - 0x41,0x17,0x6b,0x01,0x28,0x15,0xf2,0x85,0x7d,0x2c,0xd0,0xb4,0x19,0x29,0x28,0xe7, - 0x57,0x16,0x18,0xd0,0x4c,0x43,0x86,0xf5,0x1b,0xb0,0xea,0x5b,0xd0,0x8e,0xe6,0x6e, - 0x6b,0x61,0xcc,0x75,0xf0,0x40,0xa6,0x09,0x42,0x1f,0xa6,0x1e,0x68,0x97,0x79,0x32, - 0xfb,0xcf,0x3f,0x8e,0x82,0xfc,0x95,0x4e,0x2e,0xcc,0xdc,0x98,0x05,0x2f,0x7b,0x3b, - 0x4f,0x9f,0x6e,0xff,0x80,0x6f,0x14,0x8d,0x12,0x66,0xec,0xe3,0x4b,0x59,0x89,0x19, - 0x14,0xf9,0xa4,0x1f,0xca,0xdc,0x49,0xd8,0x79,0xb2,0x96,0x05,0x65,0x8b,0x22,0xaa, - 0x24,0x7c,0x0e,0x9d,0x04,0x7c,0xa8,0x76,0x70,0xf8,0x57,0xac,0xa7,0x78,0x3f,0x96, - 0x6d,0x41,0x1e,0x3e,0x75,0xcf,0x43,0x8e,0xfe,0xfb,0xfd,0xcb,0xc3,0x34,0x24,0xd5, - 0x32,0xea,0x3a,0xc5,0x36,0xaa,0x9f,0xcc,0x6f,0xe7,0x9f,0xc8,0xfe,0x0f,0x45,0x24, - 0x66,0x79,0x9d,0x9c,0xcf,0xa6,0x9f,0x90,0xcc,0xbf,0xd4,0xe7,0x92,0x0e,0x8a,0xf8, - 0x44,0xb9,0x68,0x6f,0x06,0xc9,0x80,0xb8,0xb3,0x89,0xd1,0x95,0x74,0x00,0x8e,0xcd, - 0xcd,0x1c,0x4a,0xed,0x04,0xd3,0xda,0x27,0xc3,0xad,0xd0,0x1a,0xe2,0x45,0xe9,0x07, - 0xef,0xde,0xbc,0xdf,0x7f,0xfb,0xea,0xdd,0x5b,0x35,0x9d,0x72,0x0f,0x79,0xf4,0x14, - 0xbb,0xf2,0x64,0x67,0x95,0x31,0xc9,0x85,0x39,0x4f,0x7d,0xb8,0x3d,0xc8,0xbf,0x6a, - 0xfc,0xe1,0x9b,0xa4,0xf0,0x53,0x09,0x2f,0xfc,0x1a,0x4d,0x45,0x1d,0x9e,0x0b,0xab, - 0x2c,0xc8,0xe4,0x2a,0x1e,0xf7,0x35,0xde,0xde,0x9c,0x89,0xb1,0x98,0x9c,0xbd,0x61, - 0xb8,0x31,0x01,0x04,0x65,0x2b,0xda,0x58,0x93,0x4a,0xb5,0x6d,0x41,0xfe,0x11,0x9f, - 0xa1,0x90,0x0d,0x18,0x9a,0xf3,0x0d,0x46,0x9c,0x81,0x0f,0x46,0xe8,0x54,0x56,0x20, - 0x5a,0x81,0x7c,0xb0,0x73,0x9f,0x4d,0x48,0x7d,0x9a,0x93,0xd0,0xe7,0xbd,0xa2,0x85, - 0xca,0xb6,0x08,0x11,0x34,0x54,0xa3,0xc0,0x7c,0x09,0xe4,0x13,0xe7,0x04,0xed,0xb4, - 0x17,0xb0,0xc1,0x78,0xbc,0xc8,0x19,0xab,0xba,0x88,0xa4,0x7d,0xe1,0x60,0x4a,0x47, - 0x2c,0x06,0x11,0x3a,0xae,0xaa,0xb0,0x0a,0x62,0x41,0x0f,0xf7,0x57,0x74,0x60,0xfe, - 0x65,0x03,0x87,0xc1,0x6d,0x3e,0x96,0xdd,0x23,0x78,0x45,0x2d,0x99,0xc1,0x21,0x06, - 0x61,0xfc,0x78,0xd2,0x83,0x5b,0x7a,0x6e,0x89,0xd2,0x3a,0x31,0x83,0x8a,0x87,0x08, - 0xd4,0xa2,0x52,0x40,0x5f,0xe8,0x36,0x4a,0x76,0x29,0x88,0x5d,0x81,0xae,0x2d,0x89, - 0xf3,0xf0,0x82,0x51,0xd7,0xd0,0xa6,0x18,0xdd,0xae,0x63,0x80,0x56,0x62,0x50,0x1d, - 0xd0,0x60,0xcc,0xec,0x9c,0x40,0x1f,0x30,0x2e,0xc3,0xb2,0x2a,0x5d,0x6c,0xb3,0xe1, - 0xa5,0x66,0xa4,0x91,0x79,0x4b,0x87,0xf5,0xd2,0x6f,0x46,0x4c,0xc6,0x87,0x2b,0xcc, - 0x65,0xa2,0x0e,0xd7,0x19,0x72,0x32,0x5e,0x43,0x05,0x0f,0x61,0xd2,0xf4,0xd3,0xef, - 0x2a,0xb8,0x40,0xe0,0x02,0x05,0xd4,0x46,0x63,0xf2,0x3a,0x37,0x16,0x4b,0x64,0x65, - 0x9c,0x69,0x1f,0x92,0x77,0xc2,0xa3,0x5f,0x73,0x9e,0xb5,0x74,0x0b,0xf4,0x9c,0x9a, - 0xbc,0x3e,0x99,0xb1,0x23,0x82,0x17,0xc1,0x73,0xd2,0xf3,0xbe,0x08,0xad,0x33,0xbd, - 0x82,0xcd,0x16,0x7f,0x35,0x7b,0x53,0xda,0x03,0xfd,0x43,0xbb,0x09,0x9d,0xe6,0x91, - 0x3a,0x54,0xb4,0x12,0xb2,0x75,0x12,0x42,0x08,0x32,0xef,0x23,0xa2,0xad,0x48,0x94, - 0x56,0xee,0x21,0x7d,0xf8,0x89,0x3b,0xe7,0xb3,0x35,0x51,0xc8,0x4d,0xc6,0x5b,0x58, - 0x6f,0xfa,0x86,0x9a,0x3c,0x44,0x79,0xab,0xcb,0xa8,0x1d,0xdb,0x4c,0x7e,0x46,0x73, - 0xb1,0x61,0xa6,0x9e,0xda,0xac,0x33,0xf9,0x1b,0x64,0xec,0x77,0xd5,0xb6,0x08,0x80, - 0x39,0x82,0x1a,0x02,0xd0,0x9e,0x4b,0x85,0x86,0x58,0x45,0x04,0xd1,0xcf,0x34,0x86, - 0xf5,0x2c,0xbb,0x65,0xe6,0xce,0xef,0x9b,0xdf,0x37,0x63,0xcb,0x32,0x40,0xd0,0xe0, - 0xb1,0x12,0x8b,0x1e,0xec,0x8a,0x66,0x96,0x47,0xc1,0x44,0x4e,0xdc,0xbb,0xa2,0x7b, - 0x05,0x5f,0x8e,0x0e,0xde,0x17,0xbc,0xc5,0x94,0x2c,0x26,0xae,0x5f,0x6b,0xfe,0xfa, - 0xe5,0x16,0xa8,0xe5,0x6a,0xc7,0x6b,0xad,0x9d,0x7a,0xbe,0xde,0xf6,0x7e,0x5b,0xa7, - 0x87,0x67,0x52,0x93,0xa7,0xb5,0xd9,0xd4,0xf6,0xd2,0x96,0x65,0x94,0x38,0x99,0x75, - 0xd4,0x12,0xd3,0xf8,0xdc,0xf1,0x6a,0x57,0x65,0xbd,0x59,0xca,0xe9,0x1e,0x16,0x27, - 0xa2,0x04,0xb8,0x5b,0x81,0x6a,0x4c,0x1b,0xd2,0xa1,0xce,0x8d,0x72,0x8e,0x0d,0x72, - 0x75,0xe6,0xd3,0xf9,0xb7,0x1a,0x01,0x3a,0x94,0xa8,0x5c,0xa5,0x3a,0x6c,0x22,0xc3, - 0x29,0xc8,0x82,0xe7,0xba,0x6c,0xfe,0xad,0x9c,0x5f,0x61,0x1d,0xf3,0xd5,0xd6,0x2d, - 0x1b,0x27,0x55,0x6b,0x10,0xdd,0x41,0xa3,0xb3,0x4b,0x4c,0x7d,0x92,0x5d,0x78,0xa9, - 0x4b,0x55,0x68,0x0b,0x2a,0x37,0xfe,0xf0,0x60,0x18,0x34,0x9d,0x0d,0xae,0x3b,0x73, - 0x56,0x04,0x14,0xf3,0xa4,0x6a,0x28,0xc7,0x93,0xe5,0x67,0x9e,0x57,0xfe,0xaf,0x65, - 0x72,0xf2,0xff,0x99,0x9c,0xa8,0xfd,0x86,0x6f,0x04,0x27,0x2d,0xaa,0xeb,0x4c,0xb1, - 0x15,0x59,0x6d,0xa9,0x12,0x54,0x9b,0x73,0xac,0xb7,0x60,0x09,0xd6,0x58,0xb0,0x7c, - 0xb9,0x25,0x48,0xf0,0xaf,0x5b,0x82,0x04,0x5f,0x61,0x09,0x22,0x08,0xd6,0x98,0x1d, - 0x7c,0xb5,0x41,0x08,0x57,0xff,0x3e,0x7b,0x90,0xaf,0xd1,0x70,0x7d,0x8d,0x3a,0xcb, - 0xb5,0x43,0x39,0x50,0x83,0x47,0x94,0xe5,0x0a,0xfd,0xaf,0x3f,0x4a,0xf4,0x8e,0x29, - 0xcb,0x26,0xe3,0x91,0x3c,0xa8,0xac,0x65,0x7d,0x87,0x7f,0x40,0xa1,0xe3,0x07,0x8e, - 0x69,0xe4,0x68,0x4c,0xc7,0x67,0x9e,0x44,0x06,0x0b,0x62,0xcf,0x24,0x1a,0x57,0x9e, - 0xad,0x65,0xbf,0x6d,0x50,0x36,0x97,0x3f,0xe0,0xa4,0xfe,0xfb,0xe6,0x72,0xe7,0x3b, - 0x59,0x74,0x15,0x26,0xae,0x32,0x4c,0xd4,0x26,0xd6,0x39,0x1c,0x77,0x2d,0x7e,0x6d, - 0x28,0xd7,0xd8,0x95,0x4b,0x91,0x22,0xbf,0xcc,0x8e,0x57,0xc9,0xf1,0x4c,0x77,0x3d, - 0x2b,0x5d,0xbf,0x65,0xd6,0x9b,0x27,0x30,0x3c,0x5b,0x28,0x00,0x3c,0x58,0x69,0xbb, - 0xf2,0x70,0x6b,0x81,0x60,0xbd,0xb5,0xc0,0xfd,0x87,0xe6,0xca,0x35,0x30,0x42,0x0e, - 0xfe,0x45,0xfa,0x54,0x9b,0x19,0xf8,0xdd,0x4c,0xcc,0x0b,0x96,0x6c,0xbe,0xfe,0xef, - 0x3c,0x6c,0xf7,0x0e,0xc4,0x83,0x08,0x8f,0x75,0x52,0xbb,0x4c,0xa7,0xd5,0x3d,0xd6, - 0xd5,0xb2,0x82,0xa4,0x57,0x99,0xce,0x9b,0x51,0xe1,0x78,0x8b,0x26,0xec,0x09,0xdf, - 0x38,0x64,0xf7,0x2c,0xaf,0x81,0x5c,0xdc,0xb3,0x70,0x88,0xe6,0x3c,0x47,0x78,0xe7, - 0xe0,0x42,0x2c,0xb0,0x4c,0x2f,0x81,0x96,0x50,0xc7,0x06,0xb5,0x5a,0x8d,0x56,0xb9, - 0x23,0xd9,0x10,0x98,0xc2,0x45,0x04,0xdc,0x43,0x47,0xf0,0x4e,0x32,0xa2,0x47,0x3a, - 0x6e,0x5a,0xe6,0x27,0x5c,0x4b,0x19,0x9d,0x1f,0xe5,0xac,0x5f,0x3d,0x8a,0x1c,0x37, - 0x4f,0x62,0xcb,0x4d,0x3f,0xd9,0x18,0xa6,0xfe,0xba,0x44,0x3c,0xc1,0x78,0x51,0x4a, - 0x95,0xba,0xd5,0xde,0xef,0x22,0xe3,0xd3,0x24,0x12,0xb1,0xb0,0x94,0x03,0xfc,0xa5, - 0x38,0x42,0x61,0x17,0x28,0xa6,0x73,0xf1,0x4f,0xb6,0x14,0x7d,0x06,0x1d,0x4a,0x2c, - 0xf9,0x58,0x65,0x99,0x9f,0x2b,0x2d,0x8d,0x93,0x14,0xe3,0x1e,0x05,0x47,0x81,0x71, - 0xb9,0x56,0x5a,0xdd,0xe8,0xa3,0x1c,0xe9,0xc5,0x7b,0xcc,0x07,0xbc,0xeb,0x39,0x5b, - 0xbc,0x17,0x7f,0xe3,0xd4,0x7e,0x03,0x95,0x16,0x17,0x5e,0x97,0xc2,0x0a,0x61,0x2c, - 0x7d,0x10,0xed,0x22,0xb5,0x57,0xba,0x60,0x45,0x70,0xab,0xbe,0x9d,0xcc,0xbb,0xc3, - 0x16,0x5c,0x83,0xd1,0x32,0xc9,0xfc,0xde,0x52,0x6a,0x6f,0x06,0x39,0xd0,0x0a,0xc3, - 0x24,0xbb,0x3a,0xa7,0x64,0xec,0x61,0x29,0x99,0x22,0xc9,0xb4,0xcc,0xad,0x65,0xda, - 0xee,0x8d,0xe5,0x19,0x43,0xce,0x3c,0xdd,0xb9,0x5d,0xec,0x88,0x18,0x95,0x2b,0x7f, - 0xf5,0xc0,0x3a,0x3d,0x96,0x4e,0x96,0xa8,0x8b,0x9c,0xa4,0x68,0x89,0x44,0xfc,0x66, - 0x9d,0xc8,0xfd,0xfe,0x96,0x68,0x57,0x0b,0xed,0x75,0x9a,0x2a,0xaa,0xbc,0x6f,0xd1, - 0x47,0x54,0xc4,0xb4,0xbc,0x76,0xd2,0xb4,0xdc,0x15,0xf3,0x4b,0x9d,0x91,0x82,0xec, - 0x55,0x68,0xcf,0x5a,0x7a,0x05,0x31,0x2e,0x7a,0x8b,0x76,0xf2,0xca,0x0e,0xc2,0x78, - 0xd1,0xae,0x59,0x7a,0x79,0xbc,0x4b,0x9e,0xb9,0x16,0x61,0x8d,0x9e,0x6a,0xe1,0x5d, - 0x28,0x37,0x40,0xd1,0x44,0x3b,0x27,0xb8,0x53,0xbc,0x13,0xcf,0x4d,0x0b,0x99,0x7d, - 0x15,0xc1,0x41,0x38,0x5d,0x1e,0x6f,0x9f,0x9c,0xc4,0x36,0xdc,0x76,0x01,0x97,0x29, - 0x5c,0x2d,0x0c,0x42,0x86,0xad,0x51,0x61,0x94,0xe1,0xae,0xc2,0xd9,0x18,0xe8,0x71, - 0xca,0x70,0xef,0xca,0xf3,0xce,0x82,0x4f,0xc1,0x56,0xb8,0x23,0x23,0xb4,0x4e,0xd9, - 0x6e,0xfe,0x40,0x11,0x48,0x0e,0xb6,0x03,0xd8,0xde,0x6d,0x07,0x25,0x6f,0x64,0x77, - 0x21,0x13,0xa8,0x7e,0x91,0xc6,0xf0,0x8b,0x34,0xb6,0xfd,0x22,0x8d,0xd9,0x2f,0x52, - 0xae,0xec,0xf6,0x19,0x7b,0x66,0x46,0x9e,0x36,0x16,0x42,0x3a,0x82,0x07,0x68,0xff, - 0x5c,0x7d,0xab,0xf7,0xc9,0x9d,0xea,0x1a,0x17,0x4a,0x63,0x78,0x04,0x08,0x6b,0x94, - 0x21,0x11,0x57,0x49,0x94,0x14,0x20,0x49,0x58,0x6d,0x57,0xd1,0xcb,0x43,0x90,0xd5, - 0xf9,0xe4,0x96,0xbd,0xf4,0xb8,0x74,0xde,0xd6,0x8e,0xa9,0xdd,0xd2,0x72,0x33,0x0f, - 0x50,0x67,0x44,0xbc,0x84,0xb3,0xfc,0x08,0x83,0x51,0xba,0xcc,0x28,0xc5,0x73,0x83, - 0xdd,0xf9,0x41,0xc0,0x58,0x7e,0x92,0xa2,0x8f,0x37,0x35,0x0c,0x6e,0x89,0xee,0x6a, - 0xf8,0x30,0x02,0x01,0x54,0x79,0x39,0x07,0x88,0x0b,0x99,0x49,0x29,0x5e,0x98,0x2e, - 0xdb,0x8d,0x3d,0x4d,0x92,0x77,0x31,0xd9,0xd2,0xe0,0xbc,0x09,0x55,0x16,0x5d,0xb2, - 0xb1,0x8a,0xe3,0x66,0x12,0xfc,0x3e,0x73,0x03,0xb6,0x17,0x55,0xd0,0x1c,0x87,0xea, - 0xbc,0x0b,0x19,0x43,0xc7,0x69,0x72,0xb3,0x18,0xb5,0x22,0x4c,0xa5,0x8e,0x27,0x18, - 0x4b,0x9d,0x75,0xef,0x38,0xdc,0x06,0xfa,0x1d,0xfc,0xdb,0xc5,0xbf,0x27,0xf8,0xf7, - 0x14,0xff,0x9e,0xe1,0xdf,0x77,0xf8,0xf7,0x3d,0xfe,0xfd,0x80,0x7f,0xdb,0x4d,0xfa, - 0x43,0x90,0xdb,0x04,0xba,0xbd,0x1b,0x9e,0xb4,0x4c,0x89,0x2a,0xed,0x75,0x8c,0x96, - 0xe3,0x04,0xd0,0x57,0x71,0x41,0x22,0xce,0xb8,0x0c,0x8d,0x19,0x02,0x04,0x98,0x1e, - 0x85,0x97,0xbc,0xbe,0x92,0x4e,0xe3,0xb8,0x78,0xcc,0xb5,0xee,0xcb,0x30,0xe6,0x52, - 0xed,0x7e,0xfd,0x27,0xca,0xf8,0xf3,0xb9,0x7b,0x80,0x9c,0x97,0xf6,0x27,0x95,0x26, - 0x0e,0x82,0x5c,0x88,0xe3,0x3f,0x8d,0x67,0xaf,0x2e,0x71,0x9d,0x09,0xd8,0xdc,0xd4, - 0xc3,0xa1,0x2e,0x8b,0x73,0x21,0xa8,0x7b,0xfc,0xe4,0x64,0x0f,0x7f,0x2a,0x89,0xb0, - 0x78,0xef,0xf5,0x35,0xb8,0x87,0x82,0xd8,0xcc,0x12,0xd2,0xfc,0x09,0x15,0x98,0x5d, - 0xf8,0xe2,0x3f,0xa9,0x9b,0xea,0x78,0xc9,0x0f,0x11,0x3a,0xf3,0x97,0xe3,0x5e,0x8a, - 0x04,0x75,0x4c,0x3c,0xad,0xe1,0x4d,0xc2,0x24,0xff,0xca,0xa1,0x02,0x5f,0x58,0xdf, - 0x4d,0x4a,0x3d,0xbf,0xb4,0xdd,0x2b,0x02,0x1d,0x9d,0xce,0x48,0xcb,0x2a,0xb1,0x8e, - 0xc8,0xe5,0xea,0x35,0x07,0x17,0x35,0x27,0x62,0x6f,0xd1,0x0f,0x53,0x90,0xd4,0xee, - 0xb9,0x4e,0x0e,0xf0,0xdc,0xde,0x20,0xec,0x74,0x8a,0x3f,0x86,0xbb,0x11,0x2c,0x5f, - 0xa2,0x1e,0xf2,0xb1,0x97,0x95,0x88,0x29,0xa1,0x34,0xbe,0x10,0x9d,0xbb,0x76,0x7b, - 0x82,0x5d,0x28,0xbe,0xc8,0x7d,0x67,0xce,0xc3,0x90,0xac,0x44,0xe7,0x57,0xd3,0xaf, - 0xb9,0x6e,0xb1,0x53,0x37,0xaf,0x26,0xda,0x89,0x7b,0x65,0x2e,0xfe,0x82,0x31,0x15, - 0x2f,0x4c,0x25,0x73,0xa6,0x86,0xe7,0x7c,0x91,0x08,0x15,0xcb,0x73,0xb9,0x79,0x58, - 0xd7,0x8d,0x5c,0x2e,0xa7,0xed,0x78,0x01,0x21,0x89,0x8d,0xc3,0x39,0x99,0xcd,0xd3, - 0x8c,0xcf,0x47,0xd1,0x94,0xf4,0x63,0x87,0x60,0xd0,0x83,0x35,0xeb,0x60,0xcc,0x3e, - 0x96,0x31,0x62,0x9d,0xb8,0xd7,0x16,0xec,0x62,0x43,0xe9,0xc2,0x15,0x1e,0x32,0x59, - 0xc1,0xd9,0x04,0x1f,0xe0,0x84,0x35,0xcc,0xd2,0xb3,0xf9,0x5f,0x09,0x2a,0x6e,0x97, - 0xc0,0x9c,0xa5,0x9e,0xc4,0x0d,0x8f,0xf2,0xe3,0x64,0x93,0xb8,0x01,0xa1,0x74,0xbd, - 0xf7,0xb1,0x57,0xfb,0xd8,0xc8,0xff,0x58,0xce,0xb9,0xce,0x6e,0x18,0x6a,0x8f,0xb2, - 0xf2,0xfd,0x36,0xb9,0x2c,0xc6,0x3a,0x2b,0xdc,0x38,0xb3,0xee,0xad,0x59,0x7e,0x29, - 0x91,0x91,0x96,0xff,0x24,0x1e,0xf8,0xae,0x55,0xe8,0xd3,0x7f,0xa8,0xde,0x98,0x70, - 0xa4,0x47,0x8b,0x78,0x32,0x45,0xa7,0xb3,0x85,0x29,0xcd,0x3a,0x82,0x56,0xee,0xa4, - 0x19,0xc7,0xab,0xac,0xcb,0x07,0xfd,0x1b,0xe1,0xc7,0xe2,0x52,0xdf,0x73,0xd8,0x31, - 0xbf,0x10,0x6f,0x50,0x1f,0x45,0x8b,0xf5,0x31,0x6c,0xe0,0xf9,0x79,0x3d,0xe0,0xb2, - 0xf1,0xd1,0x34,0x60,0x96,0x9f,0x2c,0x9c,0x5f,0x41,0x59,0xd1,0x63,0xf7,0x5f,0x59, - 0x83,0xfd,0xc7,0x95,0x89,0x3b,0xa2,0x2b,0xd2,0x74,0x14,0x25,0x97,0xed,0xb2,0xab, - 0xd1,0x08,0xfa,0x42,0x73,0x4a,0x28,0x07,0x20,0x5c,0x24,0x16,0x3f,0xc0,0xca,0xab, - 0x11,0xba,0x3b,0x2c,0xd8,0xec,0x06,0xfc,0x15,0x58,0x0a,0x3f,0xfd,0x19,0xf7,0x86, - 0x23,0xd1,0x03,0x6f,0x6e,0x7a,0xeb,0xe8,0x85,0xac,0xae,0x1b,0xb4,0x0a,0x8b,0xf1, - 0x80,0xc3,0x89,0x48,0x8e,0xc5,0x4e,0x8a,0xd8,0x96,0xd2,0x67,0xed,0xf6,0xc6,0x61, - 0x46,0x98,0x18,0x40,0x3b,0x19,0x0c,0x85,0x13,0x1a,0x52,0x32,0x07,0x5b,0xb2,0x31, - 0x75,0xff,0x53,0x7d,0xb6,0xad,0x5d,0xfe,0x38,0x06,0x9f,0x79,0xa2,0x25,0xb9,0xfa, - 0x22,0x28,0xff,0x47,0xea,0x35,0x70,0x42,0x76,0x30,0x06,0x3a,0x53,0xe8,0xe7,0x7c, - 0x55,0x59,0x73,0x89,0x67,0xa2,0x2a,0x78,0x6b,0x9f,0x1e,0x98,0x3d,0x0c,0xc1,0x8b, - 0x59,0x71,0x26,0x70,0x9e,0xa6,0x59,0xe0,0x7c,0x85,0xb1,0xa0,0x8e,0xca,0x6c,0xdd, - 0x13,0x1d,0x79,0xe0,0xff,0xc7,0x5a,0xf2,0x40,0x3e,0x97,0x15,0xb6,0xc0,0xd6,0xda, - 0x90,0x23,0x07,0xb0,0x4f,0xed,0x14,0x25,0xab,0xb9,0xa8,0xc1,0x31,0xb8,0xb1,0x52, - 0xff,0x38,0x36,0x58,0x00,0x58,0x1c,0xb3,0x0a,0x60,0xe9,0x94,0x15,0x78,0x31,0xf0, - 0x6c,0x57,0xe0,0x5c,0x4b,0xdb,0x2c,0xb9,0xa8,0xa6,0x6f,0x9d,0xfc,0x71,0x4c,0x2d, - 0x63,0xd9,0xf6,0x5a,0xd5,0x99,0xf6,0xcd,0x61,0x90,0xd8,0x0a,0x58,0x7b,0x5f,0x2a, - 0xb5,0xc5,0x23,0x5e,0xc6,0x49,0x15,0x37,0x66,0x65,0xf5,0xaf,0x27,0x52,0x42,0xf4, - 0x79,0xed,0xf0,0xb4,0x8f,0xfe,0x9c,0x0f,0x88,0x28,0xac,0x15,0xfb,0x01,0x11,0xe0, - 0xb5,0xb0,0x38,0xc6,0xbd,0x1c,0x93,0x3f,0xce,0x06,0x0f,0xe1,0xf7,0x3c,0xe0,0x33, - 0x52,0x4d,0x40,0xa6,0xd0,0x4d,0x04,0x1e,0x9e,0xd8,0x6e,0xb1,0xdb,0x09,0x56,0x46, - 0x1a,0xd5,0x5c,0xbf,0xc1,0xe7,0x8f,0x74,0xb2,0x04,0x13,0xf7,0xbe,0xd8,0xb7,0x8a, - 0x87,0x7d,0x22,0xaf,0x4a,0x8a,0x7a,0xc3,0xf0,0xf0,0xea,0x1c,0xd1,0x2f,0xac,0x4d, - 0xf0,0x23,0xcd,0x86,0xdd,0x8f,0xe3,0x54,0x86,0xd5,0xd2,0x83,0x71,0xa6,0x0e,0x68, - 0xdc,0xf1,0x8c,0x34,0x20,0x03,0xa2,0x2a,0x04,0x5e,0x64,0x6b,0x17,0xc8,0x9b,0x1d, - 0x1a,0x48,0x86,0xd3,0x66,0xf3,0xd8,0x1f,0x22,0x72,0x8f,0x5b,0xda,0x6b,0xf2,0xfd, - 0x18,0x5d,0x74,0x3e,0x27,0xff,0x70,0xe2,0x9d,0xfc,0x43,0x96,0x09,0x5b,0x1f,0xb3, - 0xda,0x96,0xb7,0x14,0x62,0x18,0x67,0x2d,0x04,0xa9,0x22,0xc1,0x4d,0xe0,0xfa,0x12, - 0xe8,0x72,0xf3,0x2a,0x4d,0x8d,0x9f,0x37,0x9d,0x20,0x4a,0x77,0x95,0x41,0x94,0x84, - 0xaa,0x37,0xbc,0x96,0xc5,0x8e,0x57,0x68,0xca,0x52,0x3c,0xf3,0x19,0x00,0x4e,0x39, - 0x31,0x9d,0x10,0x51,0x3c,0x73,0x1a,0x3f,0x98,0x82,0x78,0x31,0x94,0xed,0x27,0xba, - 0x4b,0xab,0x79,0x27,0xa1,0x65,0x78,0x45,0xf7,0x57,0x92,0x17,0x06,0x6b,0x66,0x72, - 0x5d,0xe7,0xb9,0x00,0x61,0x20,0x87,0x93,0x34,0x73,0x95,0x15,0x84,0x28,0x05,0xbe, - 0x21,0x31,0x89,0xb8,0xb8,0x61,0x75,0x3f,0xdf,0x07,0xbd,0x10,0x3b,0x4f,0xfb,0x58, - 0x78,0x39,0x98,0xc4,0xb4,0x47,0x99,0x32,0x9c,0x90,0x22,0xa4,0x19,0x03,0xbf,0xd9, - 0x3f,0xf4,0x01,0x91,0xbb,0xd9,0xe5,0xd2,0x84,0xb9,0xcf,0x9f,0x34,0x37,0x37,0xb5, - 0x99,0xe6,0x09,0x32,0xc6,0xf4,0x5d,0xb3,0xe9,0xde,0x0d,0xa8,0x24,0x8f,0xc3,0x0d, - 0x24,0xab,0xdb,0xda,0x67,0xcd,0x98,0x59,0x93,0xb7,0x1c,0x38,0x64,0x83,0x32,0x5e, - 0x05,0x7e,0x22,0xc0,0xe0,0xa3,0xd3,0x38,0x2e,0x2f,0x75,0x07,0x92,0xe9,0xfe,0x03, - 0x72,0x06,0xcd,0x13,0x7d,0x3c,0xac,0xc5,0xf4,0xdb,0xf8,0x56,0x77,0x20,0x8f,0x46, - 0xb1,0xb3,0xd0,0xd4,0xed,0xae,0x6c,0x69,0x78,0xef,0x20,0xa0,0x48,0x5f,0xdb,0xac, - 0x90,0x77,0xbd,0x34,0x53,0x6a,0xf3,0x2a,0xd5,0x47,0xd8,0xf7,0xe6,0x7c,0x48,0xc8, - 0x1e,0xa7,0x97,0x52,0x92,0xec,0xe9,0xb1,0x46,0xe2,0xb4,0x06,0x86,0xd2,0xfc,0x95, - 0x34,0x46,0x98,0x48,0x47,0xc2,0x67,0x8a,0xed,0xb4,0x20,0xdc,0x35,0x03,0xa8,0x05, - 0xe0,0x1b,0x4c,0xe7,0xda,0x9c,0xe8,0x7c,0x32,0x1f,0xee,0xa4,0x07,0xc9,0x27,0xb7, - 0x17,0x61,0x69,0xc6,0x9d,0x87,0xea,0xe4,0x77,0x9b,0x6b,0xb1,0x2c,0x74,0x33,0x79, - 0x5d,0x05,0x48,0x64,0xab,0xc9,0xe4,0x5d,0x27,0x79,0x4b,0xbc,0x85,0x51,0x01,0x73, - 0x0e,0xde,0xd7,0x65,0x67,0xe9,0x34,0x2b,0x32,0x32,0xe7,0x28,0x5b,0x2e,0x33,0x99, - 0x4a,0x79,0xf1,0xdb,0x57,0xb1,0x62,0xae,0x4d,0x40,0x34,0x13,0xe8,0xec,0x2c,0x65, - 0xaf,0x28,0xcb,0x38,0xde,0x8a,0x02,0xc8,0x95,0x11,0xba,0xa3,0xf4,0x37,0x4d,0xfa, - 0x89,0x04,0x03,0x6f,0x2b,0xa1,0xaa,0xa0,0x82,0x48,0x32,0x0e,0xc6,0x90,0x07,0x3e, - 0x14,0xfb,0xfb,0x01,0x27,0xc4,0x4a,0x2c,0xf7,0x6d,0xcf,0xc9,0x98,0xf8,0x4d,0xea, - 0x9a,0x7c,0x6c,0x84,0x46,0xab,0x3a,0x2f,0xab,0x58,0xa7,0xf1,0xfa,0x44,0x95,0xbd, - 0xae,0x5f,0x7c,0x79,0xa6,0xde,0x9a,0xe6,0xfe,0x93,0xf7,0x42,0x4c,0x1a,0xd7,0xe2, - 0x98,0x8a,0x27,0xc4,0xab,0x31,0x50,0x61,0x95,0x1a,0x19,0x30,0xd9,0x1f,0x03,0x50, - 0x97,0xb0,0x00,0xd6,0x6b,0x2a,0x30,0xab,0xc1,0xaa,0xc5,0x2c,0x6a,0x51,0x84,0xc7, - 0x62,0xb3,0x81,0x76,0x59,0x2c,0x2e,0xc8,0x74,0xdb,0xac,0xbd,0x04,0x25,0x5a,0x5b, - 0x68,0x0a,0xe7,0x05,0xbc,0x96,0x55,0x1a,0xad,0xca,0x85,0x2a,0xcb,0x0a,0x6c,0x6f, - 0xfb,0x69,0x6b,0xcc,0x85,0x6b,0x5d,0xfd,0x59,0x2d,0xd2,0x31,0xae,0x82,0xd9,0x9d, - 0x10,0x79,0x2d,0x06,0x2c,0xf9,0x6c,0x33,0x6a,0x50,0xbf,0xb3,0x66,0x1c,0xf1,0x6d, - 0x3b,0xb9,0x4d,0xdd,0xc9,0x4a,0x84,0x02,0x83,0xab,0x6f,0x4f,0x7b,0x06,0x74,0xfc, - 0x0a,0x5f,0xb0,0x97,0x5c,0x81,0xf6,0x85,0x2f,0x87,0x9b,0x53,0xc9,0x40,0x91,0x05, - 0x48,0x0a,0xeb,0xf8,0x1d,0x51,0x9f,0x88,0x21,0x12,0xa0,0x2b,0x2d,0x7f,0x95,0x6f, - 0x08,0x19,0x57,0x4b,0x9d,0xa0,0x05,0xd9,0xb9,0x84,0x17,0x1f,0x68,0x2c,0x3a,0xc4, - 0x2d,0x78,0x5c,0x33,0x39,0xf6,0xc2,0xe7,0x57,0x08,0x62,0x40,0xe5,0x51,0x08,0x03, - 0x3c,0xf3,0x18,0x8b,0x6b,0x54,0x86,0x04,0x58,0xc3,0x1a,0xac,0x8f,0xa1,0x09,0x2f, - 0x67,0x03,0x09,0x63,0x47,0xaf,0xb1,0x89,0x81,0x20,0x81,0xc4,0x25,0xf2,0x81,0x19, - 0xb9,0xe0,0x92,0x1d,0x78,0xae,0x8d,0xf7,0x95,0x0e,0xf0,0xe8,0xa3,0xb5,0x1b,0x6d, - 0x96,0x1b,0xef,0x3d,0x16,0x19,0xec,0x55,0xf1,0x1b,0x9b,0xef,0x41,0x03,0xd5,0xaa, - 0x0c,0xa1,0xa2,0x2c,0x84,0xd2,0x73,0x80,0xae,0x22,0x2d,0xa8,0x51,0x50,0xbc,0x58, - 0x4b,0x93,0xb1,0x69,0x43,0x52,0xaa,0x01,0xc8,0x90,0x82,0xbb,0xd4,0x13,0xc4,0x98, - 0xbc,0x89,0xbd,0x94,0x68,0xc1,0xf6,0x21,0x2d,0x8c,0xbc,0x0e,0x2d,0x03,0x43,0x56, - 0x82,0xc5,0xde,0xe4,0x4f,0x55,0xec,0xc9,0x39,0x80,0x74,0x2a,0x77,0x6a,0x43,0x5f, - 0x93,0xce,0x25,0xbf,0xe8,0xf0,0x51,0x0f,0x8e,0xf2,0x9a,0x2d,0x17,0xbe,0xbe,0x1d, - 0xb7,0x22,0x81,0xa9,0xf5,0x6a,0x25,0x64,0xff,0xe1,0xbe,0x13,0x56,0xe1,0x99,0x47, - 0xd3,0x3e,0xbb,0x24,0x8e,0x72,0x06,0xf5,0x53,0xc9,0x0a,0x09,0xc3,0x21,0x9b,0xfb, - 0x4e,0xc8,0x66,0x04,0x74,0x4a,0xed,0x31,0x02,0x74,0x48,0x32,0x03,0x85,0x17,0x07, - 0x6d,0x7a,0xd5,0x85,0x24,0xe1,0x82,0xc6,0x9c,0x47,0x4a,0x3e,0xe6,0xda,0xb9,0x51, - 0x35,0xae,0xad,0x18,0x49,0x00,0x63,0x52,0xb5,0x1d,0x63,0x17,0xb0,0xf3,0xce,0x25, - 0x2f,0x8f,0x03,0x18,0xdf,0xb0,0xd6,0x84,0xbd,0x92,0x61,0x49,0x4f,0xa7,0xd2,0x5c, - 0x56,0xa6,0xb5,0x50,0x4d,0x3a,0x54,0x5b,0x51,0x35,0x6b,0x17,0x5a,0xf4,0x4a,0xbe, - 0xb3,0x90,0x12,0x76,0xf2,0x4c,0xa9,0x9c,0xc9,0x53,0xdd,0x21,0x4b,0x81,0x28,0x2b, - 0x64,0x45,0xc5,0x42,0x2e,0x19,0x9e,0x4e,0x95,0xa7,0x4d,0x52,0xa7,0xa9,0x3c,0x59, - 0xbd,0xd0,0x1a,0xa3,0xcb,0x1b,0xd5,0xce,0xf8,0x39,0xf2,0x0b,0xad,0x88,0xbc,0xf5, - 0x9c,0x78,0xac,0xaf,0xf4,0x89,0x2e,0x65,0xed,0xcf,0xa3,0x31,0xcd,0xa5,0xfc,0x51, - 0x13,0x62,0xe8,0x8f,0xdb,0x1b,0x54,0x3c,0xfe,0xa9,0xb8,0xb0,0x42,0x88,0x15,0x98, - 0x5f,0xa0,0x3e,0xca,0xad,0x8a,0x7a,0x11,0x06,0x12,0x7b,0xae,0xec,0x2a,0x78,0x64, - 0xdc,0x15,0xda,0x63,0xb1,0x32,0x6e,0xf8,0x68,0x42,0xd3,0x08,0x76,0x32,0xa5,0xd8, - 0xe1,0xfd,0x6b,0x92,0x3a,0x04,0xfb,0x93,0x39,0x85,0x8d,0x62,0x90,0xe8,0xe3,0x7b, - 0x70,0x1c,0xf2,0x59,0x55,0x1c,0x72,0x96,0x0e,0xdc,0x05,0x66,0xf6,0x68,0x93,0x2a, - 0xd4,0x66,0x1a,0x23,0x69,0x20,0x2c,0x72,0x24,0x0e,0x2d,0x50,0x68,0xaf,0x65,0xba, - 0x18,0x77,0x6c,0xd0,0x71,0x9c,0x3f,0xe8,0xb0,0xa4,0xb3,0x09,0x86,0xd3,0x2f,0x53, - 0xcd,0xda,0xb6,0xb3,0xe6,0xac,0xc7,0xda,0x55,0x93,0xe0,0x89,0xfe,0x6c,0xee,0x0e, - 0x1c,0x4f,0x29,0x02,0x38,0x95,0x23,0xab,0x86,0x24,0xea,0x58,0x2a,0xc6,0x8e,0xdc, - 0x2f,0xc8,0x9f,0x9b,0x6e,0xde,0xe0,0xb3,0xac,0x54,0x87,0x71,0x3b,0x2f,0xbb,0x84, - 0xe1,0x2e,0x27,0xaa,0x96,0xf6,0x4a,0x68,0xf2,0x1c,0x4d,0x3b,0xfd,0x45,0x19,0x01, - 0x95,0xa6,0xb5,0x2a,0xa4,0x86,0x92,0x70,0x27,0xfb,0x04,0xfd,0x52,0x62,0x32,0x85, - 0x96,0x74,0xe6,0x50,0x19,0x2a,0x9a,0x41,0xa5,0x1d,0x7c,0xdc,0x2e,0x28,0x15,0x8d, - 0x79,0x98,0xdf,0x69,0xe6,0xe8,0xd0,0xd1,0x18,0xfd,0xff,0xce,0xdc,0x29,0x41,0x4b, - 0x52,0x54,0x08,0x9b,0x75,0x7e,0x1f,0xd3,0x10,0x76,0xda,0xc7,0x9c,0x5a,0xc8,0x90, - 0x90,0xde,0xba,0x1e,0x11,0xac,0x04,0x66,0x0e,0x1e,0xeb,0xee,0x4c,0x51,0xad,0x04, - 0x97,0x7e,0x1e,0x84,0x8e,0x65,0x6c,0x99,0xae,0x9f,0x07,0xf3,0x87,0x11,0x83,0x45, - 0x57,0xc5,0x38,0x34,0x47,0x05,0x34,0x76,0xf0,0xdd,0x1c,0xb6,0xd1,0xba,0x0a,0xc2, - 0x35,0xac,0x1c,0xa4,0x6d,0x95,0xbc,0x85,0x54,0xd0,0x5c,0xfb,0x14,0xbf,0xf9,0xf7, - 0x29,0xa2,0x9c,0x16,0xaf,0x3f,0x51,0x99,0x52,0x4e,0x2f,0x2d,0xa5,0xef,0x6d,0xb7, - 0xa8,0xbb,0x57,0x95,0x43,0x48,0x6d,0x4d,0x44,0x5c,0x4c,0xa6,0x6d,0xee,0x34,0xce, - 0xc0,0x70,0xdd,0x9d,0x0b,0x39,0x2f,0x49,0x7b,0x84,0xb2,0x1f,0x84,0x7f,0x73,0xf3, - 0x81,0x73,0x01,0x67,0xea,0x8e,0x06,0x84,0xa4,0xa2,0xcc,0x0c,0xe7,0x38,0x7d,0x14, - 0xea,0xd1,0x5f,0xbd,0x18,0xa4,0x05,0xb7,0xf4,0x7d,0xd1,0x71,0x48,0x3f,0x73,0x50, - 0x1b,0xdc,0xc3,0x9c,0xb1,0xaf,0x43,0x90,0x8b,0x4a,0x9d,0xce,0x67,0x43,0xb4,0xc4, - 0xca,0x86,0x12,0xa5,0xfb,0xdd,0xc6,0x43,0xfa,0x07,0x2b,0x95,0xab,0x7a,0xc7,0x69, - 0x97,0xba,0x07,0xd0,0x4d,0x59,0x21,0xfa,0x13,0x1d,0xea,0x2f,0x45,0xa3,0xe4,0xa4, - 0x8a,0x14,0xea,0x3a,0xcb,0x07,0x3a,0xc8,0x48,0x4f,0xbb,0x0d,0xc8,0x65,0x82,0x89, - 0x42,0x4a,0x08,0x63,0x0d,0x33,0xf9,0x68,0xeb,0xf8,0xe3,0xec,0xe3,0xf8,0x44,0xb6, - 0x06,0xf4,0x35,0x56,0x04,0x95,0x0d,0xc7,0x34,0xd1,0xdd,0x2e,0x5e,0xe1,0xcc,0xb2, - 0x3e,0x67,0x92,0x0f,0xec,0x40,0x24,0x2d,0xb8,0xca,0x65,0x70,0x62,0x03,0x57,0xc6, - 0x46,0xdc,0xce,0xc8,0xab,0xf2,0x89,0x5e,0xe8,0xbc,0x8b,0x41,0x6a,0xf2,0xd6,0x76, - 0x5a,0xe5,0x8e,0xc9,0x74,0x73,0xb9,0x3a,0x3e,0xec,0x2f,0x29,0xd0,0x59,0xae,0x92, - 0xab,0xd7,0xcd,0x9a,0x86,0x38,0xca,0x8a,0x71,0x72,0xac,0xae,0x8a,0xbd,0x46,0xe8, - 0x0c,0x1c,0x0b,0x6f,0x4a,0x47,0xdc,0x0b,0xab,0x6c,0x21,0xc7,0x9f,0x86,0x5d,0x99, - 0x48,0x2d,0x2d,0x6e,0xc6,0x29,0x87,0x3f,0x95,0x59,0x6c,0x92,0x36,0xcd,0x77,0xf1, - 0x94,0xa4,0xca,0x31,0x34,0xc3,0xf2,0xe3,0x6c,0xf9,0x71,0xbc,0xe5,0xaf,0xa8,0x2d, - 0xfd,0xd5,0x30,0xc5,0xb3,0x70,0xd3,0x34,0xe1,0x70,0xb9,0x1c,0xe6,0x8b,0x90,0x26, - 0x5b,0xc5,0xfc,0x45,0x0f,0xa2,0x3d,0x9d,0xe9,0xd6,0x96,0xb9,0x7c,0xc4,0x46,0x45, - 0xcc,0x15,0x34,0x6f,0xb6,0x31,0x4c,0x87,0xd6,0x52,0x0a,0x41,0x0f,0x8f,0x5f,0x7c, - 0x73,0xb2,0xcc,0xef,0x94,0x7c,0xcc,0xbe,0xc5,0xfb,0x5f,0x4e,0x62,0x55,0x96,0x01, - 0x0f,0xf8,0x3d,0x64,0x1f,0x30,0x41,0xc7,0xf0,0xba,0x67,0x2c,0xff,0x4e,0x67,0x83, - 0xe9,0x9c,0x57,0x3b,0x85,0xa2,0x61,0xe8,0x1a,0x7f,0x20,0xdd,0xbe,0x59,0xf6,0xe1, - 0xd5,0xe1,0x6f,0x64,0x9e,0xbb,0xf5,0x77,0xbe,0x22,0xf4,0x0d,0x8a,0xe0,0x87,0xcc, - 0xf7,0x04,0x57,0x79,0x6d,0xc8,0x36,0xf1,0xb4,0xaf,0x10,0x01,0xa1,0x7a,0xba,0x03, - 0x4e,0xb3,0x91,0x77,0xdd,0x86,0x8a,0x0e,0x59,0x92,0x09,0x87,0x64,0xd4,0x5c,0xab, - 0x00,0xa2,0xdc,0x85,0xdd,0x32,0x77,0x79,0x17,0x03,0x9a,0x13,0x33,0xcf,0x2f,0x1e, - 0xe0,0x0b,0x0f,0x87,0x00,0xeb,0x89,0x87,0xc3,0xac,0x70,0x71,0xd8,0xcf,0xc8,0xcd, - 0x8d,0x9e,0x70,0x38,0x1e,0x0e,0x33,0xc1,0xe1,0xda,0x47,0x13,0x9f,0x28,0x25,0xf3, - 0x2c,0xa4,0x59,0x73,0x16,0x98,0x40,0x4a,0x11,0xd9,0xa8,0x2d,0x61,0x10,0x83,0xc6, - 0x43,0x06,0x09,0x63,0xc4,0x06,0x16,0x3c,0x54,0x5c,0x67,0xf5,0x3d,0xf8,0x78,0xb0, - 0x50,0x94,0x82,0x30,0x39,0x18,0xe6,0x5e,0xdc,0x85,0x2d,0xdb,0x6a,0xc3,0x89,0x97, - 0x80,0x92,0x24,0x78,0x8a,0x80,0x42,0xf5,0x8f,0x8f,0xa6,0xf1,0xfa,0x79,0x8c,0x82, - 0xd1,0x55,0x26,0xa1,0x04,0x2d,0x12,0xd8,0x0e,0xd3,0x29,0x78,0x56,0x36,0x9b,0x05, - 0xf2,0x4e,0x70,0x33,0x23,0xef,0x5c,0x3c,0x72,0x65,0x3b,0x43,0x55,0xd3,0x56,0x50, - 0x57,0x17,0x05,0x66,0x32,0xab,0xf5,0x6a,0x74,0xa6,0x46,0xb6,0xff,0x02,0xd6,0x5c, - 0xe3,0xe3,0x61,0xf5,0x2f,0xf4,0x08,0x0d,0x30,0x56,0xfe,0x48,0x73,0x3f,0xe7,0x90, - 0x01,0x98,0x55,0x76,0x68,0xdf,0x5e,0xee,0xc3,0x20,0xbb,0xcc,0x58,0xe6,0x68,0xf0, - 0xfe,0xfe,0x18,0x71,0x17,0x54,0x49,0x48,0x9f,0x7c,0x51,0x72,0x0a,0xe8,0x7c,0xd4, - 0x79,0x5f,0x35,0x38,0x27,0x04,0x9f,0x99,0x12,0x28,0x04,0xe4,0x23,0xc2,0x7c,0x3c, - 0x63,0x7b,0x93,0x45,0xf1,0x0c,0xf3,0x19,0x1d,0xe1,0x94,0x20,0x53,0x9d,0x3f,0xd0, - 0x95,0xea,0xb2,0xac,0x14,0x71,0x88,0x9e,0x91,0x5a,0x92,0xf8,0x85,0xb8,0x60,0x67, - 0xf1,0x46,0x1f,0x63,0xfa,0xc8,0x10,0xba,0xab,0x12,0x90,0xfc,0x72,0x2e,0xb1,0x22, - 0x75,0x79,0x92,0x40,0xb3,0x96,0x96,0xe4,0x7b,0x7b,0x85,0xcd,0x41,0x02,0xf5,0xc7, - 0x7d,0x16,0x03,0x00,0xb1,0x6c,0x06,0x42,0xce,0x8c,0x08,0x9c,0xa1,0x28,0x91,0xef, - 0xc9,0x7e,0x61,0xe7,0xbd,0x40,0xa6,0x0b,0xc7,0xe0,0x00,0xb4,0xee,0xf1,0xdd,0x2e, - 0x6e,0x7a,0x99,0xac,0xf6,0xa0,0xff,0x93,0xc4,0x7e,0x46,0x7a,0x37,0xae,0x8d,0x7f, - 0x56,0x85,0xae,0x85,0x5e,0xd5,0x9f,0xed,0x09,0x99,0x8e,0xd1,0xc2,0x85,0xb0,0xe8, - 0x26,0x3d,0x64,0x27,0x18,0xf6,0x94,0x17,0xcb,0xaf,0xc9,0x95,0xcd,0x3f,0x0f,0xfb, - 0xb4,0x84,0xcf,0x03,0x59,0x46,0x61,0xbd,0x8e,0x15,0x6b,0x74,0x53,0xa3,0x20,0x75, - 0x18,0x95,0xf1,0xca,0x3e,0x25,0xfa,0x9e,0xfb,0x0d,0x2f,0x7a,0x36,0x1f,0x86,0x63, - 0xe1,0xde,0x78,0x65,0xae,0x8c,0x0a,0x1d,0x3b,0xbc,0xe2,0x78,0xd7,0x58,0xc5,0x76, - 0x3e,0x47,0x37,0x75,0xa9,0xd4,0xa0,0xb6,0x9d,0x57,0x06,0x4f,0x1a,0x8a,0x07,0x3a, - 0x31,0xfe,0x04,0x6e,0x05,0x28,0xaa,0xe7,0x70,0x06,0x1b,0x73,0x37,0xa1,0x44,0xc3, - 0x11,0xca,0x24,0xfb,0x0e,0x0c,0x81,0x0a,0xbe,0xf6,0xa4,0xa7,0x4b,0x17,0xd5,0x03, - 0x9b,0xf5,0xd5,0x9f,0xdb,0xd5,0xbf,0x01,0x49,0x73,0xa7,0x6a,0xe1,0x3b,0x38,0xbb, - 0xb3,0x2e,0x5e,0x86,0x35,0xe9,0xe7,0xb5,0x50,0xce,0x1d,0x21,0x6f,0x73,0xf7,0xd3, - 0x3d,0x23,0xbf,0xfb,0x3c,0x87,0x71,0x64,0x19,0x16,0xdf,0xa4,0x8e,0x0f,0x7d,0x7a, - 0xe7,0xb9,0x66,0x98,0xc7,0x8a,0xf0,0x4a,0x77,0xef,0xeb,0xa9,0x9e,0x95,0xa9,0x9e, - 0xb9,0x54,0xff,0xb1,0xff,0xe1,0xed,0xab,0xb7,0xbf,0xb4,0x38,0xf4,0x09,0x88,0xe6, - 0x22,0xa4,0x0d,0xda,0x2c,0xe5,0x49,0x39,0x59,0x45,0xd5,0x4c,0xa8,0xf2,0xad,0x30, - 0x36,0x37,0x79,0x47,0x8d,0x89,0x4b,0xd6,0x8c,0x74,0x6f,0xdb,0x91,0x62,0x22,0x63, - 0x30,0x15,0x9b,0x49,0x66,0xa9,0x93,0xbd,0x5a,0xa1,0x9e,0x62,0x6f,0xa6,0x91,0x0e, - 0xd7,0xd7,0x71,0x5a,0xae,0xe3,0x74,0x45,0x1d,0xf9,0xce,0x9f,0x27,0xd3,0x4d,0x83, - 0xb5,0x78,0x05,0x5a,0x32,0xf9,0xa8,0xe7,0x6f,0xb0,0xfd,0x30,0x07,0xca,0x12,0x39, - 0x46,0xe6,0x5c,0x1c,0x48,0x5f,0x65,0x7c,0xd5,0x51,0x6c,0x47,0x98,0x01,0x72,0x39, - 0x4a,0x2e,0x6d,0x7c,0xc6,0x6b,0xbf,0x8a,0x81,0x53,0xbd,0xa3,0xdf,0x9d,0x8f,0xb3, - 0x7b,0xea,0x48,0x20,0x76,0x35,0xe9,0x5d,0x46,0xe0,0xf9,0x64,0x65,0x5e,0x73,0x67, - 0x07,0xd9,0xcf,0x27,0x76,0xe6,0xf3,0x09,0xb2,0x22,0xa9,0x4a,0x8c,0x89,0xe0,0x5a, - 0x29,0xb2,0x34,0x04,0xca,0x03,0x4a,0x1d,0xbb,0x45,0x84,0x07,0x1d,0x9c,0xb3,0x0f, - 0x51,0x36,0x51,0xef,0xf0,0xe2,0x7c,0x22,0x55,0x74,0x46,0x39,0x12,0xcb,0x4c,0x23, - 0x20,0x6b,0x8d,0xce,0xab,0xc9,0xa1,0xae,0xd0,0x19,0x85,0xa8,0xc7,0x85,0xce,0xfb, - 0x18,0x9b,0x95,0x3a,0x4f,0xe6,0x59,0x93,0x79,0x34,0xf0,0x46,0x81,0xf8,0x37,0x19, - 0xab,0x96,0x2e,0x1d,0xbb,0xaf,0xf7,0xea,0xec,0xda,0x06,0x01,0xab,0xe5,0x52,0x4b, - 0x33,0x21,0x15,0xca,0x9b,0x63,0x2c,0x61,0x7a,0x5a,0xf9,0xcb,0xca,0x86,0x21,0xa8, - 0xb8,0x2d,0xa6,0x3c,0x04,0x42,0x65,0x8c,0xd7,0x95,0x21,0xed,0x31,0x34,0xe2,0x68, - 0x2c,0x7b,0x31,0x0a,0x9b,0x97,0x11,0xbb,0xc2,0x55,0x96,0x63,0xbe,0x79,0x1d,0x38, - 0x14,0xb7,0xef,0xb3,0x8a,0x73,0x91,0x91,0x8a,0x07,0x6d,0xa4,0x3e,0x43,0xd4,0x0e, - 0x23,0x90,0x13,0x39,0x72,0x7c,0x98,0x41,0x34,0xe6,0x77,0x93,0x46,0xf4,0x07,0xa7, - 0x58,0xa0,0xd1,0x5d,0x97,0xa8,0x56,0x81,0x97,0x3f,0x6a,0xd4,0xb4,0x56,0x15,0x9f, - 0x90,0x48,0xb6,0xb4,0x61,0xb2,0x29,0x73,0xf6,0x87,0xb2,0x45,0x03,0xa0,0xe2,0x72, - 0x94,0x9b,0x96,0x5e,0x4e,0xb6,0xe4,0x8c,0x34,0x4d,0x4d,0x08,0x0e,0xe8,0x1c,0x8a, - 0x77,0x0c,0x9b,0x85,0xea,0x15,0x9c,0x6d,0xac,0xc0,0xb0,0x45,0x95,0x95,0x65,0x0f, - 0x19,0xc4,0xac,0xcb,0x85,0xd7,0x95,0xd2,0x31,0x81,0x9e,0xc4,0x3a,0x1d,0x58,0x0b, - 0x34,0xf9,0xa4,0xd9,0x4c,0xa7,0xd0,0xe4,0x12,0xfb,0x7e,0x04,0xb7,0xd0,0xdf,0xc0, - 0xbe,0x9c,0x77,0x10,0x06,0xe5,0xe6,0xd2,0xd0,0x8e,0xf2,0xa9,0xc1,0x9f,0xce,0x27, - 0xa5,0x4f,0xcc,0x32,0x3a,0x08,0x12,0x35,0x07,0x6f,0x09,0xde,0xf4,0xe1,0xa4,0x21, - 0x0a,0xb1,0xed,0xe2,0x3b,0x0b,0xad,0x33,0xe2,0x1e,0x32,0xf2,0xc7,0x7e,0x16,0x3f, - 0xc8,0xb2,0x46,0x7b,0x75,0xb5,0x8d,0x9b,0x39,0xb8,0xe0,0x24,0x85,0xd4,0xfa,0x4b, - 0x25,0x25,0xfe,0xa8,0x5a,0xb5,0x99,0xbe,0x81,0x5d,0xc3,0x00,0xe6,0x01,0x97,0x1f, - 0xfa,0xff,0x78,0xd5,0x93,0x44,0xb9,0x26,0x9b,0xba,0xea,0x0a,0x7b,0x9d,0xbb,0xbd, - 0x17,0xce,0x64,0x40,0x36,0xb7,0x4a,0x43,0xd2,0x8c,0x57,0x1e,0x8f,0x4e,0x78,0x32, - 0xbe,0xbb,0xb3,0xe0,0xf2,0x5a,0xfc,0x97,0x31,0xb6,0xe8,0x4f,0x45,0xc0,0x32,0xee, - 0x6c,0x18,0x3e,0x51,0x01,0x9a,0x34,0x13,0x26,0x8c,0x1e,0x9a,0xab,0xe2,0x8e,0x6d, - 0xd8,0x81,0xc7,0x52,0x0d,0x3c,0xb6,0xc8,0x99,0xc0,0x76,0x37,0x71,0x9b,0x11,0xa9, - 0xb0,0x54,0x5e,0x99,0xdc,0xe6,0x23,0x32,0x3f,0x69,0x3e,0xe1,0x9c,0xb0,0x7a,0x8d, - 0x4c,0xa2,0x38,0xee,0x56,0x73,0xbe,0x8b,0x0e,0xed,0x77,0xf2,0x9b,0x48,0x01,0x44, - 0x02,0x37,0x73,0xb5,0x44,0x59,0x5d,0xcc,0x0f,0xd0,0xcb,0x35,0xb8,0xa6,0x38,0x13, - 0xe0,0x5f,0xaf,0xdc,0x7d,0xc2,0xd7,0x9f,0x89,0xa0,0xb0,0x23,0x52,0x4a,0x4b,0x50, - 0x99,0x1c,0x84,0x32,0x60,0x53,0xd5,0xe1,0xe7,0x75,0x05,0x36,0x97,0x4b,0xfb,0x7d, - 0x7b,0xb7,0x5c,0x9e,0xf2,0x90,0x23,0xa6,0x49,0x6c,0xce,0x6e,0x11,0x77,0xd3,0x46, - 0xfe,0x80,0xa6,0xd2,0xc9,0x5e,0xfb,0x69,0xba,0x90,0xfb,0xf9,0x74,0x37,0x06,0x95, - 0x6a,0x91,0x7d,0xc9,0x2c,0x9b,0xcc,0xf0,0x40,0x57,0x76,0xe8,0x77,0x0a,0xac,0xa8, - 0x99,0xdc,0x8d,0x81,0x4c,0x65,0x63,0xed,0xe4,0xcf,0x49,0xd7,0x3c,0xf4,0x29,0xae, - 0x6e,0xd6,0x6a,0xba,0x97,0x65,0xa4,0x00,0x8e,0xfd,0xc3,0x3d,0x89,0xc4,0x8e,0xea, - 0xcf,0xd5,0x58,0x98,0x0b,0x01,0x5d,0x45,0x8a,0x10,0xe4,0xda,0x14,0x83,0xb4,0xb4, - 0x69,0xbd,0x1b,0x22,0x91,0x64,0x65,0x04,0x41,0x6a,0x77,0xec,0x99,0x22,0x6b,0x92, - 0xa1,0x56,0x72,0xda,0x9d,0x11,0xac,0xf1,0xc9,0xa7,0x45,0xbc,0x4c,0xec,0x2c,0x56, - 0xf8,0xd1,0x70,0x7c,0xe5,0x66,0xf0,0x2b,0x6c,0xcf,0xa9,0x08,0x87,0xfa,0xe5,0xd2, - 0x7d,0x6f,0x90,0xc9,0xf0,0x98,0xf7,0x15,0xb1,0x5b,0x4d,0xd7,0x0a,0x36,0x0c,0x63, - 0xbd,0x3c,0xd4,0x25,0x0f,0x61,0xa9,0x0d,0xed,0xec,0x1a,0x6a,0xf4,0x5c,0x68,0xef, - 0x3e,0xce,0xb6,0xce,0x8b,0xec,0xc4,0x53,0x87,0xc3,0xe4,0xba,0x07,0xfe,0x48,0x52, - 0x3c,0x6e,0x6e,0xe2,0x4f,0x83,0xd5,0x9c,0xf4,0xc0,0x06,0x20,0x27,0x32,0x8b,0x79, - 0x57,0xed,0x38,0x1e,0x92,0xb6,0x96,0x4f,0x45,0x6a,0xf0,0xee,0xe5,0xf4,0xb6,0xf2, - 0x07,0xd9,0xb2,0xb3,0x93,0xa7,0x67,0x0f,0x37,0x80,0xaf,0x6e,0x4e,0x15,0xcb,0xd5, - 0xd3,0x34,0xd2,0xd6,0xee,0x15,0x68,0xe7,0x88,0x1e,0x81,0xe2,0xc9,0x19,0xed,0x0c, - 0xd5,0xec,0xf3,0x13,0x40,0x72,0x99,0x4c,0x76,0x09,0x32,0x1d,0xc0,0xb7,0x36,0x6f, - 0x1f,0xb4,0x65,0xd0,0xf5,0xe8,0x32,0xb0,0x9c,0x9c,0xf7,0x6f,0x4f,0x79,0x91,0x11, - 0xd6,0xdc,0x3c,0xb5,0x10,0x23,0x1c,0xdb,0x8f,0xf6,0x1a,0xd9,0x25,0xbb,0x9e,0x47, - 0xde,0xa8,0x89,0xbd,0x14,0x7b,0x56,0xf1,0xe6,0x20,0x7b,0xe8,0x2c,0x74,0x22,0x10, - 0x96,0xc7,0x09,0x37,0x69,0xab,0x29,0x82,0x81,0x15,0x99,0x68,0x19,0x9c,0x04,0xf4, - 0x1b,0xd0,0xeb,0xf1,0x2a,0x4c,0x71,0x90,0x8f,0x12,0x7f,0xc6,0xb4,0xbf,0x2d,0x56, - 0xf4,0xa8,0x9c,0x50,0x8f,0x74,0xed,0xc1,0xc4,0xaf,0xb4,0xa2,0xb3,0xb5,0x37,0xf0, - 0xcc,0xb2,0xa1,0x56,0x73,0x64,0x45,0x9b,0xd2,0x85,0xde,0x54,0xe9,0xf5,0x4c,0xc8, - 0xb7,0xfe,0xce,0x3e,0x76,0x3e,0x66,0x79,0xac,0x5f,0x29,0x2b,0xde,0x13,0xe7,0x3b, - 0xdf,0xca,0x7f,0x61,0x4b,0xbe,0x00,0x85,0x2f,0x5d,0x9c,0x09,0x36,0x6f,0xc9,0x30, - 0x51,0xd1,0x2a,0xbf,0xcc,0x46,0x21,0x38,0x11,0x7c,0x39,0x5e,0x7f,0xee,0xe5,0x1e, - 0xea,0xb7,0x66,0x9a,0x7a,0x2d,0xcd,0x52,0x7f,0xdd,0x4c,0xec,0x61,0x79,0xa4,0x58, - 0xac,0xae,0xaf,0x53,0xd3,0x0b,0x9a,0x99,0x30,0x15,0xca,0xeb,0xf3,0xa7,0xa5,0x79, - 0xea,0x69,0x73,0xd7,0xeb,0xd5,0xf6,0x44,0x25,0x1d,0x5c,0x83,0x49,0x53,0xb7,0xf5, - 0xa7,0xbe,0x78,0xe1,0xb4,0x18,0xc2,0x4f,0x56,0x4a,0x72,0x5b,0x44,0xcb,0x81,0x73, - 0x79,0x6e,0xb1,0x4f,0x0f,0x7d,0xa6,0xf8,0x5d,0x52,0xbf,0xdf,0x3f,0x2d,0x55,0x0f, - 0xb2,0xe5,0xb2,0x48,0x92,0xc9,0xd1,0x99,0x13,0xd6,0x74,0x68,0x2f,0xa3,0x04,0x4e, - 0x47,0xcf,0x29,0xf5,0x9f,0x3d,0x9d,0x07,0x6b,0x46,0xc8,0xc0,0xaf,0x1d,0x59,0xeb, - 0x4f,0xc6,0xb4,0x71,0x94,0x8f,0x50,0x8b,0x6c,0xb2,0xa2,0x1c,0x50,0xe5,0xc9,0x31, - 0x59,0x88,0xb7,0x8b,0x16,0x1a,0xb0,0x09,0xdf,0x8c,0x7e,0xe4,0x4d,0x9f,0x1c,0x89, - 0x9a,0x7e,0x5f,0xaf,0x59,0xb8,0x7c,0xb4,0x17,0x21,0xfe,0x3c,0xcb,0xf1,0x3d,0xc9, - 0x75,0x4a,0x5c,0x92,0x84,0x87,0xe4,0x4a,0x2f,0xaf,0x6f,0xee,0x43,0xa9,0x7f,0x3b, - 0xa5,0xcb,0x96,0x12,0x8f,0x5a,0x9d,0x0d,0xe5,0xfd,0xc8,0x99,0x99,0x81,0xd7,0xe4, - 0xe2,0x8b,0x3b,0xfe,0xf2,0x60,0x26,0x0f,0x44,0x83,0xc2,0x6e,0x6e,0x3a,0x1d,0xcd, - 0x92,0x98,0xd5,0x42,0x43,0x32,0xd3,0xd6,0x2f,0x5e,0x94,0x7a,0x48,0x6a,0xdb,0x04, - 0xd8,0x2c,0x49,0x9a,0xca,0x93,0x6a,0xa9,0x27,0x58,0xd9,0xd8,0x05,0xcb,0x4c,0xaf, - 0x4f,0x5b,0x4b,0x46,0x9e,0x6a,0x67,0x2c,0xe6,0xd2,0x54,0xe4,0x07,0x25,0xf4,0xd0, - 0x15,0x4c,0x1b,0xee,0x53,0x17,0x88,0x8e,0x2b,0x24,0xe4,0x09,0xc5,0x21,0xae,0x96, - 0x59,0xc0,0x5c,0xab,0x29,0xe4,0x73,0x7a,0x72,0x8f,0x49,0x5d,0xe9,0xad,0x14,0xdd, - 0x3b,0x4c,0x25,0x52,0x77,0x90,0x93,0x5e,0xb0,0xb2,0x6e,0x71,0xf8,0xc5,0x6e,0x13, - 0xff,0xad,0x9e,0x1e,0xe5,0xda,0x05,0x0f,0x5a,0x0a,0x14,0xcf,0x37,0xb0,0xba,0x1a, - 0x64,0xbf,0xdf,0x93,0xf8,0xf0,0xba,0x16,0x56,0xff,0x21,0x26,0x06,0x45,0x87,0xdc, - 0x72,0x48,0x97,0xf1,0x79,0x2b,0xe2,0xe2,0xc1,0xcd,0xe9,0x54,0x7a,0x0f,0xce,0x63, - 0x5b,0x10,0x61,0xd5,0x32,0xf7,0xdf,0x30,0xac,0x3c,0xe9,0xb9,0xed,0x6e,0x1c,0x9a, - 0xbb,0xa5,0xf7,0x27,0xcb,0x65,0xad,0x56,0x1e,0x8b,0x2f,0x76,0x9a,0x6b,0xe5,0x76, - 0xbe,0x8d,0xf5,0x06,0xdd,0xff,0x04,0x03,0xbf,0x13,0x76,0x51,0x26,0xd9,0x97,0x57, - 0x58,0x31,0x80,0x10,0xe3,0x57,0xd4,0x9e,0x07,0xab,0x17,0x3a,0x42,0x83,0x84,0x1d, - 0xf6,0xe6,0xde,0x11,0xdc,0xea,0x4f,0x7a,0x2d,0xf2,0x32,0x0e,0x67,0xd5,0x14,0xe1, - 0xa0,0x43,0x01,0x13,0x5b,0x24,0x6e,0x13,0x32,0x8e,0xed,0x63,0xcb,0xb2,0x08,0x65, - 0xf5,0x59,0xa7,0x5b,0x70,0xd8,0x2f,0x43,0x9f,0x94,0xc7,0x05,0xd8,0xfa,0x33,0x23, - 0xb7,0x10,0x09,0x54,0xa6,0xbd,0xcf,0xad,0xff,0x3c,0x7c,0xf7,0xb6,0x61,0xdc,0x80, - 0xc3,0x9b,0x7d,0xa4,0x53,0xbb,0x47,0x17,0x4f,0xf2,0xce,0xcc,0x56,0xdb,0xd6,0xc9, - 0xde,0xf6,0x9d,0x76,0x17,0x57,0xc7,0x32,0xf6,0xcf,0xff,0xad,0xfd,0x20,0xbc,0x6f, - 0xc6,0x0b,0x6f,0xe3,0xc2,0x1f,0x6d,0x1d,0x22,0xb7,0xad,0xec,0xae,0xfd,0x48,0xda, - 0xee,0x76,0xc5,0x5a,0x43,0xbb,0x1f,0xd6,0x2c,0xa7,0xfd,0x9d,0x26,0x45,0xcd,0xcc, - 0x37,0x9b,0x28,0x3c,0x4b,0x06,0x3d,0x1c,0xbb,0x3b,0x9e,0x85,0x91,0x6b,0xcb,0x38, - 0x83,0xdf,0xe3,0x8c,0xd5,0x13,0x1b,0x7f,0xa2,0x69,0x8d,0x30,0x02,0x84,0x7e,0x1e, - 0x32,0x93,0xb1,0x34,0x25,0x02,0x38,0xce,0x39,0x95,0x1e,0x42,0x46,0xae,0xdf,0xcd, - 0xb3,0x0b,0x2f,0xb2,0x3a,0x80,0x14,0x99,0x9c,0x89,0xf9,0xbc,0x6c,0xec,0xcd,0x3e, - 0x9e,0x0e,0xd9,0xf9,0xd2,0xa3,0x4a,0x1a,0x39,0x56,0xe5,0x92,0x9c,0xad,0xbd,0x96, - 0x9f,0xe6,0xe5,0x1b,0xaa,0xe8,0x11,0x6b,0xa8,0x78,0x51,0xed,0x7a,0xf9,0xa1,0xbc, - 0x64,0xff,0xca,0x09,0x09,0x1d,0x2d,0xb2,0x54,0x19,0x3d,0x15,0x18,0xd3,0x51,0xb9, - 0x46,0x5a,0xb0,0x7d,0x21,0xbb,0x1b,0x08,0x10,0x6c,0xda,0x03,0x6e,0xa2,0x8f,0x4f, - 0x2a,0xac,0x46,0x6e,0xf9,0x58,0xce,0x5d,0x32,0xf3,0xfc,0x42,0x14,0xd6,0x06,0x27, - 0x3c,0xeb,0xca,0x36,0xf8,0x32,0x8d,0x6e,0x11,0xc4,0xfb,0x91,0x71,0x42,0xbd,0x47, - 0xcf,0xad,0x47,0x64,0x55,0xfb,0x2d,0xaa,0x90,0x2f,0xaf,0x6f,0x8d,0xf3,0x34,0x2b, - 0x1f,0xbf,0xa7,0xce,0x07,0xcb,0x90,0xe4,0xc5,0xc7,0x6c,0xaf,0xb8,0x5d,0xc5,0x20, - 0xba,0x86,0x98,0x5c,0xee,0xf1,0x56,0xb7,0x65,0x04,0x19,0x7f,0x94,0xc1,0xc3,0xe4, - 0xa5,0x6e,0xf5,0xf4,0xac,0xb2,0xd4,0x53,0x68,0x12,0x95,0x96,0x72,0x54,0x6b,0x71, - 0xc5,0xe8,0x51,0x6d,0x9b,0xe9,0x96,0xb5,0xb0,0x4a,0xe9,0xd6,0xde,0xf8,0xf2,0x86, - 0x16,0x0d,0xcd,0x5d,0xb2,0xf3,0xb4,0xe9,0x2c,0x67,0xcb,0x0a,0x32,0x6f,0xe8,0xeb, - 0xe4,0xcf,0x08,0x67,0xff,0x7e,0x7d,0x9c,0xaf,0xb7,0xaa,0xd6,0xcf,0x69,0x67,0x9c, - 0xb0,0x03,0xb3,0xfe,0x8c,0x95,0x74,0x1d,0x09,0x07,0xc1,0x77,0x8d,0xed,0xf1,0x56, - 0x1e,0x4b,0xd4,0xef,0x9f,0xef,0x34,0xbf,0x62,0xd4,0xd4,0xb6,0x45,0x06,0xdd,0xf1, - 0xdc,0xa3,0xc8,0x2b,0x45,0x00,0xa8,0x2d,0x2e,0x8f,0xca,0xd2,0xd3,0x3e,0x0f,0xe0, - 0x2d,0xb8,0xb4,0xfe,0x43,0x25,0x83,0xbf,0xf5,0x70,0x9b,0x4a,0x4e,0x7c,0x27,0x57, - 0x40,0xd1,0x93,0x05,0xc2,0x1a,0x9b,0x0b,0x30,0xc5,0xb6,0x10,0xd1,0x13,0xca,0x58, - 0x8e,0x39,0x65,0x23,0xc1,0x60,0x11,0xb8,0xb6,0xcc,0x61,0x63,0x1b,0x58,0x8a,0x13, - 0x60,0x39,0x80,0x96,0xc4,0x98,0xea,0x64,0x5c,0x95,0x1d,0x4e,0xce,0xe6,0xf9,0xca, - 0x97,0xc5,0x28,0x9f,0x8b,0x7e,0xa2,0x5b,0xe9,0x64,0x11,0xe7,0xaf,0xda,0x60,0x44, - 0x17,0x18,0x20,0xe1,0x90,0x5e,0x80,0x66,0xd6,0xe9,0x56,0x30,0xf8,0x99,0x42,0x25, - 0x4b,0x04,0xf0,0xab,0xb1,0x75,0x8f,0x5d,0x17,0x6c,0x76,0xff,0x77,0xcb,0x47,0xb1, - 0xe4,0xa5,0xe7,0x03,0xbf,0x44,0x45,0x1f,0x1b,0x64,0x62,0x87,0x45,0xe5,0x35,0x82, - 0x23,0xd7,0x26,0x89,0x74,0xb1,0xec,0x9d,0x51,0x5a,0x38,0x50,0xaf,0x81,0x9d,0x21, - 0xa9,0x67,0x13,0xe2,0x85,0x5d,0xea,0xfa,0x46,0xa8,0x36,0xdd,0x52,0x06,0xaf,0x22, - 0x90,0xf3,0x88,0x1f,0xd0,0x46,0xf0,0x41,0x89,0xe1,0x74,0xa2,0xaf,0xcb,0x5f,0xc1, - 0x1a,0x0a,0xb1,0x05,0xaa,0x8c,0xb6,0x35,0x7c,0x6f,0xe5,0x13,0x6d,0x7e,0xbe,0xb8, - 0xb6,0xcd,0xd3,0xb4,0xfc,0x7f,0x23,0x83,0xfc,0xfe,0xcc,0xe6,0xcb,0xe2,0x2c,0xe8, - 0x3a,0x95,0x65,0xdd,0xf5,0x20,0xbb,0xea,0x0c,0xe9,0x96,0x0d,0x99,0x94,0x25,0x85, - 0x7a,0x34,0xb7,0x74,0xc7,0x6e,0x8d,0x93,0xea,0xc0,0xb0,0xf6,0x36,0xb2,0x81,0xbb, - 0xae,0x63,0x55,0xb6,0x16,0xae,0x70,0x9b,0x23,0x46,0x28,0x17,0xbc,0x66,0x21,0x0d, - 0x72,0x50,0xfd,0xdf,0xd6,0x16,0xb3,0x59,0xfd,0x2f,0x53,0x2e,0xd8,0xd0,0xf5,0xc9, - 0x77,0xb3,0xc9,0x6c,0xae,0x7e,0x5e,0xdb,0xfb,0x7a,0xf6,0x5c,0x98,0xce,0xc5,0x7f, - 0x95,0xac,0x8b,0xf8,0x43,0x9f,0xdc,0xbb,0x51,0x3d,0x47,0x1d,0x3e,0x3e,0x3a,0xa7, - 0x50,0x09,0x57,0xec,0x9f,0xf3,0x80,0x95,0xbe,0x68,0x6f,0x70,0x0a,0xae,0x28,0xe6, - 0xe0,0x6c,0x7d,0x7e,0x0f,0x40,0xed,0x99,0xe8,0x11,0xba,0xcc,0x3b,0x72,0xd1,0xd6, - 0xed,0xcc,0xcc,0x5d,0x88,0xac,0x5b,0xc9,0x08,0x6a,0x76,0x30,0x82,0x09,0xa9,0xa5, - 0x00,0xf2,0x89,0x9c,0x63,0x85,0xb7,0xba,0x64,0x7c,0xad,0x5f,0x5f,0x4b,0x36,0x2c, - 0x06,0xc5,0x8d,0x0a,0x45,0xb4,0x4a,0x39,0x78,0xc3,0x8c,0x72,0x45,0x00,0x31,0xfc, - 0xa9,0x53,0x06,0x2e,0xce,0xb4,0x2a,0x43,0x3e,0x27,0x0e,0xc5,0xa5,0x56,0xe0,0xdc, - 0xf0,0x22,0x17,0xc1,0x25,0x60,0xc2,0x60,0x58,0xde,0x4d,0x6f,0xd9,0x78,0xa5,0xd2, - 0x66,0x08,0xb7,0x47,0x38,0xfe,0xa1,0x55,0xac,0xcb,0xf4,0x6f,0x9b,0x8d,0x67,0x3b, - 0x06,0x49,0xbc,0x42,0x0b,0x7f,0xff,0x49,0x30,0x0b,0x97,0xca,0x2e,0x8b,0x1e,0x5d, - 0x99,0x5e,0xb1,0x61,0xc1,0xa8,0x1a,0xfc,0x13,0xdb,0x15,0x33,0x16,0xe2,0xf6,0x83, - 0x33,0x1a,0x5a,0x34,0xa3,0x33,0xb0,0x00,0xd8,0x9f,0xa1,0x71,0x68,0x68,0x69,0xa5, - 0xc4,0xb7,0xc8,0xca,0x40,0x0c,0x62,0x00,0xf3,0x48,0x0d,0x60,0xac,0x6b,0x25,0xec, - 0xda,0x2c,0x5e,0xe8,0x23,0x4b,0x7f,0xdb,0x3b,0x8b,0x6e,0xc9,0x72,0x86,0x45,0x58, - 0x8e,0xd8,0xe7,0xe2,0xaa,0xa4,0x19,0x64,0xfc,0x7e,0x83,0xa0,0xa4,0x48,0xed,0x74, - 0xdb,0x01,0x61,0xa4,0xe0,0x02,0xb4,0x82,0x1e,0xcc,0x37,0x44,0x2a,0x98,0xd2,0xbf, - 0xf6,0x00,0x76,0x21,0x16,0x0b,0x87,0x4c,0x16,0xef,0xdd,0x8c,0x10,0x62,0xf9,0x86, - 0xa7,0xe7,0x5b,0xc6,0x5e,0xf8,0x05,0x9e,0x68,0x9f,0x46,0xbf,0x17,0xf3,0xd1,0xf0, - 0xc5,0xc6,0xff,0x1f,0xa0,0x4f,0x89,0x0a,0x25,0xd2,0x01,0x00, + 0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00,0x02,0xff,0xac,0x3a,0x69,0x9b,0xa2,0x38, + 0xb7,0xdf,0xfd,0x15,0xbc,0xe5,0x5d,0xca,0x19,0xb1,0x01,0x41,0x2d,0x98,0xee,0xbb, + 0xef,0xfb,0xbe,0x2f,0x01,0x0e,0x9a,0x5b,0x6c,0x4f,0x12,0xb5,0x6a,0x78,0xfa,0xbf, + 0xdf,0x9c,0x48,0x34,0x10,0xec,0xb6,0xdf,0x9e,0xad,0x24,0x21,0x39,0x39,0xfb,0x16, + 0x7e,0xfa,0xd5,0x1f,0xfe,0xcd,0x1f,0xfc,0xe3,0xbf,0xfd,0xed,0x1f,0x39,0x07,0x51, + 0x95,0x9f,0x66,0x3f,0xe1,0x8f,0x53,0x92,0x7a,0xff,0xf1,0x09,0xea,0x27,0x9c,0x00, + 0x92,0xcb,0x9f,0x0a,0x04,0x71,0xb2,0x03,0x61,0x1c,0xc4,0xc7,0xa7,0xa3,0x28,0xdc, + 0xdd,0x93,0x9e,0xae,0x49,0x05,0x1f,0x9f,0x4e,0x14,0xce,0x6d,0xc3,0xc4,0x93,0x93, + 0x35,0xb5,0x80,0x5a,0x2e,0x3b,0xd3,0x5c,0x1c,0x3e,0xe6,0x70,0xa2,0x19,0xb8,0x6a, + 0xb0,0x74,0x68,0x4d,0x05,0x25,0xa5,0xcb,0x33,0x52,0xc2,0x47,0x7f,0xe9,0x54,0xe4, + 0x8d,0x56,0xc7,0xea,0x36,0xa1,0x01,0xb9,0x05,0x15,0x1f,0xb3,0xe6,0x04,0x0c,0x4f, + 0x12,0x54,0x94,0xf0,0xe9,0xaf,0x80,0x1f,0xfe,0xa0,0x61,0xe0,0xfc,0x41,0x53,0x17, + 0x74,0xff,0xd3,0x07,0x35,0x2d,0x5f,0x73,0xf1,0x8e,0xbf,0x31,0x6b,0x1a,0xd1,0xcd, + 0x5c,0x37,0xdd,0xc7,0xf3,0x22,0x2c,0x36,0xc5,0x2e,0x71,0x5c,0x37,0x23,0x2c,0x97, + 0xe3,0xa2,0xc0,0x01,0xad,0x5f,0xe3,0xb9,0x4f,0x82,0xf5,0xda,0xc3,0x61,0x75,0x14, + 0xf1,0x7c,0xb3,0xd9,0xae,0x77,0x04,0x87,0x25,0xad,0x21,0x9e,0x43,0x00,0x5b,0x80, + 0x44,0x02,0x22,0x59,0x16,0xcf,0x83,0x74,0x9b,0xc3,0x4b,0xe2,0xa8,0xa1,0x02,0xa0, + 0x81,0x35,0x08,0x2b,0x7f,0xc9,0x23,0x35,0x02,0xc6,0xe2,0x79,0xbe,0x09,0xa3,0x30, + 0xc2,0xe1,0x99,0xb0,0x3a,0x9e,0x67,0xbb,0xdd,0xd6,0x27,0x08,0x2b,0x3b,0xd0,0x56, + 0xc2,0x86,0x22,0x28,0xb6,0x17,0x4c,0x10,0xcf,0x1b,0x5e,0xea,0x70,0xdc,0x90,0x07, + 0x39,0xe0,0x14,0x3f,0x90,0xbc,0x39,0xc7,0x9e,0xe3,0xb7,0x6f,0xce,0x5a,0xfe,0xcf, + 0xf6,0x29,0x79,0xf6,0x37,0xcb,0x60,0xb7,0x0c,0xa3,0xe5,0xca,0xdb,0x2d,0x92,0xd9, + 0xe7,0xd9,0xef,0x56,0x90,0x53,0xe2,0x3c,0xb7,0x0c,0x0a,0x60,0xdc,0xcd,0x9a,0xb2, + 0x61,0x92,0xa1,0x07,0xa8,0x20,0xce,0x09,0x7b,0x5d,0x74,0x03,0xc6,0xf8,0x9e,0x1f, + 0xf9,0x99,0x66,0x8c,0x62,0x86,0x1f,0xa4,0x57,0xde,0xc0,0x06,0xd2,0x22,0xb8,0xf2, + 0x66,0x97,0xbe,0xec,0x48,0x7a,0xe3,0x4d,0x40,0xd6,0x61,0x18,0x5c,0x79,0x13,0x92, + 0x97,0xb0,0x40,0x4e,0xf6,0xe4,0x05,0xeb,0x20,0x5f,0x13,0x83,0x3c,0x3f,0x94,0xf0, + 0x83,0x01,0x85,0x6b,0x12,0x6e,0xa2,0xcd,0x7d,0x0a,0xbd,0x25,0xfe,0xbb,0x0a,0x91, + 0xba,0xcf,0xb3,0x1f,0xba,0xb4,0x79,0x73,0x39,0xfd,0x99,0xd6,0xfb,0x38,0x6d,0x58, + 0x0e,0xcc,0x95,0x33,0x49,0x45,0xd8,0x9e,0xd6,0xb1,0xf7,0x79,0x86,0x5a,0xdb,0xb9, + 0x67,0x48,0x5f,0xa9,0x70,0x05,0xbc,0x09,0x5c,0x0d,0x2e,0xc9,0xff,0xef,0xc8,0x45, + 0xec,0x7b,0xde,0x6f,0x7e,0x9e,0xa5,0x4d,0xfe,0xde,0x15,0x4d,0x2d,0xc7,0x51,0xfb, + 0xf6,0xc1,0x5f,0x85,0x91,0xc3,0xdf,0xb9,0x80,0xca,0x3d,0xd2,0xa5,0x4b,0xda,0xb6, + 0x04,0xf7,0x32,0xb1,0x7c,0xfa,0x07,0xd8,0x37,0xe0,0xfc,0xd3,0x9f,0x3d,0x2d,0xff, + 0xbe,0x49,0x1b,0xd1,0x2c,0x39,0xa9,0xb9,0xcb,0x81,0xd1,0x22,0x49,0x49,0xf6,0xba, + 0x67,0xcd,0xb1,0xce,0xe3,0x13,0x61,0xcf,0xc8,0xd2,0x45,0xa2,0x58,0xae,0xc6,0x8a, + 0x89,0x8b,0xa4,0x25,0x79,0x2e,0xf1,0x75,0xe5,0x6e,0xd1,0x54,0xf1,0x8b,0xd7,0xbe, + 0x25,0xa8,0xcb,0x45,0xd9,0x9c,0xdd,0xb7,0xf8,0x40,0xf3,0x1c,0x6a,0x89,0xb9,0xaf, + 0x70,0x52,0xf8,0xc6,0xfe,0x56,0x2e,0x52,0xc3,0x33,0xd0,0xfd,0x41,0xc4,0x9b,0x08, + 0x89,0x0b,0xcc,0x25,0xa1,0xbd,0x24,0x51,0x14,0x0b,0x26,0x51,0x2c,0x1a,0x56,0xc5, + 0xc7,0xb6,0x05,0x96,0x11,0x0e,0x49,0x09,0x42,0x00,0x73,0x79,0x4b,0x32,0xe4,0xdd, + 0xca,0x8b,0xa0,0x32,0x51,0x45,0x01,0x2f,0x34,0x1f,0x83,0x40,0xb2,0x5f,0x0a,0x42, + 0x62,0x8a,0x87,0xc6,0x05,0x65,0x5c,0xa0,0x50,0xcb,0xbc,0xbb,0x2c,0x71,0x45,0xd3, + 0x22,0xbb,0x49,0x67,0xc0,0x40,0x2d,0x58,0xc8,0x0d,0x40,0x72,0x60,0x5d,0x4e,0x79, + 0x5b,0x92,0xf7,0xb8,0x28,0xe1,0x2d,0x21,0x25,0xdd,0xd7,0x2e,0x15,0x50,0xf1,0x38, + 0x83,0x5a,0x00,0x4b,0xf6,0xa4,0x8d,0xf1,0x04,0xcd,0x9f,0xd8,0xc7,0x53,0xfd,0x8d, + 0x9c,0xb1,0xf8,0x8a,0xca,0xb9,0x48,0x7a,0x81,0xf7,0x7c,0x44,0x35,0xe1,0x4d,0x49, + 0x73,0x47,0xad,0x51,0xfa,0x24,0x99,0xdd,0x70,0x2a,0x68,0x53,0xc7,0x5c,0xd0,0xec, + 0xf5,0x3d,0x51,0x78,0x26,0x3f,0x4b,0x49,0xe4,0xf0,0x26,0xcf,0xd3,0xe8,0x39,0xfc, + 0xb4,0xef,0x10,0xb5,0xb8,0x6e,0x6a,0xf8,0x3c,0x5b,0x1d,0xd0,0x81,0x75,0x15,0xad, + 0x2f,0xee,0x29,0xf6,0xf4,0x9c,0x93,0xd3,0x93,0xc1,0x76,0xc4,0xd2,0x66,0xdc,0xf9, + 0x40,0x05,0x28,0xee,0x82,0x04,0x78,0x66,0xa4,0xbd,0x8a,0xb8,0x17,0xf0,0x45,0x34, + 0xd7,0x49,0x28,0x4b,0xda,0x72,0xca,0xe5,0x29,0x29,0xc9,0xf7,0xa0,0xf9,0x5a,0x42, + 0x21,0x62,0x72,0x14,0x4d,0x72,0x45,0x2e,0x31,0x0e,0xf7,0x6d,0x99,0x5f,0xf9,0x87, + 0x36,0xf3,0xd2,0xbe,0x69,0x36,0x31,0x92,0xd3,0x23,0x8f,0x5f,0x5e,0xa6,0x18,0x8a, + 0x06,0xba,0xb0,0xc8,0xd0,0xc8,0xac,0x38,0x88,0x63,0xdb,0x19,0xbb,0xe6,0xc5,0x1a, + 0x76,0xf9,0xba,0xdf,0x31,0xdf,0x91,0x28,0xf3,0x14,0x87,0x68,0xd6,0xd4,0xdd,0x0d, + 0x55,0x93,0x8a,0x5d,0xfb,0x36,0xc0,0x6d,0x77,0xc5,0xcd,0x92,0x5d,0xef,0x0e,0x16, + 0x23,0xdc,0xd1,0x08,0x66,0x16,0xee,0xca,0x99,0xd8,0xc8,0x27,0xd9,0x91,0x71,0x39, + 0xd3,0x36,0x54,0xe9,0x17,0x02,0x74,0x0f,0x17,0x36,0xf9,0xab,0x75,0x32,0x53,0x16, + 0xbf,0xf5,0xa4,0x5e,0x07,0xca,0xea,0xd7,0xce,0x91,0xba,0x55,0x53,0x37,0x4a,0x6c, + 0xcb,0xbf,0x82,0xba,0x6c,0x96,0x32,0x9a,0x48,0xc4,0x08,0x5f,0x5e,0x5f,0x68,0x2a, + 0xe3,0x03,0x0a,0xcf,0xd2,0x77,0x8d,0xf2,0x78,0xfe,0x21,0x5f,0x7c,0x97,0xdd,0x6b, + 0x12,0x14,0x7e,0xa8,0xd9,0x0d,0x5e,0x1a,0x46,0x99,0xf4,0x7f,0x15,0xa1,0x75,0x27, + 0xc3,0x64,0xaf,0xa3,0x9b,0xd0,0x6b,0x6f,0xce,0xcf,0x51,0x6a,0xa3,0x39,0x8e,0x86, + 0x24,0x51,0x47,0xcb,0xe9,0xbe,0x60,0x4f,0xb6,0x30,0x26,0x25,0x81,0x2c,0x1b,0x80, + 0x96,0xef,0xdf,0xb4,0xcb,0x56,0xdb,0xfa,0x81,0xf6,0x21,0x57,0x2b,0x0d,0x15,0x1a, + 0x82,0xa4,0x7c,0xe8,0x11,0xd0,0xfc,0xc3,0xfb,0xaa,0xa9,0xcf,0x0a,0x2d,0x85,0x46, + 0x9f,0x71,0xff,0x10,0x27,0x3d,0x0a,0xa1,0x55,0xd2,0xd7,0x24,0x7a,0xe6,0x31,0xa8, + 0xa8,0xb6,0xf6,0x28,0xed,0xa0,0xf5,0x01,0x18,0x15,0xa6,0xc5,0xad,0x57,0xd1,0xd8, + 0xe6,0xbc,0xab,0xcd,0xa1,0x86,0x3a,0x16,0x8a,0x38,0x3b,0xd2,0xc6,0x21,0x76,0xab, + 0xa6,0x9e,0x96,0x89,0x1d,0x3d,0xee,0xf2,0x59,0x42,0x2c,0xba,0x11,0x1b,0xd6,0x8a, + 0x0d,0x85,0x53,0x92,0x14,0xca,0x2b,0xbb,0xd3,0xb2,0xc9,0x5e,0x4d,0x92,0x82,0x49, + 0x92,0x86,0xb0,0xc2,0x1e,0x94,0xd4,0xfd,0x5a,0x74,0xa6,0x07,0xc2,0xcd,0x36,0xfb, + 0x8c,0xb0,0xa0,0xb0,0xa0,0x75,0x7b,0x14,0xff,0x21,0xde,0x5b,0xf8,0x88,0x8e,0xef, + 0xbf,0x96,0xc6,0x44,0x4b,0x38,0x3f,0x4b,0x86,0x0d,0x26,0xeb,0x63,0x95,0x02,0x1b, + 0x4c,0x41,0x45,0x68,0xf9,0x5f,0x4b,0x0e,0x25,0x64,0xa2,0x9b,0x29,0x9d,0x57,0x21, + 0x5c,0xb3,0x1f,0x5d,0x8c,0x8a,0x52,0x77,0xa5,0x87,0x9a,0x6a,0xb3,0xf4,0x8e,0x47, + 0x99,0x7d,0x9b,0x77,0x42,0x7f,0xd6,0x1c,0x05,0xbe,0xba,0x04,0x11,0xc7,0xf9,0xf0, + 0x83,0xf3,0xe9,0x23,0x1e,0x1a,0x3b,0x5c,0xb2,0x82,0x3b,0xf4,0x6f,0xfe,0xc1,0xf9, + 0xb9,0x69,0x2a,0xb7,0xa9,0xdd,0xa2,0xc9,0x8e,0xdc,0x79,0xe6,0x34,0x87,0x33,0x79, + 0xe7,0x2e,0xcf,0x58,0x53,0x96,0x0e,0xad,0x9d,0x8c,0xb4,0x82,0x9e,0xc0,0xe1,0x07, + 0x00,0xb1,0x70,0x7e,0xf8,0x70,0x61,0x5f,0xac,0x76,0xf4,0xf4,0x5f,0x06,0xdd,0xb4, + 0xb7,0x19,0xa8,0x89,0xe7,0xe0,0xbf,0x18,0x4c,0x2f,0x1e,0xa7,0xa2,0x6f,0xcf,0xf2, + 0x10,0xce,0xf6,0xe9,0xf2,0xb6,0xc3,0x09,0xa2,0xdf,0x5c,0xaa,0x4c,0xa1,0x25,0x0c, + 0x6a,0xb1,0xe8,0x65,0xb6,0xca,0x29,0x13,0xef,0xfd,0xa1,0x97,0xc1,0xd4,0xa1,0x98, + 0xd0,0xa2,0x0e,0xb6,0xaf,0xfb,0xab,0xa2,0xed,0x19,0xcd,0x13,0xfc,0xe3,0x0a,0xa8, + 0xe4,0x8c,0x00,0xdc,0x72,0xac,0x6a,0x1e,0x33,0x68,0x81,0x88,0x67,0xf4,0x50,0x6e, + 0x41,0xcb,0x72,0x59,0xd1,0x5a,0xfa,0xb1,0x67,0x1f,0x53,0x8d,0xa5,0x5f,0xb0,0xc5, + 0x42,0x79,0x84,0xa0,0x8f,0x13,0xdf,0x2e,0x0a,0x53,0x27,0xee,0x49,0x18,0x35,0xfa, + 0x42,0x92,0x83,0x88,0x7f,0x99,0xae,0x87,0x12,0x18,0xd4,0xaf,0x2f,0x5a,0x56,0x78, + 0xb5,0x2c,0xe9,0x84,0x66,0x92,0x6a,0x1d,0x92,0x82,0x8d,0xed,0x24,0xf0,0x58,0x47, + 0x49,0xa1,0xeb,0x95,0x1d,0xc1,0xf5,0x1b,0xf0,0xf9,0x06,0xca,0x48,0x5d,0x70,0x93, + 0x14,0x62,0xdd,0x3d,0x96,0x71,0x4c,0xe4,0x2a,0x0a,0x06,0x79,0x3c,0x63,0x33,0x8c, + 0x1d,0x91,0x1a,0x7b,0x07,0x09,0xae,0xac,0x5f,0xbb,0xb1,0xcb,0xed,0x45,0xaa,0x9e, + 0xb5,0xb0,0x3c,0xdb,0x72,0x6d,0x3f,0x63,0xea,0xf9,0x6c,0xc8,0xb2,0x0b,0x8d,0x39, + 0x64,0x0d,0x23,0x2a,0xed,0x93,0xa7,0x01,0x2b,0xe9,0x85,0x2f,0x05,0x3f,0x56,0x9d, + 0xe5,0xaa,0xc6,0x99,0x96,0x5c,0xc9,0x9a,0xb3,0x1d,0x9d,0x54,0xfa,0x8b,0xaf,0x3e, + 0xad,0x0a,0x1d,0x4f,0x86,0xf9,0x61,0x7b,0x36,0x36,0xda,0x6c,0xe3,0x82,0x81,0xc8, + 0x0e,0x08,0x0c,0xb5,0x52,0x6f,0xe8,0x25,0x7c,0x1f,0xa2,0x23,0x7f,0xf8,0x41,0x42, + 0xbe,0xbd,0xdb,0x04,0x6a,0x3f,0x3f,0x7f,0x55,0x48,0x58,0xe7,0xd0,0xe2,0xdd,0xed, + 0x4b,0xef,0x58,0xc9,0xd9,0x4d,0x41,0x9c,0x01,0x6a,0x3b,0xe9,0x7e,0xc1,0x4c,0x5f, + 0x41,0x56,0x3a,0xe4,0xa4,0x76,0xd8,0xf8,0x52,0x24,0x34,0xb7,0xd2,0x3e,0x4c,0x88, + 0xf7,0x12,0x15,0x8b,0x55,0xa4,0x9c,0x12,0xa8,0x95,0x72,0x8a,0x7d,0xd9,0x5d,0xd3, + 0x76,0x06,0x25,0x41,0x5f,0x98,0x5c,0xe8,0x0e,0x83,0x9b,0x01,0x04,0x18,0x68,0x0d, + 0xbd,0xc7,0x8d,0x3d,0x2f,0xaf,0xdb,0x49,0xca,0xa5,0xc7,0x11,0x90,0x34,0x58,0xe8, + 0x88,0x77,0xa9,0x60,0x46,0xd8,0xe8,0x01,0xa9,0x67,0x6d,0x49,0xb6,0x0d,0x22,0xd8, + 0xe3,0x04,0x48,0x5a,0x73,0x10,0xc3,0x54,0xc2,0x72,0x4a,0x56,0xe6,0x8d,0x1e,0xb6, + 0x07,0xb4,0xf2,0x23,0x9e,0xf4,0xc7,0xb8,0x70,0x82,0x5a,0x70,0x93,0x92,0x63,0x9c, + 0x42,0xd1,0x30,0xe8,0xb4,0xe4,0x9e,0x9e,0x12,0x1b,0x89,0x3e,0xc0,0x26,0xa8,0xbd, + 0xf8,0xa0,0xc9,0xdb,0x19,0x8e,0x62,0xe4,0x01,0xb1,0xab,0x30,0x42,0x2d,0x92,0x0c, + 0x18,0x61,0x66,0xf2,0x33,0xce,0x0e,0x90,0xbd,0x42,0xfe,0xe3,0xd1,0x4e,0x53,0xd0, + 0x0a,0xa7,0xd7,0x6a,0xfc,0x15,0x6a,0x81,0x8f,0x0a,0xdb,0xa7,0x3b,0xa9,0xa8,0xaf, + 0x6a,0x45,0x6b,0x95,0x98,0x3f,0xaa,0xbe,0x43,0x5f,0xdb,0x93,0x61,0xb9,0x8d,0x2f, + 0x17,0xc5,0x33,0x53,0xd9,0xfd,0x8d,0x5d,0x22,0x59,0x9e,0x38,0x99,0x24,0x7b,0xec, + 0x8d,0x54,0x36,0x61,0x12,0xb9,0xe2,0x90,0x75,0x5f,0xaf,0xb5,0xac,0x7d,0xb1,0x64, + 0x0e,0x49,0x4b,0xc8,0x3b,0xad,0xb6,0xab,0x48,0x63,0x94,0x43,0x41,0x8e,0xa5,0x18, + 0x1e,0x53,0x75,0x56,0xd0,0xe9,0x69,0x44,0x2e,0xf5,0x85,0xfb,0x0a,0x0f,0x1e,0xf3, + 0x5d,0x59,0xf5,0xa3,0x15,0xa5,0x8e,0xc6,0xb6,0x5e,0x0f,0x9c,0x28,0x72,0xf4,0x04, + 0x4c,0xd0,0x8c,0x94,0xae,0x92,0x69,0xec,0x5f,0x11,0x58,0x35,0x83,0x48,0x70,0x2f, + 0x25,0x69,0x5e,0x17,0x8e,0x3f,0xca,0x48,0x4c,0x9e,0xe1,0x02,0x0d,0x11,0x18,0x7b, + 0x04,0xa4,0x5c,0xf6,0x15,0x98,0xb8,0x02,0x1d,0x18,0x39,0x41,0x4a,0xd8,0xcd,0xe4, + 0x0b,0xfa,0x06,0xf9,0xc5,0xc4,0xbc,0x84,0x29,0xb6,0x78,0x49,0x9f,0x18,0xdf,0x9a, + 0x09,0x81,0xf7,0x95,0x46,0x05,0xda,0xea,0x64,0x71,0x75,0xd3,0x48,0xdf,0xeb,0x55, + 0xd2,0x91,0xbc,0xcb,0x9e,0xd5,0xf0,0x47,0x07,0xea,0xd3,0x33,0x27,0x05,0xb8,0x84, + 0x01,0x71,0x95,0xdf,0xe9,0xf3,0x72,0x99,0x26,0x69,0x81,0xa2,0xeb,0xb8,0x1b,0xa5, + 0xa5,0xe4,0x6e,0x84,0xad,0xf8,0x61,0x18,0xa6,0x8c,0x77,0x4e,0xda,0x8d,0x5d,0xbc, + 0xf1,0x72,0xc5,0xdb,0x3e,0x4e,0xe1,0x64,0xd9,0x88,0xee,0xf1,0x9a,0xd1,0x6a,0xee, + 0x58,0x55,0x9b,0x7c,0xdf,0x83,0x95,0x07,0x89,0x87,0xd2,0x8f,0xdd,0xd7,0xa0,0x4c, + 0xd3,0xd3,0xd2,0xb2,0x34,0xe7,0x3d,0x2b,0x94,0x6d,0x3d,0x4b,0xed,0xbf,0xa3,0x91, + 0xf2,0x0d,0x7d,0xb8,0x10,0xaa,0x1e,0xc1,0x5f,0xd6,0x52,0x14,0xc4,0x82,0xd0,0x72, + 0x79,0x79,0x94,0xdc,0xcd,0x7e,0x51,0xab,0x51,0x50,0xcf,0x84,0x8a,0x47,0xa0,0x62, + 0x5a,0x3d,0x0d,0xd6,0xca,0xbc,0x05,0x2d,0x81,0x7f,0x57,0x4d,0x11,0x7a,0x66,0x4d, + 0xa1,0x35,0x04,0xe1,0x4e,0x3b,0xe7,0x69,0xc5,0x1d,0x58,0x68,0x70,0x05,0x31,0x99, + 0xe6,0x68,0x6c,0x1f,0xf1,0xae,0xdf,0xaf,0x2c,0x88,0xc6,0x50,0xcf,0x77,0xf6,0x31, + 0x7a,0x1d,0xef,0xc6,0x29,0x32,0x3a,0x8e,0x47,0x12,0xb3,0x8c,0xd4,0x27,0xc2,0x3b, + 0x3b,0x7f,0x8a,0xd0,0xe1,0x0f,0x48,0x96,0x87,0xd5,0x20,0x1e,0x2f,0x20,0x0c,0x98, + 0x0f,0x75,0x68,0x30,0x60,0x0e,0x43,0xfe,0xd0,0x83,0x22,0x42,0x8f,0x74,0x87,0x27, + 0x8a,0x87,0x3e,0x60,0xa1,0xb3,0xbf,0x50,0x11,0x97,0xe4,0xda,0xec,0x1e,0xc2,0xf4, + 0xd4,0x02,0x74,0x33,0xbc,0xf7,0x8a,0x56,0x13,0xe5,0x7b,0x4a,0x30,0x04,0xcd,0x2b, + 0x52,0x96,0xdd,0x44,0x92,0xcc,0xa5,0x34,0x5a,0x52,0x43,0xf9,0xcd,0x1e,0x78,0x3a, + 0x46,0x7d,0xad,0x7f,0x17,0xbb,0xfd,0x1d,0x80,0xcc,0x31,0xcd,0xe3,0x31,0x24,0xb8, + 0xd8,0x42,0xff,0xb5,0xca,0xe3,0x5f,0xfe,0xc6,0xc2,0x32,0x53,0x27,0x1c,0x21,0x3c, + 0xc7,0x47,0xc9,0x1e,0x2e,0x54,0xe7,0xb4,0xd7,0xe1,0x30,0x3a,0x1d,0x6e,0xd2,0x1a, + 0x74,0x4e,0x3d,0x67,0xa7,0x54,0x4a,0x81,0x11,0xd0,0x4e,0x34,0x2e,0x37,0x76,0x18, + 0x32,0xd6,0x3b,0x54,0xab,0x87,0x3e,0xcc,0x0a,0x26,0x81,0x25,0x18,0x2d,0xc2,0x1b, + 0x10,0xbb,0x4b,0x68,0xa4,0xdf,0x0d,0xe1,0x62,0x9c,0xb0,0x60,0xbe,0xb1,0x09,0x75, + 0x71,0x80,0x39,0xfe,0x8d,0xaf,0xea,0x09,0xdd,0xe7,0xbf,0x3e,0xbb,0xf2,0xcd,0xe2, + 0x9a,0xc5,0x84,0x93,0x05,0xcd,0xeb,0xd0,0x37,0xab,0xee,0xd8,0xc3,0x4d,0xd1,0xfb, + 0x69,0xb6,0x51,0x96,0x99,0xe5,0x47,0x30,0x5d,0x18,0x25,0xb7,0x4e,0xf7,0x8b,0x77, + 0x3a,0x6b,0xb2,0x2f,0xe9,0x8c,0x86,0x84,0x99,0x09,0xca,0x51,0xca,0x67,0xcc,0x0f, + 0x5d,0xb0,0x69,0x52,0x23,0x6f,0xea,0xc6,0xce,0xca,0xa8,0x1e,0xab,0x49,0x4c,0xef, + 0xa1,0x67,0x34,0x03,0xb0,0x52,0xbd,0xa1,0x35,0x9d,0x7e,0xb5,0xb4,0xee,0x5d,0x6b, + 0x60,0xd6,0xb8,0xc1,0xad,0xc8,0x59,0x7f,0xc9,0xc2,0xa5,0xac,0xed,0x26,0xa0,0x5d, + 0xe4,0x91,0x9a,0x56,0x17,0xaf,0xcf,0x1c,0x9f,0x3b,0x08,0x82,0x30,0x87,0xd6,0x05, + 0x5e,0xbe,0x43,0x32,0x55,0x1c,0xc8,0x8b,0x8b,0x57,0x78,0x2f,0x18,0xa9,0x80,0x3b, + 0xac,0x13,0x4d,0x77,0xd3,0x22,0xd6,0x08,0x22,0xe0,0x79,0xbd,0xf1,0x72,0x90,0xed, + 0x34,0x49,0x07,0x30,0xe6,0x22,0x23,0xba,0x71,0x86,0x30,0xe8,0x1c,0x0c,0x7b,0x46, + 0x3b,0x1c,0xca,0x67,0xa3,0x5e,0x95,0x90,0x5e,0x4f,0x9d,0xa5,0x61,0x26,0xd3,0x1e, + 0xe9,0x6c,0x04,0xa3,0x42,0xc8,0x7b,0x24,0x2a,0xa8,0xb3,0xbf,0xe4,0xf5,0xf1,0xfd, + 0x64,0xd8,0xb7,0xfd,0x34,0xae,0x4c,0xbb,0xb1,0x61,0x18,0x9a,0xc2,0x70,0xf2,0xf1, + 0xbb,0x41,0xf9,0x1e,0x3a,0x53,0x3f,0x7f,0x45,0xab,0xb6,0x61,0x82,0xd4,0x2a,0x5a, + 0x35,0x02,0xac,0x4a,0xd0,0xf6,0x91,0x0f,0x25,0x3d,0xbb,0x51,0x53,0x48,0xa5,0x2e, + 0x93,0xf7,0x0b,0x02,0x58,0xd5,0xb9,0xae,0x28,0xe2,0x79,0xbe,0x05,0x0f,0x48,0x22, + 0x07,0x39,0xad,0xe2,0xf9,0x26,0xdf,0x66,0xbb,0x02,0x87,0xea,0x7b,0x80,0x68,0x47, + 0x36,0x85,0x1a,0xee,0x59,0x2d,0x87,0xdb,0x2c,0xd8,0x00,0x0e,0x81,0x31,0xec,0x4a, + 0x6c,0xd3,0x6d,0x80,0xc3,0xcb,0xc7,0x11,0xb0,0x4e,0xd7,0xa1,0x3f,0xb8,0xef,0x9b, + 0x7b,0xa9,0x07,0x7e,0x30,0xa0,0x48,0x14,0x13,0x17,0x57,0xf3,0xc0,0x0b,0x76,0xeb, + 0x60,0xe2,0xd2,0xaa,0x77,0x5b,0x05,0xa9,0x68,0xf9,0x1e,0x0f,0x2e,0xfc,0xfe,0xe1, + 0x8f,0xff,0x4a,0x3e,0xbb,0x7f,0x0f,0xfb,0x63,0x49,0xd8,0xf8,0xfe,0xef,0xe9,0x2f, + 0x69,0x0a,0x97,0x8c,0xc9,0xc1,0x75,0x4f,0xb7,0x1b,0x41,0x84,0x69,0xea,0xf6,0xe8, + 0xaa,0x31,0x1a,0xaa,0x2d,0xfe,0x71,0x73,0xca,0x20,0x53,0x76,0x78,0xc9,0x5e,0x2d, + 0x0d,0x98,0xf5,0xdb,0xb7,0xbb,0xd3,0xc1,0x34,0x8e,0x00,0x93,0x59,0x7d,0x97,0xf8, + 0xdc,0x3b,0x49,0x09,0x84,0x30,0x0e,0x8b,0xee,0x22,0x8b,0xe1,0x7d,0xc7,0xe7,0xcb, + 0x07,0x0e,0x78,0xdf,0xe4,0x66,0x25,0xed,0x7a,0xa1,0x9a,0xea,0x8c,0xbb,0xdc,0xc3, + 0x63,0x21,0x7c,0x67,0x36,0xdd,0xac,0x2e,0xc3,0x50,0x5c,0xbe,0xef,0x6f,0xfc,0x7c, + 0x64,0x73,0xb6,0x94,0x6e,0xf8,0xae,0x76,0xc1,0x28,0xa8,0xa3,0x22,0x2d,0x6e,0x28, + 0x1a,0x15,0xa8,0x31,0x69,0xde,0xf1,0x21,0x5a,0x56,0xee,0x38,0xa1,0x20,0x64,0xbd, + 0x5e,0x5b,0x6d,0x30,0x24,0xc0,0x3a,0x7d,0x98,0x68,0x6a,0x8a,0x11,0xd6,0xce,0x6a, + 0x14,0x59,0x48,0x4d,0xdc,0x12,0x8b,0x62,0x74,0x49,0x3c,0x5f,0xe7,0x21,0x89,0x88, + 0xde,0xdb,0xdc,0x9a,0xc1,0x5a,0x2b,0xdc,0x77,0x95,0x92,0xd8,0x9f,0x89,0x0c,0xf2, + 0x9d,0x44,0x7f,0xe7,0xa2,0x97,0xf5,0x57,0x4a,0xf8,0x5e,0x34,0xc7,0xec,0x60,0x9c, + 0xf0,0x09,0xbf,0x62,0x30,0xd3,0xce,0x96,0x81,0xab,0xbe,0x53,0xc0,0x9b,0x38,0x37, + 0x65,0x40,0x5e,0x63,0xf5,0xd7,0xc5,0x09,0x63,0xa7,0xb3,0xca,0xaa,0xbc,0x27,0x08, + 0x5b,0x89,0xe3,0x57,0x56,0xdb,0xf2,0x93,0xf3,0x64,0x8a,0x54,0x59,0xff,0x62,0xb0, + 0x8b,0x41,0xab,0x01,0x6e,0x01,0xb6,0xbb,0xed,0xe0,0x2d,0xb0,0x11,0xff,0xe4,0xc4, + 0x70,0x3f,0x7f,0xe7,0x9d,0xad,0x34,0xe6,0x0a,0xa9,0xb9,0x5d,0x6f,0x41,0xab,0x28, + 0x82,0x4a,0xbf,0x24,0x75,0x76,0x68,0xd8,0x44,0xbb,0xb9,0x5f,0x6c,0x5c,0xac,0xdc, + 0xfa,0x3c,0x7a,0x33,0x3f,0xee,0xed,0xb6,0xf0,0xdd,0x36,0x91,0x91,0x6c,0x2a,0x2c, + 0x71,0xbb,0x9c,0x5b,0x86,0xe1,0xe9,0xb0,0xb0,0x24,0x3d,0x74,0x7b,0xe0,0xaf,0x7d, + 0x62,0x84,0x7a,0xdb,0x88,0x86,0x17,0x7e,0xae,0x4a,0x7f,0x83,0x70,0xf4,0xd5,0x54, + 0x14,0xa9,0x74,0x72,0x3f,0x7d,0xb7,0x31,0xb0,0xf8,0x94,0x70,0x28,0xa9,0x61,0xe1, + 0x91,0xb6,0x70,0x4b,0xe1,0xf9,0xde,0x49,0x0d,0xdb,0x33,0x83,0x5d,0xe4,0xe9,0xf2, + 0x76,0x9e,0x15,0xb0,0x96,0xce,0x7f,0xa4,0x72,0xfd,0x76,0xe7,0x38,0x94,0x1f,0x66, + 0x2f,0x56,0x3b,0x66,0xa2,0x6e,0xed,0xf7,0x53,0xf3,0x3b,0x9d,0xc4,0x8e,0xcb,0xa6, + 0x83,0x09,0xa7,0x1c,0x4c,0x32,0xfb,0x9e,0x42,0x8d,0xef,0x47,0xa9,0xf9,0xdc,0x87, + 0x20,0x5d,0x13,0x53,0x26,0x2a,0xf7,0xc4,0xcf,0xd8,0xd4,0x65,0xac,0x41,0xa6,0xde, + 0xef,0xa4,0xa6,0x4d,0xe9,0x49,0xaa,0x27,0x77,0xe9,0x4b,0x4a,0xae,0x66,0x88,0x92, + 0xf9,0x0e,0x6f,0xad,0xaf,0xc9,0xbf,0x59,0xcb,0xf4,0xf9,0x2d,0x37,0x04,0x3e,0x61, + 0xdb,0x73,0xb5,0x8a,0xd6,0x13,0x97,0x5a,0xb7,0xb2,0xca,0x28,0xf5,0x4d,0x2f,0x7c, + 0xb7,0xf4,0x57,0xf7,0x16,0xb3,0x81,0x33,0x36,0xaf,0xdb,0x93,0x8c,0x30,0x10,0xee, + 0x17,0xb0,0x19,0x5c,0x99,0xc7,0x9e,0x29,0x1e,0x04,0x60,0x2c,0x8c,0x25,0x63,0x33, + 0x38,0x34,0xa5,0x5c,0xa8,0x25,0x10,0xbe,0x44,0xdb,0xcd,0xd6,0x58,0xa4,0x9b,0xf4, + 0xf7,0x5d,0xcf,0xbe,0xe9,0x6c,0xe6,0x07,0x9a,0xf9,0x0f,0x06,0xa5,0xcd,0x48,0x4e, + 0x36,0xcf,0xed,0x20,0x35,0x1d,0x94,0xf6,0x8d,0x1d,0x8d,0x14,0x8f,0xa6,0xe3,0x91, + 0xb1,0xcd,0xbe,0x8f,0x08,0x47,0xf7,0x11,0x7a,0x71,0x56,0x54,0xdd,0xd7,0x08,0x43, + 0x0f,0x69,0x55,0x33,0x2a,0xeb,0xb3,0x92,0x50,0x2b,0xa3,0x08,0xfc,0x9d,0x5f,0x58, + 0x8a,0xac,0x9b,0x14,0x2a,0xc7,0x37,0x50,0x71,0x56,0x07,0x93,0x58,0x7d,0xc8,0x20, + 0x8d,0x45,0xcf,0x36,0xd8,0x52,0xd6,0x5a,0xe4,0xe4,0x25,0xdd,0x66,0x9b,0xe4,0xf1, + 0x30,0x79,0x6d,0x43,0x29,0x1a,0xfb,0x43,0xeb,0xe5,0x3a,0x3b,0xf4,0x5d,0x3d,0x8c, + 0x20,0x52,0x4e,0xaa,0xb9,0xef,0xfa,0xce,0x0f,0x8e,0xb9,0x64,0x31,0x42,0xc3,0xee, + 0xd5,0x4d,0x0b,0x7f,0xb8,0xef,0xfc,0x05,0x8a,0xed,0x1b,0xfa,0xd5,0x0b,0x54,0x83, + 0xed,0xa9,0xa8,0xad,0x06,0xc7,0xcd,0x8f,0x28,0xda,0x63,0xfc,0x33,0x2a,0xe0,0x0c, + 0x18,0x3a,0x1d,0xfb,0x06,0xfd,0x1e,0x88,0x38,0x0d,0xa2,0xb5,0x67,0xe5,0xf8,0xb3, + 0xc9,0x2c,0x2c,0x54,0x5d,0x1e,0x3b,0x2a,0x59,0xd8,0xac,0xf6,0xcd,0xd0,0x43,0xe7, + 0xeb,0x34,0xd8,0x8d,0xf4,0x3e,0x28,0x36,0x69,0x18,0x25,0xda,0xe5,0x16,0xe0,0x91, + 0xc8,0x06,0x35,0x65,0x0d,0x91,0x6d,0x0e,0x59,0x49,0x5d,0x41,0xdb,0xaf,0x7e,0x2a, + 0x6a,0xf0,0x11,0x3b,0x22,0x76,0x68,0x0e,0x2c,0xde,0xdf,0xa0,0x3b,0xaf,0x69,0xde, + 0x0d,0x38,0x73,0xaf,0xbc,0xe9,0xeb,0x99,0xeb,0xf8,0x5e,0x15,0x38,0x1b,0x4a,0x27, + 0x34,0xca,0x40,0xef,0xd2,0x4b,0xfb,0xe9,0x43,0xff,0x49,0xfd,0xff,0xb3,0xf3,0xa4, + 0xcd,0x6d,0xe3,0x4a,0x7e,0x9f,0x5f,0xd1,0xc5,0xad,0x4a,0xec,0x5a,0x8b,0x96,0x64, + 0x59,0x71,0xc6,0xb1,0xa6,0x7c,0xe4,0xf0,0x6e,0xae,0x8d,0x3d,0xef,0xf8,0xb4,0x05, + 0x91,0x90,0xc5,0x0d,0x45,0x70,0x00,0x28,0xb6,0xe6,0xd7,0x6f,0x77,0x03,0x10,0x45, + 0xd3,0x54,0x68,0x4f,0x66,0xcf,0xf7,0xde,0xcc,0x48,0xc2,0xd9,0xe8,0x6e,0xf4,0x0d, + 0xbf,0xda,0xf7,0x4f,0x00,0xc8,0xbf,0xf0,0x0f,0x02,0xa4,0xc6,0x2f,0x58,0x4b,0x0b, + 0xae,0xc2,0x3f,0x1a,0x8e,0x23,0x70,0x56,0x0f,0x7f,0xe7,0x12,0xfe,0x33,0x75,0x77, + 0x12,0x71,0x4d,0xd2,0x08,0xff,0x89,0x80,0x82,0xf5,0x27,0x11,0xb1,0x76,0x04,0xc6, + 0x6a,0xf5,0x55,0x9e,0x44,0x55,0x14,0x23,0xb4,0xf5,0xc2,0x8a,0xa1,0x81,0xb5,0x60, + 0x22,0xca,0x93,0x88,0x4f,0x11,0xe1,0xc6,0x49,0xa6,0x93,0x5c,0x42,0x82,0xeb,0x0f, + 0x70,0x5c,0xb2,0x72,0x9f,0x1a,0x67,0xc5,0xc3,0xb0,0x51,0x73,0x69,0xbf,0xf9,0x3e, + 0xae,0x50,0x0a,0x3b,0x87,0xf4,0x24,0xfa,0xf0,0x22,0x7e,0x01,0xf8,0xaf,0x18,0xc3, + 0x18,0xfa,0xfe,0xff,0x47,0xf1,0xf8,0xc3,0x60,0x1c,0x1f,0xd4,0x3a,0x06,0xbe,0x63, + 0x14,0xbf,0x04,0xfc,0x57,0x0c,0xb0,0xc9,0x0d,0xe7,0xde,0x51,0x3c,0xfc,0x30,0x78, + 0x19,0x0f,0xee,0xf5,0x0d,0x7c,0x1f,0x6f,0xba,0x8f,0x08,0xc3,0x0f,0x34,0xc9,0x21, + 0xc9,0x85,0x31,0x27,0x11,0x57,0x1a,0x47,0x84,0xd3,0x01,0x64,0x29,0xfe,0xee,0x15, + 0x62,0x21,0xa3,0xf5,0x2b,0x07,0x44,0xfd,0xc0,0xcd,0xf0,0xdd,0x66,0x39,0x8d,0x26, + 0x89,0x2a,0x10,0x23,0x16,0x69,0xf5,0x6c,0xce,0x26,0xcb,0xf1,0xab,0x7d,0x1c,0x82, + 0x03,0xfd,0x07,0xd7,0x65,0xf8,0x2d,0xb8,0xd4,0x14,0x28,0xa0,0x10,0xf9,0x35,0xb8, + 0x25,0x9a,0x20,0x38,0x38,0x0c,0x47,0x3b,0x76,0x0f,0xe3,0xb9,0xe8,0xb5,0x36,0x3e, + 0x61,0xdf,0x18,0x7f,0x72,0x75,0x5e,0xe4,0x86,0x47,0xa0,0x0a,0x64,0xce,0xe4,0xeb, + 0x49,0xc4,0x66,0xc8,0xb9,0x1b,0xb4,0xb3,0x1b,0xfd,0x64,0x33,0x9b,0xe3,0x38,0xdf, + 0x02,0xbd,0x1e,0x98,0xaf,0x59,0x09,0x5c,0xed,0x0a,0xa2,0x48,0xa1,0x14,0xc6,0x4a, + 0x10,0x50,0x6a,0x49,0x19,0xa1,0x14,0x12,0x7e,0xcb,0x11,0xfd,0x24,0x74,0x26,0x7a, + 0x5c,0xc5,0x78,0x12,0x7d,0x2a,0x65,0x01,0x61,0xeb,0xc9,0xb3,0x1b,0x7b,0xfc,0xef, + 0xaf,0xf6,0xdd,0xde,0x81,0x25,0x99,0x09,0xa9,0x36,0x76,0x03,0x45,0xb9,0xa2,0x5b, + 0x46,0x11,0x92,0x28,0x9c,0x88,0x7e,0xf8,0x03,0x69,0x45,0x90,0x19,0x2b,0xec,0xd2, + 0x10,0x06,0x3c,0xba,0x9c,0x8f,0xce,0xf3,0xbf,0xf5,0x78,0x85,0xf5,0x64,0x9e,0x57, + 0x27,0x1a,0x05,0xd2,0x99,0x66,0xc3,0xc9,0x69,0xba,0xc8,0x0a,0xe0,0x19,0x08,0xd2, + 0x90,0x18,0x0b,0xf8,0xd6,0x9c,0x44,0x8d,0xa0,0x56,0x8b,0x44,0xf0,0xea,0x89,0xef, + 0x7f,0x34,0x79,0x4d,0xb8,0x04,0x3b,0xcf,0x0c,0x14,0x2a,0x95,0xcf,0x0d,0x08,0xde, + 0x22,0xd4,0x4e,0xc6,0xaf,0xf6,0x4b,0xdc,0x85,0xa2,0x72,0x1b,0xc7,0xa5,0x9f,0xf7, + 0x80,0x9c,0xe1,0xf1,0x18,0x93,0x80,0x9d,0x61,0x5c,0x79,0x8b,0x80,0x7f,0xf6,0x4b, + 0xbd,0xda,0xe7,0x7e,0x9c,0xc6,0x05,0x1d,0x9e,0xba,0x61,0x23,0x47,0xfc,0x6a,0x1a, + 0x57,0x19,0x27,0x6a,0x51,0xe6,0xd2,0xe2,0x30,0x14,0x83,0x5a,0xe2,0x01,0xfd,0x70, + 0xdf,0xcf,0x86,0x97,0x43,0x6b,0x83,0xaf,0x50,0xe1,0x04,0x0e,0x42,0x26,0x5e,0x64, + 0x76,0x73,0x07,0xea,0x9c,0x5c,0xa1,0x69,0x0b,0x59,0x11,0xa8,0x5c,0x3f,0x8f,0x0f, + 0x38,0xd6,0x66,0x61,0x5b,0x45,0xc4,0x7d,0x42,0x02,0x7d,0xfa,0x9f,0x9e,0xa8,0x0d, + 0xf2,0xde,0x66,0xbf,0x23,0xfd,0xb6,0xd1,0x97,0x99,0x87,0x47,0x27,0x85,0x70,0xac, + 0x34,0xb9,0x2c,0x90,0x28,0x12,0xfe,0x9a,0xbd,0xc9,0xc0,0xb0,0x09,0x8e,0x34,0x51, + 0xe5,0xb2,0xfc,0x05,0x2e,0x2d,0x4e,0x54,0x46,0x1a,0xc8,0x66,0xb0,0x52,0x4b,0x0d, + 0xe5,0x5c,0x15,0x12,0x4c,0x2e,0x65,0x69,0xe2,0x9f,0x5e,0x09,0x98,0x6b,0x39,0x3b, + 0x89,0xfe,0x69,0xe3,0xce,0xe0,0xdc,0x4f,0x4b,0xbb,0xb3,0x7b,0xac,0xa5,0x5d,0xea, + 0x02,0x66,0x22,0x37,0x32,0x0a,0xbc,0xd3,0x74,0x3f,0xa2,0x09,0xdf,0x87,0xac,0x70, + 0x3b,0x4c,0xb5,0xba,0x35,0x52,0xbf,0xda,0x17,0x13,0xb0,0x0a,0xbe,0xe2,0x4e,0x7e, + 0x6b,0xad,0x6e,0xb4,0x34,0x26,0x66,0x3c,0xd4,0xcf,0xc5,0xf9,0x05,0x44,0x58,0xc6, + 0x67,0x33,0xb6,0x1c,0xac,0xb1,0xa0,0x0a,0x42,0x64,0xb6,0xd1,0x37,0xbc,0xdf,0x70, + 0x70,0xbf,0x61,0xe4,0x1b,0xaa,0x8d,0xb8,0xe7,0xf6,0xf7,0x41,0xfb,0x7d,0xb9,0x42, + 0x10,0x60,0x00,0xcf,0x16,0x59,0x9a,0x2a,0x7b,0xcc,0xf8,0xfc,0x21,0x17,0xc7,0x6f, + 0x8d,0xd4,0x9d,0x65,0x28,0xb0,0xca,0x55,0x34,0x39,0x77,0x52,0xb2,0xba,0x4c,0x84, + 0x29,0x46,0x12,0x53,0xb1,0x90,0x16,0x19,0xf7,0x2b,0x18,0x05,0x19,0x52,0x50,0x14, + 0xa0,0xa5,0x48,0xe6,0x4c,0xe6,0x0f,0xff,0x76,0x7d,0x0d,0x88,0x5f,0x34,0xa2,0x09, + 0x93,0x65,0x93,0x3f,0xf0,0xec,0xd3,0xc9,0x67,0x96,0x5f,0x28,0x86,0xe9,0x8e,0xe1, + 0xf4,0x05,0x76,0x40,0x2a,0xcb,0x5c,0xad,0x16,0xb2,0xb0,0xbf,0x20,0x27,0x4f,0xe0, + 0x9a,0xb6,0x77,0x4c,0x07,0x56,0x1a,0x6b,0x2a,0x46,0x72,0x11,0x14,0x9c,0x38,0x55, + 0xca,0x3a,0xa1,0x9d,0x0a,0x2b,0x7a,0xac,0xec,0x0e,0x86,0x2f,0xc6,0x47,0xd1,0x04, + 0x96,0x45,0x2e,0x8d,0x21,0xc0,0x41,0xe4,0x46,0xd1,0x13,0xbc,0xe2,0x46,0xf2,0x22, + 0x66,0xce,0xd2,0xf3,0xf5,0xd5,0xe7,0xde,0xc7,0x4f,0x7f,0xe5,0x9e,0x42,0xe6,0x5e, + 0xae,0xc7,0x70,0x39,0xe3,0x51,0x15,0x40,0xeb,0x33,0x33,0x42,0x2c,0x88,0x6f,0x22, + 0xcb,0xc9,0xc4,0x81,0xb9,0xd4,0x72,0x0f,0x96,0x46,0xc2,0xaf,0x57,0x67,0x74,0xf2, + 0x4c,0xe4,0x20,0x2c,0xe0,0x21,0x9d,0x6c,0x8e,0x17,0xd2,0xcc,0x13,0x84,0x36,0xce, + 0x14,0x1f,0x8b,0xe4,0xb8,0x5e,0x16,0x34,0x82,0x3c,0x5e,0xc2,0x7b,0x6c,0x4c,0x96, + 0x42,0x1c,0xc7,0x61,0x40,0xad,0xb3,0xbc,0x5d,0xf7,0xc5,0x88,0x14,0xe9,0x48,0x42, + 0x15,0x27,0x8c,0x91,0x05,0x8e,0xb2,0x73,0x0a,0xe2,0x54,0xda,0xcd,0x6d,0x22,0xad, + 0xce,0x70,0x8c,0x98,0x91,0x64,0xac,0x0e,0xe3,0x38,0xbc,0x45,0xe8,0x4d,0x3e,0xfa, + 0x93,0x92,0x3a,0x85,0x9d,0xab,0xab,0xcb,0x8b,0x5d,0x2f,0xef,0xea,0x33,0xf0,0x1e, + 0xad,0x6f,0x9d,0x37,0x80,0xa3,0x7b,0x12,0xd1,0x49,0x1d,0x26,0x0c,0x5e,0xdc,0xf5, + 0x41,0xd7,0x2c,0xe7,0x7e,0xb0,0x78,0x14,0x65,0x66,0x45,0x8e,0xac,0x8b,0x37,0x6a, + 0x36,0x0b,0x32,0x53,0x53,0x0c,0xd8,0xb7,0xf8,0xad,0x9c,0xbf,0x1c,0x3d,0x24,0x24, + 0xc1,0xc8,0xa4,0x5a,0x3b,0x11,0x2c,0x1c,0xef,0xeb,0x5e,0x56,0x94,0x14,0x79,0xd3, + 0x2a,0xc7,0x69,0x3c,0x8c,0xd3,0x9e,0xbe,0x4b,0xde,0xe1,0xaf,0x54,0xe2,0x22,0x5e, + 0xb0,0xa8,0x62,0xa1,0x90,0xbc,0xe8,0x03,0x17,0x27,0x11,0xe7,0xda,0xe2,0x52,0xf3, + 0xe7,0x85,0xb3,0x64,0x51,0x71,0x57,0xd2,0x49,0x95,0xb2,0xb8,0xc2,0x35,0x77,0x9e, + 0xfb,0xf3,0x3d,0xdf,0x8d,0x26,0xd4,0x50,0xc9,0x66,0x87,0xfd,0x6d,0x34,0x68,0x28, + 0x9a,0xda,0x30,0xae,0x78,0x8d,0x5a,0x95,0x4f,0x40,0x77,0x60,0x9d,0xfa,0x05,0xe7, + 0x06,0x0c,0xaa,0xe5,0xb2,0xb8,0x21,0x5b,0x71,0x3c,0xaa,0xeb,0x27,0x46,0x76,0x2b, + 0x76,0xc1,0x2c,0xc0,0x55,0xda,0x3e,0x88,0xd6,0x92,0xe4,0x67,0x85,0xba,0x3a,0xae, + 0xeb,0x30,0x54,0x18,0xb3,0xea,0xe6,0x26,0x97,0x74,0xab,0xc3,0xa9,0x77,0x48,0xee, + 0x10,0xda,0x70,0x9f,0xfb,0x68,0xab,0xdb,0x80,0x59,0x61,0xa3,0xc9,0x7b,0x89,0x37, + 0x01,0xa6,0xb9,0x28,0xbe,0xb2,0x34,0x11,0x05,0x10,0x15,0xc2,0x95,0x8d,0xa1,0x92, + 0x0f,0xeb,0xfd,0x7b,0x34,0x95,0xd1,0x5c,0xce,0xb5,0x20,0x0d,0xb4,0x10,0x2b,0x98, + 0x4a,0x58,0x96,0x24,0xeb,0xc6,0x07,0xfc,0x5e,0x57,0x24,0x56,0x6a,0x73,0x0c,0x02, + 0xc6,0xa3,0xde,0xba,0x01,0x30,0xd9,0x07,0x8b,0xa5,0xb1,0x34,0x7e,0x2e,0xef,0x44, + 0x2a,0x93,0x6c,0x21,0xf2,0xd8,0x8b,0x0f,0x18,0xc6,0xa3,0x67,0x16,0x37,0x30,0xe5, + 0xf1,0xdb,0x77,0xbf,0x07,0x38,0x0c,0xa8,0x22,0x5f,0xc5,0x5b,0xa8,0xdf,0x14,0x61, + 0x9e,0x1d,0x82,0x98,0xda,0x67,0xe1,0x17,0xa4,0xd5,0xc3,0x56,0x88,0x7b,0x15,0x52, + 0xb1,0x81,0x34,0x25,0xea,0xc1,0xd8,0xcf,0x41,0xda,0x67,0xc8,0xc6,0x03,0xe6,0x01, + 0xfc,0x3c,0xa0,0x7b,0x25,0x4b,0x6e,0xf1,0x17,0xac,0x4a,0x21,0x0f,0x86,0x7d,0xbe, + 0xd3,0x4d,0x94,0x7f,0xa0,0xd3,0x2f,0x84,0xf5,0x42,0xff,0xde,0x81,0xb5,0x5a,0x22, + 0x9a,0x58,0x04,0x49,0xd4,0x03,0xab,0x20,0x66,0x59,0x6e,0xc5,0x40,0xb7,0xa1,0x60, + 0xd1,0x9f,0xe5,0x39,0x4b,0x30,0x3f,0xe3,0xb9,0x09,0x47,0x8b,0xe1,0x57,0x23,0x19, + 0x5f,0x20,0x42,0x1b,0x94,0x52,0x2f,0x32,0x6b,0x65,0x0a,0xb9,0x4a,0x44,0x8e,0xb8, + 0x84,0xd3,0xb5,0x4c,0x17,0x5f,0xa5,0x01,0x39,0x9b,0x91,0xda,0x62,0x79,0xe7,0x75, + 0xc3,0x1e,0x18,0xe5,0xb0,0x96,0x19,0xf8,0x0f,0x95,0x15,0x32,0xf5,0xfd,0xbc,0x2f, + 0x8f,0x01,0xab,0x54,0xdc,0xe1,0x56,0x7e,0x44,0xf0,0x59,0x2c,0x56,0x98,0x6f,0x97, + 0x76,0x34,0xae,0x76,0xd3,0x0e,0x06,0x0f,0xa1,0x32,0x5c,0x4e,0x1a,0xce,0x4c,0xe9, + 0xd8,0xbe,0x00,0xe5,0xcc,0x26,0x52,0x1e,0x8c,0xc9,0xac,0xf0,0xba,0x95,0x2d,0x70, + 0x6a,0x37,0xe2,0x46,0x9a,0x3a,0xdc,0xed,0xf6,0x63,0xb8,0x6f,0xb4,0xd9,0x5b,0xb5, + 0x33,0xc4,0xeb,0xf5,0x11,0xe1,0xfd,0x19,0xbe,0x88,0x34,0x53,0x0f,0xde,0x32,0x0f, + 0xda,0xb0,0xa3,0x41,0xcf,0x06,0xca,0xb0,0x32,0x50,0x78,0xe1,0x1f,0x62,0xa1,0x30, + 0xe2,0xdd,0xf5,0x81,0xb9,0x14,0x1a,0xd8,0xda,0x50,0x88,0x1e,0x0d,0x6c,0x9c,0xca, + 0x82,0x2b,0x69,0x41,0xd3,0x96,0xe4,0x2d,0x91,0x0a,0x34,0x31,0x7c,0xc6,0x03,0x33, + 0x16,0x49,0x30,0x49,0xeb,0x4c,0x18,0x66,0x1e,0x87,0xd7,0xa5,0x61,0x04,0x96,0x6d, + 0x04,0xc7,0x44,0x67,0xa6,0x0a,0x3f,0xbb,0x22,0xba,0x7b,0xe9,0x13,0x28,0xa7,0x4b, + 0x46,0x2e,0xf3,0x21,0x35,0xf0,0xb9,0xaf,0x64,0xee,0xa5,0x18,0x92,0xc6,0x8d,0xdf, + 0x42,0x7c,0x5d,0xf6,0x92,0x25,0x1a,0xe4,0x1d,0x78,0xf0,0xfa,0x6f,0x50,0xaa,0x5b, + 0xa9,0x61,0x27,0x3d,0x5b,0xec,0x76,0x13,0x01,0xf6,0xce,0x5f,0xfb,0xde,0x4b,0x7f, + 0xef,0x0f,0xfa,0x8f,0xbb,0xee,0xee,0xcf,0x0c,0x40,0x2e,0x6f,0x44,0xee,0xf7,0xff, + 0x26,0xd8,0xb6,0x98,0xae,0x40,0x33,0x96,0x90,0xf0,0xa9,0x30,0xf3,0x63,0xe0,0xea, + 0x76,0x8f,0x65,0xbd,0xcc,0x1b,0x2c,0xda,0x30,0x07,0x3f,0x4a,0x99,0x06,0xa2,0x91, + 0x38,0x10,0x16,0xa8,0xd8,0xf1,0xb9,0x05,0x2a,0x41,0x92,0xe9,0x2f,0x70,0x3e,0x57, + 0xca,0x48,0xb2,0x89,0xfe,0x95,0xcc,0x75,0xef,0x41,0xad,0xe7,0x90,0x61,0xb4,0x07, + 0x54,0xa0,0x61,0xe6,0xce,0x57,0xde,0x23,0xaa,0x17,0xd4,0x24,0x7b,0x76,0x59,0x48, + 0xc8,0xdc,0x6d,0x6a,0x3a,0x14,0xc1,0x09,0x3f,0x2d,0xcb,0xfb,0x2e,0x05,0xba,0xa8, + 0xdf,0x44,0x91,0x20,0x70,0x32,0xcd,0xac,0x62,0x97,0x21,0xae,0x5d,0xb4,0xc6,0x55, + 0x58,0x3b,0x9b,0xbd,0x86,0xa7,0x1b,0x7a,0x7e,0xcc,0x8d,0xf8,0x54,0xc8,0x7b,0xee, + 0x2d,0xcc,0x54,0xdd,0xfb,0x75,0xd6,0xe7,0xd2,0x27,0xe4,0x4b,0x14,0x16,0x84,0x23, + 0xbd,0xb8,0x15,0x9a,0xd4,0x5c,0xae,0x44,0x6a,0xf6,0x5c,0x50,0x41,0x2b,0x2b,0x13, + 0xc4,0xb4,0x43,0x1e,0x8b,0xcb,0x6d,0xd7,0xe2,0xa3,0xbc,0x85,0xb2,0xa3,0x2b,0x1c, + 0x78,0x30,0xb4,0xd4,0x44,0xe2,0xe0,0xf0,0xbe,0xf1,0x51,0xc8,0xdb,0xca,0x31,0xde, + 0xc6,0x8a,0x83,0x43,0xf8,0xf5,0xfa,0x4d,0xef,0x08,0x19,0xd0,0x4a,0xe3,0xf4,0xc5, + 0x51,0x0f,0x5b,0x4b,0x8d,0xe3,0xd8,0x32,0x3f,0xbd,0x3a,0xbf,0xbc,0xdc,0xd0,0xe3, + 0x60,0x15,0xfb,0x01,0xe1,0xbc,0xcc,0x11,0xd5,0x89,0xbb,0x68,0x00,0x74,0x8c,0x08, + 0x85,0x8f,0x3b,0x3d,0xc6,0x45,0x9f,0x78,0xfe,0x56,0x66,0x63,0xe3,0xbb,0xdd,0x04, + 0xae,0xcb,0xfa,0x01,0x0a,0xa1,0x33,0x0c,0x65,0x06,0x21,0xdf,0x36,0xcf,0x07,0x7a, + 0xea,0x76,0x76,0x10,0x51,0x2c,0x5a,0x7b,0x14,0x8d,0xaa,0x2d,0x7f,0x85,0x0d,0x2c, + 0xf0,0x76,0x70,0x13,0xfa,0x01,0x3c,0x70,0xdb,0x56,0xdb,0x77,0x28,0x50,0x29,0xd5, + 0x76,0x40,0xc2,0xfa,0x0d,0xbc,0xc6,0x62,0x35,0xd8,0x50,0x58,0x4d,0xbd,0x75,0xf0, + 0x18,0xbd,0x75,0x50,0xe9,0x2d,0xb7,0x3c,0x76,0xb4,0xf0,0xc0,0xa7,0xa9,0x73,0x6f, + 0xbd,0x83,0xa4,0x74,0x86,0xb7,0x73,0xb7,0x8b,0x49,0xb0,0xf8,0xcd,0xda,0xd8,0x8d, + 0x7f,0xd0,0xeb,0x79,0x90,0xe1,0xdf,0xa9,0x5b,0x77,0xad,0x95,0xdf,0xd7,0xeb,0xbb, + 0x19,0x49,0xdf,0xcc,0x1a,0x99,0xcf,0x80,0xc4,0xc0,0x72,0x9a,0xa3,0xf8,0x93,0xa9, + 0x37,0x10,0xf6,0x4b,0xa4,0xb8,0xb4,0x95,0x9d,0x00,0x97,0x05,0x85,0x79,0x58,0x1a, + 0x88,0x9c,0x95,0x69,0x10,0xd9,0xec,0xd1,0x2e,0x8d,0xf4,0x32,0x44,0x95,0x59,0x82, + 0xdb,0x69,0x02,0x71,0xce,0xaa,0x95,0x27,0xa1,0x3a,0xd5,0x92,0x4c,0x36,0x99,0xb2, + 0xc3,0xc9,0xd7,0xa7,0x08,0x26,0x51,0x97,0xdb,0x73,0x79,0x7a,0x7d,0x1a,0xb4,0x45, + 0x82,0x13,0x3b,0xe3,0x2c,0xc3,0x1f,0x75,0x5b,0xaa,0x89,0xbf,0xea,0x9e,0xaf,0x19, + 0xac,0xb5,0x50,0xb6,0x8b,0xce,0xfb,0x28,0x85,0x96,0xc6,0x82,0xc8,0x34,0x95,0x8f, + 0x31,0xc0,0x7b,0x20,0xe3,0x9b,0x98,0xf4,0xd0,0xc5,0xeb,0x8f,0xa4,0x75,0x58,0xee, + 0xb0,0x6d,0xc6,0x58,0x03,0x8a,0x8d,0x9b,0x2e,0xa8,0xf8,0x74,0x5b,0x48,0xed,0x88, + 0x96,0x90,0x3f,0xd1,0x9d,0x7d,0x68,0x62,0xc3,0x83,0xeb,0xe6,0x42,0xd7,0x64,0x4d, + 0x3b,0xc7,0x7d,0x2a,0x3d,0x8f,0x04,0xf6,0xf0,0xce,0x0f,0xf9,0x3a,0x1b,0x20,0x83, + 0xf2,0x31,0x3b,0x5a,0x51,0x14,0x38,0xc5,0xdb,0xf7,0x97,0x78,0x79,0x97,0x29,0xa3, + 0x85,0x59,0x08,0xfe,0xe5,0xaf,0xd7,0x06,0x8c,0xe2,0xb0,0x50,0x96,0x48,0xaf,0xe3, + 0xcd,0xb2,0x64,0xc4,0xfa,0x10,0x52,0xee,0xec,0x33,0x02,0x25,0x5b,0x54,0x8a,0xac, + 0x3b,0x32,0xf9,0xed,0xfb,0xc3,0x78,0xe4,0xae,0x7b,0x88,0xe4,0xb6,0x06,0xe6,0xba, + 0x23,0x85,0x35,0x49,0xf6,0xd0,0x51,0xf9,0x16,0xf1,0x31,0xd0,0x38,0xa9,0x4e,0x42, + 0xa6,0xaa,0x51,0x0b,0xb9,0x46,0x43,0xfd,0x68,0x2c,0x8a,0x5c,0xdc,0xac,0x92,0x3e, + 0xeb,0x60,0x46,0xae,0xac,0xf9,0x51,0xfa,0x60,0xd8,0x51,0x1f,0xdc,0x13,0xd4,0x0d, + 0xb9,0xff,0x01,0xd1,0x18,0xc4,0x7e,0x10,0xca,0xdd,0xa5,0x7e,0x5d,0xc4,0x87,0xb5, + 0xbe,0x48,0x4a,0x7f,0x75,0x90,0xee,0xa3,0x6e,0xd2,0x7d,0xad,0x5c,0x78,0xdd,0x1e, + 0xe7,0x57,0x22,0x27,0xf2,0x47,0x95,0xc8,0x77,0xbb,0xc2,0x33,0xb1,0x28,0x8f,0x39, + 0xae,0xd6,0xa0,0x80,0x5f,0xa0,0x9d,0x04,0xc1,0x98,0xbd,0x12,0xdf,0x88,0xea,0x55, + 0xb8,0xd2,0x19,0xff,0x32,0x65,0x1b,0x63,0x0f,0x28,0x76,0xc2,0x1d,0xc1,0x4c,0x43, + 0x8d,0xbf,0x0e,0x2e,0x8a,0x34,0xa5,0x08,0x8a,0xb3,0x5e,0xbd,0x73,0x6a,0x00,0xf9, + 0x4f,0x81,0xab,0xd3,0xa1,0xc0,0x86,0xf6,0xd2,0xf8,0xda,0x07,0xaf,0x71,0x2c,0x5b, + 0x77,0x1b,0x31,0x49,0xaa,0x5a,0xd7,0x7b,0xb5,0x20,0xa3,0x9c,0x2e,0x33,0xc4,0x39, + 0x0b,0xad,0x47,0xf3,0x4f,0x1d,0x89,0x94,0x16,0xbd,0xcf,0x53,0x07,0x4d,0x9e,0xea, + 0xac,0xf8,0x09,0xe1,0x9b,0xeb,0x71,0xc0,0x17,0xf1,0x28,0x99,0xb9,0xf0,0xd3,0x13, + 0xc6,0xe1,0xa3,0xc9,0x1b,0x2d,0xa9,0x0e,0x5e,0x1b,0x1b,0x1a,0x34,0x5b,0x9b,0xde, + 0xcd,0x72,0xf4,0x2a,0xd3,0xcc,0x85,0xa1,0xd1,0xe4,0x51,0x0e,0xc3,0x43,0x26,0x7d, + 0x79,0xf7,0xa0,0x1f,0xc1,0xd6,0x75,0x7b,0xa6,0x45,0x94,0xe5,0x36,0xfe,0xb6,0x62, + 0x6a,0xf8,0x88,0xee,0x5b,0x85,0x6c,0x96,0x70,0x28,0xed,0xd9,0x96,0xaa,0xa5,0x28, + 0x6a,0x6e,0x7e,0x63,0x02,0x8b,0xc4,0x68,0xc2,0x97,0xb8,0x6d,0x0c,0x07,0x14,0xa3, + 0x09,0xb1,0x71,0xfb,0x18,0x32,0x3e,0x0c,0x52,0x8d,0x3e,0xda,0x47,0x21,0x1e,0x31, + 0xc9,0xf0,0xfe,0xb2,0x3d,0xec,0x60,0x9d,0x39,0xd8,0x7a,0xaf,0x39,0x24,0xb0,0xcd, + 0x4a,0xfb,0xb8,0x11,0xa6,0x79,0x64,0x94,0xe6,0xbb,0xc1,0xb9,0xc1,0xf8,0xe0,0x68, + 0xb4,0xde,0xe9,0x2c,0x5f,0x4a,0xab,0x94,0x9d,0x77,0x0e,0x0d,0x4d,0xc3,0x8c,0xf8, + 0xa1,0xed,0x61,0xa3,0xb2,0xea,0x24,0x22,0xbf,0x26,0xa4,0xb4,0x7b,0xcf,0x72,0x7b, + 0xbc,0xb6,0xb8,0x28,0xaf,0xbb,0x5d,0x55,0x05,0x55,0x0f,0x15,0x88,0xfc,0xf7,0x04, + 0xbd,0xc5,0x06,0x9b,0x81,0x53,0xab,0x60,0xa6,0xf2,0x5c,0xdd,0x76,0x30,0xeb,0x9a, + 0x18,0x19,0x1f,0x1e,0x1e,0x8c,0x9b,0x18,0x09,0x02,0xed,0x71,0x48,0x59,0x88,0xa4, + 0x86,0x93,0xe1,0xe8,0x01,0x9c,0xcc,0x44,0x62,0x95,0x5e,0x85,0x1d,0x1e,0x44,0x04, + 0x8d,0x3b,0x1f,0xe2,0x73,0x3d,0x7c,0x24,0xf2,0xf3,0xc1,0xc1,0xcf,0xa3,0xd1,0xcf, + 0x87,0x87,0x28,0x16,0x45,0x91,0xaa,0x45,0xf8,0xec,0x71,0x88,0xb2,0xe7,0x62,0x85, + 0x4a,0x87,0x56,0x8e,0x11,0xf6,0x7c,0x42,0x25,0x86,0xf3,0x5c,0x0a,0xec,0x93,0x06, + 0x37,0x65,0x03,0xa6,0x01,0x41,0xec,0xd2,0x55,0xa9,0x92,0x9c,0x21,0xaa,0x25,0x9b, + 0xac,0x14,0x39,0x62,0x63,0x96,0x8b,0x9b,0x8e,0x08,0xc5,0x3a,0xc3,0xfe,0x8b,0x61, + 0x13,0xa3,0x61,0xad,0x46,0x30,0xaa,0x89,0x46,0x3f,0x12,0xd7,0x50,0xcc,0x10,0xf0, + 0x4d,0x60,0x9f,0xb7,0x70,0x3e,0xcd,0x66,0xaf,0xf6,0x5d,0x7b,0xa3,0xbf,0xc0,0xee, + 0xa2,0xea,0x6d,0x0f,0x5f,0x61,0x6a,0x37,0x95,0xa5,0xe4,0x82,0x2d,0x50,0x9c,0x32, + 0x0b,0xd8,0x08,0xb1,0x99,0x18,0x4e,0x53,0x7e,0xe8,0x6e,0xa4,0x57,0x61,0xf9,0x0a, + 0x96,0x85,0xcd,0x72,0xe0,0x3f,0x91,0x07,0xa5,0xc8,0x34,0x8e,0xf3,0x2a,0x4f,0x24, + 0x89,0x2c,0xad,0x73,0x4e,0xd8,0x48,0x9c,0xaa,0x82,0xcc,0xab,0x52,0x4a,0x8d,0x4b, + 0x15,0xeb,0xe5,0xb5,0xb2,0x82,0x81,0xd6,0x92,0x62,0xfd,0x26,0xac,0x83,0x94,0x62, + 0xbc,0xe3,0x08,0xf9,0xdb,0x32,0xd3,0x12,0x84,0xd7,0x1b,0x1d,0x11,0x3f,0x1c,0x0f, + 0x07,0xa3,0x51,0x48,0x95,0x1b,0x94,0x43,0xb2,0xcc,0x57,0x3d,0x7f,0x9c,0x35,0x41, + 0xde,0x53,0x97,0xf3,0xb4,0xd8,0x84,0x04,0x1e,0xd6,0x46,0x15,0x5e,0x29,0xe6,0x21, + 0xad,0xe4,0x80,0x1d,0x5f,0x18,0xb5,0xdb,0x46,0x98,0x42,0xa1,0x18,0xa7,0x35,0xe0, + 0xa3,0x6a,0x1b,0xb3,0x92,0x26,0x0c,0xfa,0xbb,0x34,0x5d,0x88,0x58,0x8d,0x06,0xa5, + 0x71,0x65,0x92,0x04,0xd1,0xe9,0x02,0x2e,0x81,0x80,0xfe,0x25,0x82,0x99,0x56,0x0b, + 0x36,0x8a,0x28,0x50,0x94,0x7d,0x13,0x56,0x12,0x6f,0x73,0xb2,0xd1,0x8a,0xc4,0x1a, + 0xb8,0x25,0xca,0xb1,0x99,0xeb,0xa5,0x4b,0x66,0x2a,0x5b,0x24,0x06,0x5a,0x9f,0xb3, + 0x90,0x5a,0x82,0xa6,0xd9,0x79,0xb6,0xc8,0xac,0x4c,0x63,0xf8,0x3b,0x7b,0x0f,0x73, + 0xe5,0xe7,0xb8,0x3d,0x54,0x6d,0xad,0x36,0xaa,0xb1,0xc5,0x52,0xbb,0x30,0x51,0x9b, + 0x26,0x78,0x2f,0x6c,0x66,0x97,0x95,0xb7,0xb9,0x35,0x54,0x9a,0x0b,0x1b,0x32,0x22, + 0xa2,0x58,0xb5,0xa8,0x82,0x8a,0x09,0x8a,0x9b,0x47,0x2c,0xad,0x8a,0x87,0x96,0xfe, + 0x31,0x01,0xc5,0x86,0x25,0xca,0xd2,0xaf,0x4b,0x50,0x90,0x22,0x80,0x8d,0xb8,0x60, + 0x43,0x37,0x04,0x4b,0x33,0xc4,0x5e,0xab,0xaa,0x1a,0xf8,0xf3,0x22,0x72,0x21,0xcc, + 0x90,0x99,0x6a,0x3b,0xc6,0xd3,0x7f,0x77,0x60,0xf2,0x7f,0x49,0x90,0xb0,0x62,0x19, + 0x64,0xd5,0x2f,0xc2,0xa7,0x47,0x6a,0x25,0x6e,0x54,0xd1,0x08,0x52,0xeb,0x8d,0xaa, + 0x35,0x1e,0xc5,0x7f,0x5b,0x20,0x9a,0xac,0xf3,0x63,0x20,0x4a,0x96,0x6f,0x9c,0xe0, + 0x6c,0xe3,0xb8,0x37,0x24,0x73,0x65,0x91,0xac,0xf6,0x60,0x8a,0x5c,0xe5,0xff,0x68, + 0xf1,0xd5,0x1b,0x66,0xb1,0xf3,0x2f,0xb0,0xa8,0xb2,0x86,0x1c,0x38,0xe0,0x1c,0x8c, + 0xbc,0x43,0x5e,0xd8,0x88,0x45,0x09,0xb8,0xd5,0x78,0xaf,0x58,0xa0,0xf9,0xbc,0xde, + 0xa6,0x0f,0x3d,0xf3,0x6a,0x26,0xd3,0x6b,0x35,0x72,0x47,0x52,0x03,0x95,0x8c,0x2f, + 0xbe,0x68,0x73,0x6f,0x5a,0xc8,0x55,0x41,0x0d,0x3b,0x1f,0xde,0xfd,0xbe,0xfb,0xfd, + 0xbb,0xac,0x6f,0x70,0x3a,0x4e,0x0a,0xb7,0xb9,0x1f,0xf7,0xfb,0x83,0x90,0x58,0x3d, + 0xec,0xfb,0x14,0xcb,0x10,0x5f,0x76,0x7c,0x87,0x51,0xce,0x02,0x92,0x60,0xe7,0x6b, + 0xe7,0x9d,0xa7,0xb7,0xd5,0xbe,0xeb,0x6d,0x5f,0xf8,0x4d,0x6b,0x7b,0x3e,0x0e,0x0d, + 0x57,0xa5,0x96,0x82,0x8a,0x58,0xbd,0x61,0xd3,0xd4,0x65,0x01,0x02,0x43,0x93,0xbc, + 0x62,0x39,0xbc,0xaf,0x88,0x26,0xe3,0x46,0xcb,0x8b,0x46,0xcb,0x51,0xa3,0xe5,0x65, + 0xa3,0x65,0xd0,0x6f,0x36,0x0d,0x9a,0x4d,0xc3,0xa6,0x8e,0xfb,0xce,0xe5,0xa4,0x33, + 0xb2,0x22,0x6a,0x3f,0x61,0xa2,0x7f,0xdc,0x09,0x1b,0x60,0x3d,0x3e,0xbb,0xf7,0x03, + 0x93,0x7b,0xdf,0xd1,0x36,0x95,0x14,0xf0,0x45,0xd6,0xc1,0xf0,0x31,0x5e,0x8e,0x5c, + 0xb8,0x66,0x96,0x00,0x9d,0x59,0xeb,0x53,0x01,0x53,0x61,0xad,0xd4,0x6b,0x03,0xe9, + 0xbe,0x7d,0xe4,0x77,0x8b,0x17,0x2a,0x95,0x4f,0x34,0x58,0xdb,0x7a,0x7d,0x81,0xca, + 0xe4,0x8c,0x3f,0xdb,0x46,0x79,0xf3,0x91,0x4a,0x3c,0xf9,0x0b,0x9b,0xa0,0xdb,0x97, + 0xec,0x85,0x39,0x7e,0x69,0xf8,0x67,0xf0,0x2d,0x6d,0xf3,0x48,0x8a,0x53,0x00,0x3e, + 0xc1,0x90,0x40,0xf8,0xfa,0x48,0xf6,0xbd,0xce,0x16,0x92,0x2a,0xbd,0x76,0x8c,0x4c, + 0x54,0x91,0x9a,0x6e,0x3c,0x12,0xd0,0x6b,0xdd,0xec,0x7b,0x45,0x20,0xf8,0x36,0xbd, + 0x5f,0x95,0x81,0x3c,0x51,0x7c,0x7c,0x2a,0xb8,0xfe,0x8d,0xb9,0xf7,0x7b,0x54,0x5e, + 0x9a,0xe9,0x9f,0x4a,0xe9,0x7f,0x50,0x9a,0x51,0xfc,0x07,0xa9,0xcd,0xde,0x41,0x05, + 0xbe,0x8f,0x5c,0x1a,0x2b,0xb4,0x2f,0x46,0x0f,0xb9,0x25,0xf2,0x00,0xb2,0x5c,0x3a, + 0xbd,0x5c,0x96,0x64,0xca,0x23,0x18,0xce,0x75,0x66,0x3b,0xff,0xbc,0x2a,0x4b,0x64, + 0x83,0xd2,0xf0,0x50,0x0f,0x2a,0x69,0x7c,0x1f,0x1e,0x52,0x3a,0xe0,0x15,0x58,0x27, + 0x1b,0x97,0x19,0xb8,0x45,0x1b,0x00,0x32,0x1b,0x57,0x0c,0x06,0xa9,0xb4,0x3e,0x5e, + 0xe6,0x1c,0x50,0x13,0xca,0x65,0xa6,0x4a,0xe8,0x34,0xee,0x64,0x12,0x85,0xa8,0x5c, + 0x9b,0x2c,0x6b,0x77,0x11,0xd7,0x34,0x3a,0xcd,0x34,0x21,0xd9,0x6b,0xcc,0x4e,0x04, + 0x12,0xb3,0x4a,0x7d,0x07,0xed,0xdd,0x6f,0x2d,0x0c,0x12,0xb3,0x5e,0x8a,0x3c,0xd4, + 0xcd,0x75,0x1d,0x55,0x75,0x2b,0x7f,0x43,0xbc,0x20,0x6e,0x61,0x2a,0x4c,0x37,0xe7, + 0x44,0xdf,0xf1,0x84,0x26,0x6c,0x6b,0x73,0xa6,0xd5,0xb0,0x68,0xc0,0x71,0x38,0xa8, + 0x30,0x74,0xed,0x21,0x79,0x0c,0x8a,0xec,0x77,0x61,0xd9,0xa6,0xdf,0x1a,0xb0,0x99, + 0x9a,0x9f,0x48,0x45,0x75,0xce,0x88,0x9d,0x4e,0xce,0x4f,0x2f,0x60,0x87,0x6b,0x4c, + 0x8a,0x50,0x50,0xcc,0xd9,0xc2,0x45,0x46,0x4e,0xf8,0x14,0xa1,0x9c,0x9c,0xfb,0xda, + 0x33,0x84,0x3e,0xfb,0x96,0xd9,0x55,0xc5,0x79,0xae,0x80,0x9b,0x97,0xaa,0xbf,0x1a, + 0xb1,0x37,0x79,0x54,0x3f,0x20,0x57,0xc4,0x4c,0xd5,0x5d,0x75,0xc4,0x44,0x90,0xe1, + 0xbe,0xc4,0x05,0x96,0x7e,0x91,0xef,0x43,0x3e,0x18,0x57,0xa0,0x13,0x85,0xa7,0x4a, + 0x51,0x75,0x0c,0xdc,0x88,0xac,0xf0,0xd0,0x5e,0xfd,0x6d,0x30,0x1c,0xdf,0x81,0x96, + 0x89,0xcc,0x28,0x91,0xc4,0xb2,0xed,0x0f,0x01,0xca,0xce,0x40,0xac,0xef,0x68,0x93, + 0x47,0x43,0x3c,0xec,0x8f,0x36,0xd1,0xfd,0xe6,0xf5,0x07,0x08,0x70,0x7b,0x80,0x5f, + 0xdf,0x59,0xa9,0x29,0x54,0x39,0xd3,0x14,0x33,0x97,0x45,0xda,0x43,0xc5,0xb0,0xcc, + 0x25,0xbc,0xff,0x78,0xfa,0x03,0x00,0x9f,0xc9,0xc5,0x53,0x81,0x3f,0x1a,0xbc,0x1c, + 0x6e,0x00,0x7f,0xc1,0xe1,0x08,0x2f,0x7e,0x0c,0x27,0x79,0xfc,0x19,0xbe,0xc8,0x74, + 0x99,0x48,0x1f,0xaf,0x60,0xb9,0xf8,0xf6,0xf3,0x15,0x64,0x69,0xee,0x47,0xff,0xa1, + 0x63,0xf0,0x0a,0x6e,0xbb,0x6d,0x27,0xd8,0x10,0x02,0xfd,0x97,0x63,0xef,0xc7,0xdd, + 0x95,0x86,0x1f,0xc4,0x45,0x8d,0x63,0xd6,0xf8,0xe8,0x81,0x23,0x5d,0x2c,0xed,0xaa, + 0x97,0xac,0x12,0x2f,0xd4,0xd9,0x79,0x0c,0x4c,0x75,0x4c,0x3e,0x18,0xc7,0x03,0x0c, + 0x87,0x80,0xb2,0x62,0xa9,0x96,0x26,0x74,0x3f,0xfd,0xb0,0x04,0x2e,0xa5,0x56,0x28, + 0x50,0xd0,0xe1,0x72,0xb0,0x90,0xae,0xce,0xe9,0x54,0xab,0x69,0x33,0x4f,0xf0,0x9c, + 0x48,0x93,0x5c,0x7e,0x93,0x79,0x8b,0xd5,0xcf,0xbb,0xf3,0x80,0x86,0x55,0x82,0x5a, + 0x72,0x00,0x3b,0x78,0x56,0x4a,0xdc,0xf2,0xdf,0x3e,0x68,0x0d,0xd1,0x21,0xc7,0x0c, + 0xdb,0xfa,0x0e,0xa2,0xc9,0x41,0x5b,0x1f,0x8a,0xee,0x51,0x5b,0xdf,0x61,0x34,0x39, + 0x84,0x9d,0xa9,0xc8,0x59,0x5b,0xb5,0x6e,0x8d,0xd2,0x61,0xdc,0xd6,0xf7,0x22,0x9a, + 0xbc,0x68,0xeb,0xc3,0x1b,0x7a,0xd4,0xd6,0xf7,0x32,0xaa,0x1c,0xb3,0x06,0x56,0xfa, + 0x88,0x96,0x7e,0x5b,0xef,0x42,0x14,0x4b,0x81,0xa8,0xfc,0xc0,0x9f,0x60,0x39,0x17, + 0xfe,0x50,0x3c,0xb2,0xc6,0x12,0xee,0x2f,0x0b,0x34,0xa5,0x4f,0x69,0x5a,0x3c,0xe9, + 0x8a,0x01,0xc8,0x7b,0x5d,0x20,0xeb,0xf4,0x66,0x99,0xcc,0xd3,0xaa,0x90,0xde,0x37, + 0x6f,0xa3,0x7a,0x98,0xda,0x20,0x7c,0xdf,0x99,0x3f,0x3e,0x02,0xda,0xf0,0x8f,0x5b, + 0xf0,0x32,0x46,0xbc,0x8c,0xc1,0xac,0x16,0x53,0x95,0x9b,0x56,0x66,0x18,0x22,0x37, + 0x0c,0xc3,0xa8,0xee,0xce,0x22,0xf3,0x7d,0x70,0xd3,0xc2,0xd9,0x3d,0xb2,0x5b,0x79, + 0xdf,0x5d,0x4d,0xb8,0xcd,0x8a,0x14,0x27,0xef,0x60,0xda,0x3b,0xd1,0xea,0xb8,0x83, + 0x45,0xe9,0x11,0xa4,0x83,0x8b,0x39,0xe8,0xf7,0xfb,0x6b,0x27,0x93,0xff,0xd7,0x30, + 0x25,0x5b,0xc3,0x0b,0xb9,0x94,0xe5,0xd3,0x41,0x30,0x34,0xbd,0x3b,0x14,0xed,0x06, + 0x6d,0x85,0x35,0xfe,0xd9,0x18,0xde,0xa2,0x0e,0x98,0x60,0x95,0xd4,0x94,0xa5,0x14, + 0x41,0x87,0xbd,0x51,0xfa,0x56,0xe8,0xd4,0x45,0xb3,0xac,0x16,0xb3,0x59,0x96,0xc4, + 0x40,0x11,0xfd,0x13,0x70,0xc6,0x45,0x8f,0xf3,0x19,0x3b,0xc6,0x66,0x79,0x1e,0xca, + 0xb8,0x0c,0x6b,0x8a,0x50,0xb5,0x65,0x76,0xe3,0x3f,0xa6,0xed,0x18,0xa0,0xae,0x52, + 0x33,0x18,0x4f,0x55,0xb2,0x1b,0x73,0xdd,0xb5,0x74,0xde,0xa8,0x3d,0x9a,0xce,0x75, + 0xbd,0x82,0x93,0x3a,0xb0,0x83,0xf4,0xe8,0xe6,0x97,0xb8,0x09,0x31,0xa2,0x9c,0x64, + 0x68,0x7e,0xdf,0xa0,0x1b,0x3d,0x68,0x02,0x4f,0xfa,0x70,0x42,0xda,0xa6,0x43,0x09, + 0xd0,0x9b,0x5c,0xa9,0x74,0x0d,0xd6,0x5c,0x77,0x74,0x97,0x66,0x34,0x2d,0xde,0x0e, + 0xdc,0x60,0x7c,0xb4,0x0d,0xb8,0x3d,0x90,0xb9,0x91,0x70,0xf0,0xac,0xe0,0xf8,0x25, + 0x8e,0x66,0x40,0xbb,0x85,0xf7,0x37,0x23,0xae,0x04,0x4b,0x2d,0xcc,0xcf,0x67,0x42, + 0x81,0xe3,0xcb,0x1f,0xf0,0x57,0x69,0xda,0x42,0xaf,0xef,0x54,0xe9,0xf2,0x2a,0xae, + 0xfa,0x88,0xd7,0x0a,0xcc,0xb8,0x11,0x3e,0x9d,0x31,0xaf,0x72,0x7c,0x9f,0xb5,0x3e, + 0x4b,0x23,0xa7,0xc7,0x45,0x56,0xe0,0x98,0xcc,0xac,0xa0,0xa0,0xc7,0xe8,0x53,0xb5, + 0xa4,0x97,0x2f,0x56,0x29,0xdc,0xf8,0xd6,0xc7,0x61,0x4b,0xa1,0xad,0x09,0x99,0x3e, + 0xe6,0x77,0xb5,0xb4,0xf4,0x9b,0xdf,0xff,0xc5,0x1d,0xb2,0x34,0xc3,0xa3,0x56,0xce, + 0xc2,0x3c,0x82,0x87,0x7b,0xce,0x07,0xed,0x4c,0x3e,0xa4,0x52,0x9d,0x64,0x4d,0xfe, + 0xf5,0x14,0xf3,0x34,0x1a,0x8f,0x62,0xf0,0x6f,0xb7,0x00,0xbf,0x77,0x60,0x2f,0x82, + 0xcd,0x33,0xd7,0xe3,0x81,0xf3,0xfc,0xf5,0x74,0x18,0x8f,0x3c,0x88,0x9d,0xfc,0x2f, + 0x46,0x72,0x0d,0xf0,0x65,0x61,0x12,0x55,0xca,0xf4,0xc9,0xd8,0x8d,0xc3,0x0a,0x8d, + 0x23,0x3c,0xea,0x15,0xc1,0x69,0xe9,0x12,0x81,0x56,0x81,0x2b,0x4e,0x35,0x2e,0xc1, + 0x53,0xa8,0x50,0x14,0xca,0xbb,0xc4,0x10,0x70,0xb0,0x95,0x36,0x1d,0xc4,0xd8,0xf0, + 0x70,0xbc,0x21,0xb7,0x54,0x59,0x39,0x6f,0x5b,0x12,0xb5,0xaa,0x8c,0xdd,0xb0,0x47, + 0x47,0xa7,0x10,0x37,0xd9,0x82,0x8d,0x1e,0xf7,0xa5,0x75,0x9c,0x4a,0x25,0xc5,0x9f, + 0x71,0xa0,0xff,0xd6,0x36,0xd2,0x58,0x9d,0x11,0x20,0x57,0xfc,0xd9,0x29,0x9b,0x7b, + 0xa1,0x91,0xbc,0x9e,0xd2,0x1e,0xcb,0xfe,0x49,0x45,0x4e,0xf6,0xcb,0x0a,0x12,0xa1, + 0xf5,0xaa,0x96,0x13,0x9c,0x23,0xae,0x63,0x70,0x7b,0x48,0x0d,0x27,0x30,0x93,0x24, + 0x1b,0x9c,0x4e,0x21,0x72,0xe5,0x0c,0x64,0x1a,0x7c,0xe4,0x14,0xb7,0x28,0x51,0x2e, + 0x3d,0xcc,0x95,0x8d,0x42,0x1e,0x2e,0x2d,0xea,0x56,0x8a,0xcd,0x0f,0x9c,0x5c,0xe0, + 0x88,0xcd,0xf9,0x6d,0x05,0x3e,0xdb,0x35,0xa2,0xaf,0xf1,0x0c,0xde,0x04,0xbc,0xe6, + 0x6f,0x40,0x1b,0x54,0xb4,0x6f,0x20,0xef,0x7a,0xa9,0x0b,0x97,0x62,0x52,0x55,0x08, + 0x8b,0x50,0x97,0xc3,0x54,0xab,0xaf,0x52,0xfb,0x50,0x17,0xbb,0x3f,0xae,0xb8,0x53, + 0x66,0xba,0x7a,0x70,0xd4,0x44,0x48,0xeb,0x51,0x2f,0xb9,0x88,0xdb,0xae,0x9e,0x5e, + 0x69,0xfe,0xdf,0x5e,0x68,0x1e,0xc2,0x7f,0xc7,0x90,0x35,0x4a,0xcb,0x63,0x38,0xe3, + 0xd4,0xf1,0xc9,0x8f,0xa9,0x10,0xff,0x6f,0x2f,0x10,0x7f,0x52,0x31,0xf7,0x9f,0x53, + 0xcb,0xdd,0x4e,0xc1,0xd6,0x3a,0x6d,0xd6,0xd7,0xbc,0xdb,0x73,0x53,0x2f,0xd7,0x26, + 0xb6,0xf2,0xe5,0x62,0xbb,0x4f,0x2c,0xb5,0xee,0x58,0x69,0xdd,0xed,0x5a,0x7c,0x76, + 0xdc,0x85,0xb7,0xa9,0xcd,0xd2,0xb9,0x0e,0x92,0x8b,0xf9,0x8c,0x1f,0x98,0x52,0x91, + 0xab,0x2f,0x5c,0x20,0x9b,0x9c,0x6e,0x2f,0x4b,0x92,0x1e,0xe0,0x14,0x5a,0xcb,0x79, + 0x70,0xe2,0x3f,0xdb,0xfb,0xf7,0xfe,0xb6,0x6d,0xa4,0x6f,0x1c,0xfe,0xdf,0xaf,0x82, + 0xe1,0xf6,0x72,0xc8,0x8a,0x92,0x65,0x3b,0x49,0x5b,0x29,0x8c,0x3e,0x6e,0x9a,0xb6, + 0xb9,0x9a,0x26,0xb9,0x62,0x77,0xbb,0x7b,0x3b,0x5e,0xdf,0xb2,0x25,0xdb,0xaa,0x75, + 0x5a,0x51,0x3e,0x64,0x25,0x3f,0xaf,0xfd,0xf9,0xce,0x60,0x38,0x04,0x08,0x4a,0x76, + 0x9a,0xdd,0xdf,0xb9,0xfd,0xc4,0x22,0xc1,0x01,0x30,0x18,0x00,0x83,0xc1,0x60,0x30, + 0x23,0x93,0x38,0x40,0x01,0x83,0xf1,0x1f,0xac,0x9c,0x66,0xe3,0x5a,0x15,0x67,0x84, + 0x02,0x2b,0xd5,0x25,0x6c,0x75,0x28,0x17,0x2c,0x44,0xfa,0x7f,0x8f,0x33,0xe7,0x49, + 0x0f,0x94,0xbe,0x60,0x6b,0xab,0x2d,0xfa,0x98,0x05,0xa6,0x4c,0x81,0x34,0x77,0x03, + 0xbe,0x48,0xbe,0x67,0x3a,0x9a,0xd2,0xd6,0x0b,0xf9,0x3e,0xca,0x42,0x51,0x59,0x0c, + 0x04,0x6d,0xc8,0x05,0x19,0xf1,0xfa,0x0c,0x0b,0xf0,0xe9,0x05,0x8b,0x8c,0x60,0x72, + 0x02,0xa3,0x72,0x23,0x7a,0x77,0x72,0xf3,0xe5,0x78,0x4b,0xcd,0x9f,0x8b,0xf8,0x5e, + 0xaf,0x87,0x63,0xda,0x9b,0xc0,0xf8,0x55,0x16,0xbc,0xf7,0x86,0x7c,0x8f,0x60,0xdc, + 0x33,0x26,0x78,0x57,0x40,0x9a,0x46,0x3b,0xc3,0x08,0xd5,0x39,0xd3,0xbf,0x89,0xe4, + 0x28,0xea,0x73,0xd1,0x96,0xdd,0x76,0xcf,0x25,0x38,0x92,0xf9,0xb2,0x83,0x24,0xf2, + 0x35,0x56,0xb1,0x5a,0x10,0x73,0x86,0x7f,0x03,0xb2,0xb7,0x9f,0x89,0x2b,0x0b,0x0b, + 0x38,0x23,0xd0,0x8d,0x13,0xb9,0x67,0xc1,0x18,0x9b,0x29,0xb9,0xcd,0x8d,0x2e,0x69, + 0x91,0x40,0x89,0x3c,0x41,0x81,0x32,0x02,0xbc,0x0f,0xce,0xf4,0x7e,0xd0,0x3b,0x55, + 0x0c,0x7e,0xf8,0x31,0x20,0x6e,0x75,0x25,0xd2,0xcc,0x20,0x1b,0x9c,0x0c,0xa9,0x7f, + 0x90,0x8a,0xfb,0x43,0xa4,0x3e,0xc9,0xbe,0xbc,0xbd,0xb2,0x6d,0x63,0x1c,0x3e,0xfd, + 0xd9,0x69,0x21,0x9b,0x9d,0x59,0x79,0x3e,0xeb,0x87,0x80,0x4d,0x97,0x78,0xb7,0xce, + 0xe2,0x69,0x16,0x44,0xef,0xf7,0x3f,0xec,0xfd,0x6a,0x8e,0x9a,0x8c,0x8a,0x3d,0xfe, + 0xf2,0xc6,0x28,0x1e,0x5f,0xb6,0x89,0x5f,0x79,0x9a,0x28,0xe7,0x1a,0x73,0x7b,0x60, + 0xba,0x32,0xb0,0x8b,0xcf,0xfc,0xf6,0x4f,0x9d,0xce,0xee,0x61,0x42,0x1e,0xfc,0x6d, + 0x15,0x84,0x6c,0x84,0x68,0x15,0xd1,0xc1,0x44,0xf4,0x7b,0x90,0x64,0x5b,0x9a,0x41, + 0x2a,0xc1,0x32,0x3b,0x78,0xd0,0xa5,0xab,0x7d,0xc3,0x8e,0xf3,0x7d,0xfe,0x83,0xd5, + 0x17,0x42,0x12,0xc9,0x57,0xf6,0xa1,0xf0,0xcc,0x3d,0x19,0xfb,0xf2,0xbe,0x7a,0x2b, + 0x43,0xc1,0xc6,0x14,0xee,0x5d,0x1e,0xaa,0xd3,0x70,0x87,0x93,0x87,0xf5,0x4e,0xae, + 0x3a,0xdb,0x7d,0xb6,0x52,0x0c,0x9c,0xc0,0xf8,0x99,0xae,0xb4,0xe5,0xc2,0x1e,0xf3, + 0xa8,0xd2,0x84,0x40,0x20,0xca,0x3a,0xca,0x48,0x02,0x31,0x5b,0x85,0x9f,0xba,0xb8, + 0xf1,0x39,0xaa,0x8f,0x75,0x57,0x9e,0x70,0x8c,0xbc,0xfe,0xce,0x93,0x5b,0x0a,0x1f, + 0x96,0x8b,0x9a,0x64,0xff,0xed,0xaf,0xef,0xd7,0x5e,0x0c,0x38,0x78,0x2f,0xfe,0x89, + 0x1e,0x2a,0xa6,0x8d,0xe7,0xd3,0x6a,0xa9,0xcc,0xb5,0x4a,0x9f,0x4e,0x26,0x43,0x82, + 0x85,0xe0,0x7d,0x5e,0x45,0x59,0x71,0x50,0x06,0xde,0x43,0xae,0xf4,0x44,0x50,0x01, + 0x04,0x56,0x82,0xf5,0x56,0xae,0xeb,0x2c,0x04,0xfe,0x85,0xa2,0xc0,0x90,0xde,0xed, + 0xbf,0xfe,0xdb,0x43,0x36,0x06,0x73,0xc9,0xf2,0x90,0xf6,0xfc,0xba,0x7f,0xf0,0xcd, + 0xaf,0x3f,0x1c,0x24,0xbf,0xee,0x36,0x76,0x1a,0xcd,0xe4,0x57,0x44,0xbd,0xd9,0x6e, + 0xac,0x32,0x69,0xab,0xd0,0x03,0x90,0xd7,0x51,0xc5,0xf5,0xb7,0x83,0x97,0xb4,0xb1, + 0xc2,0x4e,0x69,0xdd,0x18,0xf6,0xf0,0x6c,0x98,0x3c,0xb9,0x85,0x93,0x0e,0xde,0xed, + 0x27,0x8a,0xc7,0x7d,0x8c,0x9e,0xc6,0x43,0x80,0x6d,0xca,0x78,0xae,0x2b,0x31,0xdb, + 0x30,0xe4,0x06,0xe2,0xbd,0x2f,0xe2,0xdd,0xd9,0x78,0x34,0x5d,0xc3,0xb1,0xfd,0x4e, + 0x63,0x74,0x20,0x82,0x8f,0xae,0x10,0x4e,0xe2,0xde,0x9d,0x82,0xd4,0xd0,0xd0,0x0c, + 0xd5,0x1d,0x77,0xdf,0x1e,0x9c,0xdd,0xde,0x3c,0x70,0x0f,0x6e,0x3c,0xcc,0xe8,0x1e, + 0x7c,0x95,0x18,0xce,0x66,0xf6,0x24,0x5a,0x33,0xfc,0xcc,0xd0,0x94,0x0d,0x3b,0xac, + 0xcc,0x6a,0xd4,0x29,0x36,0xbc,0xe7,0x74,0x08,0x31,0x1c,0xb2,0x06,0x81,0x56,0x54, + 0xbd,0x6b,0x82,0x02,0x30,0xe5,0x31,0x13,0xd4,0x90,0xc3,0xba,0x16,0xd7,0x08,0x7e, + 0x1c,0x00,0x16,0x5b,0x50,0x4e,0x7d,0xfd,0xde,0x88,0xf3,0x6c,0x42,0x2a,0xae,0x66, + 0x26,0x2c,0x46,0x89,0x01,0x68,0xee,0xfa,0xf0,0xff,0x1a,0x6e,0xae,0xd0,0xae,0xff, + 0x9c,0x9f,0x2b,0x14,0xfe,0x7f,0xbe,0xa3,0x2b,0x20,0xf1,0x7f,0x25,0x4f,0x57,0x40, + 0xe7,0xff,0x7c,0x57,0x57,0x40,0xe2,0xff,0x15,0xbe,0xae,0xfe,0x9f,0xe0,0xcd,0x4a, + 0x8d,0x7c,0xb6,0xeb,0xdb,0xbb,0x74,0x9b,0x65,0xd6,0xcf,0x3d,0x4c,0x15,0x3e,0xa7, + 0xd8,0xf1,0xde,0x7a,0xcf,0x56,0x96,0x7d,0x3b,0xd4,0xa9,0xfd,0x61,0xee,0x89,0x0f, + 0xfb,0x06,0x2a,0xbf,0x97,0x77,0x92,0xf8,0xbd,0x22,0x7e,0x26,0xed,0x68,0xe3,0xe1, + 0x8b,0x6e,0x2d,0x6d,0x37,0x77,0x9e,0x14,0x53,0x2a,0x37,0xe8,0xf0,0x4f,0xbd,0xdd, + 0x19,0x43,0x70,0x04,0x16,0x56,0x68,0xb2,0x45,0x8b,0x7d,0x35,0x5a,0x7d,0x1b,0x69, + 0x8c,0x8c,0x6f,0x59,0xfe,0x18,0xa2,0xa4,0x6c,0xce,0xd7,0x8e,0x61,0x47,0x1f,0x57, + 0x67,0xe1,0xbe,0x28,0x1c,0xb8,0x44,0x62,0x12,0x1c,0x3f,0xfc,0xf0,0xdb,0xd5,0x15, + 0xe3,0xc0,0x0a,0xd5,0x91,0x51,0x44,0xb5,0x05,0xdf,0xe7,0x5f,0x6b,0xef,0x4d,0x3e, + 0x30,0xd1,0xf9,0x22,0x3a,0x3f,0x71,0xbf,0x7e,0xf6,0x3d,0x79,0x71,0xb3,0x8a,0xb1, + 0x42,0x7c,0xd9,0xa9,0xe0,0x0d,0x27,0x47,0xb1,0xb8,0x6c,0xc5,0xb3,0x55,0xfa,0x3d, + 0x8b,0x38,0xab,0x96,0x1e,0xb8,0x8a,0x8b,0xb9,0x12,0x73,0x03,0xce,0xce,0x99,0xeb, + 0x58,0x81,0x2d,0x6c,0x27,0xdd,0xb9,0x44,0x57,0x72,0x23,0x52,0x78,0x21,0xe6,0xd0, + 0xd7,0x5e,0x74,0x39,0x48,0x82,0x2b,0xaf,0x83,0x70,0x40,0x4a,0xa6,0x83,0x3c,0x3e, + 0xac,0x4b,0x71,0x13,0x83,0x98,0x4c,0x77,0x1a,0x44,0xbf,0x7c,0x1f,0x73,0xb1,0xcf, + 0x4d,0x48,0x45,0x2e,0x0a,0x95,0xcd,0x2e,0xeb,0xf4,0xbd,0x70,0x98,0xcd,0x27,0x3c, + 0x5b,0x06,0x28,0xbf,0x18,0x3c,0xc8,0xfa,0x7c,0x00,0xa2,0x56,0xf4,0x95,0xe5,0x8c, + 0x09,0xae,0xba,0xa0,0xb5,0xc7,0xb5,0xbc,0x29,0x90,0xce,0xa8,0x97,0xcf,0x2e,0xb2, + 0xca,0xdd,0x0c,0xc1,0xca,0x76,0xe6,0xc1,0x5e,0x9f,0x68,0x6a,0xf1,0x74,0x0d,0x3e, + 0xf5,0xe7,0x8d,0xfb,0x86,0x06,0xc6,0xd7,0x7d,0x03,0x43,0xab,0xb6,0xe3,0xcb,0x96, + 0xe0,0xc8,0x8d,0x3b,0xb7,0x91,0x9f,0xbc,0x8f,0x1c,0xb5,0x27,0x74,0xa5,0x64,0x50, + 0xd3,0xf7,0x87,0xed,0xac,0x97,0x0e,0x5e,0x5a,0x78,0x9d,0xaf,0x79,0x3d,0x4c,0xe8, + 0xd8,0xd0,0x09,0x44,0xcb,0xf1,0xef,0xec,0x1f,0x80,0xa6,0xd0,0x26,0x82,0x50,0xc1, + 0x1e,0x8d,0x4b,0xf2,0x27,0xa9,0x8b,0xc4,0xe7,0x09,0x37,0xf8,0xf9,0xb9,0x3f,0x9c, + 0x52,0x25,0x17,0xf8,0x95,0xc2,0x3f,0xb3,0x85,0xc5,0x09,0xd2,0xe7,0x36,0x73,0x70, + 0x16,0x3d,0xc2,0x63,0xe3,0xe4,0x2a,0xfb,0x14,0xe3,0xe1,0xc3,0xd5,0x38,0x3a,0x7c, + 0x5c,0x94,0xf7,0xf8,0x08,0x88,0x15,0xaf,0xff,0xf6,0xb6,0xf3,0x6d,0x67,0x6a,0x3c, + 0xef,0x4e,0xd7,0x8a,0x25,0x79,0x00,0x21,0x6e,0xb7,0xbe,0x55,0xee,0x12,0xad,0x70, + 0x42,0xf8,0xee,0x7e,0xe0,0x50,0x41,0x81,0x12,0x50,0x93,0xd6,0xd8,0x3e,0x6b,0x98, + 0x97,0xf2,0x88,0x94,0xf8,0x2b,0xc6,0xf3,0xb9,0x0e,0x4d,0x5f,0x60,0xd7,0x7a,0x06, + 0xe3,0x2a,0xc1,0xd0,0x13,0xcd,0xab,0x25,0xf8,0x8d,0x6c,0x0a,0x47,0xf2,0xbc,0x33, + 0x54,0x61,0x90,0x1d,0x44,0x40,0x72,0x22,0xf1,0x02,0xbb,0x86,0x49,0x69,0x67,0x4d, + 0x48,0x04,0x5d,0xde,0x05,0x42,0x92,0xf0,0x17,0x2a,0x46,0x8a,0x72,0x7d,0x7e,0x37, + 0x6e,0xd8,0xdd,0xb8,0xcf,0xce,0xc2,0xa9,0x1f,0x67,0x57,0x9e,0x54,0x5e,0xd5,0x99, + 0x12,0x32,0x41,0x08,0x0a,0xce,0x8e,0xd8,0x09,0x2f,0x0e,0xba,0x27,0xcf,0xb7,0xe8, + 0x41,0xfd,0x09,0x08,0x4d,0x2d,0x98,0xcd,0x2b,0x9a,0x89,0x0c,0x26,0x09,0xbd,0x22, + 0x01,0xdd,0x9a,0xd1,0x4d,0x79,0xc9,0x66,0x97,0xfd,0x2a,0x3b,0x15,0x18,0x8c,0xe6, + 0xd1,0x20,0xcb,0x9c,0xa2,0x8d,0xb3,0xfb,0x11,0x5a,0x36,0x40,0xbd,0x1c,0x8a,0x91, + 0x8f,0x56,0xd0,0x1a,0x92,0xaa,0xcc,0xb5,0x3d,0xc1,0xc6,0x6b,0x96,0xef,0xcc,0x7c, + 0x4b,0xfd,0xdd,0x6b,0x83,0x25,0x6a,0x37,0x8d,0x05,0x7d,0xe1,0xfe,0xd0,0x84,0x3a, + 0x24,0x21,0x56,0x1c,0xdc,0xc7,0xf3,0xbc,0xdd,0x83,0x35,0xa5,0xa8,0x97,0x66,0x73, + 0xe8,0x46,0x59,0xb2,0xe0,0x97,0xf5,0x42,0xc5,0xa8,0xc0,0xc8,0x11,0x21,0x78,0x63, + 0xe1,0xb8,0x46,0x11,0xc1,0x71,0xed,0x1c,0xd5,0xc8,0xae,0x3a,0xc1,0x9c,0xed,0xa0, + 0xb8,0xf6,0xe7,0x63,0x57,0x54,0x65,0x47,0x12,0x20,0x27,0x58,0x27,0x9f,0x1c,0xaf, + 0xdf,0x99,0x40,0x18,0x5b,0x4d,0x0c,0xd6,0xd9,0x55,0x79,0xb9,0x91,0x78,0xb7,0xe1, + 0x0b,0x93,0x5d,0x73,0x32,0x0d,0x5d,0x61,0xe9,0x41,0x74,0xfc,0x12,0x6e,0xc6,0x7a, + 0x09,0xde,0xa7,0x12,0xa2,0x4c,0xfe,0xcc,0xdd,0xa3,0xfe,0x67,0xea,0x65,0xbf,0xf6, + 0x5c,0x2f,0xea,0x7c,0x49,0x2f,0x5a,0x65,0x79,0xf9,0xd6,0x68,0xbb,0x39,0xed,0x71, + 0xd8,0x42,0xea,0xc4,0x21,0x6e,0xc9,0x4b,0x12,0x2d,0x04,0x39,0xa9,0x39,0xdf,0x4a, + 0x0f,0x36,0xba,0xba,0xb3,0x9e,0xa2,0x34,0x6a,0x07,0x63,0xa5,0xf7,0x7d,0xa6,0x0a, + 0x1c,0x37,0x96,0x87,0x0a,0x3f,0x56,0x73,0x74,0x09,0xd7,0x6a,0xc0,0xfa,0xb7,0x1c, + 0x57,0x4f,0xc6,0x82,0xbf,0xff,0x7a,0x42,0xfb,0xaf,0x72,0x00,0x69,0x09,0xe0,0x21, + 0xc0,0xbe,0xa7,0x4b,0x3f,0x64,0x2c,0xa8,0x69,0xac,0xce,0xfb,0xbe,0x4b,0x7f,0x8e, + 0xf8,0x31,0x19,0x56,0x08,0x59,0x4f,0xbd,0x98,0x93,0xdf,0xb5,0x9d,0x40,0x44,0x3b, + 0xe5,0xc8,0x33,0x67,0xe7,0x31,0x21,0x37,0x1c,0x80,0x01,0x4e,0xd9,0xe5,0x9b,0x68, + 0x6d,0xc9,0x10,0x83,0xde,0x5f,0xd2,0xd6,0x63,0x48,0x29,0x71,0xee,0x5e,0x14,0xab, + 0x05,0x1d,0x8f,0xf3,0x81,0xfb,0x20,0x13,0x6b,0xd7,0xc6,0xf3,0x93,0x99,0x30,0xbd, + 0x2a,0xe9,0xaf,0x52,0xf6,0x83,0xff,0xf9,0x6e,0x76,0xd9,0xef,0x25,0xc1,0xa9,0xba, + 0x3e,0xa5,0xfb,0xf4,0xbf,0x8b,0xa3,0xf7,0xd7,0x44,0x09,0x4c,0x2b,0xc6,0x67,0x8b, + 0xbe,0xee,0xcf,0xb1,0xa7,0xd7,0x3b,0x57,0x94,0x5e,0x6c,0xd1,0xd1,0x06,0x6e,0x08, + 0xc7,0x41,0xd8,0xef,0x9e,0x61,0x48,0x91,0xc6,0xec,0xe5,0x05,0xd4,0x68,0x7d,0xcf, + 0xe1,0x82,0x82,0xff,0x44,0xbe,0x20,0x50,0x76,0x05,0xd6,0xdf,0x4c,0x6f,0xad,0x4e, + 0xbf,0x9a,0x0d,0x21,0x27,0xcd,0xe7,0xd3,0xd6,0xd6,0x16,0x6e,0x4d,0x34,0x60,0x03, + 0xd9,0x78,0xd2,0xd8,0x26,0x24,0xa4,0xb4,0xad,0xc9,0xd0,0x57,0x22,0x56,0x9d,0x8b, + 0x6c,0x3f,0x41,0xc9,0xa5,0xc6,0x00,0x0b,0x1b,0xc3,0xc7,0x19,0xb5,0xb7,0xf0,0x12, + 0xc0,0x34,0x50,0xfd,0xc7,0xdf,0xed,0x50,0x0e,0x01,0xef,0xe5,0x07,0x19,0x7c,0xc9, + 0xb2,0xdd,0xd3,0x20,0xbf,0x29,0xae,0x7a,0x49,0xf5,0x37,0xa0,0x1a,0x4c,0xe9,0x4a, + 0x19,0x53,0x89,0xe8,0x03,0x06,0xe4,0xaf,0x0e,0x6e,0xdb,0xc4,0xe5,0x3e,0xb6,0xf4, + 0xb3,0x3e,0x88,0x49,0xd1,0x7f,0xd5,0x12,0xea,0xe1,0xae,0xa5,0x9a,0x2b,0x5d,0x4b, + 0xf5,0x10,0x06,0x84,0x5d,0xf4,0x9f,0xf7,0xe7,0xaf,0x86,0x7d,0x7a,0xfc,0xfe,0xd3, + 0xeb,0x5e,0xf4,0x58,0x66,0xd7,0xe3,0xb8,0xc1,0x14,0x7c,0x33,0x60,0x87,0x22,0x23, + 0xb4,0x26,0x7a,0x4c,0x52,0xf1,0xe3,0x07,0xfa,0xa2,0x42,0xa7,0x92,0xff,0x2e,0xf5, + 0x41,0x25,0x98,0xdf,0x37,0xb9,0x59,0x1b,0xa1,0xd3,0x9b,0x40,0x3d,0xd6,0xa2,0x55, + 0x9a,0xe9,0xbe,0xfb,0x44,0x63,0x34,0xf3,0xb3,0x72,0x1e,0x7f,0xc2,0xb3,0xaf,0xad, + 0x80,0x83,0x88,0x3b,0xb5,0xb1,0xb7,0x36,0xd9,0x8a,0xbb,0x21,0x7b,0x78,0xa2,0x4f, + 0x6d,0xd8,0x51,0x76,0xae,0x08,0xf8,0x1e,0x74,0x5d,0x26,0x14,0x4a,0xd3,0xa7,0xbe, + 0xe0,0x2e,0xa5,0x0d,0xa6,0xab,0x07,0xe7,0x5b,0xdf,0x61,0x5b,0x0b,0x53,0x1c,0xfd, + 0xe9,0x96,0x40,0xb2,0xe9,0x65,0xa8,0x7d,0xec,0x77,0x08,0x50,0xf1,0x82,0xbb,0x13, + 0x6a,0x5d,0x45,0xaf,0x1a,0x85,0xb6,0x55,0xc4,0x33,0xbf,0x08,0xa7,0x21,0xa7,0x13, + 0x78,0x49,0x08,0x2b,0xbb,0x1a,0x43,0x78,0x30,0xc5,0x49,0x6b,0x48,0xb1,0x2b,0xc4, + 0xd2,0xb0,0xbd,0x01,0xaa,0x05,0xfb,0xaf,0xde,0x1e,0xbc,0x7e,0xfb,0xea,0x4d,0x1a, + 0x7e,0x2d,0xff,0x99,0x0f,0x80,0x4a,0x17,0x64,0xbd,0xd8,0x0a,0xc3,0x84,0x9d,0x83, + 0xf6,0x5a,0x3c,0xda,0x12,0x98,0x10,0x92,0x07,0xbf,0xe2,0xed,0xe5,0x70,0x20,0x2f, + 0xa4,0x6a,0x7a,0x9f,0x5d,0x3e,0x7b,0x22,0xef,0xb9,0xfa,0x76,0xdf,0xb8,0x7f,0xd4, + 0x22,0xc6,0xf0,0x02,0x9d,0x89,0x56,0x34,0x4f,0x63,0xc3,0xe8,0xdc,0x9d,0x95,0xa4, + 0x65,0xb9,0xc7,0x59,0xeb,0xdd,0xaa,0x1b,0xe2,0x39,0xe2,0x23,0x26,0xa7,0x67,0xe7, + 0xad,0x31,0xac,0x43,0x12,0xb2,0x82,0x6b,0x2d,0xee,0x92,0x1e,0xae,0x6a,0x7e,0xa2, + 0x07,0xe3,0xcc,0x3b,0x6b,0x1d,0x1e,0x25,0x63,0xde,0x93,0x03,0x9a,0x37,0xf3,0x74, + 0x9c,0x36,0xc3,0x0b,0x49,0xab,0xad,0x05,0xa9,0x19,0x18,0x86,0xd4,0x04,0x78,0xb8, + 0x4b,0x68,0x99,0x3e,0x40,0x4f,0xf4,0xe7,0x68,0x3e,0xbf,0x49,0x0e,0x7e,0x7e,0x35, + 0x9d,0x9c,0x5e,0xe0,0xd9,0x38,0x58,0xc9,0xdf,0xc4,0x97,0x1d,0xbe,0x13,0xef,0xd5, + 0xb6,0x1a,0xa0,0x37,0x30,0x58,0x7a,0xd9,0x9d,0x92,0xbd,0x85,0xc1,0x95,0x49,0x25, + 0x14,0xa0,0x8b,0x27,0xbc,0x0d,0xcb,0x33,0xdd,0x21,0xbe,0xdb,0xd5,0xd8,0x1c,0xab, + 0x7c,0x15,0x65,0xf1,0x42,0xa6,0xbb,0x72,0x0c,0x48,0xc3,0xb3,0x4f,0x46,0xed,0x38, + 0x99,0x01,0xe0,0xce,0x82,0xb7,0x33,0xec,0xcd,0x66,0xb8,0x20,0x4c,0x1e,0x57,0x26, + 0x24,0xe0,0x34,0xb2,0x21,0xb1,0x7d,0x52,0x77,0x46,0xd5,0x65,0x41,0x6e,0x45,0x76, + 0xbb,0x3c,0x96,0x08,0xa2,0x51,0xbc,0xa0,0x41,0x31,0x4f,0xbf,0x8a,0xc2,0xbf,0x70, + 0x52,0x88,0x18,0x7e,0x0d,0x62,0x7d,0xb4,0x44,0xa3,0x9c,0x74,0x84,0xf7,0x82,0x5f, + 0x61,0xb6,0x44,0xbc,0x85,0x07,0x1c,0xef,0x2c,0xe5,0x8e,0x73,0x34,0x6f,0x1c,0x5f, + 0x20,0x2b,0xfe,0xa6,0xe8,0x9b,0x3c,0x35,0xaf,0x2e,0x8a,0x17,0x73,0x9f,0xeb,0x49, + 0x41,0x77,0xc9,0x0e,0x2e,0x34,0xdb,0xc8,0x41,0xbe,0x2b,0x5a,0xcb,0x66,0xad,0xe3, + 0x73,0x24,0x20,0x1f,0x6f,0xc2,0xa2,0xad,0xc3,0xcd,0xe7,0x2f,0xc2,0xa3,0xad,0xf3, + 0x44,0x2b,0x38,0xcd,0xc1,0x17,0xe1,0x66,0xd8,0x0a,0xf9,0x20,0x39,0x4c,0xc2,0xe7, + 0xf4,0x3c,0x9c,0xd3,0xe3,0x0b,0x7a,0x3c,0xa7,0xc7,0xc7,0xe1,0x63,0x3c,0xfe,0xf3, + 0x6a,0x82,0x97,0xbb,0xc3,0xd3,0xa3,0x3b,0x87,0x30,0xbe,0x7e,0x1f,0x02,0x65,0xbc, + 0xe0,0xd9,0xc3,0x3b,0xd0,0xb4,0x9a,0xc3,0x33,0x1c,0x25,0xed,0xcd,0x81,0x30,0x04, + 0x45,0x34,0xd0,0x39,0x52,0x08,0x63,0x04,0x9e,0x23,0xbd,0x00,0x97,0x12,0x1b,0x74, + 0x65,0x56,0x82,0x10,0x29,0x27,0x37,0x58,0x62,0x4d,0xad,0x33,0x12,0xe4,0x29,0x3e, + 0x10,0x60,0xc7,0x6c,0x7e,0x5b,0x36,0x08,0xaa,0xb6,0x7b,0x4d,0xe0,0x7e,0x06,0x53, + 0x04,0xdc,0x3e,0x5e,0x04,0x26,0xf3,0xd1,0x93,0x63,0x90,0x30,0xe1,0x3c,0x46,0x42, + 0x6d,0xc9,0x36,0x38,0xae,0xcc,0xa5,0xbb,0x8b,0x30,0x89,0xfc,0x8a,0xe2,0x5a,0x68, + 0x76,0x1b,0x8a,0x5e,0x9c,0x37,0x81,0x23,0x64,0x45,0x78,0xb5,0xe8,0x8d,0x02,0x66, + 0xf3,0xbf,0xf6,0x67,0x91,0x90,0xf8,0xec,0x26,0xcd,0x00,0x79,0xb3,0x5c,0x62,0x8a, + 0x8e,0xd2,0xad,0x7f,0x44,0xd7,0x9d,0x8f,0xbd,0xda,0xc7,0x46,0xfe,0x27,0xea,0xb4, + 0xf8,0x37,0xee,0xc4,0x5b,0x8d,0xfe,0x6d,0xff,0x34,0x3a,0xbb,0x89,0x85,0x8c,0xe9, + 0xa8,0x33,0x3a,0xdc,0x3e,0x6a,0x45,0x9c,0xff,0x6a,0x7c,0x39,0xa6,0x38,0x0c,0xa4, + 0xcf,0xa3,0x7d,0x91,0x21,0xff,0x56,0x1d,0x42,0x48,0x54,0x5f,0x7e,0x85,0xec,0xe4, + 0xe3,0x93,0xb2,0xc7,0x59,0x2d,0x0d,0x29,0x3d,0x6c,0x07,0xd6,0x7f,0x5b,0x5b,0xc1, + 0xbb,0x83,0xbd,0xe3,0x97,0x3f,0xef,0xbd,0x05,0x2f,0x3d,0x3e,0xd8,0xfb,0x29,0x45, + 0xe4,0xfd,0x2e,0x01,0x6e,0xf0,0x95,0x11,0x2e,0x8e,0x92,0xaa,0xca,0xe3,0x0f,0x52, + 0x20,0x4a,0xea,0x06,0x9c,0x97,0x4d,0x1e,0xe5,0xd0,0x20,0x41,0x01,0x7c,0x0a,0xb1, + 0x21,0x43,0x1d,0x2d,0x87,0x93,0xcf,0x61,0xaf,0x93,0x81,0x88,0x51,0x58,0xcb,0xdf, + 0x6b,0x61,0x1c,0xb6,0x32,0x87,0x6e,0xd0,0x61,0x44,0xe4,0xab,0x38,0x81,0xea,0x3d, + 0x03,0xed,0xe8,0x27,0xa5,0x3f,0xcb,0xe5,0xe2,0xce,0x90,0x83,0xf8,0x3b,0xb3,0xb1, + 0x94,0x23,0x86,0xf1,0xa3,0x19,0x81,0x04,0x07,0x7e,0x01,0x95,0x47,0xac,0x8f,0x7c, + 0x20,0x50,0x67,0xef,0x78,0x40,0x1a,0x08,0x0f,0xde,0xed,0x07,0xfc,0x21,0x23,0xdd, + 0x07,0x56,0xaf,0x9f,0x0f,0x60,0x78,0xb1,0xf7,0xfe,0x75,0xf0,0xd3,0x2b,0xb8,0xc8, + 0xed,0xe2,0xfa,0x17,0x7b,0x89,0xcb,0x88,0xb8,0x19,0x95,0xcb,0x65,0x89,0xcf,0x82, + 0xcd,0x4d,0x91,0x9d,0xf7,0x4e,0xd0,0xc1,0x2f,0xcd,0x1c,0x80,0x19,0xba,0x74,0x33, + 0x1c,0x06,0xa5,0x74,0x14,0x5c,0xfa,0x8a,0xc1,0xc1,0x85,0xb0,0x19,0xdb,0x30,0x05, + 0x94,0x3c,0xb6,0x37,0xaa,0xd9,0x0a,0x41,0x74,0xa9,0x8c,0x08,0x7c,0xc4,0xae,0x9f, + 0x47,0x59,0x2e,0x4f,0xf5,0x71,0xa0,0x63,0x51,0xab,0x41,0x9e,0xea,0x8a,0x52,0x80, + 0x13,0x61,0x3f,0x13,0xf3,0x4c,0xcc,0xbe,0x27,0xcd,0xed,0x78,0x81,0xa4,0x82,0x82, + 0xa9,0x45,0xc3,0x98,0x06,0xfd,0x1b,0x7a,0x05,0xba,0x4a,0xe8,0xd9,0x6c,0x32,0xe3, + 0x26,0xf1,0x53,0x14,0x52,0x22,0x86,0x9c,0x7e,0x93,0xd2,0xa9,0x6c,0x37,0x71,0xd8, + 0xdf,0xc3,0x6b,0xaa,0x75,0x3d,0xb2,0xeb,0x6a,0xcf,0x21,0xe2,0xdf,0x14,0x35,0x68, + 0x9b,0x66,0x8d,0x3f,0x32,0xa2,0x00,0xfa,0x0e,0x8d,0xb3,0x48,0x22,0x6d,0x99,0x5c, + 0xc6,0x26,0xab,0x85,0xd2,0xd5,0x98,0x2e,0x10,0xb0,0xed,0x0f,0x7b,0xb2,0xe3,0x53, + 0x78,0x3d,0xc1,0x07,0xb2,0x79,0xe1,0x34,0x82,0xee,0xca,0x64,0xfa,0xc3,0x14,0xfd, + 0x88,0xca,0xde,0xdc,0xcc,0xdb,0x03,0x6c,0x11,0x36,0x59,0x7a,0xb5,0x6f,0x11,0xe0, + 0x8f,0x46,0x9f,0x7e,0x97,0xcb,0x28,0xe4,0x81,0x13,0xd6,0xf2,0x2c,0xe0,0x83,0xfd, + 0x9c,0x1a,0x79,0x1a,0x52,0x70,0x70,0x06,0xb1,0xe7,0x0f,0xf3,0x8b,0x77,0x68,0xdf, + 0xf0,0x86,0xbf,0x42,0x83,0xbe,0xd5,0xa3,0x7f,0xe0,0x99,0x7a,0xd8,0xe5,0x25,0x53, + 0x5c,0x4b,0x37,0xdd,0x4c,0xc1,0x3a,0x75,0x01,0xd1,0xa9,0xb2,0x18,0xf5,0xb1,0xf9, + 0xea,0xb5,0x42,0x58,0xdb,0x1c,0x84,0x89,0x89,0xa2,0x98,0xb5,0x16,0xa1,0xb0,0xcd, + 0xfa,0x01,0x78,0x2c,0xf8,0x18,0x79,0xca,0x12,0x93,0xc8,0x2d,0xa2,0x72,0x78,0xc7, + 0x05,0xb6,0xfe,0x7b,0xff,0xdd,0xdb,0x46,0xc6,0xcb,0x11,0xec,0x15,0x23,0xae,0xc4, + 0x59,0x3c,0x46,0x97,0x1f,0xfa,0xff,0xc4,0x4a,0x20,0xe4,0xe8,0x32,0x39,0x7e,0x83, + 0x0a,0xf1,0x5b,0x5e,0xb2,0xa3,0x6f,0x0d,0x0b,0x92,0x99,0x71,0x3a,0xfb,0x34,0x9d, + 0x4f,0x36,0x37,0xcd,0x2f,0x2d,0x1d,0x1f,0xd8,0x73,0xe5,0x5f,0xf9,0x4a,0x57,0x5c, + 0x9d,0x1c,0x75,0x51,0x06,0x33,0x9f,0x33,0x10,0x99,0x17,0xa5,0xb4,0xd9,0x1e,0x3c, + 0xff,0xb6,0x3d,0xa8,0xd5,0xe2,0xee,0xe1,0xe0,0x28,0xfd,0x15,0x6d,0x6d,0xf0,0xf1, + 0x49,0xc4,0x8f,0x33,0xce,0x1e,0xc5,0x5f,0xe3,0x36,0x0d,0x32,0xaf,0x10,0x22,0x46, + 0xdd,0xa9,0x11,0x21,0xba,0xc5,0xaa,0x7a,0x82,0x86,0x30,0x38,0x1e,0x9f,0x6f,0x3f, + 0xeb,0x84,0x4d,0x50,0x07,0x1c,0x1e,0x9e,0x49,0x26,0xb2,0x2c,0x6f,0x53,0x91,0x18, + 0x2b,0x14,0x98,0x27,0xc2,0xb7,0x12,0x93,0xc2,0x28,0xfb,0xb1,0x6f,0x0c,0x52,0x89, + 0x2a,0x10,0x63,0x1e,0x1f,0xe6,0x87,0x9e,0x47,0xd8,0x0a,0xa1,0x11,0xaf,0xba,0xf6, + 0xf8,0xed,0x0f,0x01,0xd6,0x1f,0x5a,0xd2,0x82,0x59,0x91,0x23,0x23,0xe2,0x27,0x8f, + 0x22,0x24,0x21,0x73,0xb6,0xf9,0x96,0x0f,0x96,0x23,0xc0,0x52,0x81,0x59,0x9f,0x93, + 0xe3,0x98,0xd1,0x21,0x06,0x28,0x77,0xe8,0x5e,0x42,0x7c,0x63,0xf9,0xc6,0xbb,0xa3, + 0x67,0x3a,0x43,0x81,0x62,0x7d,0x7a,0x40,0xe5,0x11,0xae,0x68,0x2d,0x41,0x4f,0xae, + 0x0f,0xad,0x0a,0x1b,0xae,0x9b,0xbf,0x15,0x2d,0x5b,0xd7,0x30,0xa4,0x78,0x92,0x75, + 0x8c,0xa6,0x28,0xd1,0x5c,0x4b,0x09,0x97,0x7a,0x6e,0x1d,0xd8,0x2d,0xbd,0x31,0x26, + 0x13,0x28,0x54,0xc5,0xf7,0x0e,0x24,0xf8,0x67,0xbb,0x5a,0xa2,0x6f,0x61,0xb0,0xae, + 0x43,0x6c,0xf1,0xc2,0x29,0x75,0xa3,0x13,0x84,0xff,0x66,0xcb,0x84,0x70,0xa3,0xf5, + 0xd0,0x32,0x1b,0xa1,0xe9,0x6e,0xea,0x60,0x37,0xc6,0x45,0xbc,0x96,0xd2,0xce,0xbe, + 0xc4,0x0c,0x04,0x4a,0x36,0xfb,0x9e,0x7c,0x8d,0x1a,0x0e,0xa0,0x39,0x4f,0x41,0xab, + 0xbf,0x90,0x93,0x66,0xf1,0x71,0x73,0x68,0xbb,0x40,0x06,0xc5,0xda,0xc8,0x6a,0x20, + 0x63,0xf3,0x93,0x8b,0xb7,0x82,0x95,0x39,0xda,0x8b,0x5d,0x21,0x5a,0x50,0xe1,0xd9, + 0x82,0xfc,0x48,0x94,0xfd,0x97,0x23,0x16,0x8e,0x90,0xb0,0x0e,0x03,0xfa,0x9e,0xa3, + 0x20,0xb0,0xb1,0xfc,0x7a,0x48,0x30,0x6c,0x35,0x16,0x4a,0xbe,0xdd,0xf5,0x00,0x1c, + 0x07,0x73,0x2d,0x44,0xe9,0x5c,0x75,0x3d,0xb0,0x13,0xb0,0x32,0x76,0xc6,0x57,0xf8, + 0x39,0xe1,0x2b,0xab,0x5c,0x62,0x3a,0x0e,0x4c,0x03,0x24,0x72,0xde,0x37,0x7b,0x6f, + 0x1b,0xa1,0x56,0xae,0xf1,0xba,0xca,0x95,0x73,0xf4,0x2e,0x54,0x28,0xf1,0xa9,0xa8, + 0xfa,0xcc,0x0e,0xe6,0x65,0x95,0xa1,0x11,0x4f,0xbc,0x42,0x8c,0x43,0x7a,0x85,0x74, + 0xdc,0xd7,0x03,0x76,0x80,0xf6,0xcd,0x7e,0x3e,0xf8,0x15,0x3b,0x74,0x89,0x5e,0xb2, + 0xda,0x95,0xbd,0x57,0x08,0xa9,0x7f,0x50,0x46,0xae,0x72,0xb2,0xd6,0x7e,0x89,0x0e, + 0x70,0xe7,0x70,0x61,0x36,0x88,0xc0,0x98,0xa6,0x75,0x30,0xdc,0xc2,0xdf,0x2d,0xb9, + 0x87,0x52,0x5e,0xe1,0x33,0x00,0x65,0x73,0x76,0xec,0x95,0x66,0xfc,0xd3,0xc6,0xab, + 0x51,0x13,0x20,0x81,0x1e,0xda,0xc5,0x50,0x4d,0x1f,0x3d,0x02,0x10,0x1e,0xda,0x3a, + 0x71,0x38,0x09,0x48,0xb5,0xa9,0x98,0x6c,0x4e,0x5e,0x19,0x0e,0xc8,0xfc,0x06,0x73, + 0x8c,0x3f,0xcd,0xe5,0xe5,0xd8,0x7c,0x43,0x46,0x4d,0x82,0x51,0x49,0x6a,0x01,0x80, + 0x83,0x1d,0xcb,0xe9,0xda,0x72,0xf9,0xf4,0xc9,0xb6,0x0c,0x63,0xf7,0x50,0x76,0xdd, + 0x1c,0xf7,0x10,0xc0,0xa8,0xb3,0xd9,0x16,0xe1,0xc3,0x6f,0xc7,0x53,0x7a,0xe5,0x8f, + 0x1e,0xfb,0x25,0x20,0x4d,0x3d,0xce,0xf2,0x64,0xc2,0xdb,0x51,0x76,0x30,0x1c,0xa7, + 0x1c,0xe7,0xd0,0x5c,0xa0,0xc3,0x65,0x18,0x88,0x53,0x8e,0x27,0x92,0xc4,0x40,0x9c, + 0x6f,0x9f,0x54,0x98,0x56,0x31,0x19,0xbd,0xb7,0x65,0xb5,0x49,0x33,0xfa,0xe9,0x9e, + 0x0c,0x70,0x9e,0x30,0xe8,0x43,0xc2,0x6f,0x72,0x46,0xa3,0xfc,0x48,0x8b,0x1e,0xe9, + 0xf0,0x72,0x8f,0xd6,0x46,0x59,0x83,0xdd,0x1d,0xf5,0x8f,0x09,0x04,0x19,0x50,0x31, + 0xf9,0xda,0x1c,0x69,0x42,0x33,0xf1,0x92,0xca,0x79,0x9a,0x71,0x0b,0xf5,0x10,0x77, + 0x6a,0x70,0x6f,0x8c,0x7a,0xd9,0x8b,0x66,0x0c,0x9f,0xef,0xc7,0xbf,0xee,0xfd,0x2d, + 0x2d,0x12,0x19,0x17,0xda,0xb6,0xc9,0xae,0xad,0x9d,0xef,0x5a,0x90,0xc2,0xbf,0xc7, + 0xe0,0x57,0xfd,0xfc,0x0b,0x9f,0x54,0x65,0xf4,0xa3,0x49,0x7c,0x0d,0x03,0x69,0xfc, + 0x4b,0x89,0x2c,0xec,0x7f,0x4f,0x6f,0x2f,0x51,0x7e,0x24,0x5f,0xb8,0x32,0xe1,0x1d, + 0x12,0x2a,0xdc,0x99,0x73,0x28,0x81,0x12,0x51,0x80,0x78,0x5b,0xcf,0x27,0x0e,0x07, + 0x0e,0x77,0x61,0x05,0x03,0xec,0xb2,0xbe,0x86,0x60,0x5a,0xec,0x41,0x25,0x41,0x6a, + 0x34,0x5c,0xf8,0x24,0xe5,0x42,0x24,0x72,0x78,0xdc,0x3e,0xf1,0x34,0x19,0xca,0xd7, + 0x84,0x5a,0x93,0x1e,0x6f,0xe1,0x8d,0x7d,0x44,0xbc,0x38,0x29,0xb1,0x97,0x57,0x07, + 0xbf,0xbd,0x0f,0xb5,0x18,0xe5,0x8d,0x02,0x7e,0x47,0xc2,0x5d,0x39,0x0f,0x38,0x57, + 0x78,0x27,0x8d,0x11,0xdb,0xd8,0xd5,0xcc,0xb5,0x24,0x75,0xa9,0xc4,0x67,0x0d,0x94, + 0x82,0x15,0x88,0x32,0x2d,0xf4,0x36,0x12,0xaa,0x50,0x29,0xd4,0x6d,0x77,0x77,0x71, + 0xcb,0x7e,0xad,0xd8,0x24,0x4c,0x0d,0x0b,0x11,0xa0,0x74,0x2a,0x4f,0x18,0x4e,0x87, + 0x47,0xba,0xca,0x1a,0x8e,0x12,0x2f,0xac,0x7d,0xd4,0x9d,0x6e,0xa8,0xf1,0xbd,0x4c, + 0x40,0xcb,0x66,0x44,0x00,0x17,0x1a,0xc0,0x01,0x09,0x77,0x1e,0xee,0x7d,0xb3,0x55, + 0xe9,0x37,0xe4,0x82,0x2b,0x36,0x29,0xb2,0x1f,0x5b,0xac,0x1a,0x10,0x61,0x61,0xf3, + 0xcc,0x17,0xa3,0x70,0xce,0x50,0xe7,0xf0,0xbb,0x9f,0xc8,0x71,0x53,0xdb,0xda,0x7d, + 0xb2,0x9f,0xf9,0x9d,0x26,0xab,0xac,0x4a,0x1b,0x10,0x42,0x34,0xba,0x8e,0x17,0x87, + 0xe1,0x5f,0xf2,0x50,0xea,0x09,0x3d,0x1a,0x25,0x22,0x3f,0x73,0x60,0x88,0x23,0x5f, + 0xcc,0x1a,0xf4,0x08,0x37,0xfc,0xad,0xee,0x55,0x54,0xf4,0x15,0x4a,0x5e,0x33,0xf4, + 0x54,0x2b,0x45,0xdb,0x92,0x0a,0x38,0x08,0x10,0x46,0x12,0x69,0x1b,0x7d,0x04,0x82, + 0x11,0x74,0x67,0x23,0xba,0x13,0xfe,0x89,0x57,0x36,0x7c,0x0f,0x78,0x3d,0x11,0x6f, + 0xe0,0x48,0xc2,0x5c,0xc7,0x42,0xca,0x8f,0x1c,0xd3,0x9b,0xd6,0xc5,0x8d,0xab,0x29, + 0x4d,0x67,0x3a,0xb9,0xfe,0x9e,0x2c,0x4c,0xdc,0xd6,0x4b,0x77,0xd2,0xd9,0x10,0x0d, + 0x04,0x5d,0x3c,0x58,0x9d,0xc4,0xfd,0x4f,0x9f,0xd0,0x1d,0x57,0xb0,0x5b,0xa6,0xd8, + 0x7e,0x3d,0xd3,0x23,0x56,0xe0,0x7a,0xb7,0x5b,0x28,0xa9,0xed,0x42,0xac,0xe3,0xfa, + 0xf4,0x1d,0x28,0x71,0x3f,0x68,0x1f,0xb0,0x98,0xc5,0x53,0xb9,0xd8,0x57,0xa7,0xcd, + 0x84,0x5f,0x70,0x96,0x0c,0xaa,0xa5,0xa4,0xbc,0xb5,0xb4,0xb3,0xf2,0x89,0x1d,0x18, + 0x46,0xc2,0xd1,0x81,0xa9,0xa3,0x4f,0x90,0xf9,0x63,0x6a,0xf8,0x92,0xad,0xe5,0x46, + 0xd5,0xde,0x72,0x91,0xd7,0xda,0xca,0x1f,0xee,0x30,0x06,0x36,0x7c,0xcd,0x85,0xab, + 0x0e,0xf0,0xf6,0xec,0x3a,0x8b,0xb3,0x56,0xbe,0xd5,0x4e,0xfe,0x68,0xfd,0x81,0x99, + 0x6c,0x86,0xae,0x21,0xad,0x86,0xd1,0x8f,0x69,0xcc,0xbd,0xa2,0x13,0x71,0x50,0x17, + 0x78,0x83,0x27,0xe6,0x01,0xeb,0x93,0x62,0x76,0x5d,0xd3,0x8e,0xe0,0xda,0x3b,0x3b, + 0x17,0x76,0x39,0x1f,0xa7,0x45,0xa9,0x78,0x0b,0x59,0x3e,0xc5,0x43,0x03,0x2b,0x37, + 0xdf,0xe6,0x77,0x84,0xdc,0x3e,0x77,0x47,0xad,0x56,0xf4,0x8d,0x1e,0x30,0x58,0xe5, + 0x60,0x8b,0x02,0xe4,0xd8,0x0a,0x95,0x99,0xba,0x9f,0x9c,0x62,0xdd,0xb0,0x2b,0x49, + 0xa1,0xc9,0x94,0xa1,0xa3,0xf1,0xf2,0xdd,0xb1,0x45,0x0b,0x4d,0x65,0x4f,0x7b,0x74, + 0xbe,0x15,0x7e,0xe2,0xa9,0x67,0xb4,0x25,0x45,0xcd,0xce,0x68,0xbf,0x6d,0x90,0x3a, + 0x09,0xcc,0xc2,0x99,0x0d,0x8c,0x19,0x37,0x7e,0x66,0x86,0x9f,0x35,0x14,0xdb,0xfe, + 0xb0,0x44,0x39,0x06,0x2e,0x36,0x3f,0xa0,0xf4,0x43,0x99,0xa5,0xc7,0x2b,0x85,0xcf, + 0xae,0x23,0xcb,0x6d,0x43,0x55,0x37,0x21,0xc3,0x08,0x3f,0xe4,0x9d,0x96,0xbf,0x4a, + 0x30,0x5d,0x3c,0x15,0xd9,0xa2,0x82,0x20,0x7e,0xa5,0xd5,0xec,0x97,0x2b,0x0f,0xef, + 0x68,0x80,0xea,0x48,0x08,0xb9,0x76,0x6b,0x8a,0x16,0x86,0xb8,0x0b,0x56,0xfb,0xe8, + 0x6c,0x44,0x1a,0xa6,0x63,0x79,0x61,0x02,0x98,0x3d,0xc4,0x7c,0x2a,0x2b,0xf3,0x22, + 0x25,0x46,0x55,0x3b,0x1d,0x45,0xcf,0xac,0x6f,0x45,0xd6,0xeb,0xbf,0x83,0x19,0x41, + 0x44,0x09,0x09,0xf1,0x9f,0xc4,0xf4,0x52,0x42,0xf7,0x68,0xff,0x0a,0x71,0x5d,0x76, + 0x93,0x24,0xb9,0xa7,0x04,0xb4,0xb9,0x49,0x7f,0x1b,0xf4,0x0e,0xe5,0x18,0x88,0xa2, + 0x0b,0x84,0xc3,0xd9,0xc4,0xa3,0x4f,0x96,0x73,0xf8,0x4e,0xbe,0x78,0xb4,0xec,0x0c, + 0xf7,0xce,0x21,0xa9,0xf2,0x11,0xd7,0x49,0xf6,0xda,0xa3,0x29,0x05,0x64,0xe5,0x57, + 0xe5,0x31,0x44,0x5d,0x51,0x77,0xc6,0x0b,0x07,0x52,0x06,0x2b,0xa7,0xd9,0x9d,0xa1, + 0x4d,0x48,0xe9,0x8f,0x79,0x95,0xd8,0x2a,0xd2,0xdd,0x77,0x1e,0xfb,0xe7,0x03,0xa3, + 0xd7,0x72,0x99,0x91,0x86,0x6e,0x71,0x68,0x17,0xb7,0x9d,0xd7,0x14,0x82,0xe7,0x17, + 0x2d,0x0b,0xee,0xe2,0xb8,0x86,0x63,0xdc,0xc7,0x1f,0xb4,0xc7,0xf3,0xc6,0xd1,0x88, + 0x17,0x4a,0xb9,0x8d,0x66,0x3a,0x91,0x80,0xa3,0xfd,0x6e,0xa4,0x01,0x7a,0x6a,0x7b, + 0x53,0x18,0x83,0xc9,0x1e,0x82,0x79,0x29,0xe8,0x06,0xa7,0x04,0x67,0x45,0x5d,0xc3, + 0x60,0x9d,0xd9,0xf6,0xe8,0x91,0xf4,0x94,0x14,0x27,0x6f,0xca,0x76,0x57,0x30,0xbd, + 0xff,0x00,0xcf,0x73,0x59,0x9e,0x3f,0xe9,0x0a,0xa2,0x7e,0x26,0x5f,0x62,0xd3,0xfb, + 0xc1,0x58,0xa3,0x58,0x6a,0x50,0x0b,0x27,0xa2,0xee,0x7f,0x98,0x65,0xbd,0x9c,0x5c, + 0x0d,0x7b,0x64,0x98,0x92,0x09,0x36,0xea,0x33,0xda,0x84,0x36,0xe7,0xdb,0xa2,0x6b, + 0xb0,0x6b,0x78,0x3c,0xce,0x11,0x26,0xcf,0x26,0x74,0x52,0x6d,0x2c,0x40,0x31,0x11, + 0xf5,0x38,0x32,0xcb,0x53,0x84,0xb1,0x68,0x7e,0xfd,0xb0,0xb9,0xa9,0x8f,0x8d,0xf5, + 0x43,0x41,0x94,0x4f,0x7c,0xb4,0xae,0xa0,0x20,0x8b,0xc2,0xf5,0xfa,0x1c,0x7e,0xca, + 0x83,0x29,0x69,0x25,0x95,0xe0,0x47,0xc9,0xa1,0x17,0x0c,0x63,0xb5,0xae,0x92,0x7b, + 0x62,0x28,0xb3,0xd1,0xaa,0x55,0xd3,0xc2,0x90,0x28,0x24,0x48,0xf8,0x8d,0x72,0xe8, + 0x05,0x83,0x01,0xa8,0xc8,0xa3,0xcb,0x78,0x41,0xe2,0x2d,0xd4,0xd9,0x50,0x37,0xfe, + 0x6f,0xac,0x8a,0xff,0x9b,0xf5,0x8c,0x73,0x56,0x15,0x69,0x4f,0x70,0xf1,0x81,0x91, + 0xb7,0x12,0x3e,0x07,0xa1,0x36,0xa2,0x08,0xa3,0xf9,0x4b,0xcd,0x4b,0x32,0x4a,0x66, + 0xe9,0xa9,0xd9,0xb4,0x27,0xff,0xc4,0x13,0xa9,0x3b,0x70,0xc0,0xc6,0x3b,0x64,0x36, + 0x29,0xb8,0x41,0x22,0x69,0x11,0x98,0x92,0xd1,0x28,0xbd,0x6c,0x8c,0x78,0xb4,0x6d, + 0xfd,0x83,0x40,0xa3,0xc3,0xed,0xfa,0x77,0x47,0xf1,0xc7,0x46,0xf4,0xf1,0xa6,0x16, + 0x7f,0xb5,0x15,0xc7,0xe6,0xc0,0x3d,0x4b,0xa3,0x7f,0x36,0xb8,0x10,0xda,0x17,0xc5, + 0x87,0x35,0x3a,0xb5,0xac,0x6f,0x1f,0xf1,0xd9,0x1d,0x2f,0x16,0x69,0x76,0x38,0x3a, + 0xdc,0x39,0x3a,0x12,0x93,0x20,0x24,0xf0,0x8c,0xe9,0x84,0x61,0x4b,0x14,0xef,0xd7, + 0x98,0x33,0xc6,0xf9,0x07,0x35,0x79,0x83,0x9c,0xde,0x98,0x58,0x68,0x2d,0x15,0x09, + 0xe9,0xb5,0x4d,0x1f,0x9c,0x78,0x65,0x0e,0x88,0x7e,0x38,0xa6,0x0f,0x66,0xf3,0xad, + 0x39,0x34,0x98,0x57,0x65,0x06,0xa4,0xbb,0xf0,0x6e,0xd4,0xaa,0xca,0x3c,0xf2,0xad, + 0x43,0x9e,0x06,0x5a,0x6c,0x7c,0x2d,0xd9,0x8b,0xf0,0x4a,0x56,0x3e,0x4a,0x3c,0xe6, + 0xc4,0x34,0x35,0x81,0x91,0x96,0x4b,0x37,0x95,0x43,0x2a,0x75,0xec,0x34,0xb7,0xd4, + 0xee,0x5c,0x8b,0x13,0xb2,0x01,0xb6,0x8b,0xc3,0x41,0xa9,0x74,0xec,0x7f,0x46,0x62, + 0x2c,0xd9,0xe7,0xb7,0xfe,0xe7,0xf9,0xad,0x64,0xee,0x9e,0xf9,0x1f,0xbb,0x67,0x92, + 0x55,0xbd,0x71,0x7b,0x20,0xf2,0x41,0x0a,0x99,0xaf,0x02,0x93,0x0f,0x52,0x1c,0x7b, + 0x9b,0x2e,0xe8,0x82,0x37,0x9b,0x82,0x0c,0xe1,0xb8,0x79,0x56,0x50,0x49,0xf0,0xe9, + 0xad,0xce,0x95,0xfd,0x2c,0x48,0x3c,0x5e,0x9f,0x8d,0xdd,0xb9,0x6a,0x06,0xbc,0xbc, + 0xe4,0xa9,0x77,0xd5,0x8f,0x66,0x82,0xb0,0xe3,0xf5,0xb8,0x28,0xda,0x4a,0xf5,0xca, + 0x76,0x22,0x48,0x68,0x9e,0xc8,0x4c,0xc4,0x86,0x7c,0xa4,0x09,0x12,0x33,0x04,0x86, + 0x9e,0x98,0xf5,0xba,0xd9,0xe5,0xfc,0xd7,0xeb,0xf7,0xca,0x82,0x04,0x76,0xb9,0xdc, + 0x7e,0x2a,0x88,0xfb,0x11,0x0e,0xd6,0x62,0x02,0xa8,0xe3,0xb5,0xd8,0x00,0xe0,0xe1, + 0x18,0x49,0x81,0x3e,0x56,0xe2,0x1d,0xd4,0xee,0x57,0x4e,0xf0,0x89,0xa8,0x1e,0xff, + 0xfc,0x21,0xc5,0x9f,0x48,0xb1,0x2a,0x85,0x7a,0xee,0x0d,0xd7,0x64,0x39,0x36,0x10, + 0x9a,0xd3,0xf7,0x2b,0xb8,0x26,0x6f,0x0e,0x23,0xb9,0x1d,0x0f,0x7d,0x45,0x8b,0x28, + 0xf5,0xd8,0xa4,0x1a,0x38,0xcf,0xe3,0xa8,0x57,0x85,0x01,0x38,0xce,0x01,0x5c,0xec, + 0xd6,0xe7,0x56,0x04,0x57,0x94,0xa1,0x4b,0x97,0x64,0x53,0x3e,0xa7,0x77,0xc3,0xb5, + 0xc0,0x1b,0x7e,0x35,0xb3,0x50,0x4f,0xe7,0xf4,0x23,0xde,0xe4,0x9b,0x7b,0x63,0xd3, + 0x82,0xd0,0x34,0xa9,0xc2,0xb9,0x21,0xeb,0x21,0x7e,0xd3,0x30,0xdf,0x8f,0xe5,0x3b, + 0x86,0x89,0x20,0xed,0x78,0xcc,0xd3,0x6c,0xff,0xcc,0x53,0xbc,0xc1,0xe2,0x38,0x99, + 0x53,0x70,0x49,0x60,0x9c,0x2d,0xd7,0x6c,0xfa,0x9d,0x5f,0xed,0x02,0xe4,0x30,0x41, + 0x01,0x24,0xc1,0xe3,0x50,0x8e,0x27,0x29,0x85,0xce,0x53,0x7c,0xec,0xd4,0x7d,0x93, + 0xc2,0xd2,0x5b,0x75,0xb1,0xca,0xa9,0x01,0x85,0x17,0xeb,0xcb,0xcc,0xfa,0x82,0x17, + 0xbf,0x1a,0xdf,0x11,0x91,0x95,0x41,0x46,0x87,0x49,0xaf,0xcc,0xbb,0x7a,0x84,0x81, + 0x52,0xee,0xa0,0x2a,0xbb,0x09,0xd2,0x6a,0x34,0xcd,0x25,0x9a,0x9f,0x65,0x4d,0x5d, + 0x0a,0xe3,0x0d,0x65,0xf5,0x80,0xa2,0xf5,0xd1,0x9b,0x7e,0x54,0x2f,0x76,0xfa,0xd9, + 0xbc,0x6b,0xfd,0xe2,0xfe,0xcd,0xfa,0xce,0xef,0x52,0x80,0xfa,0x23,0x29,0x3e,0xe7, + 0x49,0x5c,0x42,0xd9,0x11,0x88,0x87,0xb9,0x82,0x1f,0x1b,0x00,0x41,0x9b,0xbd,0x66, + 0x58,0x85,0xd2,0xab,0x47,0x1d,0xd7,0xb3,0x46,0x09,0xfa,0x58,0x3f,0x14,0x86,0x23, + 0x25,0x11,0xbb,0x3f,0xc4,0xb2,0x65,0x4e,0xb8,0x59,0x12,0x55,0xeb,0x3b,0x75,0x13, + 0x12,0x4b,0x91,0xf8,0xc6,0x69,0xa5,0x69,0xa4,0x5f,0x8d,0xbc,0xea,0x14,0x8e,0xb6, + 0xbc,0xa2,0xc2,0x93,0xeb,0x35,0xc5,0x17,0xe5,0xa6,0xd1,0x35,0x7d,0x42,0xe1,0x62, + 0xe0,0xa1,0xa5,0xa6,0xd7,0x28,0xd7,0xdb,0x89,0xbe,0x54,0x0b,0xd4,0x57,0x3d,0x48, + 0xb6,0xd1,0xa9,0xb1,0x43,0x15,0x23,0x1d,0x79,0x73,0x34,0x6d,0xe8,0xd6,0x2c,0x7d, + 0x77,0x42,0x6e,0xf3,0x2c,0xbb,0x0f,0x1c,0x09,0xc0,0x99,0xd3,0xfb,0x19,0xc5,0xa5, + 0x26,0x52,0x21,0x37,0x01,0x1a,0x5b,0x10,0x29,0xc6,0xe0,0x91,0x25,0x16,0xf7,0x8b, + 0x37,0x36,0x37,0xdd,0xaf,0x87,0xd6,0xd7,0x23,0xec,0x18,0x33,0xc3,0x5b,0x9c,0x64, + 0x64,0x7a,0xb4,0xb6,0x74,0xe6,0x9e,0x5c,0xb8,0x66,0xd7,0xd4,0x23,0xd0,0x27,0x37, + 0x6c,0x46,0x33,0xdd,0xdc,0x0e,0x1c,0xba,0x59,0x3f,0x57,0x9a,0xe4,0xca,0x8e,0x54, + 0x8e,0xdf,0xef,0x03,0x4d,0x19,0xd8,0x6f,0xb0,0x8b,0x5a,0x18,0xca,0x86,0x4c,0xa0, + 0x7a,0xfb,0x68,0x72,0xfa,0x30,0x5a,0x76,0xd6,0x90,0xb2,0x55,0x45,0x48,0xee,0x27, + 0xa7,0xa2,0x6a,0x82,0x7f,0x11,0x1d,0x15,0xea,0x7e,0x6a,0xca,0xf6,0xff,0x8e,0x07, + 0x6e,0x09,0xb5,0x15,0x63,0x81,0x55,0xa2,0xf7,0x75,0x0f,0xfe,0x97,0x11,0x8b,0x4d, + 0x5c,0x56,0xa2,0x61,0xc5,0xa6,0xf2,0x32,0xd7,0xb6,0xa5,0xa5,0x66,0x5d,0x1e,0x19, + 0x03,0xf2,0xf4,0xba,0x40,0x07,0x89,0xce,0x3e,0x76,0xe5,0x36,0x15,0xc4,0xb6,0xed, + 0x8c,0x2e,0x41,0x40,0x54,0x64,0x4d,0xf0,0x76,0xa5,0x61,0x0f,0x57,0x18,0x9a,0x7a, + 0xe5,0xb0,0x08,0x05,0x99,0xd7,0x7c,0x47,0x0d,0x1c,0x30,0xbf,0x99,0x6c,0xa5,0xbd, + 0x36,0x63,0x87,0x3c,0x95,0x04,0x38,0x35,0x11,0x2a,0x57,0x90,0x80,0x1b,0xa5,0x1b, + 0xf1,0x95,0xcd,0x72,0x5b,0x05,0x48,0x6e,0x97,0xb2,0x9d,0x72,0x5d,0x40,0xe8,0x2e, + 0x96,0x56,0x28,0x22,0xbc,0x23,0x40,0x8d,0x3e,0x92,0xf2,0x6d,0x4d,0x27,0xe1,0x7e, + 0x22,0xe1,0xa9,0x41,0xfb,0x1e,0xd7,0x2e,0x6b,0x8f,0xc5,0xa0,0x85,0x10,0x54,0x02, + 0x3b,0x05,0x02,0x8d,0xc2,0xc6,0x4b,0xf5,0x72,0x7c,0xa1,0x20,0x65,0x80,0x97,0x13, + 0x84,0x64,0x88,0xe2,0x84,0x5f,0x7e,0xe0,0x4e,0x7f,0x74,0x4a,0x69,0xaf,0xfe,0x19, + 0x39,0xe0,0x89,0x8c,0x03,0x41,0x94,0xc7,0x82,0xa2,0xb3,0x92,0x6a,0x6b,0xba,0xda, + 0xaa,0x32,0x16,0x3a,0x49,0x8a,0xdd,0xe5,0xa6,0xba,0xd4,0x41,0xc5,0x1f,0x01,0x0a, + 0xe8,0x32,0x29,0xde,0x7c,0xf9,0xf4,0xd6,0x4f,0x0f,0x25,0x37,0x40,0xd7,0x13,0x5c, + 0x4b,0x2c,0xe8,0x8d,0x7b,0x30,0x40,0xfa,0xe2,0x03,0x12,0xf9,0x2e,0x26,0x25,0x3b, + 0x2b,0x93,0xb3,0x15,0x54,0x73,0x51,0x4a,0x3e,0xee,0x8f,0xed,0xa3,0x1f,0x59,0x3e, + 0x09,0x2b,0x8e,0xd8,0x92,0x8a,0x31,0x9f,0x00,0x73,0x5a,0x4c,0x56,0x0a,0x79,0x64, + 0x8f,0x12,0x40,0x9e,0x4c,0x30,0x4c,0x66,0xce,0xf1,0x22,0xdd,0xde,0xdc,0xe4,0xa7, + 0xe7,0xe9,0x76,0x33,0xaf,0x8a,0x13,0x70,0xa8,0xcf,0xbf,0xb5,0x28,0xd2,0x22,0xd3, + 0x74,0xfb,0xd9,0x72,0x69,0xbd,0xee,0xee,0x40,0xcb,0x1e,0xe4,0x09,0xc8,0x92,0x3f, + 0xb6,0xd8,0xb0,0xd1,0xdf,0xca,0x03,0x93,0x19,0xf6,0x37,0xd0,0xe2,0x3c,0x7b,0xfa, + 0x6c,0xe7,0x29,0xcc,0x07,0x90,0xc9,0xfd,0xce,0x61,0x2f,0x0c,0x48,0x13,0xff,0xb9, + 0xe7,0xc5,0xe4,0xf0,0x96,0xa9,0x99,0x9b,0x45,0x0b,0x95,0xca,0xfd,0x24,0xc9,0xd4, + 0x53,0x09,0x37,0xa3,0x0c,0xc0,0x89,0xdc,0x91,0x4c,0x73,0x81,0x5f,0x2e,0x1f,0xf1, + 0x07,0x95,0x02,0x24,0x5d,0x45,0x8e,0x47,0xa5,0xde,0x31,0x3d,0x32,0x5e,0xd5,0x1b, + 0x6d,0x3c,0x29,0x77,0x18,0x33,0xb5,0xc7,0x44,0xe9,0x8e,0x34,0x79,0x1c,0xb7,0x24, + 0x6c,0x0c,0xfa,0xb6,0x84,0x61,0x4e,0x4a,0x42,0x52,0x4a,0x70,0x09,0x55,0xea,0x16, + 0x2f,0x15,0xbd,0xd3,0x29,0x25,0xb6,0x9a,0xb1,0x57,0xcf,0xec,0xb6,0xb2,0x06,0xaf, + 0xab,0xbc,0x8c,0xdc,0x51,0x6e,0xde,0x35,0xdd,0xe8,0x4e,0x06,0x5e,0xfd,0xdc,0xae, + 0xb5,0x3f,0x8f,0xe0,0xad,0xe4,0xc1,0x1d,0x9c,0x77,0xce,0xfa,0x8e,0x16,0x2c,0x4d, + 0x87,0x19,0x9a,0xa7,0x26,0x43,0xaa,0xa1,0x7b,0x8a,0xc9,0xb3,0xbe,0x2f,0xf4,0x4c, + 0xd5,0x0a,0x45,0xb3,0xee,0x90,0xdd,0x40,0xc4,0x92,0xc7,0x0f,0xdd,0xb3,0x26,0xaf, + 0x66,0x05,0xda,0xb6,0x53,0x52,0x1e,0xb6,0x42,0x04,0xa6,0x14,0x7d,0x31,0xc0,0xb0, + 0x2f,0x5d,0xd3,0xc5,0x3c,0xe3,0xd6,0xf7,0x24,0x8c,0x49,0xcb,0x3c,0x40,0xf0,0x65, + 0xbb,0x90,0x66,0xb8,0x66,0xce,0x8b,0xdd,0x80,0xdc,0x94,0xe7,0x7a,0xbc,0xc0,0x46, + 0x3c,0xed,0x0c,0x84,0x0c,0x1d,0xab,0x6b,0x8c,0xcc,0x41,0x03,0x60,0x73,0x93,0x93, + 0x2d,0xe9,0xc3,0x29,0xc3,0x59,0x7c,0x90,0xf2,0xa7,0x96,0x9f,0x9e,0xbd,0xf2,0xf0, + 0xa8,0xa3,0x3f,0xbc,0xfa,0x44,0x76,0x6d,0x09,0xa3,0x92,0x18,0xa4,0xad,0x8e,0xac, + 0x32,0x87,0xcc,0x99,0x09,0xd9,0xf9,0xc2,0x75,0x6c,0xcb,0x8f,0x27,0x26,0x31,0x72, + 0xec,0x60,0x62,0xc3,0x4f,0x6c,0xc4,0xab,0x3d,0x18,0xbe,0xbc,0xc2,0x62,0x37,0xca, + 0xb3,0x6c,0x65,0x56,0x2c,0x21,0x13,0x57,0x9e,0x0d,0x23,0xc8,0x9b,0xf7,0x08,0x36, + 0x29,0x50,0x31,0xf4,0x87,0x9f,0xc8,0x49,0x17,0x72,0xd0,0x29,0x28,0x3e,0x74,0xcf, + 0xb0,0xad,0x15,0x9f,0x5a,0x5c,0x78,0xf8,0x86,0x3a,0x53,0x02,0x53,0x91,0x9d,0x0a, + 0x0a,0xef,0x0e,0x4f,0xaf,0xa0,0xdf,0xd5,0xb0,0xe9,0xfd,0x80,0x1d,0x52,0x51,0x82, + 0x04,0xb1,0xd6,0xb0,0xd6,0x6c,0xe6,0x62,0x22,0xd6,0x37,0xdc,0x5d,0xa1,0x2d,0x44, + 0xc8,0x11,0x4b,0x0a,0xbd,0x3c,0x59,0x79,0xab,0x70,0xb0,0xca,0xc0,0x7b,0x7a,0x68, + 0x49,0x54,0x80,0x4b,0x73,0x7e,0x79,0x57,0x2c,0x20,0xd3,0x06,0xc5,0x9e,0xae,0x85, + 0x09,0x06,0x5b,0xe3,0xe4,0x46,0x1e,0xb2,0x33,0x79,0x38,0x9d,0x79,0x6b,0x84,0xd9, + 0xeb,0x45,0xfc,0xa8,0xdb,0x3c,0xfb,0xe0,0x97,0x54,0x89,0x0c,0xa3,0x97,0x7c,0x1c, + 0x60,0xeb,0xb9,0x41,0xcf,0x0c,0x95,0x72,0x66,0xc5,0xaa,0x30,0x09,0x33,0x25,0x79, + 0xd6,0xa1,0xa7,0xee,0x81,0xa0,0x5b,0x65,0x2c,0xa5,0xc8,0x3e,0xc0,0xa8,0x36,0xd3, + 0xd3,0xb6,0x8c,0x75,0xa2,0x5f,0x2e,0xd5,0xc8,0xb3,0xde,0x02,0x95,0xbd,0x83,0x24, + 0xb1,0x65,0xa9,0x96,0x72,0xdf,0x7e,0xc3,0xb5,0x9d,0x5e,0xb0,0xb9,0xe1,0x3e,0x9d, + 0xab,0x60,0x40,0x17,0x1e,0x68,0xe3,0xb6,0xf3,0x01,0x86,0xb4,0x92,0x7e,0xb7,0x51, + 0x74,0xea,0xe5,0xca,0x3e,0x65,0x4a,0x5f,0xa6,0xf6,0x06,0x20,0xb9,0x4e,0xf5,0xb8, + 0x89,0xf1,0xa4,0x46,0x1a,0x51,0xde,0xdd,0x15,0xf8,0x67,0xd2,0x32,0x57,0x85,0x07, + 0xc2,0x40,0x99,0x0a,0x66,0x5f,0x13,0x64,0xc5,0xd0,0x38,0xc3,0x17,0xfa,0x80,0xfe, + 0xc1,0xb7,0xcd,0x4d,0xfc,0x71,0xef,0x72,0x02,0x86,0x42,0xbe,0x1b,0xab,0x1a,0x10, + 0xfe,0xf4,0x22,0x2f,0x59,0xa4,0x34,0x6e,0x92,0xca,0xfe,0xab,0x1a,0x55,0x3a,0x62, + 0x5b,0x3f,0xb8,0xdd,0x3c,0xba,0x36,0xca,0xc9,0x58,0x69,0xc8,0xaf,0x6f,0x76,0x6e, + 0xac,0xef,0x45,0xa7,0x5e,0xb3,0xe0,0x9c,0x36,0x04,0x5a,0x44,0x74,0x2f,0x73,0x60, + 0x0c,0x6a,0x0f,0x4b,0x01,0x82,0x8f,0x92,0xf5,0x90,0x5e,0x74,0xe0,0x75,0x4c,0x57, + 0xd6,0x80,0x47,0x91,0x62,0xb3,0xb9,0xa9,0x8f,0x0d,0x29,0x81,0xdb,0xae,0x67,0xc8, + 0x9a,0x8b,0x1a,0x9d,0x7d,0x1a,0x9f,0x4a,0xec,0x6d,0xb1,0x24,0x64,0xdb,0x4c,0x15, + 0x01,0x85,0x98,0x48,0xd2,0x5d,0x89,0xb7,0xa5,0x69,0x77,0xcf,0x7e,0x06,0x87,0xa6, + 0x7c,0xc5,0xed,0x9f,0x6d,0xdc,0xfe,0x49,0xd5,0x1c,0x98,0xaf,0x01,0x2d,0x44,0xfa, + 0xa0,0x11,0xff,0x23,0x2d,0xc9,0x59,0xf4,0x95,0x3b,0x23,0x92,0x41,0xdc,0xae,0x04, + 0xe2,0xd9,0xa1,0x30,0x77,0x8c,0xf6,0x7b,0x52,0xd1,0x02,0x66,0x08,0x0e,0xcc,0x48, + 0x57,0xab,0xa0,0x1c,0x96,0xd3,0x2e,0x1b,0x0a,0x2a,0xa3,0x91,0x9d,0xbd,0x2b,0x2e, + 0x55,0x52,0x67,0xb1,0x71,0x18,0x0a,0x81,0xc3,0xc4,0x3e,0x52,0xa9,0x32,0xa0,0x9c, + 0xa2,0x39,0x83,0x5b,0x99,0xad,0x74,0x26,0xe3,0x2c,0xd7,0x8f,0x6b,0xe6,0x7b,0xed, + 0x71,0x03,0xdf,0x5c,0xc9,0xa7,0x1a,0x4c,0x4e,0x61,0x18,0x52,0x7b,0x34,0x12,0x6b, + 0x2b,0x16,0x5a,0x96,0x4b,0x7d,0x1b,0x17,0x2f,0x3a,0xfa,0xfc,0xfb,0x69,0xc5,0x62, + 0x0c,0x06,0x92,0xe4,0x8a,0x85,0xeb,0xd4,0x56,0x48,0xc4,0x0b,0x5f,0x0d,0x60,0xcc, + 0xb8,0x1c,0x8d,0x01,0x6f,0x09,0x51,0xc2,0x3a,0x69,0xe0,0x12,0x36,0x09,0x5a,0x8c, + 0x91,0x09,0x48,0x73,0x41,0x27,0x97,0xb1,0x0e,0x24,0x4d,0x75,0x8e,0xdf,0x96,0x4b, + 0x4e,0xf3,0x0e,0xc3,0xe2,0xaa,0x7e,0xf2,0xfa,0xda,0x6d,0xb5,0x54,0xa5,0x57,0x04, + 0x79,0x24,0x72,0x54,0xe4,0x98,0xed,0x65,0x1c,0x25,0x25,0xa0,0x61,0x06,0x30,0xcb, + 0xfa,0x3f,0x92,0x6f,0xc3,0xc8,0xee,0x1b,0xa0,0xad,0xbd,0x46,0x2a,0x52,0x47,0x4a, + 0x19,0x64,0xf0,0x30,0x0c,0x6f,0x3b,0x11,0x8e,0x60,0x61,0x60,0x75,0xf6,0x22,0x6d, + 0x76,0xc2,0xff,0x1f,0xc4,0x39,0xb9,0x02,0x37,0x81,0xc1,0x69,0x44,0x61,0x07,0xb7, + 0x00,0x51,0xdb,0x8e,0xe3,0x2d,0x6c,0x10,0x6b,0xe1,0x7f,0x05,0x3d,0x04,0x4a,0x0d, + 0x38,0x50,0x6a,0xd8,0x32,0xda,0x61,0x35,0xa4,0xf5,0x4d,0x21,0xf9,0x1a,0xb3,0x6b, + 0x09,0xa9,0x5b,0x6b,0x18,0x44,0xce,0xd9,0xb7,0x40,0xdb,0xd7,0x16,0x59,0xd7,0xb6, + 0xa0,0x00,0x05,0x24,0x5d,0x23,0xa1,0xe5,0xcc,0xbe,0x67,0x1e,0x3f,0x68,0xb9,0xf3, + 0x0b,0x56,0x2d,0xa2,0xd8,0x57,0xe1,0xce,0x0a,0x08,0xd1,0xb3,0x8b,0xa6,0x5c,0x83, + 0x5e,0xa2,0xea,0xee,0xb8,0x5c,0x94,0x28,0x15,0xfc,0x0d,0xbe,0x68,0xf4,0x5c,0x68, + 0xd6,0x30,0xb9,0xd3,0xc6,0xfe,0x5a,0x7b,0x5c,0xcd,0x48,0x27,0xac,0x71,0x9a,0x40, + 0x76,0x50,0x55,0xc3,0xc4,0xc2,0x89,0x26,0x8b,0xce,0x10,0xa7,0xba,0x02,0x08,0x4f, + 0x1e,0x4e,0xaa,0xbd,0x2a,0xeb,0xbd,0x14,0x2f,0x85,0x78,0x10,0x66,0x13,0x59,0xe4, + 0x54,0x72,0xf3,0x6b,0x94,0xa5,0x4e,0x75,0x8d,0x0e,0x8f,0x5e,0xbf,0x96,0x4a,0x75, + 0x93,0xd5,0xd3,0x56,0x15,0x94,0xaa,0x98,0x72,0x29,0x13,0x72,0x22,0xe0,0xf4,0xd6, + 0x7b,0x7e,0x3b,0x08,0x42,0x01,0xdf,0xdc,0x26,0xfb,0x31,0x16,0x7e,0x8d,0x95,0x60, + 0x60,0x6c,0xf0,0xd9,0x67,0x37,0xf9,0xbe,0x42,0xfc,0xb8,0x31,0x18,0x38,0x0b,0x4f, + 0xd0,0x0f,0x37,0x24,0xf2,0x6e,0xc3,0x78,0x59,0xce,0x39,0x68,0x5a,0xdf,0x6e,0x7f, + 0xd8,0xfb,0xe1,0xf5,0xbb,0xe3,0xf7,0x1f,0x5e,0xe1,0xce,0xc2,0x7e,0x05,0xcb,0x4d, + 0x06,0x4c,0xb8,0x5c,0xb9,0x66,0xea,0x31,0x74,0x98,0xc6,0x40,0x30,0x1e,0xa5,0x03, + 0x5e,0xfb,0x84,0xa4,0xa3,0x17,0xa9,0x2a,0x0b,0x46,0x71,0x2b,0xca,0xdb,0xe2,0x30, + 0xaa,0x4e,0x48,0xf8,0x87,0x2d,0xce,0xa4,0x4a,0x26,0x4b,0xb1,0x4e,0xd4,0xf1,0xfc, + 0x6f,0xd8,0x4a,0xc9,0xcd,0xcd,0x42,0xa4,0xb2,0x9f,0x0b,0x45,0x19,0xf6,0x10,0xb1, + 0xaf,0xd6,0xf5,0x95,0xe1,0xf6,0xd7,0xa3,0x54,0x87,0xe1,0xfa,0x29,0xce,0xc5,0xac, + 0x57,0x97,0x3f,0x5a,0xc5,0x04,0x08,0x5d,0xa9,0x84,0x8f,0x14,0x4c,0xe3,0x57,0x8c, + 0x77,0x4f,0x41,0xeb,0x7e,0xd7,0xcd,0x07,0x88,0x53,0x39,0x7e,0xdd,0xb3,0x22,0x19, + 0x6c,0xce,0x1b,0xc9,0xea,0xda,0x98,0x0a,0x61,0xcf,0xa1,0x89,0xe2,0xe9,0x73,0x16, + 0xa7,0x1e,0x4e,0xb2,0x5f,0xb4,0x16,0x55,0x39,0x96,0x0a,0x28,0x55,0x73,0xe7,0x9a, + 0x02,0x97,0x16,0x9f,0x85,0x28,0xb1,0x6c,0x0d,0xa9,0x0e,0x2e,0x19,0xe4,0xb2,0xd6, + 0x4c,0x61,0x66,0xc9,0x81,0x6d,0xd2,0x47,0xc6,0x0e,0x17,0x29,0xeb,0x8c,0x70,0x45, + 0x76,0x15,0x37,0x83,0x95,0x22,0x2b,0xfb,0x34,0x49,0xc6,0x88,0x02,0xb9,0x59,0x14, + 0x6f,0xe5,0xab,0x8f,0xcb,0xa6,0xac,0xb5,0x68,0x4c,0x3a,0xaf,0x4e,0x28,0x9e,0x00, + 0xc3,0x56,0xfe,0x94,0x95,0xae,0x53,0x5b,0x4e,0x08,0x17,0xd6,0xb6,0xb0,0xbc,0x51, + 0x93,0xad,0x34,0x4d,0x4d,0x7d,0x36,0xfe,0x5e,0x42,0xe3,0xb9,0xb0,0xdf,0x23,0x39, + 0xdc,0xcc,0xa9,0xfd,0x37,0xef,0x0e,0xe8,0x42,0xd7,0x9b,0x57,0x6f,0xd3,0xc5,0x1c, + 0xc1,0xb5,0xc6,0xad,0x27,0xdf,0x24,0x70,0x28,0x34,0x23,0x83,0xb0,0xd6,0xee,0xb6, + 0x5a,0x12,0xe3,0xee,0x70,0x62,0xbc,0xe3,0xd2,0x13,0x87,0x67,0x6a,0x7d,0xf7,0x14, + 0x5e,0x84,0x7a,0x03,0x72,0xe2,0x88,0x44,0xf1,0x3b,0xf1,0xfe,0x97,0x83,0xe3,0x83, + 0xbf,0xbf,0x7f,0xb5,0x9f,0x1e,0x1e,0x36,0x93,0xf0,0xc3,0xab,0xff,0x21,0xb3,0xc0, + 0x6d,0x7a,0xda,0x7f,0xff,0xee,0xed,0xfe,0x2b,0x7a,0xdd,0x49,0xc2,0x83,0xbf,0xa1, + 0xe6,0xfd,0x9f,0xe8,0x6d,0x37,0x09,0xf7,0x5e,0xfe,0x42,0x4f,0x4f,0xf0,0xf4,0xc3, + 0x5f,0x5f,0x7d,0x38,0xc0,0xcb,0xc6,0xe1,0xd3,0x24,0xfc,0xe9,0xc3,0xfb,0x63,0x40, + 0xd2,0xb7,0x67,0xe6,0xed,0x07,0x84,0x98,0xa3,0xd7,0x6f,0x00,0xfa,0xf6,0xdd,0xdb, + 0x63,0xa9,0xe0,0xdb,0x24,0x7c,0xbf,0x77,0xf0,0x33,0x3d,0x7e,0x87,0xc2,0x3f,0xec, + 0xbd,0x7c,0xc5,0x65,0x6c,0x03,0x87,0x5f,0x7f,0x7b,0x73,0xf0,0xfa,0xfd,0x1e,0x4a, + 0x25,0x4c,0x80,0xca,0xcb,0x77,0x6f,0x0f,0x3e,0xbc,0x7b,0xc3,0xaf,0x40,0x65,0xd6, + 0xe7,0x96,0xf5,0xf8,0x7d,0xb7,0xf4,0xfe,0xc4,0x79,0x47,0x81,0xc0,0xea,0xc3,0xde, + 0xef,0xc7,0x2f,0x7f,0xdb,0x3f,0x78,0xf7,0x6b,0x78,0x74,0x54,0x34,0xfb,0xed,0xde, + 0xaf,0xaf,0x7e,0xc8,0x47,0x1e,0x1c,0x8c,0x61,0x5c,0x46,0x64,0xb7,0x87,0x7e,0x54, + 0xaa,0x54,0xf0,0x51,0xee,0xaa,0x29,0x6c,0x00,0xc1,0xfa,0x8b,0xba,0x62,0x2d,0xf1, + 0x90,0xbe,0x61,0x88,0x71,0xc8,0xd7,0x97,0x98,0x16,0x51,0x7c,0x94,0x4e,0x0f,0x9b, + 0x47,0xce,0x3c,0x38,0x63,0x01,0x1d,0x71,0xc1,0x2e,0x23,0x1a,0x60,0x32,0x11,0xe6, + 0xb2,0x5b,0xe3,0xb4,0xc2,0x8a,0x90,0x21,0x1a,0xf8,0x32,0x12,0x21,0x70,0xce,0xfc, + 0x66,0xb9,0xe4,0x5f,0x9c,0x57,0xea,0xd1,0x77,0xf3,0xf6,0x47,0xfc,0xa7,0x30,0xc6, + 0x6d,0xb8,0x7e,0x14,0x0d,0x24,0x2a,0x4d,0x9b,0xc9,0xe4,0x52,0xce,0xed,0xb0,0x97, + 0xc7,0xb8,0xc3,0x80,0x4b,0xaa,0xd6,0x3f,0x08,0x78,0x8a,0x1d,0xb2,0xd0,0xab,0x60, + 0x92,0x8c,0x69,0xd9,0x61,0x37,0x2d,0xff,0x38,0x6c,0xc2,0x76,0xb2,0xf6,0x95,0x78, + 0x55,0x01,0x60,0x1c,0x8f,0x8d,0x6c,0xf8,0x7a,0xcc,0xef,0x09,0x44,0x38,0xe5,0x6c, + 0x94,0xe0,0x52,0x88,0x16,0x15,0xa5,0x20,0xb2,0x16,0xd4,0xf4,0x40,0xcd,0x71,0xea, + 0xf8,0x79,0x73,0xb9,0x1c,0xbf,0x80,0xd5,0xd5,0x02,0x58,0x19,0x91,0xcb,0x34,0xf3, + 0x6e,0x83,0x1a,0xb8,0x4c,0xa3,0xed,0xe7,0xcf,0xc7,0x22,0xd7,0x0b,0x01,0x26,0x97, + 0x1d,0xfa,0xd6,0xca,0xa9,0x74,0x57,0xee,0x8f,0x03,0x10,0x3a,0x22,0x10,0xe6,0x82, + 0xfc,0x04,0x2a,0x1a,0x70,0xa1,0x22,0x93,0xbb,0x6d,0x7f,0x95,0x0f,0x86,0xd6,0x72, + 0x7a,0x0f,0xcf,0x43,0x74,0x87,0xce,0x75,0xfb,0xb0,0xfd,0x8c,0x37,0x7c,0x92,0x75, + 0x93,0x10,0x1c,0xc4,0x31,0x60,0x1b,0xd3,0xab,0xec,0x22,0x1a,0x28,0xa2,0x94,0x5f, + 0x9c,0x34,0x24,0x25,0xb6,0x92,0xe5,0x1b,0xc0,0x9f,0xe7,0xa3,0x61,0x34,0x48,0xce, + 0x12,0x32,0x0c,0x48,0xd8,0xc5,0x4f,0x42,0x1a,0x41,0xbd,0xf9,0xf4,0xd8,0x71,0x5f, + 0x1f,0x64,0x67,0xf5,0xc7,0xb5,0xb3,0xda,0x63,0xf5,0x5b,0xff,0xb8,0xc6,0xbf,0xb5, + 0xc7,0x95,0x51,0x51,0x1e,0xd7,0xe8,0x17,0xe0,0x4e,0x70,0x9e,0xc7,0xb5,0x01,0x76, + 0x5b,0x5c,0xce,0x83,0x03,0x6c,0xf8,0xae,0x7e,0x51,0x75,0x44,0xa8,0x76,0x1c,0x14, + 0x29,0x85,0x3e,0xd1,0x2f,0x90,0x62,0xb7,0x69,0x8f,0x5b,0x8f,0x1f,0xc7,0xfa,0xe2, + 0xfa,0x0f,0xb1,0xf6,0xb9,0x86,0x16,0x32,0x4a,0x61,0xaa,0xd1,0xcf,0x52,0x9d,0xc1, + 0xe4,0x2b,0xc3,0x99,0xbd,0x4a,0x1e,0x6e,0xb5,0xc6,0xbe,0xb8,0x5c,0x1f,0x7c,0x66, + 0x0a,0xaf,0x72,0xdc,0xfa,0x50,0x54,0xe1,0x78,0xa3,0x49,0x4d,0x04,0x0d,0x8c,0xff, + 0xdc,0x3c,0x21,0xa0,0x87,0x6d,0x3c,0xa8,0x47,0x48,0x21,0xb8,0xeb,0x7b,0x63,0x65, + 0x37,0x99,0xa1,0xa8,0xfd,0xc4,0x1b,0x7a,0x83,0x55,0xa6,0x45,0x6d,0xa0,0xf4,0xca, + 0x50,0xfe,0x5e,0x67,0x49,0x69,0x9c,0x85,0xab,0xd2,0x06,0x9f,0x13,0xb5,0x99,0x5a, + 0x4a,0x61,0x0f,0xa6,0x0b,0x34,0xd6,0xf9,0xe0,0x1e,0x8e,0x2f,0x95,0x40,0x10,0x00, + 0x84,0x46,0x2d,0xcc,0x11,0x0e,0x4e,0xa6,0x4e,0x58,0xb9,0xe4,0x3f,0x51,0x50,0x11, + 0xf6,0xc0,0x29,0xca,0xf1,0x86,0x88,0x0c,0x57,0x23,0xd7,0xd3,0x2a,0x03,0xf9,0x83, + 0xeb,0xf7,0x8b,0xc1,0x29,0x85,0x66,0xfc,0x44,0x0b,0x32,0xe3,0x61,0xf4,0xd9,0x26, + 0x9a,0x65,0xe1,0xfa,0x52,0x22,0x57,0x36,0x02,0x2b,0x86,0x32,0xbc,0xa4,0xe6,0x51, + 0x1d,0x8d,0xae,0xbb,0x7b,0x23,0xf9,0xb2,0xb6,0x44,0x9e,0xe4,0x74,0xb5,0xed,0xe2, + 0x92,0xc7,0xb4,0x86,0x0b,0x73,0xa1,0xa8,0x16,0x2c,0x53,0x82,0xc1,0x4b,0x3c,0x0b, + 0x50,0x3f,0x2f,0x44,0x82,0x67,0xba,0x61,0x7e,0xdd,0x21,0xef,0xab,0x77,0xdc,0xbd, + 0xdd,0x57,0x69,0x28,0xdd,0x5d,0xbd,0x73,0xca,0xb7,0x0b,0x83,0xf4,0x42,0x25,0xb6, + 0x15,0x36,0xf0,0x5b,0x31,0x46,0xb0,0xe1,0x65,0xe4,0x1c,0x02,0x19,0x0a,0xad,0x27, + 0xb1,0x20,0x51,0x07,0xd0,0x37,0x61,0x7f,0xd6,0xda,0x62,0xad,0x6d,0x17,0xba,0x2f, + 0x20,0x50,0xdf,0xd1,0x9d,0xa0,0xae,0xb3,0xab,0x1a,0xf1,0xd3,0x13,0x12,0xd3,0x4f, + 0xf4,0x28,0xb4,0xe0,0x9f,0xba,0xc4,0xe0,0x2b,0xd7,0x44,0xeb,0x4c,0x1c,0x63,0x69, + 0x6e,0x16,0x66,0x07,0x18,0x1e,0xa9,0x5f,0x3d,0x5a,0x62,0x46,0x8e,0x59,0x52,0xf1, + 0x14,0xe3,0x9f,0x23,0xee,0x39,0xfc,0xbf,0x43,0x9c,0xdf,0x0c,0x9a,0xb0,0xa5,0xcc, + 0xbf,0x13,0x4a,0xbf,0xe9,0x20,0x0a,0x5b,0xe5,0xb5,0x44,0xd0,0xb8,0x99,0x75,0xa7, + 0x0e,0x21,0xcf,0xa4,0x6a,0xfa,0x10,0xd3,0x9f,0xd5,0xfb,0x4c,0xab,0xc3,0x9c,0xfd, + 0x17,0x37,0x72,0x15,0x5b,0x7c,0xc9,0x82,0x69,0x0f,0xab,0x04,0xf7,0xd3,0xc2,0x5a, + 0xfd,0xbf,0xbc,0x3f,0x08,0xf1,0xa2,0x4b,0x62,0x59,0x73,0x57,0x76,0x49,0xd1,0x1b, + 0xc2,0x9d,0x42,0x14,0xaf,0xc3,0x15,0x2a,0xfa,0x32,0xd1,0x1c,0x63,0x1f,0xb1,0x7e, + 0x58,0x39,0xac,0x2f,0xf2,0xc3,0x3c,0xaa,0xc4,0xd1,0xdc,0xe1,0xdd,0x9f,0x36,0x2e, + 0xc9,0xac,0xf3,0x86,0x4c,0x8f,0x10,0x2e,0x26,0x19,0x3c,0x2d,0x72,0x02,0x8f,0x74, + 0x7a,0x77,0x46,0xfa,0x05,0xd6,0x1c,0xde,0xf3,0xad,0x57,0xee,0x32,0x2c,0xfb,0x7b, + 0x7b,0x5c,0x19,0xd1,0xa5,0x1e,0xd0,0x6f,0x50,0xd7,0xb0,0x2c,0x98,0xf2,0xc5,0x9d, + 0xfc,0x4a,0xf1,0x93,0x4a,0xab,0x95,0x8b,0x03,0x81,0xc8,0x13,0xe3,0x94,0xef,0x8c, + 0xc4,0xb4,0x2a,0x95,0x12,0x8a,0x0a,0x88,0x46,0xd5,0x65,0x9c,0xf2,0xc1,0x5f,0xf8, + 0xc2,0xfc,0x36,0x1a,0x0d,0x1b,0x2b,0x6a,0x30,0xb2,0xd8,0x5c,0x95,0xda,0x29,0x5c, + 0x9b,0x1e,0x65,0xcc,0xf8,0x6b,0x4d,0x36,0x0f,0x39,0x36,0x1c,0x60,0x02,0x06,0x01, + 0x33,0xf7,0x18,0xb5,0x17,0xaa,0x8a,0x49,0xa0,0xc2,0x49,0x45,0xd4,0x4c,0x2e,0x4a, + 0x48,0x45,0xed,0xe5,0x46,0xa1,0x6c,0x03,0x5a,0x54,0x50,0x96,0x99,0x42,0xde,0x3a, + 0x85,0x89,0x1a,0x8e,0xe3,0x71,0xef,0xf4,0x94,0x3c,0x18,0xe7,0x5f,0xc2,0xb8,0x22, + 0x5b,0xbe,0xd1,0xc2,0x77,0xe2,0x12,0xf8,0xf9,0x4d,0x53,0xaa,0x73,0x68,0x05,0xce, + 0xe3,0x7b,0x7d,0xac,0xce,0x65,0x36,0x6e,0x45,0x2d,0xfb,0xfc,0xce,0x43,0x72,0x65, + 0x45,0x93,0x19,0x7d,0x93,0xf8,0x4d,0xa8,0xc2,0xbc,0x37,0x03,0xe0,0xcc,0x4e,0x01, + 0x34,0x6e,0x24,0x41,0x92,0xcb,0xec,0xae,0x09,0xe7,0x9b,0x99,0xb2,0x7f,0xfb,0xf0, + 0xa6,0xb2,0x5c,0xde,0x39,0x16,0x98,0x1c,0xd0,0x6b,0x40,0xb7,0x4d,0xe9,0xe0,0x96, + 0xea,0x29,0x02,0x2d,0x64,0xad,0x60,0x41,0xe6,0xe6,0x77,0xc1,0xc2,0x78,0x8e,0xc6, + 0x03,0xb8,0x25,0xff,0x10,0x55,0xef,0x2a,0x2b,0x90,0x1d,0xa9,0x45,0xd3,0xff,0xfe, + 0xfd,0x20,0xb0,0x52,0x73,0x8f,0x2c,0x41,0xdd,0x8a,0xc3,0x45,0x3d,0xb1,0x45,0x14, + 0x65,0x67,0x7b,0x54,0x70,0x85,0x38,0xb8,0xe1,0x08,0x8e,0x44,0x3d,0xcb,0x93,0x0f, + 0x8d,0x66,0x87,0x0b,0xf8,0x07,0x2c,0x94,0x23,0x21,0xa9,0xd2,0x9f,0xff,0xba,0x2c, + 0x22,0xd5,0x65,0xa2,0xcc,0xb2,0x74,0x3e,0x28,0x0f,0xad,0x5e,0x2d,0xcd,0xd0,0x7d, + 0x35,0xf4,0x56,0x27,0x29,0xa7,0x7a,0xa8,0x73,0x79,0x9c,0x9f,0x86,0x5e,0x9a,0x17, + 0x62,0x1b,0x99,0xa0,0xb3,0xe5,0xa6,0xf4,0x7a,0x56,0x02,0xac,0x0c,0x83,0xc0,0x52, + 0xc6,0x7c,0x82,0x32,0x4e,0x73,0x4e,0xcd,0xde,0x6d,0x52,0xf3,0x59,0x99,0x43,0x27, + 0x7f,0x68,0x45,0x00,0xee,0xe0,0x5f,0x83,0xe1,0x5a,0xb2,0xd7,0x2c,0x9c,0xa4,0xfe, + 0xda,0x9d,0xe6,0x5a,0x0a,0x86,0xa0,0x42,0x64,0x7e,0xa9,0xca,0x42,0x3f,0x50,0x0a, + 0x75,0x28,0x36,0xb5,0x9a,0x26,0x15,0x25,0x7a,0xeb,0x72,0x3d,0x78,0x0e,0x55,0x55, + 0x84,0xe8,0x42,0xfc,0xa2,0x69,0x3a,0xf8,0xc9,0x3c,0xec,0xfd,0xe4,0x7c,0x58,0xfa, + 0x5f,0xcc,0xea,0xd5,0xa2,0x36,0x3d,0xca,0xb7,0xdd,0x77,0xae,0x35,0xa8,0x90,0xa4, + 0x62,0x01,0x3b,0x93,0x65,0xe2,0xa6,0x5a,0x4a,0xc1,0x96,0x20,0xac,0x9d,0xf1,0x10, + 0xba,0x89,0x6f,0x56,0x9f,0xbc,0x4a,0x05,0x87,0x67,0x62,0x02,0xb8,0xfe,0x78,0x44, + 0xf4,0x57,0xf7,0x9c,0x8f,0x24,0x23,0x4f,0x7d,0xba,0xb9,0x89,0xab,0x93,0x48,0x58, + 0x2f,0x41,0xca,0xb0,0x33,0xd7,0x28,0x37,0x0e,0xed,0xf3,0xcc,0xc4,0x3a,0xb7,0xf4, + 0xcf,0x06,0x79,0xc9,0xad,0x3a,0x13,0xe5,0x0f,0x09,0xdf,0xbe,0x8c,0x57,0xa9,0xf9, + 0xa7,0x44,0x4a,0x9d,0x9d,0xf8,0xe0,0x49,0xad,0xd4,0x1a,0x9e,0x87,0x15,0x82,0x92, + 0x5b,0x52,0xc2,0x60,0x6d,0x51,0x60,0xae,0xa1,0x24,0x3b,0x62,0xa9,0x22,0xe4,0x49, + 0x41,0xc7,0x1c,0x91,0x8e,0x97,0x42,0xc7,0x0f,0xba,0xed,0xc1,0x09,0x44,0x4b,0xfd, + 0x48,0x3c,0x3a,0x71,0x99,0x05,0xf9,0xcb,0x4f,0x4f,0x14,0x43,0xca,0xa0,0xaa,0x9b, + 0x16,0x9d,0x00,0xa7,0x0c,0x82,0x3d,0x68,0x02,0x49,0xd5,0xbc,0x80,0x58,0xb9,0x8a, + 0xc8,0x62,0x5b,0x27,0xf7,0x4b,0xf3,0x5f,0x2c,0x1f,0x5a,0xe2,0x3a,0x6a,0x27,0x12, + 0xae,0x11,0x4d,0x4b,0xfe,0x22,0xc8,0x66,0xe2,0xc7,0x09,0xb9,0x8b,0x84,0x96,0x2a, + 0x19,0x65,0x50,0x7e,0xaf,0x34,0xc0,0x60,0xcc,0xf1,0xc1,0xa1,0x15,0x16,0xa4,0x74, + 0xbd,0x31,0x06,0x20,0x62,0xfc,0x53,0x73,0x0c,0xa1,0x8e,0xfa,0x8b,0x16,0x85,0xa0, + 0xb8,0x8c,0x8e,0x42,0xda,0x5b,0xd2,0xf0,0x39,0x35,0xf3,0xef,0x2d,0x31,0xc5,0x90, + 0x8a,0xa3,0x63,0x4b,0xe8,0x95,0xc2,0xc9,0x25,0x3a,0x81,0x2f,0x9e,0xb7,0x4f,0x9d, + 0x4d,0x04,0xd0,0x6f,0x6f,0x54,0x20,0x63,0xbc,0x32,0xc7,0x0d,0x8a,0xc4,0x3a,0xee, + 0xbd,0xbc,0x80,0x10,0x1a,0x9d,0xba,0x92,0x29,0xe9,0xa0,0x0d,0xa5,0xb2,0x08,0x25, + 0xce,0xba,0x09,0x51,0x76,0xbd,0xb7,0x05,0x88,0xa4,0xde,0xf7,0x6a,0xdf,0x53,0xdc, + 0x62,0x8c,0x21,0x28,0x48,0x58,0xa9,0x5f,0xad,0x83,0xcf,0xc0,0x20,0x2d,0x75,0x75, + 0x72,0xa2,0x37,0xd9,0xd3,0x2d,0x9d,0xe5,0xa2,0xf7,0xeb,0xc6,0x1d,0xcd,0x79,0xd8, + 0x3d,0x52,0x05,0x64,0xa7,0xd9,0xda,0x8e,0x5b,0x3b,0x32,0x8e,0x4f,0xfc,0x8c,0x27, + 0x76,0xc6,0x13,0x3f,0xa3,0x5a,0x63,0x61,0xe8,0x9d,0x2c,0x97,0xdd,0x06,0x07,0x8c, + 0xec,0xe3,0xf4,0x0a,0xa3,0xbc,0x8f,0xec,0x20,0x5b,0xb5,0x31,0xb5,0x69,0x1f,0x1d, + 0xc3,0xdb,0x67,0xf4,0xd2,0x78,0x72,0xe6,0x93,0x12,0x48,0xcb,0x80,0xdd,0xf1,0xbc, + 0x33,0xa4,0xde,0xdc,0xe4,0x9f,0x86,0x31,0x62,0x83,0x45,0x6d,0xe4,0x84,0x9a,0x1d, + 0x0b,0xe5,0x8a,0x0f,0xd3,0x1b,0x2f,0xdd,0xbd,0x1c,0x58,0xfe,0xea,0xde,0xda,0x76, + 0x3f,0xfa,0x57,0xb4,0x6d,0x80,0x98,0x10,0x17,0xcc,0x44,0x89,0x0b,0xbc,0xed,0xfe, + 0x13,0x40,0x39,0x41,0xa1,0x8d,0x2a,0xce,0xb2,0xad,0x5c,0xf1,0x42,0x0e,0x19,0xde, + 0xca,0xee,0x75,0x3e,0x31,0xee,0x0b,0x63,0xd5,0xa2,0x12,0x81,0x8c,0x9b,0x5f,0xf5, + 0x94,0xdb,0x96,0x12,0x28,0x91,0xff,0x16,0xbe,0xab,0x53,0x75,0x82,0x24,0xb4,0x6c, + 0xe4,0xef,0xec,0x1c,0x5c,0x5c,0x94,0xa8,0x4b,0x7e,0xf2,0xb4,0xd1,0xfa,0x32,0x77, + 0x2a,0x77,0xd6,0x39,0x0d,0x3b,0xd6,0x28,0x79,0x13,0xda,0x50,0x57,0x33,0x6a,0x25, + 0xc7,0x9e,0x81,0x7d,0x67,0x33,0x53,0xb8,0xb3,0x26,0x4f,0x17,0x43,0xda,0xb3,0x26, + 0x4d,0xfc,0x4f,0x05,0x24,0xdc,0xc2,0xc4,0xb4,0x86,0xe3,0x2f,0xb0,0x53,0xa7,0x7b, + 0xbc,0x97,0xa5,0x8e,0xf7,0x32,0x1f,0x3b,0xb5,0x0f,0xe0,0xed,0x73,0x7c,0x7a,0xc2, + 0x47,0x0e,0x09,0xa7,0x29,0xed,0xb9,0x44,0xdb,0xc3,0x35,0x74,0xdd,0xf6,0xfb,0xf6, + 0x2e,0x6a,0x5d,0x5f,0x3c,0x17,0x41,0x63,0x01,0x90,0x0f,0xb2,0x9b,0xf3,0x0f,0x49, + 0x4d,0x76,0x8b,0x17,0x9b,0xae,0xd3,0xa6,0xa2,0x63,0x67,0xfd,0x3f,0xd8,0x60,0xb3, + 0xb0,0x9f,0xa9,0x6c,0x16,0xaf,0xd4,0x66,0xc0,0x45,0x76,0x76,0x0e,0xa9,0x55,0x94, + 0x51,0x33,0x18,0x77,0xc2,0x16,0x98,0x2a,0x3f,0x92,0x5d,0x2f,0x8a,0xcd,0x59,0xbb, + 0x4f,0x98,0xef,0x04,0x73,0x19,0x94,0xa9,0x19,0x96,0x0f,0xef,0x52,0x25,0xf9,0xfd, + 0xe4,0x5c,0xdf,0xae,0x70,0x6f,0xcc,0x1e,0x48,0xe5,0x34,0x30,0x20,0x25,0x62,0x1f, + 0x13,0x4b,0x6c,0x65,0xd5,0x41,0x9d,0xf1,0xa1,0x0f,0xcf,0x09,0x4e,0xb3,0x7c,0x74, + 0xb9,0x06,0x1f,0x5f,0x5f,0xe1,0xa3,0x11,0xca,0x0c,0x5b,0x36,0xd3,0x5b,0x96,0xd7, + 0xd4,0xe3,0x59,0xc2,0x03,0x7d,0xae,0xa5,0x5f,0x7c,0xbe,0xe5,0x7f,0xf7,0x39,0x97, + 0xff,0xd9,0xe7,0x5d,0x02,0x22,0xbc,0x17,0x15,0xc3,0xf7,0x78,0xca,0x5e,0x56,0xde, + 0xf3,0x33,0x06,0x99,0x83,0xbd,0x11,0xd6,0x0c,0x1c,0x5a,0x57,0xed,0x58,0x57,0x8c, + 0xbb,0x59,0x0e,0x61,0x41,0x8c,0x96,0x72,0xee,0x12,0xc9,0xe9,0xd0,0xd9,0x5e,0x50, + 0x5d,0x32,0xba,0x3d,0x80,0x75,0x3c,0x4b,0x06,0xbd,0x61,0x3f,0x4b,0xba,0x24,0xc2, + 0x48,0x47,0xa8,0x53,0x13,0xee,0x0b,0xe0,0x44,0x70,0x29,0xfe,0xb0,0x9b,0x4f,0x86, + 0x4f,0xe9,0x2f,0xbf,0x6e,0x74,0x73,0x4f,0xf1,0xcb,0xa5,0xc5,0x1c,0xd7,0xf9,0x7d, + 0xf1,0x59,0xa5,0x06,0x22,0x51,0x5f,0x87,0xe8,0xe8,0x7b,0x86,0xaa,0xe7,0xff,0x89, + 0xc8,0xc8,0x89,0x6c,0xd1,0x3d,0x9d,0xef,0x23,0x96,0x92,0x2e,0x00,0x14,0x67,0x39, + 0xe3,0x79,0xc8,0xad,0x0f,0x6e,0xba,0x99,0x58,0x7e,0x93,0xbe,0x3a,0xf7,0xdd,0x33, + 0x99,0x51,0x62,0xee,0xe8,0x77,0x82,0x97,0x6e,0x4f,0xd4,0x0a,0x73,0x76,0x38,0x86, + 0x14,0x56,0x95,0x37,0x74,0x05,0x29,0xf3,0x02,0x26,0xa4,0x33,0x67,0x38,0xa5,0x13, + 0xee,0xe7,0xe6,0x9e,0x19,0xe4,0x97,0x84,0xba,0x37,0x10,0x23,0x09,0x76,0xbd,0xc7, + 0x18,0x91,0xcf,0x10,0x9e,0x42,0xac,0xb9,0x07,0x02,0xf9,0xed,0x6f,0xc3,0x43,0xd4, + 0x09,0x24,0x8b,0x9c,0x76,0x48,0x7c,0x31,0x4b,0x9f,0x91,0x35,0xeb,0x46,0xd9,0x6c, + 0x7a,0xcb,0xb4,0xb9,0x63,0x98,0x47,0x58,0xc3,0xde,0x0e,0x86,0x73,0xbf,0x7d,0x78, + 0x4d,0x82,0xc5,0x64,0x4c,0x82,0x1f,0x7f,0x8a,0x93,0x85,0x58,0x18,0xb6,0xc0,0x8b, + 0x9b,0x77,0x2b,0x83,0x12,0x30,0xf4,0x23,0xe5,0x42,0xa6,0xbf,0x94,0x1e,0x1a,0xb7, + 0x80,0x57,0x09,0x92,0xfa,0xd8,0xf4,0x70,0x51,0x15,0x2d,0xc1,0x67,0x61,0x3c,0xb0, + 0x94,0x8d,0xf9,0xa3,0xf1,0x2e,0x01,0x6e,0x15,0x95,0xf1,0x86,0xb4,0xc7,0x7b,0x73, + 0xc6,0x92,0xcb,0x79,0xfe,0x64,0x7d,0xb5,0xfe,0x44,0xa8,0x6d,0xaf,0x99,0x0a,0xa8, + 0xfc,0x1b,0xbb,0x72,0x6d,0x78,0x3e,0xf1,0xd6,0x0f,0x59,0x66,0x08,0x94,0x27,0x4b, + 0x9b,0x7c,0x2d,0x4f,0x22,0x43,0xe7,0x9f,0x99,0xb2,0x40,0x49,0x5c,0xf0,0x54,0x38, + 0xe4,0x9c,0xe7,0x9a,0xd6,0x4b,0x44,0x21,0x79,0xf7,0xcb,0xd6,0xc0,0xc8,0x95,0x03, + 0xf1,0x53,0x23,0x57,0xad,0x70,0x2c,0xcd,0xb5,0xd4,0x6a,0xe6,0xfd,0x14,0x36,0xdb, + 0x14,0x1f,0xc1,0x9a,0x94,0xc8,0x42,0x0b,0x0f,0x8d,0x79,0x4d,0x8d,0x01,0x91,0x0b, + 0x8f,0xe6,0x33,0x49,0xa8,0xfa,0x39,0x4f,0x2b,0xf9,0x5f,0x52,0x58,0xae,0xcb,0x3c, + 0x23,0x9b,0xe1,0x57,0xd2,0x17,0x5b,0x86,0xe1,0x79,0xe8,0xc6,0x16,0x11,0xf4,0x76, + 0xad,0xec,0xcd,0x57,0x44,0x20,0x7a,0x6c,0x44,0xa4,0xc0,0xd2,0x98,0x9b,0x3a,0x45, + 0x01,0x25,0x36,0xa8,0xee,0xd6,0x8a,0x36,0x2e,0xef,0x7e,0x09,0x5b,0x79,0xc5,0x45, + 0xd4,0x9e,0x7f,0x80,0x75,0x22,0xf2,0x5e,0xdc,0x39,0x6c,0x25,0x47,0x9d,0x8f,0xd9, + 0xd7,0x5b,0x03,0x52,0x3d,0xca,0xfa,0x53,0xb8,0xe8,0xbf,0xe9,0xce,0xc6,0xeb,0xcc, + 0xc1,0xad,0x86,0xc4,0xda,0xcf,0xdc,0xf3,0xf8,0x81,0x8f,0x62,0xba,0x3c,0x86,0xfd, + 0xe1,0x31,0x3a,0x2e,0x95,0xee,0x2e,0x7b,0xee,0xdb,0xa3,0xcb,0x24,0x1f,0x0c,0xeb, + 0x8a,0xf4,0xa2,0xa2,0xf9,0x76,0x2c,0x11,0xdc,0x31,0xd9,0x3c,0xb6,0x27,0x7b,0x06, + 0x71,0x70,0x57,0x66,0x80,0x42,0xd6,0xfb,0x1d,0x77,0x31,0xe5,0x6c,0xf7,0x71,0xa8, + 0x4b,0x50,0xe0,0x66,0x2d,0x97,0xa6,0x45,0x71,0x61,0xe5,0xb3,0x3f,0x39,0x23,0x73, + 0x5d,0xcb,0x86,0xda,0xf4,0x1e,0x6d,0xc7,0x52,0x03,0xdd,0x61,0xc6,0xeb,0xfa,0x18, + 0x13,0xd9,0xa1,0x67,0x78,0x60,0x46,0xd1,0x02,0xd5,0x14,0x1e,0xe6,0x0f,0x2a,0x2a, + 0x49,0x74,0x7c,0x76,0xb5,0x7e,0x83,0xe0,0xf6,0x54,0xae,0x75,0xd9,0x26,0x47,0xcc, + 0xe6,0xac,0xdd,0x6b,0x27,0xd7,0x20,0x13,0x78,0x7c,0x6d,0x84,0x2d,0x0f,0x70,0x25, + 0x6e,0x7c,0xfd,0xa6,0xca,0x97,0xe5,0xe6,0xa6,0x12,0x24,0xa6,0x66,0xd6,0xd2,0x90, + 0x4b,0x29,0x02,0x07,0x72,0x60,0x00,0x89,0xfb,0xd7,0x80,0xe3,0x74,0x3a,0x08,0x87, + 0x9b,0x2f,0x75,0x0b,0xc7,0xc1,0x4f,0x4a,0x95,0x0e,0xce,0x28,0xb8,0x20,0xaf,0x86, + 0x54,0xf1,0x5a,0x4f,0x8e,0xeb,0x04,0xfa,0xb5,0x6c,0xf3,0x91,0x62,0x8e,0x46,0x98, + 0xde,0xf1,0x0c,0xe0,0xd1,0x66,0xd1,0x6a,0x90,0xdb,0x24,0x7f,0x5c,0xba,0x5c,0x5e, + 0x0a,0x31,0xab,0x1c,0x0f,0xf4,0x8e,0xe1,0x3b,0x61,0xde,0xa1,0x51,0x16,0x6b,0x6f, + 0x06,0x75,0xa4,0x62,0x0d,0x63,0x3d,0x17,0x75,0x46,0x75,0xc7,0xfb,0xa0,0x96,0x41, + 0x8d,0xd2,0x7e,0xb1,0x61,0x5f,0xdd,0xe1,0x51,0xa7,0xe2,0xd8,0x9e,0x09,0x9f,0x97, + 0x0b,0x87,0x16,0xd7,0xab,0x14,0xe9,0x74,0x06,0x94,0x8a,0xd9,0x37,0x42,0xdd,0xda, + 0x62,0x54,0xf4,0xf3,0x8a,0x22,0x2d,0xa5,0xc4,0xfd,0x9f,0x19,0x9f,0xee,0x83,0x29, + 0x5d,0x3a,0xd3,0xb1,0x49,0xe3,0xa2,0xdf,0x73,0xee,0x83,0xf1,0xf8,0xa1,0x51,0x39, + 0xc8,0x38,0x62,0x00,0xaf,0xea,0x12,0x0c,0x10,0xec,0x16,0xe3,0xea,0xda,0xd8,0xee, + 0xe1,0x9e,0xd8,0x00,0x7f,0x07,0xf9,0x74,0xc8,0x30,0xd0,0x54,0x6c,0xe1,0xb0,0x02, + 0x53,0xb2,0xa7,0x0d,0x26,0xa4,0x4b,0x9a,0x42,0xcb,0x6b,0x4e,0xfc,0xbb,0xf3,0x3c, + 0x4a,0x41,0x42,0xf5,0x42,0xdc,0x99,0x8a,0x57,0x65,0xa9,0x84,0xa6,0xd5,0x2a,0x3a, + 0x3a,0xc8,0x03,0x41,0x19,0xe2,0xe8,0x3c,0x1e,0xda,0x40,0x26,0xe3,0xa1,0xfd,0x7d, + 0x9e,0x5d,0x0b,0x0d,0x7e,0x64,0xe6,0xc3,0x10,0xd0,0x45,0x59,0x10,0xfd,0x31,0x24, + 0x96,0x24,0xa0,0x48,0x77,0x41,0x97,0xbc,0x7b,0x25,0xdc,0x64,0xba,0xad,0xe0,0xce, + 0x97,0x41,0x0f,0xa0,0xf0,0x9a,0x22,0x08,0xfa,0x3d,0xb4,0x1e,0x41,0x2d,0x8b,0xe7, + 0x7d,0x20,0x7d,0x86,0x58,0x2c,0xdd,0xf3,0x46,0xf0,0x7a,0x9e,0x29,0x91,0x29,0x3c, + 0xee,0xe9,0x27,0xca,0x8d,0x59,0x26,0x9c,0x20,0xf8,0x9d,0x48,0xc5,0x37,0x0e,0xa9, + 0x2c,0xc9,0x9c,0x18,0x2c,0x27,0x98,0x9c,0x6d,0x73,0x0f,0x10,0x4b,0x44,0xcf,0x92, + 0x1e,0xaf,0x32,0x82,0xd6,0x4a,0x25,0xcc,0x28,0x37,0xe0,0x81,0x68,0x32,0x37,0x91, + 0x09,0xe2,0xf4,0x70,0xa9,0x33,0x99,0x66,0xda,0x95,0x5c,0x6e,0xd7,0x50,0x1b,0x57, + 0x0c,0x80,0x58,0xbd,0x9b,0x91,0x37,0x48,0x94,0xa8,0xdd,0x9c,0x6c,0x98,0x8d,0xd7, + 0x8a,0xbe,0xee,0x84,0x5e,0x2f,0x0a,0x4e,0x87,0xef,0x7e,0x39,0x0a,0xea,0x05,0x57, + 0x0d,0x5b,0x5e,0x6f,0x78,0x45,0x28,0xbd,0xab,0x8b,0xf0,0xf8,0xb2,0x0f,0x91,0xe8, + 0x14,0x4a,0x4c,0xe2,0x3e,0xd1,0x02,0xda,0xf2,0x19,0x6f,0x9b,0x7d,0x36,0x65,0xef, + 0x86,0xec,0xdd,0xeb,0xbe,0x96,0x1f,0x8a,0xac,0x54,0x95,0xd9,0x5f,0xe2,0x20,0x0d, + 0x7c,0x86,0x46,0x64,0x25,0x03,0x2f,0x2f,0xce,0x9d,0x87,0x6d,0x4b,0x74,0x27,0x82, + 0x3e,0x95,0x9d,0x48,0xa6,0xcb,0x99,0x32,0x4f,0xda,0x56,0xf8,0x59,0x74,0x38,0x49, + 0x0d,0xe8,0xfb,0x07,0x48,0xc1,0xeb,0x65,0x60,0x1e,0x3b,0x16,0x89,0xef,0x55,0xe4, + 0x34,0x9f,0x54,0x6d,0x12,0xa8,0xba,0xe7,0x3b,0xcd,0x87,0x4b,0xe8,0xb5,0x6d,0xc1, + 0xee,0x33,0x25,0x74,0x5f,0x9b,0x50,0xee,0xe0,0x85,0x78,0x9f,0x27,0x1b,0x8a,0x80, + 0x9d,0x8d,0x89,0xb1,0x00,0x68,0x2b,0xc1,0x91,0xa1,0x8d,0x3f,0xc1,0xa1,0x33,0xe8, + 0x2d,0x94,0x64,0xf5,0x7d,0xb6,0xf1,0xa0,0x3b,0xaa,0x7a,0xf7,0xf4,0x4f,0x5f,0xee, + 0x34,0x22,0xd9,0x8a,0x1b,0x9e,0x96,0xa3,0xde,0xc8,0x31,0x9c,0xb1,0x44,0x7a,0xc0, + 0x3d,0x4a,0x05,0xd2,0xf2,0x13,0x63,0x7d,0xa6,0x4d,0x6b,0x59,0x87,0xce,0xdf,0xc2, + 0x3c,0xc2,0x41,0x85,0x37,0x18,0x2d,0x48,0x4a,0x5e,0x7b,0xd1,0x52,0xfd,0xcd,0x3c, + 0x8a,0x8a,0x63,0x4c,0x07,0xdf,0xf8,0xcf,0xdc,0x14,0x65,0x7a,0xd9,0x2e,0x57,0x0e, + 0xe5,0xe2,0x22,0x5f,0x6a,0x4e,0xf2,0x97,0x93,0x1b,0x7d,0xcc,0xce,0xf4,0xf1,0x74, + 0x76,0xa4,0x36,0xa8,0xde,0x45,0x47,0xab,0x50,0xae,0x85,0xaf,0xb1,0x98,0x3a,0xfc, + 0x7b,0x22,0x4c,0x6e,0xf5,0xea,0xe2,0x3a,0x4c,0x49,0xac,0x92,0x84,0x04,0x5a,0x54, + 0xec,0xbb,0x58,0xd1,0xfa,0xf8,0xf1,0x3d,0x1f,0x89,0x45,0x9a,0xa1,0xe3,0x42,0xb6, + 0xec,0xb2,0x2d,0x23,0xe7,0x87,0xdd,0xa0,0x15,0x5b,0xb9,0xde,0x6d,0xba,0x20,0x6a, + 0x21,0xbc,0xec,0xc9,0x4d,0x6b,0x3b,0xc9,0xce,0x5a,0x3b,0xc9,0xe9,0xac,0xb5,0x7b, + 0x57,0xba,0x5d,0xd1,0xde,0x50,0xe2,0x17,0xc8,0x1d,0x22,0xff,0xd1,0x5a,0x87,0x43, + 0x8a,0x3c,0x4f,0xc6,0xff,0x93,0xef,0x8a,0xea,0x4d,0x43,0xff,0x92,0x60,0xa5,0x9b, + 0x75,0x97,0x79,0xa8,0xef,0x7a,0xd7,0xb7,0x56,0xba,0xa0,0x2b,0x3c,0xad,0x5c,0x87, + 0x9f,0x18,0xfe,0x41,0xc1,0x81,0x45,0xcd,0x43,0xcf,0x90,0x55,0xab,0x6e,0x0a,0xa5, + 0x52,0x86,0x91,0x1b,0xf5,0xda,0x07,0xea,0xb5,0xee,0x54,0x08,0x8c,0xaf,0xd8,0xa7, + 0xe1,0x54,0x59,0x6a,0x9a,0xe6,0x79,0x2a,0x3f,0x93,0xbe,0xaa,0x72,0x69,0xfb,0xd2, + 0x22,0xab,0xe3,0x9c,0xc8,0x1a,0xfc,0x23,0xef,0x1a,0x68,0x81,0x62,0x25,0x57,0xce, + 0x35,0x37,0xaa,0xa8,0xfc,0xd2,0xc4,0x95,0xa1,0x36,0x2a,0xd5,0x01,0xb6,0x3e,0xfc, + 0x99,0x6a,0x48,0x45,0x23,0xc3,0xa0,0x61,0xfc,0x85,0x47,0xda,0x91,0x98,0xf2,0xa2, + 0x53,0x9c,0x43,0x6b,0x9e,0x64,0x36,0x36,0xfe,0x3c,0x63,0xc7,0xe5,0xb7,0x15,0x73, + 0x03,0xc0,0xc9,0x2d,0x48,0x7a,0xc2,0x27,0xfd,0x87,0xf9,0x2d,0x3a,0x63,0x38,0x68, + 0xbc,0xb1,0xe1,0x87,0x7d,0xd0,0xe3,0x97,0x5b,0xe7,0x97,0x8d,0xcd,0x10,0x63,0x00, + 0xeb,0x89,0xf9,0x6a,0x0d,0xc5,0x1c,0xfd,0x50,0x1c,0xaa,0xcf,0x73,0x87,0x1c,0x56, + 0x12,0xf0,0x90,0xaa,0x62,0x96,0x48,0xf7,0xe9,0x59,0xe2,0x3a,0x10,0x77,0x9d,0x4a, + 0xc2,0xea,0xb0,0x2e,0x52,0xa3,0x86,0x75,0x49,0x4a,0xa5,0x53,0x9a,0x57,0xad,0x7e, + 0x30,0x1d,0x3e,0x1c,0x50,0x0d,0xee,0x1d,0x92,0xd1,0xfc,0xb7,0x29,0x05,0x02,0x63, + 0x93,0x1f,0x3b,0x94,0x64,0xb6,0xf5,0xed,0x33,0xd2,0x06,0x26,0x17,0x4e,0xea,0x7f, + 0x71,0xea,0xd6,0xee,0x33,0xfa,0x34,0x72,0x3f,0x51,0xe2,0xd6,0xb3,0x66,0xb1,0xf3, + 0xed,0xbd,0x68,0x76,0x10,0xcc,0xb6,0x87,0xb3,0x98,0x8b,0x5a,0x08,0x17,0xd1,0xd1, + 0x05,0x52,0xe8,0x11,0x29,0xa3,0x5a,0x08,0x0b,0x20,0xfe,0xeb,0x04,0x64,0x1e,0xa0, + 0x99,0x83,0xe4,0x24,0x01,0x52,0x15,0xe6,0xed,0xf4,0x99,0xcc,0xec,0x5f,0x88,0x11, + 0xe0,0x00,0x56,0x81,0x78,0x3e,0xa1,0x67,0x7a,0x88,0xb2,0xce,0x63,0x18,0xd3,0xe3, + 0xc9,0xd8,0xf1,0x95,0xec,0xff,0xad,0x8a,0xec,0x8e,0x58,0xd8,0x7d,0x40,0xc2,0x91, + 0x3c,0x97,0xc2,0x14,0x80,0xa8,0x1a,0xcf,0x40,0xa1,0x92,0xdd,0xa6,0x1b,0xce,0xba, + 0x28,0x8b,0xb5,0x3c,0x4e,0x11,0xf1,0xe2,0x73,0xa2,0x22,0xdc,0x59,0xa5,0x6a,0x7d, + 0x7e,0x68,0xb7,0xea,0xc8,0x6e,0x54,0xb5,0xaf,0x2a,0x36,0x03,0x9a,0x73,0xd5,0xc1, + 0x41,0xfc,0xb0,0x1c,0x43,0xda,0x2f,0x03,0x12,0xa6,0x9b,0xa1,0x8a,0x7a,0x6b,0xf3, + 0x84,0xb2,0x7c,0x9f,0xa4,0xd6,0xdd,0xeb,0xac,0x41,0xf1,0xd8,0x8f,0xb1,0x8a,0xf4, + 0x71,0xf5,0x7a,0xe7,0x89,0x68,0xfc,0xa8,0xfb,0x32,0x27,0x1e,0xde,0x06,0x77,0x78, + 0xf8,0xdb,0x94,0xd4,0xe3,0x61,0x22,0x03,0xb2,0x71,0xc5,0xef,0xc7,0x59,0x1c,0xd7, + 0x04,0xe2,0x7b,0x3a,0xd5,0x98,0x61,0xb9,0xc3,0xd7,0x13,0x3c,0x1f,0x8f,0xae,0x51, + 0x32,0x48,0x8f,0xb9,0xf1,0xe3,0xe0,0x16,0x96,0x20,0x3b,0x71,0x12,0xfe,0x35,0xd4, + 0x0c,0x3f,0xa2,0xee,0x80,0xb0,0xc0,0x0a,0x79,0x92,0x84,0xbf,0x7c,0x8f,0x58,0x5f, + 0xa4,0x1a,0x0a,0x6b,0x3e,0x9e,0x48,0x37,0x68,0x6a,0x6e,0x04,0xa8,0x0b,0xa0,0x55, + 0x9c,0xc0,0x74,0xd1,0x03,0x67,0x37,0xc7,0xfc,0xd1,0x64,0xa2,0xc2,0x8b,0x7a,0xdf, + 0x52,0x00,0xfa,0x80,0x27,0x45,0x98,0x64,0x8d,0x31,0xbd,0x26,0x61,0xef,0xfb,0x51, + 0x01,0xf2,0x06,0xdc,0x3a,0xf8,0xb0,0xbf,0xff,0x9a,0x00,0x66,0xd8,0x42,0xf2,0x77, + 0xe0,0xb7,0xff,0xf6,0x03,0xc7,0x23,0xcb,0xc6,0x33,0x05,0xde,0x1b,0xcc,0x88,0x16, + 0xc1,0xc1,0xdf,0x0a,0xf2,0x60,0x7f,0x2c,0xf4,0xf1,0xc0,0x3e,0x58,0x60,0x33,0xa0, + 0xe9,0x43,0x9a,0x35,0x3b,0x63,0xc8,0x8c,0xf6,0x4c,0xd7,0x09,0x99,0x9d,0x70,0xc5, + 0xc8,0x81,0x47,0x0f,0xf4,0x80,0x41,0x69,0x1b,0x54,0x90,0x97,0xfc,0x29,0xa3,0x8c, + 0xad,0x03,0x2d,0xe6,0x98,0x1a,0x8d,0x09,0x1f,0x6c,0x71,0x59,0x04,0x6e,0x92,0x34, + 0x13,0x8c,0xaa,0x31,0xbc,0x4a,0xb9,0x7a,0x9c,0xe8,0x64,0x93,0x34,0xcd,0x77,0xf0, + 0xb7,0x00,0xba,0xea,0xab,0x3e,0xe5,0x99,0xdf,0x1e,0xf3,0x33,0x3e,0x46,0x56,0x8c, + 0x33,0xe9,0xb6,0xff,0x39,0x38,0x28,0x40,0x89,0xd9,0x0b,0x70,0x2b,0x2c,0xc8,0x4f, + 0xbb,0x7f,0x25,0x3f,0xef,0x7e,0xb5,0x0f,0x0a,0xa0,0xd7,0xef,0xe9,0xeb,0x60,0x8a, + 0x13,0xb5,0x3a,0xb1,0x56,0xbe,0x60,0x45,0xf5,0x81,0x1d,0xf3,0x28,0xc0,0xa8,0x8a, + 0xdb,0x76,0xaa,0x74,0xb5,0x74,0x39,0xb2,0x64,0x53,0xd8,0x91,0xb3,0xe4,0xc4,0x4f, + 0x75,0x1e,0x8c,0x71,0x62,0x17,0x12,0xb7,0xcb,0x40,0x9c,0xb9,0x80,0x92,0xc2,0x3c, + 0xdf,0x37,0x46,0x30,0x1f,0xa6,0x59,0x11,0x58,0xa0,0xad,0xf3,0x94,0xc5,0x34,0x77, + 0x9e,0x65,0x43,0xb1,0xe4,0xe8,0xe0,0xc9,0xb9,0xd0,0x74,0x2b,0x85,0x9d,0xa5,0xd1, + 0x2d,0x59,0xd3,0xcb,0xad,0xc1,0x98,0xae,0x0d,0x3a,0xbc,0xf7,0xf2,0x9a,0x39,0xaf, + 0x61,0xba,0x60,0x73,0x9f,0x86,0xd8,0x24,0x9c,0x81,0x0d,0xd4,0x6f,0xe8,0xc6,0x0a, + 0x9f,0x6c,0xb5,0xc1,0x41,0x26,0xb3,0x16,0xca,0x8b,0xea,0xf5,0x11,0xe2,0x72,0x87, + 0x2f,0xc4,0xb0,0x31,0x78,0xbc,0xc1,0xe6,0xe4,0x52,0x87,0x5c,0x7c,0x80,0x26,0x2d, + 0x2a,0x5f,0x7f,0x88,0xed,0xfb,0x0f,0x02,0x1f,0xc7,0x8e,0xc9,0xb7,0xd8,0x5a,0x61, + 0x4e,0xce,0x33,0x42,0x7b,0x72,0x69,0x90,0x5e,0x2e,0x6f,0x29,0x68,0x88,0xd5,0x02, + 0x72,0x18,0x46,0xdf,0x31,0xbc,0x26,0x97,0x3c,0xc2,0x18,0x02,0xaf,0xf8,0xab,0x2e, + 0x7d,0x2b,0xda,0x29,0xb6,0xe6,0x00,0x1f,0x4b,0x98,0x40,0x83,0x3d,0x1b,0xb9,0xea, + 0xd2,0xe3,0x5e,0x23,0x22,0x4d,0xfa,0x63,0x81,0xa3,0x7e,0x10,0x33,0x7a,0x37,0x45, + 0x2e,0x75,0x21,0xd9,0xe0,0xef,0x34,0xac,0x76,0xe6,0x5c,0xf1,0x6a,0x81,0x9b,0x88, + 0x81,0x75,0x11,0xf7,0x54,0x3c,0x58,0x3d,0x44,0x9e,0xe6,0xe1,0xd9,0x25,0x97,0xc4, + 0xdd,0x06,0x3f,0x5f,0xb3,0x88,0xd5,0x95,0xb1,0xf0,0x02,0xab,0x75,0xb7,0x91,0x5d, + 0x0c,0x68,0xa3,0x6e,0x65,0x33,0x63,0x12,0x7c,0x81,0x44,0x09,0x19,0x1e,0xbd,0xe9, + 0x2c,0x95,0x48,0xd6,0x46,0xdf,0xf6,0x1e,0x4c,0x77,0xf8,0xa1,0x8b,0x0c,0xf0,0x49, + 0x4e,0x91,0x31,0xae,0x49,0x38,0xc4,0xe4,0xfd,0x9d,0xfc,0x6d,0x41,0x6e,0x78,0xfa, + 0xac,0xbd,0x81,0xc4,0x1b,0x7a,0x4d,0x6f,0xbe,0x46,0x01,0x6d,0xbc,0x5e,0xf0,0x58, + 0x49,0x2f,0xf8,0x9d,0x4b,0x3e,0xa7,0xac,0xe7,0x7d,0x5e,0x51,0xa8,0xc7,0xc3,0x1d, + 0xb2,0x06,0x39,0x6f,0x64,0x64,0xa0,0x15,0x01,0x2c,0xc1,0x3f,0x4a,0xe0,0xb5,0xf3, + 0x03,0xf8,0x42,0x44,0x0a,0xf9,0x9b,0xe4,0xc2,0x4c,0x0b,0x42,0x52,0x1a,0xf4,0x7c, + 0xc7,0xbd,0x4b,0x34,0x4e,0xf3,0x18,0x99,0x0d,0x0e,0x93,0xc8,0xe7,0xc8,0xa6,0x55, + 0xc9,0xe8,0x56,0x3e,0x76,0x6f,0xbd,0x8f,0x5c,0x2e,0x00,0xd2,0x74,0x84,0x73,0xee, + 0xd1,0x6d,0x0d,0x5b,0xa9,0xd1,0xb8,0x9e,0x6e,0xdf,0x6d,0x00,0xaf,0x39,0xdd,0xed, + 0xda,0xe7,0xf1,0xcf,0x68,0x8f,0xa6,0xd0,0x05,0xf6,0x38,0x21,0x52,0x01,0x2e,0x7f, + 0x10,0xfb,0xbf,0x98,0x5a,0x98,0xbb,0x5d,0x36,0x2e,0x33,0xc3,0x7a,0xbd,0x7b,0x7a, + 0x1a,0xe6,0xd7,0x72,0xc1,0x68,0xfe,0xb2,0x73,0xf2,0x4d,0xaf,0xff,0x5d,0xd8,0x46, + 0x2d,0xd0,0x88,0xf6,0x99,0x92,0xe9,0x4e,0xdb,0xbc,0xfd,0x37,0x06,0x45,0x1a,0xf2, + 0x42,0x14,0x22,0xe9,0xa4,0x0f,0x55,0xca,0x7b,0xb4,0x80,0xe5,0x46,0x60,0xed,0xcb, + 0xaf,0xd7,0x49,0x7e,0xa5,0xf1,0x36,0x1d,0x6c,0xd9,0x84,0xaa,0x6f,0xc7,0x5f,0x47, + 0x37,0xf5,0x27,0x71,0x6d,0x27,0xf9,0x94,0x5e,0xd4,0x9f,0xd4,0xa3,0xeb,0x3a,0xda, + 0xba,0x85,0x56,0xe3,0x17,0x1f,0x01,0xd2,0x24,0x3a,0x74,0x4c,0xe5,0x07,0x93,0xe8, + 0x36,0xf9,0x14,0xb7,0xce,0x1b,0xa4,0x76,0x90,0x37,0x96,0x26,0x95,0x22,0x11,0x3f, + 0x63,0xb6,0x0e,0x85,0x36,0x36,0xa5,0x80,0x30,0xb1,0x8a,0x34,0xdc,0x6e,0x4e,0x6f, + 0x71,0x0f,0x0d,0xfb,0x84,0x51,0xfd,0x6a,0x40,0x0d,0xa1,0x4e,0xdf,0x1b,0x0e,0xce, + 0xa9,0x71,0x34,0x36,0xc2,0xbc,0x18,0x9e,0xff,0x84,0xf4,0xa1,0x83,0xf9,0x51,0x72, + 0x53,0xdf,0x49,0xb6,0x5d,0xe7,0x9a,0xec,0xee,0xe2,0x97,0xfe,0x27,0x8e,0xe4,0x19, + 0x99,0xfd,0x45,0x61,0x8d,0x6c,0xde,0x37,0x37,0xb5,0x77,0xf0,0x26,0x1d,0xf3,0xfd, + 0xa7,0xd7,0x0a,0xdf,0x56,0x2f,0x3b,0x50,0xbd,0xce,0x72,0x93,0xce,0x6e,0x3f,0xd5, + 0x7c,0x26,0x66,0xaa,0x64,0x35,0xe7,0x7a,0x7d,0x5c,0xfd,0xa7,0xad,0x98,0x23,0xba, + 0x53,0x1a,0x17,0x12,0xcb,0xaf,0x6b,0x2c,0xc2,0x3a,0xe5,0x7d,0xe8,0xe6,0x15,0x53, + 0x14,0x25,0xcf,0x24,0xae,0xd1,0x4e,0x9b,0x9d,0xbc,0x80,0xe5,0x1b,0x63,0x35,0x02, + 0x7e,0x87,0x4c,0x6a,0x9b,0x86,0x2f,0x19,0xd2,0x0e,0x4c,0x1e,0xf1,0x45,0x93,0xb7, + 0xf7,0x9e,0x76,0x26,0xe0,0x3f,0x80,0xe2,0xe5,0x02,0x65,0xd4,0xf9,0x35,0xcc,0x4f, + 0x57,0xa1,0x1d,0x63,0x37,0x1a,0xfe,0x35,0xb3,0xb3,0xcd,0xcd,0xb3,0x06,0x78,0x03, + 0x8a,0x7b,0x0b,0x5d,0x78,0x6c,0xbf,0x60,0xad,0xc9,0x30,0xb6,0xbf,0xef,0x63,0x14, + 0xf6,0x23,0x2e,0x31,0x81,0x61,0x3f,0xba,0x70,0x7f,0xc0,0xea,0x7d,0x14,0xc1,0xa9, + 0xab,0xe3,0x76,0x99,0xcf,0x90,0xb2,0xf7,0xe6,0x98,0x12,0xd8,0xf2,0xe1,0x13,0xee, + 0x3a,0x76,0xeb,0x72,0x37,0x35,0x09,0x59,0x3d,0x6a,0x45,0x94,0x66,0xec,0xd9,0x20, + 0xa0,0x2a,0x5b,0xff,0x16,0x25,0xd2,0x7d,0xba,0xc4,0xa7,0x6c,0x27,0x24,0x32,0x86, + 0x2d,0xb7,0x48,0xf0,0x81,0x3f,0x51,0x26,0xe7,0xaa,0x2e,0xb4,0x62,0x54,0x22,0xb5, + 0x5a,0x2b,0x5b,0x05,0x7b,0x97,0x6c,0x3f,0xa5,0x81,0xce,0xbb,0x15,0x1e,0x30,0x5c, + 0xb4,0xcd,0xac,0xb9,0x9b,0xf8,0x13,0x46,0x91,0xdb,0xa5,0xab,0x0d,0x77,0x3d,0xb8, + 0x75,0x54,0xe7,0x46,0x7d,0x3e,0xd1,0x7d,0xd2,0x7e,0x7e,0x4e,0x66,0xf9,0x39,0xad, + 0xf2,0x21,0xaf,0x9b,0x25,0x7d,0x4b,0x9b,0x3a,0x21,0xd8,0x3f,0x61,0xad,0xe6,0xcc, + 0x36,0x8b,0x7a,0x93,0xd9,0x29,0xe9,0x60,0x1e,0x5e,0x6e,0xd9,0xf1,0xa2,0xd6,0x61, + 0x11,0x91,0x3c,0x62,0x56,0xb7,0xe9,0xe4,0x2a,0xfb,0xa4,0x14,0xf4,0x73,0xa8,0x7c, + 0x26,0xb7,0xe2,0x44,0xa8,0x22,0x8e,0x58,0xef,0x12,0x4b,0x6c,0x9d,0xf2,0xde,0x1d, + 0x53,0xa3,0x47,0xfb,0xb7,0xd6,0xf6,0xb7,0xd3,0xdb,0xd0,0x95,0x3a,0xb2,0xe9,0x60, + 0x5c,0xbe,0xbb,0xdc,0x66,0x7b,0xc0,0xa2,0xc5,0x1d,0xd9,0x2d,0x22,0x01,0xa6,0x4a, + 0xf4,0x93,0x6e,0x87,0xad,0x22,0x31,0x4c,0xb8,0x85,0xa5,0x5b,0x8d,0x5d,0xa8,0xf4, + 0x48,0x32,0x36,0xea,0x81,0x71,0x4a,0xcf,0x2f,0xea,0x4f,0x9f,0x76,0x9e,0xb4,0xcc, + 0xe3,0xb3,0x6f,0x3a,0xbb,0xf2,0xf8,0xcd,0xb7,0x9d,0x9d,0xd6,0x76,0x9b,0x00,0x27, + 0x55,0x97,0x1a,0x9f,0xb0,0xf6,0x71,0x52,0x4b,0xe5,0xe6,0x35,0xb7,0x54,0x5d,0x8e, + 0xb5,0x06,0x63,0x5a,0x64,0xea,0x27,0xd8,0x53,0x5d,0xb6,0x59,0x62,0x68,0xed,0x4e, + 0x6f,0xdb,0xb8,0x88,0x49,0x46,0xe8,0xbc,0x2c,0xb4,0xb6,0x91,0x70,0x02,0xb5,0x76, + 0x7f,0xc6,0x81,0xd8,0xaf,0x32,0x4e,0x31,0xf2,0x44,0x0b,0x5b,0xff,0xdd,0xda,0xe0, + 0xeb,0x5d,0xc8,0x57,0x04,0x86,0x7d,0xcb,0x39,0xaf,0x94,0xf4,0x01,0xd5,0xe3,0x3c, + 0x88,0x64,0x52,0x5e,0x71,0x21,0x5f,0xca,0x0b,0xd5,0x19,0x87,0xc8,0xa2,0xf4,0x7b, + 0xac,0x12,0xe1,0x3a,0x34,0xcf,0x86,0xfd,0xdb,0x36,0xf7,0x4f,0x7d,0x80,0x75,0x2c, + 0x6b,0x51,0x42,0x1d,0x5b,0xec,0x1c,0x9b,0xed,0xa7,0xd3,0x5b,0xbe,0x4f,0x58,0x0b, + 0xa5,0xe0,0xd0,0x22,0xac,0xf6,0xcd,0xd5,0x6c,0x68,0x08,0xef,0xf9,0xda,0xd4,0x51, + 0xa6,0xf2,0x0c,0xba,0x8a,0xe0,0x7d,0xc3,0xb1,0xfb,0xb3,0xba,0x56,0x63,0xf4,0x7d, + 0x6c,0x74,0x01,0xce,0x50,0xaf,0x66,0x4a,0x8a,0xab,0x3f,0x58,0x98,0x37,0x35,0x5d, + 0x73,0xef,0x31,0x85,0x81,0x46,0x6d,0x72,0x7e,0x2a,0xd6,0x56,0x46,0x9c,0x2f,0x8a, + 0x1d,0x6b,0x20,0xdb,0x31,0x5b,0x96,0x92,0x14,0x41,0x39,0xfd,0xab,0x02,0x0a,0x78, + 0xc2,0xfb,0xe4,0x7a,0x97,0x7f,0xf4,0x60,0x02,0x07,0x7d,0x64,0xa4,0xc0,0xb5,0x72, + 0x01,0x15,0x35,0xa1,0xf5,0x04,0x77,0x68,0xaa,0x3a,0x72,0x5d,0x97,0xda,0x5f,0xd2, + 0x6d,0xc7,0xde,0x26,0xfe,0x9c,0x09,0xce,0xa5,0xad,0x9f,0xe1,0x8c,0x9f,0xec,0xc1, + 0xf8,0xd9,0xd9,0x85,0x8d,0xd5,0xad,0xc4,0x7a,0x2f,0x07,0xc8,0x29,0xf7,0x65,0x09, + 0xe7,0xfc,0xd2,0xae,0x69,0x41,0xac,0xce,0x36,0xc4,0xee,0xb6,0xf8,0x2c,0x09,0x64, + 0x1e,0x2a,0x7b,0x12,0x9e,0xdd,0x63,0x26,0x67,0x5c,0xf6,0x87,0x90,0x65,0x80,0x70, + 0x0a,0xd6,0x61,0x5c,0x43,0x12,0x8c,0x1c,0x3b,0xe1,0xe6,0x5f,0xb6,0x77,0xbe,0xdd, + 0xf9,0xe6,0x49,0x9b,0x1c,0xe9,0x11,0x40,0x36,0x82,0x4a,0xe4,0x05,0xbc,0x23,0x84, + 0x5e,0x9d,0x1d,0x02,0x08,0x36,0x47,0x58,0x50,0x26,0xf3,0x36,0x00,0x4c,0xbd,0x5c, + 0x2a,0xe7,0x52,0xd7,0x0c,0xa1,0xb3,0xfd,0xc1,0xfe,0x73,0x9a,0x4f,0xc1,0xf2,0xc6, + 0xb2,0x60,0x89,0x3b,0x34,0xd7,0xb0,0x4f,0xca,0xc7,0x5c,0x70,0x46,0x13,0x1f,0x37, + 0x8f,0xa7,0x34,0x9d,0xfd,0x5d,0xd2,0xbd,0x33,0xe6,0xdf,0xdc,0xf1,0x0f,0x6f,0x04, + 0x26,0x9a,0x84,0xdf,0x15,0xf4,0xcb,0x9a,0xfb,0x35,0x3e,0xff,0xe4,0xb6,0x1d,0x0b, + 0x5c,0xd4,0x65,0x8b,0xdc,0x46,0xfa,0x75,0x2f,0xad,0x12,0x7f,0xf0,0x44,0xaa,0x0f, + 0x8e,0x90,0xda,0xaa,0x94,0x65,0xf0,0x68,0x81,0x10,0x4f,0x97,0x12,0x53,0x2e,0x75, + 0xb5,0x34,0xcd,0x9f,0xe5,0x28,0x0e,0xcf,0x36,0x1f,0x62,0xf4,0x56,0xc7,0x2f,0x31, + 0x5d,0xb3,0xd2,0x33,0x22,0xea,0x44,0x79,0x72,0x44,0x26,0x21,0x58,0xee,0x77,0xa3, + 0xa8,0x59,0x34,0xc0,0x89,0x13,0x4b,0x82,0x0f,0x2e,0x52,0x32,0x85,0xe1,0x27,0x75, + 0xfb,0x08,0xf7,0xc2,0x27,0x30,0x08,0xca,0x5a,0x39,0x37,0xb0,0xe1,0x2b,0xbd,0xb9, + 0xa5,0x80,0x94,0xfa,0x68,0xc1,0xa0,0x51,0x67,0x8a,0xb4,0x73,0x72,0x87,0x3a,0xc7, + 0xfb,0x8a,0xdf,0x23,0x2b,0x50,0x8b,0x40,0xdc,0x1f,0x33,0x45,0x73,0xab,0x26,0x96, + 0x07,0xc9,0x83,0x5b,0x25,0xd0,0x9f,0xdd,0x26,0xce,0xa7,0x2d,0xf2,0x86,0xff,0x97, + 0x9e,0x08,0xd1,0x0a,0xe2,0x9d,0x07,0xdd,0xb3,0xbb,0x71,0xb6,0x44,0x31,0x83,0xab, + 0x01,0x98,0x75,0x42,0xc3,0xf1,0xdb,0x36,0xd6,0x4c,0x25,0xa7,0x9c,0x24,0x2f,0x21, + 0xb6,0x8e,0x67,0xf3,0x34,0x4e,0x72,0xe9,0x72,0x2f,0xc9,0x05,0x31,0xc3,0x1d,0x35, + 0x14,0x46,0x81,0x9e,0x7c,0x30,0xf3,0x87,0x70,0xc1,0xa9,0x60,0xb6,0xb9,0xbb,0xf3, + 0xcd,0xb3,0x6f,0x71,0x08,0x2e,0x5f,0x11,0x8d,0x41,0x9f,0x11,0x93,0x61,0x77,0x73, + 0xd3,0x3a,0x8a,0xc9,0x4b,0xc0,0x14,0x91,0xc7,0xb2,0x07,0x4f,0xf7,0x7a,0x46,0xf5, + 0x15,0x4c,0x96,0x4a,0x4e,0x2f,0x5c,0x1f,0xd0,0x8a,0x1c,0x3e,0x7c,0x6e,0xbb,0x85, + 0x99,0x59,0xfb,0x95,0xc2,0xa5,0x87,0xe3,0x7a,0x32,0x3d,0xdc,0x58,0xe0,0xb4,0xf7, + 0xb7,0xfd,0xbd,0xad,0x97,0xdd,0x71,0xb7,0xd7,0x0d,0x22,0xb2,0xd0,0x1a,0xa1,0xa3, + 0x59,0x3d,0x98,0x9c,0xb5,0xc2,0xef,0xb6,0x9b,0x8d,0xa7,0x3b,0x4f,0x43,0x3a,0x52, + 0x0f,0x9f,0xed,0x34,0xf0,0x94,0x21,0xf9,0x9b,0x90,0x4e,0xd6,0xc3,0xa7,0xe1,0x5d, + 0xc2,0x65,0xec,0x5d,0x41,0x07,0x01,0x49,0xad,0x2b,0x99,0x9e,0x36,0xbe,0x6d,0x36, + 0x4d,0xa6,0x9d,0xa7,0x4d,0x93,0x67,0xbb,0xb9,0x2a,0x53,0x10,0xbd,0xed,0xe2,0x56, + 0xc9,0x4d,0x5e,0xe5,0xb3,0xc6,0xd3,0x6f,0x56,0x55,0xf9,0x6d,0x45,0xee,0x5f,0xc1, + 0x87,0xb5,0xe2,0x66,0x9e,0x75,0x7b,0x47,0x72,0x7e,0xb7,0xaa,0xde,0x56,0xb0,0xbf, + 0x97,0x04,0xbf,0xef,0x99,0xbc,0x3b,0xbb,0x8d,0x6d,0xbf,0xa5,0xdf,0x7a,0xd5,0x6a, + 0xe6,0xff,0x79,0xf3,0xc3,0xfa,0x9c,0x6e,0xb5,0xdf,0xcf,0xba,0xff,0x1a,0x0c,0x3f, + 0xa7,0xae,0x57,0xbf,0x6d,0xfd,0xf6,0x8b,0x4b,0x9c,0x6f,0x9f,0x7d,0xd7,0x78,0xb6, + 0xfd,0xed,0x03,0x73,0xfe,0xd0,0x9f,0x92,0xfb,0x7e,0xcc,0x20,0xcd,0x2d,0xbd,0xe9, + 0x74,0xcc,0x76,0x09,0xd3,0x97,0xff,0xea,0x43,0xbe,0xf8,0xd0,0x9f,0x5e,0x9d,0x80, + 0x99,0xf8,0x08,0x3c,0xd9,0xdd,0x59,0x3b,0x20,0x18,0x81,0xe0,0xc9,0xee,0xee,0xaf, + 0x3f,0xff,0x2b,0x88,0xde,0x4c,0xa0,0x74,0xfe,0x40,0x26,0x75,0xa6,0x04,0xa4,0x37, + 0x9e,0x51,0xdd,0xeb,0x91,0xd0,0x12,0xdc,0xfa,0x35,0xf7,0x7a,0x02,0xbc,0xed,0xd3, + 0x1d,0xaf,0x21,0x36,0xba,0x99,0x4b,0xb7,0xf5,0x68,0xbf,0xc5,0xec,0xfa,0x5f,0xfd, + 0x2e,0xe5,0x93,0x01,0xf5,0x4d,0x63,0xf7,0x9b,0xf5,0x04,0x73,0xb3,0x39,0xd8,0x6a, + 0xfe,0xf5,0xd5,0xb2,0x13,0x90,0xab,0xf3,0xee,0x90,0x5a,0xac,0xad,0xf4,0xf2,0xe9, + 0x48,0x7e,0xe6,0xe5,0xfb,0xf6,0xd9,0xb7,0xeb,0x9b,0xe9,0xe6,0xdb,0x87,0x49,0xd8, + 0xbf,0x0c,0x79,0x3e,0x67,0x54,0x21,0x7a,0xfa,0x1c,0x7a,0xf9,0x52,0x13,0x77,0x9a, + 0x0d,0x50,0x66,0xfd,0xe8,0xd7,0xbc,0xfe,0x98,0x94,0xfc,0xab,0x49,0xbc,0x71,0x64, + 0x9d,0xa4,0xbb,0xce,0x70,0x17,0x45,0xec,0x87,0x35,0x81,0x1f,0x2c,0xc1,0x4e,0x4c, + 0x9b,0x78,0xcb,0xc3,0x16,0x73,0x63,0xac,0x70,0x33,0x8c,0xf1,0x53,0x73,0x41,0xb9, + 0x15,0x98,0x26,0xa4,0x29,0xff,0x02,0x99,0x80,0x71,0xc2,0x3b,0x7e,0x1a,0xcd,0x90, + 0x85,0xad,0x2e,0x42,0x00,0x9d,0xb8,0x1b,0x1c,0xd1,0xfe,0x76,0x2d,0xe3,0x25,0x28, + 0x7c,0x4f,0xac,0xd7,0xb2,0x8f,0xc1,0x27,0xb9,0x8b,0x41,0x59,0x99,0x6e,0x0f,0x07, + 0x47,0xe4,0x0e,0x4b,0x5e,0x3f,0xd1,0xab,0x53,0x87,0x67,0xe9,0x5e,0x22,0xca,0x0f, + 0xd8,0x0e,0x94,0x69,0x12,0xd0,0xfc,0xd1,0x0d,0xc1,0xf7,0xbf,0xe7,0x24,0x2a,0xd2, + 0xf6,0x7f,0x14,0x6a,0x59,0x69,0x2f,0x3f,0x78,0x84,0xbb,0xf9,0x17,0x9b,0x3e,0xfd, + 0x38,0x60,0x37,0xa9,0xf9,0x92,0x6f,0xfb,0x48,0x4e,0x10,0x04,0xdc,0xf5,0xb0,0x4c, + 0xbb,0xa0,0xc2,0x05,0x93,0xe7,0xc3,0x08,0x72,0x78,0x7f,0xa8,0xe6,0xde,0xb3,0xfe, + 0x39,0xbe,0x6d,0x5e,0xf4,0x87,0xc3,0xc1,0xb4,0x6d,0xb9,0x33,0xe2,0x02,0xd8,0x71, + 0x05,0x3b,0xb1,0x7c,0x88,0xf3,0xe4,0x8d,0xd5,0xde,0x93,0x81,0x64,0x1c,0x9b,0xd2, + 0x06,0xea,0x29,0xc9,0x73,0xd0,0x34,0xb0,0xdd,0x32,0xcd,0xb1,0x93,0x03,0x6d,0x7a, + 0xdd,0xec,0xa2,0x8d,0x63,0x27,0x87,0xd8,0xb6,0xb7,0x26,0x5e,0x65,0x57,0x14,0xc9, + 0xbe,0x97,0x5f,0xfc,0x82,0xbf,0x1a,0x2b,0x3d,0x37,0x8b,0xb6,0x0b,0x00,0x49,0x3d, + 0xcf,0x37,0x68,0x0b,0xe3,0x0b,0x27,0xcf,0x71,0x56,0x8e,0x15,0xc1,0x5f,0xd4,0x25, + 0x82,0xc4,0x3e,0xde,0xdc,0x34,0xbf,0xe2,0x7a,0x98,0xc3,0x9f,0x6f,0x68,0x4f,0xd5, + 0x81,0x80,0xb3,0x6f,0x0a,0x5f,0x1a,0x8c,0x10,0xe5,0x3b,0xc0,0x51,0x9b,0xd9,0x56, + 0x9e,0xb2,0xe1,0x61,0xec,0x8f,0x20,0xf9,0x8c,0x51,0x14,0x97,0x86,0x91,0x7c,0xc8, + 0xce,0x62,0x77,0x2c,0xc9,0x07,0x8c,0x27,0xde,0xdf,0xa2,0x86,0x8d,0x9a,0x41,0xfc, + 0x39,0xce,0x26,0x03,0x1c,0xe5,0xf4,0x33,0x8a,0xf7,0xcf,0x49,0x41,0x57,0x46,0x42, + 0x77,0x28,0xc3,0x3a,0xe6,0x8d,0x2f,0x68,0xb3,0x3e,0xec,0x87,0x3f,0x56,0x31,0xba, + 0xc4,0x4d,0x58,0x45,0x5c,0x14,0x71,0x31,0xae,0x04,0x4d,0x78,0xbc,0x30,0xb5,0xaf, + 0xc5,0x65,0x2b,0x7e,0xa5,0xe3,0xe2,0x05,0x7f,0x75,0x47,0xb7,0x18,0x94,0x9a,0x40, + 0x36,0xce,0xa8,0x3c,0xac,0x5d,0x1f,0xb5,0x4d,0x0e,0x77,0xf4,0xdd,0x3d,0xdc,0x9c, + 0x51,0x9c,0x88,0x70,0x29,0x36,0x4f,0xf9,0x53,0x56,0x8e,0xd3,0xc2,0xc0,0x71,0x63, + 0x9d,0x85,0x23,0xd7,0xe6,0xf9,0x49,0x37,0xe3,0x3a,0xfb,0xfc,0x8c,0xbe,0x7b,0x75, + 0x81,0xf4,0xcf,0x68,0x7e,0xd7,0xc3,0x17,0x36,0x35,0x97,0xfd,0xa9,0x7f,0x28,0xa3, + 0x5b,0x94,0xd5,0x07,0x36,0x7a,0xe4,0xa3,0x9b,0x70,0xb7,0x3a,0x32,0x4f,0x34,0xd5, + 0xad,0xb6,0x7e,0x34,0x45,0x7f,0xa9,0x01,0xa4,0x14,0xb3,0xde,0x06,0xd2,0x73,0x2f, + 0xfd,0xc5,0x76,0x8b,0x8f,0xa4,0x28,0xa5,0x95,0xc3,0xbb,0xdb,0x55,0xe4,0xf6,0xb5, + 0x37,0x4a,0x1b,0xc3,0x1b,0x4a,0x71,0x89,0x04,0x17,0x27,0xf0,0x51,0xfb,0x8b,0x11, + 0x97,0xba,0xe2,0x6a,0x0c,0xcb,0x73,0xfc,0xa7,0x09,0x29,0xf3,0xb8,0xc1,0x85,0xc1, + 0x06,0x42,0xe7,0x51,0x4c,0xbb,0x78,0x0c,0x45,0x38,0x5c,0x4a,0x27,0x3b,0xc9,0x6e, + 0xf2,0xa4,0xc2,0xe2,0x10,0x8b,0x84,0x70,0x44,0x78,0x37,0x5c,0x6d,0x72,0x38,0xc0, + 0x98,0x1e,0xc7,0xb9,0xc1,0xc7,0xd4,0x87,0x55,0x1b,0xc8,0xc1,0x73,0x06,0x14,0x9b, + 0x44,0x46,0x02,0x55,0x54,0x44,0x5f,0x32,0x9a,0x7b,0x6c,0x12,0x51,0xf7,0xae,0xde, + 0x01,0x75,0x82,0x86,0x17,0x5e,0xc3,0x46,0xea,0x0b,0x85,0xed,0x21,0x96,0x4b,0x99, + 0x60,0xf2,0x26,0x37,0xc6,0x27,0x14,0xfe,0xd7,0x4c,0x75,0xb4,0x1f,0x01,0x1b,0xe4, + 0x25,0x1d,0x8f,0xda,0x93,0xcf,0xde,0x3e,0x92,0x23,0x78,0x69,0xc2,0x93,0x98,0x3d, + 0x2e,0x7e,0xe8,0x93,0x13,0x10,0xda,0x46,0x8a,0x61,0x42,0x76,0x3a,0x9b,0xe0,0xd8, + 0x78,0x42,0xf6,0x01,0xe5,0x6e,0x81,0xa3,0x3d,0x1e,0x6d,0xd1,0x0a,0xbe,0xcb,0x1d, + 0xb7,0x5b,0xce,0xb5,0x9f,0x83,0x45,0xda,0xa5,0x86,0x89,0xe4,0x4e,0xe5,0x74,0x30, + 0xdb,0x65,0xca,0x8c,0xaf,0x36,0x3e,0xf7,0x92,0xe7,0xb7,0xff,0x69,0x73,0x72,0x87, + 0xff,0xd9,0x6c,0xdb,0xf0,0xde,0x7b,0x16,0xb0,0xd8,0x5a,0xa4,0x81,0x9a,0x2d,0x39, + 0xb8,0x5f,0xd6,0x14,0xe2,0x68,0x1f,0x10,0xbe,0x7d,0x75,0xec,0x5d,0xbd,0xf5,0x20, + 0x38,0x83,0x3c,0xac,0xb5,0xbe,0x1f,0x4b,0xcf,0xe2,0x9c,0xfb,0xd4,0xb6,0x11,0xdb, + 0x6d,0x3d,0xa9,0x18,0x16,0xf4,0x29,0xaa,0x9e,0x14,0x5c,0xc0,0x93,0xaa,0x41,0x51, + 0x95,0x89,0x7b,0xbd,0xda,0x09,0x92,0xdf,0x58,0x71,0x10,0x2e,0x3e,0xcf,0x3a,0xad, + 0x8f,0x8d,0x25,0x3b,0x3e,0xfb,0xd8,0x88,0x8d,0x4b,0x23,0x40,0xc4,0xd5,0x31,0x82, + 0x1f,0x1c,0xc5,0x78,0x4d,0xe9,0x6e,0x24,0x8c,0x0a,0xba,0xbb,0xc1,0x30,0x1e,0xd4, + 0x05,0x0f,0xb8,0x7d,0xb0,0xf1,0xa0,0xeb,0x07,0x1b,0xeb,0xef,0x1f,0x08,0x50,0xd5, + 0x0d,0x04,0x7f,0x14,0x54,0x77,0xe2,0x74,0x32,0x7d,0x77,0x35,0x77,0x6d,0x69,0xc9, + 0x91,0x5f,0x77,0xb8,0xd5,0xbf,0x1d,0x10,0xf7,0x19,0x61,0xa3,0x3e,0xe9,0x61,0x2b, + 0xfb,0x6e,0xff,0x20,0x5c,0xe9,0xaf,0x61,0x73,0x73,0xd6,0xa0,0x53,0x39,0x42,0x8f, + 0x32,0xd6,0xf1,0x52,0x32,0x90,0x65,0x80,0xf6,0x86,0x42,0x4c,0xae,0xfd,0x63,0x79, + 0x0e,0x23,0x51,0x79,0x45,0x42,0xbd,0x6c,0xbc,0x9c,0x5c,0x0d,0x7b,0x24,0x8e,0xce, + 0xfa,0xe8,0xea,0xe2,0x3e,0x62,0x3d,0x20,0x9f,0x30,0x7c,0xc5,0x33,0x8c,0xcb,0x86, + 0xfe,0x67,0x88,0xf6,0xa4,0x1b,0xaf,0xd2,0xfd,0xa5,0x8e,0x35,0xaa,0x5a,0x51,0xde, + 0xeb,0xd2,0xd5,0x56,0x21,0xae,0x7f,0x95,0x33,0xc4,0x5d,0xca,0xc8,0x5c,0x4f,0xf9, + 0xa1,0xde,0x98,0xdf,0xbf,0x9a,0x12,0x09,0x75,0x81,0xd7,0x13,0x83,0x94,0xf0,0x08, + 0x73,0x30,0xda,0x91,0xa5,0x6e,0xe0,0x1e,0xfd,0x64,0xc5,0xe9,0x42,0xe1,0x5a,0x17, + 0x6f,0x1c,0xd8,0x63,0x62,0x11,0x38,0xe5,0xd1,0x34,0xaf,0x66,0x9f,0xfd,0x69,0x97, + 0x2e,0x7e,0x9b,0x15,0x28,0x82,0xf9,0xe6,0x69,0x8c,0x53,0x03,0xac,0x97,0xa7,0x39, + 0xfc,0x9e,0x03,0x98,0x05,0xbd,0x09,0x28,0x29,0x62,0xbe,0xc9,0x36,0xcd,0x35,0xd3, + 0x9f,0x30,0x55,0xc8,0x06,0x00,0x24,0x5e,0x98,0x17,0xdf,0xc1,0x07,0xa0,0x0b,0xa7, + 0x07,0xff,0x45,0x61,0x0c,0xf6,0xea,0x3f,0x1e,0x2d,0x76,0xee,0xb6,0xce,0x93,0xf0, + 0x36,0xcc,0x3d,0x68,0xdd,0x99,0x8e,0x85,0xf1,0x41,0x25,0x1a,0xc1,0x08,0xfa,0x3b, + 0x38,0xfc,0xa1,0x8d,0xd9,0xa0,0x17,0xfc,0x76,0xf0,0x63,0x1d,0xea,0x0d,0x42,0x86, + 0xeb,0x45,0x98,0x82,0xe5,0x72,0xeb,0xf0,0xe3,0xec,0xe3,0xf8,0x48,0x26,0xf0,0x34, + 0x8e,0xd7,0x97,0xb4,0x5d,0xdf,0x7e,0x6a,0x0a,0xa2,0x86,0xc8,0x7d,0x3b,0x34,0x35, + 0xa0,0x33,0xec,0xe0,0x04,0xe3,0xe8,0x32,0x63,0x43,0x42,0xed,0x2e,0x7b,0xec,0xd8, + 0x2b,0xac,0x90,0x03,0xaa,0x95,0x0c,0x41,0x09,0x92,0x9e,0xae,0xfe,0x6d,0x85,0xa7, + 0x8f,0xd1,0x90,0x2c,0x0d,0x09,0xca,0x18,0x1b,0x56,0x59,0x55,0x22,0x66,0x40,0x2d, + 0x24,0xe3,0x49,0xdd,0xd1,0x5d,0xc7,0x48,0x50,0x0b,0x48,0x1a,0x7a,0x28,0x41,0x8c, + 0x74,0xe5,0x48,0x2f,0x4c,0x7a,0xce,0x31,0x91,0xca,0x1b,0xa5,0xd4,0x30,0xa2,0x8e, + 0xe4,0xbd,0x59,0xe1,0x23,0x28,0xbf,0x65,0x2e,0x7c,0x19,0xde,0x00,0xe6,0x13,0x3a, + 0x5a,0xa5,0x55,0xe1,0xdd,0xcd,0x38,0xb7,0xc9,0x33,0x51,0xfb,0x7b,0x89,0x15,0xd8, + 0xa7,0x6d,0x61,0xa2,0xe3,0x2a,0x29,0x8a,0xec,0x44,0x3d,0x3b,0x7e,0x7e,0x27,0xfc, + 0x9a,0xff,0xc3,0xbe,0x30,0x22,0x51,0x31,0xc7,0x1e,0xc8,0xe8,0xfc,0x72,0xe1,0x23, + 0xbd,0x0a,0x1d,0x57,0x64,0x32,0x22,0x9b,0x7b,0x00,0xc0,0x08,0x21,0xae,0x4a,0xfd, + 0xed,0xbb,0xdf,0x61,0xcd,0xca,0xa8,0xe5,0x5a,0x7c,0x84,0x39,0x31,0x4f,0x38,0x60, + 0xc5,0x8c,0xf3,0x9c,0x30,0xc5,0x35,0xe0,0x5b,0x4e,0x04,0x16,0x81,0x38,0x4d,0x0a, + 0xd4,0x13,0x06,0x90,0xc9,0xab,0xef,0x55,0x08,0x78,0x06,0x8b,0xb7,0xc4,0x7d,0x8c, + 0xeb,0xe2,0x4a,0x20,0x39,0x64,0x83,0x43,0xc4,0x5c,0xeb,0xe2,0x29,0x61,0x92,0xd9, + 0x94,0xa5,0xec,0xfb,0xb5,0x27,0xeb,0x02,0x4f,0xcd,0x4e,0xe3,0x18,0x05,0x4d,0xef, + 0xf2,0x0e,0xfb,0x60,0xb6,0x74,0xb6,0x44,0x06,0x4f,0x16,0x78,0x9c,0xe2,0x72,0x94, + 0x43,0xf3,0x68,0x36,0xed,0xcc,0xa6,0x0d,0x32,0x3e,0xaf,0x07,0xe6,0x20,0x7b,0x76, + 0x6a,0xc9,0x47,0x72,0x12,0x0d,0x4a,0x33,0xf5,0x0c,0xe6,0x6c,0x56,0xec,0x94,0xa3, + 0xb4,0x9a,0xdf,0x32,0x6d,0xc8,0x5e,0x7d,0x4a,0xf1,0x46,0xc2,0x84,0xd2,0x50,0x3a, + 0x9b,0x96,0x33,0x90,0xcf,0x30,0xd9,0xef,0x41,0x99,0xc1,0x2d,0x97,0x25,0xa6,0x19, + 0x9b,0x92,0xdd,0xb9,0x1e,0x26,0x25,0xa8,0x4e,0x08,0xca,0x84,0x2d,0x67,0x22,0x48, + 0xad,0xba,0x13,0x11,0xba,0x88,0x1d,0x39,0x97,0x4a,0x66,0xf3,0x61,0x52,0x49,0x23, + 0xf5,0x93,0xaa,0xa5,0xd8,0x19,0xdf,0x9d,0x88,0xfb,0x67,0x19,0x08,0x87,0xee,0x86, + 0x41,0xfb,0xdc,0x4b,0x77,0x31,0xe4,0xb2,0x5e,0x53,0xa0,0x9f,0x24,0xca,0xcb,0x20, + 0x4f,0xd0,0x7e,0x09,0x92,0xea,0xe4,0xc7,0x86,0xe7,0x37,0xe0,0x2d,0xd1,0x5d,0x64, + 0xe0,0x21,0xf2,0x59,0x9a,0x17,0x85,0xe7,0xfe,0xcc,0x2f,0x4b,0x92,0x99,0x40,0x78, + 0x8e,0x4d,0x8b,0x28,0x31,0x80,0xf4,0x16,0x26,0x48,0xcb,0x0d,0xa5,0xb7,0x77,0x3a, + 0xf4,0x96,0xe1,0xd8,0xa1,0x8f,0xdd,0xc5,0xf6,0x0e,0x98,0x16,0x5d,0x91,0x69,0x21, + 0x55,0x2a,0xec,0x8f,0xb4,0xbe,0xfe,0x08,0x67,0xf8,0x7e,0x7d,0x92,0xcc,0xf5,0xf5, + 0x47,0x76,0x75,0xe6,0x4b,0x82,0xc4,0x07,0x79,0x83,0x9f,0x72,0x4d,0xea,0x02,0xdf, + 0xcc,0x07,0xaf,0x3e,0xf7,0xa3,0x59,0xd8,0xb0,0x14,0xaa,0x77,0x61,0x83,0x00,0x9b, + 0xb9,0x03,0x34,0x99,0x5a,0xa1,0xd7,0xd8,0x71,0xa5,0x13,0x52,0xab,0xe7,0x5b,0xf1, + 0xa8,0x64,0xf1,0x68,0xeb,0x1f,0x11,0xb1,0x35,0x08,0x99,0x86,0xbb,0x7c,0xcc,0xd9, + 0xcb,0x57,0xcb,0x7c,0x68,0x7e,0xb5,0xa4,0x11,0xf2,0xd5,0x92,0x67,0xd0,0x57,0xcb, + 0xf9,0xed,0x57,0x4b,0xc2,0xf1,0xa3,0x0c,0x09,0x79,0xa1,0xde,0x95,0x47,0xee,0x1c, + 0x79,0x66,0xf2,0xf0,0xb3,0x27,0x22,0xdf,0xe5,0xeb,0x2b,0xb7,0x8f,0xf1,0x16,0xc2, + 0x5a,0xbe,0xf4,0xb2,0x30,0xe1,0x2f,0x8e,0xf7,0x94,0xd0,0xda,0xd7,0xf0,0x32,0xe7, + 0x28,0x1f,0x69,0x15,0x93,0xd9,0x5f,0xd2,0xd3,0x88,0x7a,0x07,0xf2,0xa5,0xee,0x09, + 0x65,0x35,0x74,0x56,0x23,0x48,0x28,0xd5,0x16,0x0e,0x52,0x27,0x3b,0x7a,0x75,0x6f, + 0x52,0xbd,0x1f,0xf6,0x31,0x82,0x09,0x45,0x68,0x1b,0xed,0xf5,0x2f,0xc0,0xcc,0x83, + 0x86,0x76,0x3b,0xb6,0xee,0x64,0x49,0xc5,0xca,0xe1,0x36,0x37,0xbd,0x4d,0x1a,0xeb, + 0x0b,0xef,0xaf,0x10,0x44,0x9a,0x4c,0xf0,0xd3,0x35,0x57,0xa2,0x45,0xbd,0x29,0x75, + 0xee,0xc4,0x41,0x9d,0x05,0xcd,0x2c,0x80,0x28,0x36,0xcd,0x65,0x88,0x71,0xfd,0xb7, + 0xfd,0xdc,0x21,0x7c,0x66,0x61,0xb5,0xd2,0x2f,0x1f,0xed,0x8d,0x1c,0x77,0x7c,0xab, + 0xd1,0x32,0x00,0xb5,0x50,0x31,0x70,0x5a,0xed,0xb0,0xb2,0x9c,0x02,0xf2,0x86,0x28, + 0x52,0x7b,0xf5,0xff,0xd5,0xad,0xff,0xeb,0x68,0xb1,0x7b,0x97,0x7b,0x86,0xd5,0xde, + 0x79,0x10,0x5b,0x09,0x69,0x2f,0x74,0x2f,0xc5,0xd8,0x28,0x13,0x04,0xdb,0xad,0x63, + 0x7f,0x46,0x8f,0xc4,0xbb,0x44,0x41,0x1c,0x90,0x80,0x18,0x44,0x7c,0x13,0x89,0x1a, + 0x60,0xa1,0xbf,0xa6,0x60,0x91,0x95,0x4f,0x52,0x01,0x31,0xae,0x54,0x93,0x13,0xf6, + 0xf1,0x9b,0x9e,0xd8,0xc0,0xed,0x93,0xb2,0x9f,0x52,0xe7,0x73,0xba,0xde,0xfb,0x62, + 0x87,0x3c,0x75,0xd0,0x75,0x1b,0xf9,0xca,0x5c,0x2c,0x3c,0x00,0xa5,0x90,0xc8,0xa3, + 0x8e,0x52,0xda,0x8e,0xa3,0xc3,0x85,0x11,0x10,0x8c,0x26,0x26,0x29,0x36,0x41,0xe2, + 0x91,0x6f,0x01,0x04,0x4a,0xfe,0xd8,0x5c,0x8c,0xb8,0x15,0xa2,0x04,0x94,0x9d,0x93, + 0xe4,0xb4,0x9d,0xf9,0x14,0xbe,0x5b,0x60,0xa4,0xd9,0x9f,0xce,0xc5,0x85,0x8f,0xfa, + 0x31,0x02,0x63,0x24,0x5f,0x4e,0x14,0x65,0x01,0xef,0xec,0xe2,0x8a,0x01,0x1c,0x57, + 0x7f,0xec,0x84,0x4c,0x1d,0xfe,0xc1,0x05,0xcd,0x99,0x04,0xca,0x91,0x62,0x78,0xe9, + 0x84,0x47,0x0b,0x76,0xf8,0x01,0x7d,0x51,0xbf,0x6f,0x34,0xaf,0x59,0xf0,0x31,0x34, + 0x8a,0x50,0xe3,0xd3,0xe3,0xd1,0xc7,0x90,0x9d,0xbf,0x14,0x8e,0x80,0x78,0xe8,0x83, + 0x92,0xbb,0x4d,0x94,0xc5,0x3e,0x52,0xb8,0x74,0x00,0x90,0xff,0xa0,0x0c,0x44,0x16, + 0x57,0x55,0xe4,0xd6,0x2a,0x71,0x9d,0x1d,0x72,0x65,0xea,0xc7,0x8a,0x0b,0x96,0x10, + 0x57,0xdc,0x02,0x75,0xce,0xc4,0x6e,0x99,0x0a,0x1f,0x32,0xae,0x63,0xc3,0xa0,0x2e, + 0x3e,0x0b,0x75,0xf3,0x07,0xce,0xe4,0x38,0x6b,0x52,0xbb,0xa2,0x35,0x23,0x6d,0xe5, + 0x46,0x52,0xfc,0xf7,0x22,0xc2,0x10,0x7b,0x40,0x44,0x5b,0x33,0xf1,0xac,0x13,0xe0, + 0x29,0x9b,0xd3,0xe5,0x26,0x10,0xd8,0x6d,0x8a,0x78,0x3b,0x62,0xff,0x88,0x8d,0xd0, + 0x42,0xc0,0x72,0xc8,0xe7,0xfa,0xde,0xf3,0xd7,0x91,0x5b,0x5d,0x47,0x6c,0xc7,0x7b, + 0xb7,0xe2,0xc8,0x4e,0x34,0x97,0x5c,0x94,0xb0,0x7a,0xdf,0xe3,0xdb,0xba,0x39,0x6b, + 0xe7,0xec,0xf0,0x8b,0x77,0xff,0x4d,0x36,0xc8,0xb7,0xec,0xec,0x8e,0x7d,0xc7,0x4a, + 0xed,0x6a,0x8b,0x48,0x17,0xc0,0xe2,0xb5,0x8e,0xb5,0x1a,0x81,0xd9,0x2c,0x11,0x41, + 0xc4,0xbd,0x56,0x70,0xc2,0x97,0x21,0x68,0x83,0x0e,0x78,0xb3,0x47,0x77,0x89,0x84, + 0x86,0xa9,0xff,0x1d,0x77,0x32,0x78,0xde,0xac,0x1e,0x8b,0x50,0x6f,0x45,0x00,0xde, + 0xa8,0x85,0x8f,0xff,0xb3,0x3e,0xad,0xa4,0x8b,0xab,0x1d,0x5a,0xe9,0x28,0xe5,0x31, + 0x2d,0xe5,0x55,0xf8,0x18,0x0a,0xb2,0xc9,0x64,0xbc,0xd6,0xd1,0x90,0x88,0x98,0x46, + 0xb8,0x11,0xc9,0x53,0xf6,0x32,0xe9,0x3a,0x66,0xe6,0xf8,0x02,0x8b,0xdc,0x8c,0xe2, + 0xb3,0x0a,0x93,0x9b,0x8c,0xe5,0x82,0x7c,0xcf,0x24,0xc5,0x30,0xad,0x18,0x6f,0xa7, + 0x37,0xc5,0x9f,0x0f,0x14,0xe8,0x6c,0xa6,0xd1,0x08,0x9c,0x5e,0xc8,0xaa,0x3a,0x01, + 0x7d,0x60,0x9c,0x54,0x49,0x83,0x03,0x5a,0x01,0xee,0xd9,0x87,0x85,0x8d,0x40,0x9d, + 0x55,0x55,0xd4,0xaf,0xac,0xcd,0x54,0xdd,0x1b,0xf4,0xc4,0x3f,0x1f,0x47,0x5e,0xe9, + 0xb2,0xdb,0x2e,0x91,0x0c,0xb4,0x37,0x5c,0x1f,0x56,0xd5,0x78,0x36,0x02,0x1e,0x33, + 0x50,0x79,0x72,0xaf,0x8b,0x0f,0x2b,0xea,0xf6,0xc7,0x68,0x2f,0x10,0xc0,0x9e,0xff, + 0x31,0xb2,0x63,0xf8,0x32,0xe7,0xcb,0xfc,0xbe,0xbe,0xdf,0x9f,0x14,0xed,0xe7,0x2a, + 0x7b,0xd8,0xe5,0x54,0x25,0x4d,0x55,0x29,0x83,0x4e,0x49,0x56,0xb0,0x99,0x8f,0xc7, + 0x83,0xf1,0xf1,0x28,0xeb,0xe4,0x77,0xf6,0xa2,0xed,0x84,0x1f,0xe1,0xd0,0x69,0x18, + 0xb9,0x30,0xe6,0x5e,0x78,0xdc,0xda,0x6d,0xda,0xf7,0xc3,0xc4,0x87,0x64,0x2e,0xb4, + 0xc9,0xaa,0x11,0x85,0x26,0x99,0xf9,0x9d,0xa1,0x37,0xfa,0xaa,0x13,0xe6,0xca,0x15, + 0xc7,0x09,0x38,0x57,0x42,0xca,0x41,0x4f,0x1f,0x58,0x35,0x79,0x3d,0x2f,0x64,0xf6, + 0x5c,0x65,0xaf,0x8b,0x60,0x0c,0x44,0x6e,0x5d,0x2a,0x38,0xd2,0x21,0x2d,0x64,0xa4, + 0x8b,0x00,0x3f,0x65,0xa7,0x83,0xab,0x5c,0x64,0xad,0xf5,0x04,0x62,0x10,0x11,0x5b, + 0x62,0x62,0x68,0x0a,0x5a,0xd6,0x11,0x5a,0x68,0x23,0xce,0x40,0xa2,0xb8,0x24,0x70, + 0x0a,0x37,0xec,0x27,0x98,0xae,0xb2,0xda,0x09,0x8f,0x35,0x34,0xa8,0xf3,0xd7,0x12, + 0xa7,0xe5,0xb4,0xe5,0xd2,0x54,0xae,0x4e,0x04,0xec,0x5c,0xa8,0xa1,0x94,0x07,0x29, + 0x46,0xf2,0x19,0x4c,0x21,0x72,0xa7,0x16,0x2c,0xc5,0x59,0x40,0xf5,0x50,0x56,0x5d, + 0xba,0xc9,0x75,0x4a,0x92,0x7d,0x2d,0xb1,0x4d,0xca,0x0d,0x15,0x2b,0x42,0xf4,0xcd, + 0xe7,0xd3,0xd6,0xd6,0x16,0x36,0x33,0xd3,0x5a,0xb8,0x15,0xb6,0x4d,0x66,0xa7,0x3a, + 0xc0,0xe5,0xc9,0x17,0x50,0x32,0xcb,0x3b,0x6a,0x5e,0x79,0x2b,0x4d,0x8e,0xd3,0x2b, + 0xca,0x0a,0x43,0xa7,0xa8,0xf0,0x2f,0xa1,0x57,0x14,0xe6,0x8f,0x96,0x63,0xd1,0x61, + 0x9d,0x0e,0x58,0xc2,0x19,0x0b,0xd1,0x97,0xcb,0xdd,0x66,0xdb,0xca,0xc8,0x57,0x86, + 0xcb,0x21,0x85,0x4d,0x9e,0xb9,0xe3,0x9f,0xc2,0x1e,0x99,0xe3,0x7a,0xfd,0xde,0x32, + 0xe0,0x98,0x63,0x0c,0xfd,0x87,0x44,0x46,0x4d,0x9f,0x6e,0x6e,0xea,0x48,0x40,0x09, + 0x67,0x7d,0x8c,0x3e,0xcb,0xe5,0xc4,0x55,0x86,0x49,0x70,0x0a,0xf1,0xa1,0x4f,0x41, + 0x7b,0xea,0x6c,0xdd,0x5c,0xa9,0x24,0xe7,0x05,0x6e,0x72,0x59,0xf6,0x7b,0x01,0xeb, + 0x5c,0x8a,0xbf,0x40,0x50,0x0d,0xe3,0x91,0x19,0xf7,0x8f,0x57,0xde,0x67,0x16,0x9c, + 0x9a,0x15,0xa5,0x6c,0xf8,0xed,0xb2,0x36,0x71,0xda,0x04,0xc4,0x09,0xed,0x06,0xa6, + 0x97,0xb6,0xc2,0x17,0x1f,0xb8,0xc6,0xe7,0x5b,0x5d,0x78,0x07,0x09,0xff,0x3e,0xb9, + 0xc2,0x41,0xbb,0x5c,0xa3,0x0b,0xe6,0xf9,0x04,0x95,0x2b,0xd6,0x09,0xb3,0x92,0x5c, + 0x9e,0x79,0xf9,0xe6,0x35,0x05,0x4f,0x4e,0x77,0x9e,0xb4,0xf5,0x1d,0xc1,0x8b,0xbf, + 0x27,0x8b,0xd5,0xc3,0xd0,0x44,0xdc,0xfa,0x11,0x4c,0xe5,0x86,0x02,0x37,0xe2,0x35, + 0x43,0x23,0x38,0x86,0x70,0xc8,0x97,0xfa,0xf0,0xf5,0x7b,0xfa,0xe5,0xc5,0xe7,0x02, + 0x0f,0x0c,0x37,0x18,0x9f,0x4d,0x0c,0x10,0x50,0x20,0x0b,0xe9,0x70,0x1f,0x23,0x81, + 0xd9,0xbf,0x88,0x5f,0x9c,0x1e,0x44,0xbf,0x1d,0xbc,0x8c,0x0d,0x20,0x3b,0x7a,0x08, + 0x99,0x19,0x13,0x9c,0x00,0x2c,0xf8,0x4a,0x43,0x5d,0x46,0xce,0x9d,0x01,0x35,0x7b, + 0x12,0xab,0x50,0xeb,0x1a,0x79,0x20,0x1f,0x19,0x70,0x84,0x51,0x4f,0xee,0x35,0xc2, + 0x9f,0xe1,0x96,0x80,0x31,0x7c,0xbf,0xff,0x61,0xef,0xd7,0x80,0x5d,0x78,0x90,0x7f, + 0x8c,0x21,0x99,0x43,0x93,0x66,0x99,0xb1,0xe4,0x3c,0x1a,0xa9,0x12,0xd9,0xde,0xf2, + 0x1e,0xf1,0xa2,0x2f,0xae,0x1a,0xd9,0x6e,0x27,0x61,0x99,0x99,0x5d,0x2d,0x70,0x89, + 0xa0,0xab,0x9b,0x51,0xe6,0x1a,0xb5,0xe5,0x87,0x19,0xe4,0x0e,0x92,0x42,0xe4,0x1b, + 0xd6,0xa7,0xc5,0xb3,0x27,0xf0,0x99,0x70,0x4b,0xb7,0x59,0x66,0x75,0x88,0x66,0xd2, + 0x24,0x6c,0x35,0x4e,0x91,0x69,0xd6,0xb0,0xab,0xdf,0xcb,0x2e,0x8b,0x9c,0x1c,0x6e, + 0x93,0x1d,0x5b,0x8a,0xb4,0x3c,0x82,0x95,0xc8,0x75,0x3f,0x2b,0xe5,0xc7,0xcf,0xb4, + 0x4f,0x99,0x5f,0x1a,0xb7,0x27,0x56,0xd5,0xe6,0x53,0x10,0xb1,0x4e,0x8e,0xc9,0xa6, + 0x95,0x19,0xcd,0xb8,0xf4,0x04,0xa6,0x1c,0x14,0x4f,0xa3,0xbc,0x33,0xba,0xcc,0xf5, + 0x1f,0x67,0xc1,0xde,0xcb,0x37,0x01,0x7d,0x18,0x64,0x34,0x06,0x32,0xbf,0x29,0xc1, + 0x02,0x6e,0xb2,0xbe,0x95,0x16,0x75,0x7b,0x40,0x67,0xce,0x65,0x10,0x95,0xc6,0x81, + 0x49,0xa0,0x95,0x28,0x88,0xd8,0x83,0x06,0xf6,0x4a,0x36,0x68,0x03,0x46,0x92,0x93, + 0x8b,0xc9,0xb4,0x22,0x8b,0xd2,0xc0,0x76,0xec,0x3b,0x45,0x24,0x1a,0x93,0x9f,0x3c, + 0xc3,0x9b,0x6d,0x3e,0xf2,0x1e,0x60,0xfd,0xe1,0x17,0xb2,0xea,0xe9,0x8e,0x0a,0x8f, + 0x7c,0x99,0xd9,0x22,0xf2,0x39,0x33,0x4e,0x99,0x13,0x72,0xea,0x36,0x13,0x64,0x79, + 0x0e,0x06,0xb9,0xe7,0x24,0xb8,0x11,0x94,0x41,0xe8,0x44,0x36,0xa5,0x32,0x79,0x3e, + 0xf6,0x67,0x42,0x75,0xce,0x80,0x39,0x3a,0xeb,0x13,0xc1,0xf1,0xa3,0xdf,0x83,0x88, + 0x7d,0x90,0x88,0xf3,0x76,0x71,0x58,0x12,0xdb,0xb9,0xb8,0x68,0xae,0xee,0x7d,0x7f, + 0x26,0x6f,0x75,0xd2,0xe1,0x57,0xd6,0x21,0x16,0x3d,0x46,0x0d,0x6c,0xd5,0x42,0xc3, + 0x30,0x21,0x17,0x2b,0x49,0x60,0x9c,0x6a,0x78,0x99,0xea,0xbd,0x41,0xf7,0x1c,0x39, + 0x5f,0xdd,0xce,0xd9,0xd4,0x5c,0x1a,0x42,0xa9,0xe3,0x49,0x86,0x65,0x59,0xea,0x19, + 0x4e,0x08,0xea,0x87,0xab,0xd1,0x54,0x7c,0xe3,0xe5,0x8d,0xc7,0x87,0x4c,0x43,0xc0, + 0x16,0x3e,0xe4,0x35,0x17,0x91,0xcd,0x74,0x34,0xfd,0x5a,0xb9,0xce,0x25,0x82,0x8a, + 0xd9,0x3c,0x0c,0xfb,0xe6,0x82,0xbc,0x9d,0xcf,0x74,0x36,0x7e,0x4a,0xb9,0x0a,0x98, + 0xfe,0x0c,0xaa,0x09,0xc2,0x8b,0x0f,0x8d,0xb9,0x28,0x1f,0xbb,0x7c,0xd8,0x8e,0x33, + 0x92,0xf6,0x07,0x19,0x21,0x43,0x6b,0x50,0x00,0x97,0x3a,0xe0,0xe7,0x00,0x36,0xdf, + 0x5c,0x40,0x12,0x0f,0xb9,0xb3,0xbb,0x3d,0x9e,0xa3,0x92,0xbc,0x18,0x80,0x4a,0xb7, + 0x77,0x0e,0x68,0x66,0x40,0x7f,0xa7,0x6b,0x15,0x15,0xb0,0xc1,0x82,0x55,0x53,0x92, + 0x87,0x80,0xcf,0xa7,0x19,0xe0,0xa8,0x6f,0x49,0x63,0x0e,0x2f,0x20,0x8c,0xf9,0x4f, + 0xef,0xf7,0x4b,0x20,0x67,0x67,0x0a,0xd3,0x83,0x72,0xd0,0x85,0x22,0x08,0x3a,0x0d, + 0xf6,0x98,0x22,0x0d,0xc7,0x7c,0xa9,0x01,0x2f,0x9b,0x8c,0xfc,0x7c,0xa8,0x01,0x10, + 0x3c,0x2a,0xa7,0xcc,0x2d,0xd4,0x14,0x12,0x60,0xe8,0x8d,0x5b,0xb0,0x68,0x72,0xa9, + 0xd6,0x9d,0x6f,0x0d,0x81,0xa8,0xe6,0xd3,0x49,0x3a,0x66,0xaa,0xf3,0x29,0x22,0x40, + 0x4f,0x87,0x57,0xbd,0x3e,0x67,0x85,0xe4,0x38,0xa0,0x7a,0x91,0x28,0xc0,0x99,0x97, + 0x9b,0xb7,0x27,0xc4,0xbf,0xf8,0x75,0x90,0x71,0xbf,0xa1,0x63,0xae,0xdd,0x22,0xbc, + 0x7c,0x53,0x2c,0x66,0x99,0x97,0x4f,0xfa,0xdb,0x45,0xb5,0x0f,0x68,0x22,0x9b,0x99, + 0xd4,0xf6,0x52,0xc0,0xc9,0x75,0x93,0xce,0x6a,0x0b,0x21,0xb9,0x9b,0xc3,0xf4,0xce, + 0x2b,0xf2,0xd2,0x2b,0x59,0x84,0x3f,0x54,0x42,0x4b,0x47,0xfd,0x30,0xc8,0x7c,0x78, + 0xc5,0xc7,0xf5,0x15,0x6d,0x61,0xe4,0x3b,0xc7,0x75,0xd0,0x72,0x33,0x2a,0xd7,0x15, + 0xd0,0x85,0x3c,0x2c,0x67,0xe8,0xf5,0xc9,0x48,0x7e,0xea,0xac,0xff,0xa9,0x93,0x88, + 0x90,0xa7,0xf0,0x7e,0xad,0x2e,0xf3,0x73,0x29,0x6a,0xcc,0x3b,0x1f,0x3d,0xf5,0x41, + 0x6d,0xa3,0x48,0xe3,0x98,0xdc,0x69,0xd1,0x00,0x51,0x74,0x1d,0xc7,0xc7,0x8a,0xae, + 0x5f,0x90,0xa0,0xac,0xe0,0x8b,0xc9,0x78,0x09,0x82,0xdd,0x25,0xec,0xfe,0x52,0xdc, + 0x1a,0x97,0x7c,0x26,0x73,0x71,0x7a,0xc6,0x43,0x25,0x18,0xbd,0x9c,0x80,0x3a,0x67, + 0xbf,0x0b,0xec,0x0d,0xeb,0xf9,0x5b,0xd1,0x22,0x05,0x90,0x49,0xcc,0x0c,0x4a,0xd6, + 0xaa,0x72,0x11,0x11,0x47,0xc6,0xb2,0xb8,0x57,0xbe,0xf2,0x0c,0x69,0xdc,0x91,0x6e, + 0x46,0x57,0x1d,0x7e,0x0b,0xcc,0x87,0xc9,0xb8,0x2c,0x5d,0xc8,0x7e,0xd7,0xe4,0x9e, + 0xcc,0xbb,0x26,0xb4,0x06,0xa3,0x8f,0x5f,0x56,0xe7,0xf1,0x5e,0xb6,0x3f,0x33,0x4b, + 0xaa,0xb1,0xb8,0xe5,0x59,0x04,0x2a,0x66,0x17,0x71,0x91,0x93,0x6d,0x3a,0x78,0x96, + 0x61,0xe6,0x93,0xf0,0xc6,0xf3,0x9a,0xa1,0xb8,0x56,0xab,0x14,0xd5,0x48,0x51,0x87, + 0x17,0x25,0x9c,0xa0,0xeb,0x4f,0x9d,0x7e,0x7c,0xc7,0x1a,0x5b,0xd6,0xe7,0xfa,0xa8, + 0x32,0xb8,0xf6,0xd6,0x0a,0xf0,0x60,0x01,0x71,0xbf,0xb7,0x3c,0x81,0xdb,0xe0,0xd2, + 0x20,0x62,0x36,0x4f,0x1b,0x6a,0x43,0x0e,0x65,0xf8,0x4c,0x76,0x63,0x67,0x92,0x13, + 0xec,0xcd,0xde,0xdb,0xca,0x3c,0x08,0xcb,0xb3,0x2a,0x1b,0x7b,0xfb,0xbe,0xc9,0xd5, + 0x8d,0x7b,0xef,0xf3,0xfc,0x93,0xa9,0x5b,0x25,0x12,0xec,0xac,0x06,0x4c,0x08,0xc3, + 0x2b,0x37,0x17,0xae,0xca,0x44,0x59,0xdd,0x2f,0x57,0x42,0x24,0xe6,0x68,0x60,0xc6, + 0xd3,0x5c,0x59,0xac,0xc9,0xc7,0xf3,0xdc,0xe2,0xd1,0x9a,0x89,0xf8,0x81,0x20,0x78, + 0x71,0x35,0x27,0xce,0x5d,0x09,0x02,0x65,0x7f,0x77,0x84,0xe1,0x0c,0x64,0xa5,0x24, + 0xe9,0xfe,0x7c,0x55,0x7b,0x45,0xbf,0xa5,0xf5,0x31,0xa8,0xd7,0x55,0x7f,0x42,0x23, + 0x42,0x9d,0x99,0x87,0x47,0x1b,0x47,0x85,0x88,0xfe,0xcb,0xab,0xbf,0x1b,0x09,0x5d, + 0xae,0xf1,0x63,0x87,0x80,0xb0,0xe9,0x28,0x93,0xa3,0xbf,0x8d,0x99,0x43,0x53,0x0a, + 0xf4,0x75,0x17,0x60,0x54,0xe4,0xb7,0xad,0x99,0x60,0xdb,0x46,0xdc,0xf4,0xd3,0x52, + 0x5c,0xe7,0x2d,0xaf,0xc6,0xe4,0xf5,0x99,0x91,0xd2,0x82,0x98,0x39,0x61,0x54,0x9a, + 0x57,0xea,0x9b,0x13,0x71,0x53,0x47,0x25,0xa0,0x11,0x4b,0xcc,0x6f,0x73,0xb5,0x79, + 0x49,0x4e,0xcd,0x51,0x8e,0xbc,0xd6,0xf3,0x57,0xdd,0xf2,0xbb,0x25,0x4b,0xb4,0x18, + 0xda,0x32,0x98,0x12,0x03,0xf9,0x12,0xc8,0x17,0xa0,0x9c,0xeb,0xa1,0x83,0x68,0xbb, + 0xce,0x1e,0x19,0x51,0xab,0x53,0xc8,0x55,0x76,0x52,0x81,0xe2,0x6f,0xfb,0xdf,0x1b, + 0x22,0x7f,0x31,0x92,0x28,0xdf,0x42,0x14,0xe5,0x7e,0x0e,0x92,0xe6,0xc4,0xd8,0x32, + 0x23,0x90,0x74,0x2c,0x5e,0xba,0xae,0x05,0x78,0x19,0xcc,0xaf,0x7a,0xfa,0x91,0x56, + 0x35,0xfd,0x88,0x97,0x73,0xe7,0xab,0xb9,0x17,0x46,0x5a,0x5c,0x12,0x6e,0x2d,0x16, + 0x67,0x3e,0x04,0xfc,0x61,0xdb,0x70,0xb3,0xd3,0x61,0x2e,0xf9,0x18,0xaf,0x55,0x8e, + 0xb8,0x8e,0xb1,0x64,0xe5,0xc9,0xf2,0x4c,0xd3,0xd9,0x35,0x15,0xae,0x92,0x90,0xde, + 0x21,0x46,0x06,0x1d,0x7b,0xc1,0x02,0x17,0xe3,0x5d,0x61,0x3f,0xc7,0x0f,0xd6,0xa9, + 0xda,0x64,0x7e,0x96,0x72,0x5d,0x89,0x95,0x65,0xf1,0x3e,0xcb,0xac,0xae,0x00,0xae, + 0xe5,0x50,0x2a,0x6d,0x35,0xf1,0x73,0x05,0x83,0x24,0x8e,0x35,0x83,0xeb,0x10,0xf9, + 0xe7,0x39,0xc6,0xb6,0x9a,0x20,0xe0,0x1b,0x5b,0x1f,0xc8,0xb7,0x2e,0x66,0xa8,0xfa, + 0x0a,0x3c,0xeb,0x52,0xe0,0x17,0x1d,0x35,0x57,0xf3,0x4f,0xa7,0x9f,0x4e,0x87,0x3c, + 0x5c,0xf0,0x1c,0xf0,0x0b,0xd1,0xe5,0x94,0xe8,0x13,0xdd,0x90,0x48,0x07,0xda,0x38, + 0x99,0xb5,0x3b,0x4f,0xbb,0x3d,0x21,0x68,0x7f,0x5c,0x28,0xbe,0xbb,0xe3,0x0c,0x2e, + 0xc4,0x79,0xa0,0x99,0x95,0x2e,0x2c,0x1a,0x0c,0x67,0x83,0x6c,0xb5,0x06,0x4e,0xf5, + 0xb7,0xed,0x9d,0x67,0xb7,0x70,0x0b,0x18,0x80,0xf3,0x64,0xa4,0x43,0xe6,0x0f,0xab, + 0x72,0x4d,0x33,0xe4,0x01,0x30,0x21,0x5c,0x67,0x24,0x1d,0x31,0x43,0x87,0xf5,0x10, + 0x2b,0xff,0x90,0xcc,0xa0,0x9a,0xd6,0x23,0xf1,0xb0,0xee,0x88,0x44,0x93,0xed,0x67, + 0xcb,0xdd,0x9d,0x25,0x3c,0x1e,0x5e,0x41,0x06,0x1c,0x62,0xf9,0xc5,0x83,0x5d,0xd1, + 0x0d,0x29,0x23,0x7a,0x93,0xf3,0x12,0x27,0xe4,0x8f,0x14,0x57,0x24,0x03,0x1f,0x1a, + 0x0b,0x73,0xa6,0xa1,0x18,0x2c,0x9a,0xf5,0xed,0x9d,0x26,0x39,0x99,0xd4,0x9e,0x82, + 0xe4,0x08,0xa5,0x08,0xd9,0x32,0xa2,0x14,0x56,0x5c,0x9c,0xf5,0x67,0x14,0x00,0x38, + 0xe0,0x54,0x8a,0x7b,0xad,0x3d,0x73,0x7e,0xda,0xe0,0x93,0xd7,0xc6,0x40,0x14,0x1c, + 0xd4,0x53,0x3f,0xbd,0x0c,0x38,0x31,0xc8,0x13,0xad,0x29,0xa5,0xc3,0xea,0xb6,0xd7, + 0xc7,0xa4,0x13,0xa2,0xd0,0x23,0xd8,0x50,0xd6,0xd7,0xe1,0xa0,0x9f,0x0f,0xe4,0xb3, + 0xf4,0x1d,0x21,0xbc,0xa3,0xa8,0x1a,0x97,0x8b,0x8d,0x95,0xd0,0xbc,0x60,0x1b,0x20, + 0xd9,0x50,0x64,0x6e,0x01,0xb2,0xcd,0xc4,0xb8,0x9c,0x98,0x88,0x0d,0x74,0x9f,0x9c, + 0xc6,0xc0,0xd9,0xd9,0xe0,0xd4,0xeb,0xcc,0x11,0x56,0xcb,0x41,0x03,0xe5,0x64,0xbc, + 0xe1,0x02,0x18,0x36,0xcd,0xbf,0xf0,0xee,0x09,0x3b,0x86,0x82,0x2a,0xc3,0x21,0x34, + 0x6a,0xc4,0x79,0x1b,0x93,0xf1,0x90,0xd0,0xda,0xa3,0x94,0x80,0x52,0xea,0x94,0x12, + 0x90,0x0a,0x61,0x6e,0xce,0x0c,0xb3,0xcc,0xab,0x86,0xc5,0x65,0x87,0xa4,0x6f,0x58, + 0xbc,0xe1,0x74,0x97,0xaa,0xe8,0xb7,0x2b,0x1a,0xe0,0x51,0x33,0x48,0x69,0x49,0xd2, + 0xa1,0xcd,0x3b,0xf0,0x86,0x5f,0x12,0xbb,0xc0,0xac,0x2a,0x09,0x7b,0xe8,0xd9,0xca, + 0x72,0x46,0x5d,0x4c,0x4f,0xf6,0x2f,0xca,0xef,0x00,0x9e,0x32,0x21,0x9f,0x3d,0xb9, + 0xf3,0x00,0xa5,0x52,0x81,0x37,0x2f,0xeb,0x33,0x5c,0x8d,0x59,0x75,0xd1,0x93,0x2c, + 0x04,0xcb,0x1d,0x97,0xa7,0x9b,0x4a,0xcb,0xf9,0x91,0x36,0x85,0x5b,0xbf,0x39,0xfa, + 0x56,0x54,0x31,0x39,0x5c,0x77,0x48,0x94,0xfe,0x44,0x51,0x7f,0xf9,0x14,0xcb,0x91, + 0x1c,0x2f,0x20,0x7f,0xe9,0x6c,0x03,0xf9,0x06,0xa3,0x2e,0xcc,0x34,0xf0,0x6d,0x06, + 0x69,0x0d,0x27,0xec,0xb3,0x01,0xca,0x13,0xe9,0x15,0x32,0x30,0x81,0xe7,0xeb,0xd1, + 0x7b,0x24,0x70,0x7e,0x16,0xf0,0x81,0xce,0x72,0x7b,0x59,0x0c,0x25,0x36,0xfe,0x68, + 0xb0,0x66,0x2c,0x11,0x13,0x19,0x7a,0x09,0x48,0x65,0x19,0x44,0xcb,0xe0,0x04,0x13, + 0x00,0xa3,0xcb,0xc8,0x8f,0xc6,0x8b,0x8f,0xe4,0x3c,0xbf,0xea,0x5b,0x16,0x56,0xc8, + 0xfd,0x13,0x25,0xa8,0x74,0xab,0xc3,0xaa,0x77,0xda,0xe0,0x11,0x48,0x37,0x52,0x66, + 0xd6,0x2a,0xbb,0xf7,0xc3,0xcb,0xc0,0xfe,0xc0,0xe0,0xd6,0x39,0x4a,0xe2,0x18,0x26, + 0x3a,0x0b,0x97,0x58,0xf6,0x29,0x8c,0xd6,0xe9,0x7c,0x97,0x9d,0x52,0x3f,0x87,0xd2, + 0x3d,0x58,0x9f,0x29,0xc1,0xe4,0xa4,0x2d,0x25,0xd1,0x73,0x49,0x63,0x85,0xf3,0xb2, + 0x9a,0x39,0xd7,0xbc,0x86,0xfb,0x79,0x54,0x1b,0x8d,0x39,0xf3,0xfa,0x7d,0x12,0x50, + 0x24,0x92,0xae,0x39,0xd9,0x62,0xf7,0xb9,0xbc,0xbc,0x68,0xe6,0x5c,0xb5,0x41,0xe7, + 0x5a,0xc8,0x66,0x1c,0x23,0x68,0x80,0xbb,0x33,0xcc,0x33,0x72,0x9a,0xe4,0xe8,0x3a, + 0x9c,0xec,0xe3,0x8c,0x46,0xc6,0xdb,0xfd,0xdc,0x1d,0x65,0x12,0x9c,0xa3,0x93,0x6f, + 0xc0,0x1e,0x78,0xb1,0x44,0x1b,0x72,0x9a,0x18,0x19,0x19,0xa0,0x28,0x40,0x1b,0xae, + 0xc8,0x3b,0xa7,0x85,0xa8,0x9e,0x71,0x67,0x15,0xa1,0x87,0xb9,0xe4,0xc4,0xfa,0x4c, + 0x1d,0x44,0x16,0x39,0x64,0xd1,0x63,0xfc,0x96,0x7b,0x13,0x9d,0x4f,0xaf,0xb8,0x78, + 0xf7,0x50,0xef,0x04,0x1b,0x68,0x1f,0x9a,0x24,0x17,0x51,0xa0,0x88,0xe4,0x22,0x6f, + 0x1e,0xa4,0xbb,0x75,0xfe,0x81,0x35,0xb2,0xce,0x72,0xe3,0xe5,0x38,0xe7,0xf5,0x89, + 0x77,0xef,0x04,0xe6,0x7d,0x97,0x9a,0x1a,0x90,0x8f,0xa6,0x2a,0x38,0x51,0xdb,0xd9, + 0x64,0x84,0x53,0xad,0xee,0xd1,0xf9,0x05,0x94,0x97,0x44,0x8f,0xe5,0x09,0xf6,0x93, + 0x5c,0x92,0x58,0x95,0xf1,0xc6,0x9c,0x46,0x1d,0xe7,0x1f,0xe1,0xfc,0x87,0x70,0x83, + 0x2a,0x0f,0x1b,0x18,0x8e,0x6c,0x00,0x95,0x25,0xf9,0x61,0x9c,0x29,0x59,0x62,0x0f, + 0x27,0x2e,0x69,0x76,0xc5,0x8e,0xa1,0x88,0x88,0x17,0x7c,0xfe,0x69,0x30,0xc2,0x7c, + 0xd7,0x2f,0xdc,0x2d,0x8e,0x2d,0x5f,0xe2,0xda,0x00,0x62,0x9e,0x1a,0xc9,0x29,0x23, + 0x5d,0x92,0x9c,0x39,0xe9,0x4a,0xa5,0xb6,0x36,0xc8,0xe6,0x99,0xcc,0x5c,0x65,0xc8, + 0x81,0xec,0x1c,0x3a,0x3f,0x20,0x8e,0xe1,0xe6,0xd3,0x11,0xf4,0x52,0x07,0x4f,0x16, + 0x6c,0xd1,0xd0,0x1b,0x4c,0x7a,0xc8,0x61,0xbe,0x9b,0xda,0x8d,0xc2,0xa7,0xba,0x99, + 0xb9,0xea,0xf2,0xbd,0x41,0x73,0x8b,0x1d,0x04,0xab,0x9e,0xd0,0x69,0x23,0xef,0x77, + 0x18,0x78,0xef,0x1a,0x47,0x69,0x44,0xe8,0x9c,0x96,0xf2,0xc9,0x01,0x37,0x5b,0xaf, + 0x06,0x9b,0x70,0x5b,0x54,0xc4,0x1f,0x43,0x49,0xf3,0x9d,0x63,0x20,0xb1,0x76,0xc4, + 0xc9,0xcc,0x6b,0xaa,0x8d,0x98,0xac,0xb2,0x4a,0xc4,0x15,0x9d,0xd6,0xbd,0xe1,0x45, + 0x31,0x83,0xe0,0x28,0xf9,0xce,0x70,0x04,0x1b,0x20,0x3d,0x38,0x83,0x20,0xb9,0x32, + 0xdf,0xad,0x57,0x53,0xae,0xbe,0x9f,0x5c,0x0b,0xd2,0x10,0xf5,0xaa,0x33,0xcb,0x5a, + 0x68,0xcc,0x51,0x64,0xc5,0xd0,0xe0,0x3a,0xb2,0x4e,0x89,0xbd,0xf9,0x49,0xb7,0x67, + 0x38,0x13,0x4e,0x53,0x57,0xe1,0x32,0xaf,0xc2,0x45,0x17,0x1a,0x96,0x07,0x32,0x7b, + 0xb3,0x62,0x2a,0xd0,0x02,0x9c,0x45,0x79,0x5f,0x47,0x01,0x97,0x96,0x7f,0x81,0x54, + 0x5e,0x7f,0xa6,0xb2,0x99,0xe6,0x74,0xce,0x10,0x04,0x03,0xd4,0x6c,0x9f,0x42,0xcc, + 0xb9,0xd7,0x23,0x73,0x1a,0xc2,0xe7,0x38,0xab,0xe6,0x8f,0x96,0x65,0xe3,0xf3,0x56, + 0x0b,0xaa,0x40,0x69,0xa7,0xbe,0xbb,0xfb,0xcc,0x88,0x0b,0x2e,0x5a,0xbc,0x00,0xea, + 0xda,0x57,0x6c,0x45,0xbc,0x83,0x04,0x37,0x9b,0xd8,0x91,0xda,0x56,0xa5,0xb9,0x32, + 0xc9,0x6d,0xf5,0x7c,0x4a,0xa8,0x1d,0xbc,0x0f,0x64,0xea,0x46,0xec,0x8a,0x99,0x55, + 0xfb,0x19,0xf4,0x0b,0x71,0x19,0x5a,0x96,0x0f,0xe3,0xb9,0x1c,0xf9,0x58,0xd9,0x2a, + 0xd1,0x7a,0xf2,0x51,0x4c,0x8c,0xfb,0x5f,0xac,0x0c,0xa5,0x4b,0x33,0xaf,0xff,0x16, + 0xe4,0x09,0x98,0x99,0x33,0xc3,0x28,0x1d,0xb8,0x06,0xa8,0x87,0x29,0x04,0x70,0x9c, + 0x6c,0x05,0xe6,0xa5,0x90,0x9e,0x16,0x90,0xa5,0x49,0x18,0xdc,0x2e,0xa4,0x94,0x6c, + 0x3c,0x62,0x9d,0xc8,0xdb,0x5f,0xdf,0xe3,0x28,0x89,0xf7,0x24,0x72,0xb8,0xae,0xa6, + 0xeb,0x5e,0xcf,0x70,0xa6,0x06,0x39,0x8f,0xb9,0x1a,0x93,0x62,0x40,0xb2,0x6b,0x82, + 0x83,0x9b,0x28,0xb9,0x78,0x3e,0xe1,0x57,0xd5,0x42,0x6e,0x99,0x02,0xd5,0x98,0x66, + 0x97,0x65,0x48,0xe2,0x0a,0x75,0xb1,0x38,0x41,0xe7,0x38,0xa5,0xb2,0xf8,0x33,0x67, + 0x2a,0xba,0x79,0x24,0xdd,0x05,0x36,0x8c,0x51,0x61,0x85,0x4f,0x1a,0xd3,0x29,0x1b, + 0xd2,0x19,0xfb,0xbf,0x92,0x08,0x76,0x35,0x52,0x49,0xf6,0x04,0x2b,0x32,0x19,0xb8, + 0x31,0x60,0xe6,0x66,0xa3,0x9e,0x55,0x45,0x1e,0x7f,0x07,0xb5,0x99,0x4d,0xad,0x68, + 0x2e,0xad,0x3d,0x8a,0x0f,0x70,0x31,0xd2,0xcb,0x6c,0x82,0xd9,0x31,0xf2,0xe7,0xf5, + 0xc9,0x6c,0xd0,0x3b,0xef,0x5b,0x8b,0xd3,0x3e,0x78,0x05,0xc6,0xbc,0xf0,0x34,0xf3, + 0x79,0x55,0xae,0x0c,0x23,0xe0,0x94,0xc7,0x91,0xf2,0x82,0xbe,0x64,0x61,0x41,0x74, + 0x20,0x8c,0x64,0x76,0x0b,0x43,0x62,0x27,0xe7,0x49,0xf7,0x8a,0x8f,0x59,0x0d,0x6c, + 0x66,0xea,0xa4,0x44,0xf0,0x43,0x16,0x03,0x6c,0x60,0xd9,0xe8,0x28,0x34,0x91,0x42, + 0xd2,0x1c,0x38,0xe9,0xa8,0x02,0x52,0x13,0x1c,0x30,0x88,0xd9,0x23,0xde,0xff,0x88, + 0xad,0x51,0x8e,0xf1,0x0d,0x06,0x66,0x20,0x1f,0x09,0xeb,0x9b,0x59,0x97,0xac,0xec, + 0x97,0xe0,0xd0,0x6e,0xab,0xfb,0x30,0x47,0x9c,0x17,0xb5,0xc8,0x38,0xca,0x93,0x9b, + 0x8e,0x4e,0xeb,0xfb,0x77,0x7b,0x1f,0x7e,0x28,0x34,0x5b,0x12,0x93,0xa9,0x3f,0xd2, + 0x4d,0x75,0x55,0xd2,0x8f,0x33,0xf2,0xd6,0x4e,0xcd,0x84,0xa8,0x79,0x35,0xa4,0x60, + 0x01,0x6b,0x76,0xda,0x9c,0x77,0xee,0x17,0x37,0x5f,0x59,0xdc,0xc1,0x8a,0xe2,0xce, + 0xba,0xc6,0x79,0x2f,0x67,0xea,0x8e,0xc5,0x42,0x92,0x8e,0x22,0xfb,0x33,0x5e,0x17, + 0xc4,0x22,0x72,0x32,0x34,0xfa,0x41,0xcd,0xce,0x8a,0xa7,0x52,0x19,0x90,0xdb,0x4c, + 0x31,0x75,0x00,0x38,0x85,0x80,0x77,0xbc,0xe4,0x4d,0x78,0xb3,0x99,0x60,0xec,0xd3, + 0x36,0x91,0xe0,0x2f,0x06,0xe0,0x20,0x3b,0x6e,0x21,0x48,0xcc,0x0b,0x19,0x57,0x94, + 0xd1,0x3d,0xa1,0x53,0x69,0x53,0x59,0x12,0x40,0x0a,0x0f,0xb0,0xb1,0xe7,0x52,0x1c, + 0xa7,0x2f,0xbc,0x1a,0xfc,0xdc,0xcd,0x22,0x12,0x85,0xd5,0x66,0x09,0xfb,0x0f,0xfe, + 0xf0,0x72,0x04,0x13,0x51,0x3e,0xf5,0x7a,0x77,0x66,0x20,0x5e,0xa4,0xb6,0x45,0x12, + 0xd8,0xdd,0xf7,0x39,0x1c,0x5c,0x75,0xcf,0x69,0x58,0xc7,0x8b,0xdc,0xd3,0xc3,0x15, + 0x32,0x9e,0x91,0xe5,0x1f,0x3b,0x7c,0xe0,0x6b,0x32,0xf8,0xc8,0x40,0x29,0xfe,0x4a, + 0x84,0x70,0x00,0xf3,0xcb,0x73,0xb8,0xc3,0xae,0x72,0xe0,0xe9,0x05,0x0b,0xb9,0xaa, + 0x8c,0x16,0xe2,0xa0,0x92,0x19,0xf4,0x8f,0x4f,0xf1,0x62,0xb0,0xaa,0x6d,0xc3,0x6a, + 0x68,0x63,0x85,0x75,0x46,0x92,0xbb,0x58,0x8f,0x10,0x09,0xe5,0xeb,0x28,0xcf,0x90, + 0xec,0xb0,0x11,0x96,0x6d,0xed,0x68,0x13,0x26,0xbd,0xb6,0xaf,0xd9,0x88,0x49,0xe8, + 0xf7,0x18,0x01,0xfd,0xee,0x98,0xbd,0xd2,0x0d,0x1a,0xa4,0xce,0x9f,0xe3,0xf6,0x5d, + 0x60,0xfd,0xb7,0xb5,0xc5,0xbc,0x80,0xd8,0x37,0x86,0x8c,0xac,0xcd,0x83,0x8c,0x98, + 0x6d,0x9f,0x8e,0x26,0x59,0x6a,0x68,0x07,0xec,0xf4,0x96,0x5d,0x76,0xf0,0x99,0xc0, + 0x06,0xfb,0x77,0x2f,0x5a,0xe8,0x5a,0x40,0xb9,0x1f,0xf5,0xb2,0xdb,0x6d,0x5a,0xc4, + 0x93,0x4b,0x3f,0x7a,0xd3,0xe9,0x63,0x48,0x81,0x0e,0x05,0xf4,0x03,0x4c,0x97,0x66, + 0xb7,0xb0,0x99,0xb9,0xb5,0x3c,0xd8,0x65,0x37,0x62,0xa4,0xc4,0xdf,0x63,0xfe,0xbb, + 0x3a,0xcc,0xb1,0x8e,0x25,0x7f,0xe2,0xc6,0x52,0xcf,0x7c,0x25,0x4a,0xf3,0x32,0x4a, + 0x73,0x46,0x69,0x0e,0x94,0xe6,0x95,0x28,0xf1,0xf7,0x78,0xfe,0xf9,0x28,0xcd,0x05, + 0x25,0xc7,0x26,0x66,0xff,0xcd,0xbb,0x03,0x66,0x43,0x72,0xd9,0x24,0xd1,0x07,0x23, + 0x19,0x18,0x21,0x03,0xc9,0xa7,0x57,0x19,0x14,0xc9,0xb9,0x08,0x7d,0x81,0x7d,0x26, + 0x6f,0xa0,0x65,0xa3,0xc5,0x2b,0xaf,0x7c,0xa3,0x37,0x56,0x52,0x3c,0x7d,0xba,0xfb, + 0xb4,0x1d,0x34,0x69,0x77,0x90,0x05,0xb8,0x77,0x19,0xb8,0x27,0x2d,0x48,0x9e,0x89, + 0x26,0x59,0x1f,0x9d,0xf3,0x32,0x7c,0xd0,0x47,0xfe,0x30,0x47,0xf9,0xc4,0x05,0xf8, + 0x37,0x88,0x72,0xc9,0x01,0x77,0x24,0x4d,0xc0,0x64,0x11,0xec,0x63,0x81,0xa6,0xcd, + 0x48,0x81,0x39,0xbf,0x32,0xc3,0x80,0x66,0x1a,0x3c,0xac,0xdf,0x80,0x55,0xdf,0x82, + 0x76,0x34,0x77,0x5b,0x0b,0x63,0xae,0x83,0x07,0x32,0x4d,0x10,0xfc,0xb0,0xf4,0x40, + 0xbb,0xcc,0x8b,0xd9,0x7f,0xff,0x7e,0x10,0xe4,0xaf,0x74,0x72,0x61,0xd6,0xc6,0x2c, + 0x78,0xd5,0xdb,0x79,0xfa,0x74,0xfb,0x3b,0x7c,0xa3,0xd8,0xa7,0xb0,0x95,0x1f,0x5f, + 0x8a,0x24,0x66,0x8a,0xc8,0x17,0xfd,0x50,0xd6,0x4e,0x2a,0x1d,0x4b,0xa2,0xca,0xfb, + 0x2d,0x0a,0x54,0x93,0xf0,0x39,0x74,0x12,0xf0,0xa1,0xda,0xcb,0xfd,0xbf,0x42,0x9e, + 0xe2,0xfd,0x58,0xb6,0x05,0x7e,0xf8,0xd4,0x3d,0x0f,0x39,0xf8,0xfb,0xfb,0x57,0xfb, + 0x69,0x48,0xaa,0x65,0xb4,0x75,0x8a,0x6d,0x54,0x3f,0x99,0xdf,0xce,0x8f,0xc9,0xfe, + 0x0f,0x55,0x24,0x46,0xbc,0x4e,0xce,0x67,0xd3,0x63,0x24,0xf3,0x2f,0x8d,0xb9,0xa4, + 0x8b,0x2a,0x8e,0x29,0x17,0xed,0xcd,0xc0,0x19,0x70,0xe3,0x35,0x31,0xba,0x92,0x2e, + 0xc0,0xb1,0xb9,0x99,0x43,0xa9,0x9d,0x60,0x59,0x3b,0x36,0xd4,0x0a,0xad,0x29,0x5e, + 0xd4,0xfe,0xf2,0xdd,0xaf,0xef,0xf7,0xde,0xbe,0x7e,0xf7,0x56,0x4d,0xa7,0xdc,0x43, + 0x1e,0x3d,0xc5,0xae,0x3c,0xd9,0x59,0x65,0x4c,0x72,0xc1,0xe7,0xa9,0x9f,0x61,0x0f, + 0xf2,0x67,0x8d,0x3f,0x7c,0x93,0x14,0x7e,0x2a,0x95,0x0b,0x77,0x51,0x53,0x51,0x87, + 0xe7,0xcc,0x2a,0x0b,0x32,0xb9,0xef,0xc7,0x63,0x8d,0xb7,0x37,0x67,0x62,0x2c,0x26, + 0x67,0x6f,0x98,0x6e,0x8c,0x00,0x41,0x39,0x8a,0x36,0xd2,0xa4,0x52,0x6b,0x5b,0xe0, + 0x7f,0x44,0x67,0x28,0x64,0x03,0x86,0xe6,0x7c,0x83,0x11,0x67,0xe0,0x83,0x11,0x08, + 0x73,0x39,0x44,0x2b,0x90,0x0f,0x76,0xee,0xb3,0x09,0xa9,0x4f,0x73,0x14,0xfa,0xbc, + 0x57,0xb4,0x8a,0xb2,0x2d,0x42,0xa4,0x18,0x6a,0x51,0x60,0xbe,0x04,0xf2,0x89,0x73, + 0x02,0x77,0xda,0x0b,0x28,0x58,0x3e,0x5f,0xe4,0x8c,0x55,0x3d,0x6f,0xd2,0xbe,0x70, + 0x30,0xa5,0x23,0x16,0x53,0x10,0x06,0xae,0xaa,0xb0,0x0a,0x64,0x81,0x0f,0x8f,0x57, + 0x0c,0x60,0xfe,0x65,0x03,0x87,0xc1,0x6d,0x3e,0x97,0xdd,0x23,0x78,0x2d,0x5a,0x32, + 0x83,0x42,0x0c,0xc2,0xe5,0xe3,0x49,0x0f,0x6e,0xe9,0xb9,0x25,0x4a,0xeb,0xc4,0x4c, + 0x2a,0x9e,0x22,0x50,0x8b,0x4a,0x05,0x7d,0xc1,0xdb,0x28,0xd9,0xa5,0x22,0xf6,0xb0, + 0xba,0xb6,0x26,0xce,0xc3,0x02,0xa3,0xca,0xd0,0xa6,0x1a,0xdd,0xae,0x63,0x82,0x56, + 0x96,0xa0,0x3a,0xa0,0xc1,0x98,0xc9,0x39,0x81,0x3e,0x60,0x5c,0x86,0x65,0x55,0xba, + 0xd8,0x66,0xc3,0xf9,0xcf,0x48,0xe3,0x40,0x97,0x0e,0xeb,0x65,0xdc,0x8c,0x18,0x8d, + 0x0f,0x57,0x58,0xcb,0x44,0x1d,0xae,0x2b,0xe4,0x64,0xbc,0x06,0x0b,0x9e,0xc2,0x6c, + 0x07,0x86,0xdf,0x55,0x70,0x81,0xc0,0x05,0x0a,0xa8,0x9d,0xc6,0xe8,0x75,0x6f,0x2c, + 0x92,0x88,0x64,0x9c,0xe9,0x18,0x92,0x77,0x2a,0x47,0xbf,0xe6,0x34,0x6b,0xe9,0x16, + 0xe8,0x39,0x75,0x79,0x7d,0x32,0x63,0xff,0x0e,0x2f,0x82,0xe7,0xa4,0xe7,0x7d,0x11, + 0x5a,0x67,0x7a,0x05,0x99,0x2d,0xfa,0x6a,0xf6,0xa6,0xf4,0x07,0xc6,0x87,0x0e,0x13, + 0x3a,0xcd,0x23,0x75,0xa8,0x68,0x25,0x64,0xeb,0x24,0x88,0x10,0x64,0x3e,0x46,0x44, + 0x5b,0x91,0x28,0xae,0x3c,0x42,0xfa,0x70,0xbf,0x77,0xce,0x67,0x6b,0xa2,0x90,0x9b, + 0x8c,0xb7,0x20,0x6f,0xfa,0x86,0x9a,0x3c,0x45,0x79,0xab,0xcb,0x45,0x3b,0xb6,0x99, + 0xfc,0x8c,0xee,0x62,0xc3,0x4c,0x3d,0xb5,0x59,0x67,0xf2,0x37,0xc8,0xd8,0x9d,0xad, + 0x6d,0x11,0x00,0x73,0x04,0x35,0x04,0xa0,0x3d,0x97,0x32,0x0d,0xb1,0x8a,0x08,0xa2, + 0x1f,0x69,0x0e,0xeb,0x59,0x76,0xcb,0xac,0x9d,0xdf,0x36,0xbf,0x6d,0xc6,0x96,0x65, + 0x80,0x14,0x83,0xc7,0xca,0x52,0xf4,0x60,0x57,0x34,0xb3,0x3c,0x0b,0x26,0x72,0xe2, + 0x7e,0x22,0xba,0x57,0xd0,0xe5,0xe0,0xe5,0xfb,0x82,0xb6,0x58,0x92,0xc5,0xc4,0xf5, + 0x4b,0xcd,0x5f,0x3f,0xdf,0x02,0xb5,0xdc,0xec,0x78,0xad,0xb5,0x53,0xcf,0xd7,0xdb, + 0xde,0x6f,0xeb,0xf4,0xf0,0x4c,0x6a,0xf2,0xb4,0x36,0x9b,0xda,0x5e,0xda,0xbc,0x8c, + 0x12,0x27,0xb3,0xae,0x5a,0x62,0x1a,0x57,0x46,0x5e,0xeb,0xaa,0xac,0x37,0xdd,0x9c, + 0xa5,0xc3,0xe2,0x44,0x94,0x00,0x77,0x2b,0x8a,0x1a,0xd3,0x86,0x74,0xa8,0x6b,0xa3, + 0x9c,0x63,0x03,0x5d,0x5d,0xf9,0x74,0xfd,0xad,0x2e,0x00,0x03,0x4a,0x54,0xae,0xd2, + 0x1c,0x36,0x91,0xe1,0x14,0x64,0xc1,0x73,0x5d,0x36,0xff,0x56,0xce,0x2f,0xb0,0x8e, + 0xf9,0x62,0xeb,0x16,0x96,0x80,0x3c,0x19,0x44,0x77,0xd0,0x7c,0x5d,0x90,0x2f,0x7d, + 0x11,0xef,0xc2,0x4b,0x5d,0x9a,0x42,0x5b,0x50,0xb9,0x56,0x88,0x07,0x43,0xa0,0xe9, + 0x6c,0x70,0xdd,0x9d,0xb3,0x22,0xa0,0x58,0x27,0x55,0x43,0x39,0x9e,0x2c,0x3f,0xf1, + 0xba,0xf2,0xff,0x99,0x9c,0xfc,0x5f,0xcb,0xe4,0xc4,0xb5,0xdf,0x70,0x24,0x2c,0xe9, + 0x51,0x95,0x33,0xc5,0x56,0x64,0xb5,0xa5,0x4a,0x50,0x6d,0xce,0xb1,0xde,0x82,0x25, + 0x58,0x63,0xc1,0xf2,0xf9,0x96,0x20,0xc1,0x9f,0xb7,0x04,0x09,0xbe,0xc0,0x12,0x44, + 0x0a,0x58,0x63,0x76,0xf0,0xc5,0x06,0x21,0xdc,0xfc,0xfb,0xec,0x41,0xbe,0x44,0xc3, + 0xf5,0x25,0xea,0x2c,0xd7,0x0e,0xe5,0xa5,0x1a,0x3c,0xa2,0x2e,0x97,0xe9,0x7f,0xf9, + 0x51,0xa2,0x77,0x4c,0x59,0x36,0x19,0x8f,0xe4,0x41,0x79,0x2d,0xeb,0x3b,0xfc,0x03, + 0x0a,0x9d,0x3f,0xf0,0x7e,0x23,0x47,0x63,0x3a,0x3f,0xf3,0x24,0x32,0x58,0x10,0x7b, + 0x26,0xd1,0xb8,0xf2,0x6a,0x2d,0xfb,0x6d,0x53,0x64,0x73,0xf9,0x1d,0x4e,0xea,0xbf, + 0x6d,0x2e,0x77,0xbe,0x11,0xa1,0xab,0x30,0x71,0x95,0x69,0xa2,0x36,0xb1,0xce,0xe1, + 0xb8,0x63,0xb8,0xeb,0x40,0xb9,0xc6,0xae,0x5c,0x8b,0x54,0xf9,0x79,0x76,0xbc,0x8a, + 0x8e,0x67,0xba,0xeb,0x59,0xe9,0xfa,0x3d,0xb3,0xde,0x3c,0x81,0xe1,0xd9,0x42,0x01, + 0xe0,0xc1,0x4a,0xdb,0x95,0x87,0x5b,0x0b,0x04,0xf7,0x5b,0x0b,0xac,0x3f,0x34,0x57, + 0xaa,0x81,0x10,0x72,0xf0,0x0f,0xee,0xb3,0xde,0xcc,0xc0,0x1d,0x66,0x62,0x5e,0xb0, + 0x64,0xf3,0xf5,0xff,0xe4,0x61,0xbb,0x77,0x20,0x1e,0x44,0x78,0xac,0x93,0xda,0x65, + 0x3a,0xad,0x1e,0xb1,0xae,0x96,0x15,0x28,0xbd,0xce,0x74,0xdd,0x8c,0x0a,0x7f,0x66, + 0xb4,0x60,0x4f,0xf8,0xc6,0x21,0xfb,0x80,0x79,0x83,0xc2,0xc5,0x07,0x0c,0x47,0xbe, + 0xce,0x73,0x84,0x77,0x4e,0x59,0x08,0xb1,0x96,0xe9,0x25,0xd0,0x52,0xd1,0xb1,0x29, + 0x5a,0xad,0x46,0xab,0x7c,0x9e,0x6c,0x08,0x4c,0xe1,0x87,0x02,0x5e,0xb7,0xe1,0x69, + 0x2f,0x1a,0xd1,0x23,0x1d,0x37,0x2d,0xf3,0x13,0xae,0xa5,0xcc,0xce,0x8f,0x72,0xd6, + 0xaf,0x6e,0x4b,0x0e,0x9b,0x47,0x71,0x11,0xfd,0x80,0x6d,0x0c,0x53,0x5f,0x2e,0x11, + 0x77,0x33,0x5e,0xf0,0x57,0xc5,0x6e,0xb5,0x53,0xc1,0xc8,0x38,0x4e,0x89,0x84,0x2d, + 0x2c,0xe5,0x00,0x7f,0x29,0xde,0x56,0xd8,0xcf,0x8a,0x19,0x5c,0xfc,0x93,0x2d,0x45, + 0x9f,0x41,0x87,0x12,0x4b,0x3e,0x56,0x59,0xe6,0xe7,0x4a,0x4b,0xe3,0x89,0xc5,0xf8, + 0x60,0xc1,0x51,0x60,0x5c,0x6e,0x95,0x36,0x37,0xfa,0x28,0x47,0x7a,0x71,0x87,0xe9, + 0x80,0x77,0x3d,0x67,0x8b,0x3b,0xf1,0x57,0x4e,0xeb,0x37,0xd0,0x68,0xf1,0x13,0x76, + 0x29,0xa4,0x10,0xc2,0xd2,0x07,0xd1,0x2e,0x52,0x7f,0xa5,0x0b,0x56,0x04,0xb7,0xea, + 0xdb,0xc9,0xfc,0x64,0xd8,0x82,0xff,0x31,0x12,0x93,0xcc,0xef,0x2d,0xa5,0xf6,0x66, + 0xe0,0x03,0xad,0x30,0x4c,0xb2,0xab,0x73,0x4a,0xc6,0x1e,0x96,0x92,0x29,0x40,0x4f, + 0xcb,0xdc,0x5a,0xa6,0xed,0xde,0x58,0x9e,0x31,0xe5,0xcc,0xd3,0x9d,0x3b,0xc4,0x0e, + 0x88,0x50,0xb9,0xf2,0x57,0x0f,0xac,0xd3,0x43,0x19,0x64,0x89,0xfa,0xe1,0x49,0x8a, + 0x9e,0x48,0xc4,0x39,0xd7,0x91,0x78,0x09,0x68,0x89,0x76,0xb5,0xd0,0x5e,0xa7,0xa9, + 0x16,0x95,0x8f,0x2d,0xfa,0x88,0x86,0x98,0x9e,0xd7,0x41,0x9a,0x96,0x87,0x62,0x7e, + 0xa9,0x33,0x52,0x90,0x4e,0x85,0xf6,0xac,0xa5,0x57,0x10,0xe3,0x62,0xb4,0xe8,0x20, + 0xaf,0x1c,0x20,0x5c,0x2e,0xfa,0x35,0x4b,0x2f,0x0f,0x77,0xc9,0xfd,0xd7,0x22,0xac, + 0xd1,0x53,0x2d,0xbc,0x0b,0xe5,0x06,0x28,0xba,0x68,0xe7,0x08,0x77,0x8a,0x77,0xe2, + 0xb9,0xe9,0x21,0xb3,0xaf,0x22,0x38,0x30,0xa7,0xcb,0xc3,0xed,0xa3,0xa3,0xd8,0x86, + 0xdb,0x2e,0xe0,0x32,0x85,0xab,0x85,0x41,0xc8,0xb0,0x35,0xaa,0x8c,0x32,0xdc,0x55, + 0x78,0x34,0x03,0x3e,0x4e,0x1d,0xee,0x5d,0x79,0xde,0x59,0xf0,0x29,0xd8,0x0a,0x9f, + 0x67,0x54,0xac,0x53,0xb7,0x9b,0x3f,0xd0,0x02,0x24,0x07,0xdb,0x01,0x6c,0xef,0xb6, + 0x83,0x92,0xcb,0xb3,0xbb,0x90,0x11,0x54,0xe7,0x4b,0x63,0x38,0x5f,0x1a,0xdb,0xce, + 0x97,0xc6,0xec,0x7c,0x29,0x57,0x76,0xfb,0x84,0x3d,0x33,0x33,0x4f,0x3b,0x0b,0x91, + 0x32,0x41,0x03,0xf4,0x7f,0xae,0xbe,0xd5,0xfb,0xe4,0x4e,0x73,0x8d,0x9f,0xa6,0x31, + 0x3c,0x02,0x84,0x35,0xca,0x90,0x88,0x3f,0x26,0x4a,0x0a,0x90,0xc4,0xa4,0x76,0x9a, + 0xe8,0xe7,0x21,0xc8,0xea,0x7c,0x72,0xcb,0x5e,0x46,0x5c,0x3a,0x6f,0xeb,0xc0,0xd4, + 0x61,0x69,0x79,0xef,0x07,0xa8,0x33,0x23,0x5e,0x21,0x06,0x41,0x84,0xc9,0x28,0x43, + 0x66,0x94,0xe2,0xb9,0xc1,0x5e,0x12,0xc1,0x60,0x2c,0x67,0x4c,0xd1,0xc7,0x9b,0x1a, + 0x26,0xb7,0x04,0xcd,0x35,0x74,0x18,0x01,0x01,0x6a,0xbc,0x9c,0x03,0xc4,0x05,0xcf, + 0x34,0x29,0xae,0x0f,0x0e,0x27,0x3a,0x00,0x2d,0x92,0x77,0x31,0xd9,0xd2,0xe0,0xbc, + 0x09,0x4d,0x16,0x5d,0xb2,0xb1,0x8a,0xe3,0x6e,0x92,0xf2,0x7d,0xe2,0x06,0x6c,0x2f, + 0xaa,0xa0,0x79,0x19,0xaa,0xf3,0x2e,0x78,0x0c,0x1d,0xa7,0xc9,0xcd,0x62,0xb4,0x8a, + 0x4a,0x2a,0x0d,0x3c,0x29,0xb1,0x34,0x58,0x3b,0x87,0xe1,0x36,0x8a,0xdf,0xc1,0xbf, + 0x5d,0xfc,0x7b,0x82,0x7f,0x4f,0xf1,0xef,0x19,0xfe,0x7d,0x83,0x7f,0xdf,0xe2,0xdf, + 0x77,0xf8,0xb7,0xdd,0xa4,0x3f,0x04,0xb9,0x4d,0xa0,0xdb,0xbb,0xe1,0x51,0xcb,0xd4, + 0xa8,0xdc,0x5e,0xe7,0x68,0x39,0xfc,0x02,0x7d,0x15,0x6f,0x25,0xe2,0xf1,0xcb,0xe0, + 0x98,0x21,0xee,0x82,0x19,0x51,0x78,0xc9,0xdb,0x2b,0xe9,0x34,0x8f,0x8b,0xc7,0x5c, + 0xeb,0xbe,0x0c,0x63,0xae,0xd5,0x1e,0xd7,0x7f,0xa0,0x8e,0x3f,0x9e,0xbb,0x07,0xc8, + 0x79,0x6d,0x7f,0x50,0x6d,0xe2,0x85,0xc8,0x85,0x38,0xfc,0xc3,0xb8,0x0f,0x3b,0x31, + 0x54,0x47,0x55,0x9b,0x9b,0x7a,0x38,0x74,0xc2,0xec,0x5c,0x10,0x3a,0x39,0x7c,0x72, + 0xd4,0xc1,0x9f,0x4a,0x24,0x5c,0xda,0xbb,0x63,0x0d,0x3e,0xa8,0xc0,0x36,0xb3,0x84, + 0x34,0x7f,0x82,0x05,0x56,0x17,0xbe,0xf8,0x4f,0xea,0xa6,0x3a,0x5e,0xf2,0x43,0x84, + 0xee,0xfc,0xd5,0xb8,0x97,0x22,0x41,0xfd,0x3d,0x4f,0x6b,0x78,0x93,0xe8,0xd3,0x3f, + 0x73,0x04,0xc6,0x17,0xd6,0x77,0x93,0x52,0xcf,0x2f,0x6d,0xf7,0x8a,0xf8,0x51,0xa7, + 0x33,0xd2,0xb2,0x4a,0x08,0x29,0xf2,0x64,0x7b,0xcd,0x31,0x5b,0xcd,0x89,0xd8,0x5b, + 0x8c,0xc3,0x14,0x28,0xb5,0x7b,0xae,0x93,0x03,0x3c,0xb7,0x37,0xa8,0x74,0x3a,0xc5, + 0x1f,0xc3,0xdd,0x08,0xc4,0x97,0xa8,0x87,0x7c,0xec,0x65,0x25,0x62,0x4c,0x28,0x8d, + 0x2f,0x44,0xe7,0xfe,0xe3,0x10,0x1a,0x3d,0xc6,0x17,0xb9,0xef,0xcc,0x79,0x18,0x92, + 0x95,0xe8,0xfc,0x6a,0xc6,0x35,0xb7,0x2d,0x76,0xda,0xe6,0xb5,0x44,0x07,0x71,0xaf, + 0x4c,0xc5,0x9f,0x30,0xa7,0xe2,0x85,0x69,0x64,0x4e,0xd4,0xf0,0x9c,0x2f,0x12,0xa1, + 0x61,0x79,0x2e,0x37,0x0f,0xeb,0xba,0x91,0xcb,0xa1,0xb4,0x13,0x86,0x21,0x24,0xb6, + 0xb1,0x3f,0x27,0xb3,0xf9,0x06,0xf5,0x09,0xf7,0x1f,0x92,0xbe,0xef,0x12,0x0c,0x46, + 0xb0,0x66,0x1d,0x8c,0xd9,0x75,0x35,0x66,0xac,0x13,0x4e,0xbc,0x80,0x45,0xcf,0x2a, + 0x5e,0xb8,0xc2,0x43,0x26,0x2b,0x38,0x9b,0xe0,0x03,0x9c,0xb0,0x86,0x55,0x7a,0x36, + 0xff,0x2b,0x41,0x81,0x16,0x2e,0x98,0x23,0xea,0x49,0x38,0xf6,0x28,0x3f,0x4e,0x36, + 0x89,0x1b,0x60,0x4a,0xd7,0x9d,0x8f,0xbd,0xda,0xc7,0x46,0xfe,0xc7,0xf2,0x00,0x76, + 0x76,0xc3,0x50,0x1d,0xca,0xca,0xf7,0xdb,0xe4,0xb2,0x18,0xeb,0xac,0x70,0xe3,0xcc, + 0xba,0xb7,0x56,0x38,0xbf,0x44,0x46,0xde,0x0f,0x10,0x7b,0xe0,0xbb,0x56,0xa1,0x8f, + 0xff,0xbe,0xba,0x7c,0xa2,0x23,0x3d,0x08,0xf1,0x64,0x8a,0x4e,0x67,0x0b,0x53,0x5a, + 0x75,0xa4,0x58,0xb9,0x93,0x66,0xfc,0xd9,0xb2,0x2e,0x1f,0xf8,0x6f,0x84,0x1f,0x8b, + 0x4b,0x7d,0xcf,0x61,0xc7,0xfc,0x42,0x5c,0x4e,0x7d,0x14,0x2d,0xd6,0xc7,0xb0,0x81, + 0xe7,0xe7,0xf5,0x80,0xeb,0xc6,0x47,0xd3,0x81,0x59,0x7e,0xb2,0x70,0x7e,0x05,0x65, + 0x45,0x8f,0x7d,0x8c,0x65,0x0d,0x76,0x52,0x57,0x46,0xee,0x80,0xae,0x48,0xd3,0x51, + 0x94,0x5c,0xb6,0xcb,0xae,0x46,0x23,0xe8,0x0b,0xe5,0x94,0xd0,0x1c,0x80,0x70,0x95, + 0x10,0x7e,0x50,0x2a,0x4b,0x23,0x74,0x77,0x98,0x4b,0x73,0x3b,0xf0,0x67,0x94,0x52, + 0x84,0x3f,0xc8,0x78,0x34,0x1c,0x88,0x1e,0x78,0x73,0xd3,0x93,0xa3,0x17,0x22,0x5d, + 0x37,0x48,0x0a,0x8b,0xf1,0x80,0xc3,0x89,0x48,0x8e,0xc5,0x8e,0x8a,0x90,0xa1,0x32, + 0x66,0xed,0xfe,0xc6,0x61,0x46,0x98,0x18,0x40,0x3b,0x19,0x04,0x85,0x13,0x1a,0x52, + 0x32,0x07,0x5b,0xb2,0x31,0x75,0xfe,0x53,0x7d,0xb6,0xa3,0x5d,0xfe,0x38,0x06,0x9d, + 0x79,0xa1,0x25,0xbe,0xfa,0x22,0x28,0xff,0x47,0xea,0x35,0x50,0x42,0x76,0x30,0x06, + 0x3a,0x53,0xe8,0xe7,0x7c,0x55,0x59,0x73,0x89,0x67,0xa2,0x2a,0x78,0x6b,0x9f,0x1e, + 0x98,0x3d,0x0c,0xc1,0x8b,0x59,0x71,0xc6,0x70,0x9e,0xd2,0x58,0xe1,0x7c,0x85,0xb1, + 0x14,0x1d,0x95,0xc9,0xda,0x11,0x1d,0x79,0xe0,0xff,0xc7,0x5a,0xf2,0xc0,0x7c,0xf6, + 0x14,0xb6,0x28,0xad,0xb5,0x21,0x47,0x0e,0x20,0x9f,0xda,0x29,0x4a,0x56,0x73,0x51, + 0x83,0x43,0x9b,0x43,0x52,0xff,0x38,0x36,0xa5,0x00,0xb0,0x38,0x66,0x15,0xc0,0xd2, + 0x29,0x2b,0xca,0xc5,0xc4,0xb3,0x3d,0xac,0x73,0x2b,0x6d,0xb3,0xe4,0xa2,0x99,0xbe, + 0x75,0xf2,0x47,0x50,0x53,0xa0,0x45,0xd7,0x5a,0xfc,0x37,0xed,0x9b,0xc3,0x20,0xb1, + 0x15,0xb0,0xf6,0xbe,0x54,0x6b,0x8b,0x67,0xbc,0xcc,0x93,0x2a,0x6a,0xcc,0xca,0xea, + 0x5f,0x8f,0xa5,0x84,0x18,0xf3,0x3a,0xe0,0x69,0x1f,0xfd,0x29,0x9f,0x10,0x51,0x58, + 0x2b,0xf6,0x03,0xc2,0xc0,0x6b,0x61,0x71,0x8c,0x7b,0x39,0x26,0xa7,0x9f,0x0d,0x9e, + 0xc2,0xef,0x79,0xc2,0x67,0xa4,0x9a,0xe8,0x0e,0xd9,0xb1,0x32,0x4f,0x4f,0x6c,0xb7, + 0xd8,0xed,0x04,0x2b,0x23,0x8d,0x6a,0xae,0xdf,0xe0,0xf3,0x47,0x3a,0x59,0x82,0x89, + 0x7b,0x5f,0xec,0x5b,0x25,0x70,0x01,0xa1,0x57,0xc5,0x45,0xbd,0x69,0xb8,0x7f,0x75, + 0x8e,0xa0,0x22,0xd6,0x26,0xf8,0x91,0x66,0xc3,0xee,0xc7,0x71,0x2a,0xc3,0x6a,0x69, + 0x38,0xad,0x52,0x07,0x34,0xee,0x7c,0x46,0x1a,0x0a,0x43,0x41,0x55,0x05,0x78,0x01, + 0xc3,0x1d,0x20,0x7f,0x75,0x68,0x20,0x19,0x9e,0xa1,0xcd,0x63,0x7f,0x88,0x80,0x48, + 0x6e,0x6d,0x6f,0xc8,0xc1,0x64,0x74,0xd1,0xfd,0x94,0xfc,0xd3,0x09,0x23,0xf3,0x4f, + 0x11,0x13,0xb6,0x3e,0x66,0xb5,0x2d,0x4f,0x14,0x62,0x18,0x47,0x16,0x02,0x57,0x91, + 0x98,0x31,0xf0,0xaf,0x89,0xe2,0x72,0xf3,0x2a,0x4d,0x8d,0x9f,0x37,0x9d,0xd8,0x54, + 0x77,0x6e,0x6c,0x2a,0x17,0xab,0x5f,0x59,0x96,0xc5,0x8e,0x37,0xdf,0xf5,0xa5,0x78, + 0x2e,0x7c,0x79,0xff,0x83,0x90,0xe2,0x95,0xd3,0x38,0xdb,0x94,0x82,0x17,0x43,0xd9, + 0x7e,0x62,0xb8,0xb4,0x9a,0x77,0x12,0xb1,0x87,0x25,0xba,0xbf,0x12,0xbf,0x30,0xa5, + 0x66,0x26,0xd7,0x75,0x9e,0x0b,0x10,0x06,0x72,0x38,0x49,0x33,0x57,0x59,0x41,0x05, + 0xa5,0x28,0x6f,0x48,0x44,0x22,0x2a,0x6e,0xe8,0xf0,0xab,0x72,0xed,0x2f,0xc8,0xce, + 0xd3,0x3e,0x04,0x2f,0xa7,0x24,0x31,0xed,0x51,0xa2,0x0c,0x27,0xa4,0x08,0x69,0xc6, + 0x28,0xdf,0xec,0x1f,0xfa,0x80,0xc8,0x7d,0xf9,0x72,0x6d,0x42,0xdc,0xe7,0x4f,0x9a, + 0x9b,0x9b,0xda,0x4d,0xf3,0x04,0x19,0x63,0xfa,0xae,0xd9,0x74,0xef,0x86,0xa2,0x24, + 0x8f,0x43,0x0d,0x24,0xab,0x6f,0xdc,0x67,0xcd,0x98,0x49,0x93,0xf7,0x1c,0x28,0x64, + 0x83,0x72,0xb9,0x0a,0xfc,0x04,0xc0,0x42,0x47,0xb7,0x73,0x1c,0x5a,0xea,0x0e,0x24, + 0xd3,0xfd,0x07,0xf8,0x0c,0xba,0x27,0xfa,0xb8,0x5f,0x8b,0xe9,0xb7,0xf1,0xb5,0xee, + 0x40,0x1e,0x8d,0x62,0x47,0xd0,0xd4,0xed,0xae,0x6c,0x69,0x78,0xef,0x20,0xa0,0x48, + 0x5f,0xdb,0xad,0xe0,0x77,0xbd,0x34,0x53,0x6c,0xf3,0x26,0xd5,0x47,0xd8,0xf7,0xe6, + 0x74,0x48,0xc8,0x1e,0xa7,0x97,0x52,0x92,0xec,0xe9,0x21,0x23,0x71,0x5a,0x03,0x53, + 0x69,0xfe,0x5a,0x3a,0x23,0x4c,0x64,0x20,0xe1,0x33,0x85,0xcc,0x5a,0x50,0xd9,0x35, + 0x03,0xa8,0x15,0xe0,0x1b,0x4c,0xe7,0xda,0x9c,0xe8,0x7c,0x32,0x1f,0xee,0x64,0x04, + 0xc9,0x27,0x77,0x14,0x41,0x34,0xe3,0xc1,0x43,0x6d,0xf2,0x87,0xcd,0xb5,0x58,0x16, + 0xba,0x99,0xbc,0xa1,0x82,0x42,0x64,0xab,0xc9,0xe8,0x5d,0x27,0x79,0x4f,0xbc,0x85, + 0x51,0x01,0x53,0x0e,0x2e,0xde,0x65,0x67,0xe9,0x74,0x2b,0x32,0x32,0xe5,0x28,0x5b, + 0xce,0x33,0x19,0x4b,0x79,0xf1,0xfb,0x57,0x4b,0xc5,0x5a,0x9b,0x00,0x69,0x46,0xd0, + 0xd9,0x59,0xca,0x5e,0x51,0xc4,0x38,0xde,0x8a,0x02,0xc8,0xe5,0x11,0xba,0xa3,0xf4, + 0x37,0x4d,0xfa,0x89,0x18,0x03,0x6f,0x2b,0xa1,0xaa,0xa0,0x8a,0x88,0x33,0x0e,0xc6, + 0xe0,0x07,0x3e,0x14,0xfb,0xfb,0x01,0x25,0xc4,0x4a,0x2c,0xf7,0xb0,0xcf,0xc9,0x58, + 0xf8,0x4d,0xea,0x9a,0x7c,0x6c,0x84,0x46,0x52,0x9d,0x97,0x55,0xac,0xd3,0x58,0x3e, + 0xb1,0xa3,0x14,0x58,0xce,0xf7,0xe5,0x99,0x46,0x6b,0x9a,0x3b,0x69,0xee,0x84,0x58, + 0x34,0xae,0xc5,0x31,0x15,0x2f,0x88,0x57,0x63,0x14,0x05,0x29,0x35,0x32,0x60,0xb2, + 0x3f,0x06,0xa0,0x8a,0xb0,0x00,0xd6,0x6b,0x2a,0x30,0xab,0x81,0xd4,0x62,0x84,0x5a, + 0x54,0xe1,0x91,0xd8,0x6c,0xa0,0x5d,0x12,0x8b,0x0b,0x32,0xdd,0x36,0xeb,0x28,0x41, + 0x8d,0xd6,0x16,0x9a,0xa2,0xa4,0xa1,0x5c,0xcb,0x2a,0x8d,0xa4,0x72,0xc1,0xca,0xb2, + 0x02,0xeb,0x6c,0x3f,0x6d,0x8d,0xb9,0x72,0x6d,0xab,0xbf,0xaa,0x45,0x3a,0xc7,0x95, + 0x31,0xbb,0x0b,0x22,0xcb,0x62,0x28,0x25,0x5f,0x6d,0x46,0x0d,0x1a,0x77,0xd6,0x8a, + 0x23,0x0e,0x74,0x27,0xb7,0xa9,0xbb,0x58,0x09,0x53,0x60,0xf0,0x7c,0xce,0x2e,0xec, + 0x15,0xd0,0x71,0x5e,0x7c,0xc1,0xae,0x78,0x05,0xda,0x67,0xbe,0x1c,0xc5,0x4f,0x39, + 0x03,0x85,0x2f,0x20,0x2e,0xac,0xf3,0x77,0x44,0x63,0x22,0x06,0x4b,0x80,0xae,0xb4, + 0xfc,0x55,0xbe,0x21,0x12,0x5f,0x2d,0x75,0x22,0x23,0x64,0xe7,0x12,0xb5,0x7d,0xa0, + 0x21,0xfe,0x10,0x1c,0xe1,0x71,0xcd,0xe4,0xe8,0x84,0xcf,0xaf,0x10,0x29,0x81,0xea, + 0xa3,0x38,0x09,0x78,0xe6,0x39,0x16,0xd7,0xa8,0x0e,0x89,0x5b,0x07,0x19,0xac,0x8f, + 0xa9,0x09,0x2f,0x67,0x03,0x89,0x0e,0x48,0xaf,0xb1,0x09,0xb4,0x20,0xf1,0xd9,0x25, + 0xbc,0x82,0x99,0xb9,0xa0,0x92,0x1d,0xcf,0xaf,0x8d,0xf7,0x95,0x0e,0xf0,0xf8,0x63, + 0xb1,0x1b,0x6d,0x96,0x3b,0xef,0x3d,0x84,0x0c,0xf6,0xaa,0xf8,0x95,0x4d,0xf7,0xa0, + 0x81,0x66,0x55,0x46,0xa6,0x51,0x12,0x42,0xe9,0x39,0xc0,0x50,0x91,0x1e,0xd4,0xe0, + 0x32,0x5e,0x08,0xab,0xc9,0xd8,0xf4,0x21,0x29,0xd5,0x00,0x64,0x50,0xc1,0x5d,0xea, + 0x09,0x42,0x77,0xde,0xc4,0x5e,0x4a,0xb4,0x60,0xfb,0x90,0x16,0x66,0x5e,0x97,0xc4, + 0xc0,0xf0,0x8e,0xd9,0x95,0xb7,0xf8,0x53,0x13,0x7b,0x7a,0x0e,0xc0,0x83,0xca,0x5d, + 0xda,0x64,0xac,0x61,0x70,0xc9,0x2f,0x06,0x7c,0xd4,0x83,0xa3,0xbc,0x66,0xcb,0x85, + 0xaf,0x6f,0xc7,0xad,0x48,0x60,0x6a,0xbd,0x5a,0xa9,0xb0,0xff,0x72,0xdf,0xa9,0x54, + 0xa1,0x99,0x87,0xd3,0x1e,0xfb,0x3d,0x8e,0x72,0x02,0xf5,0x53,0xc9,0x0a,0x0e,0xc3, + 0x91,0xb0,0xfb,0x4e,0x24,0x6c,0xc4,0xc9,0x4a,0xed,0x39,0x82,0xe2,0x90,0x64,0x26, + 0x0a,0x0b,0x07,0x6d,0x7a,0x55,0x41,0x92,0xca,0x82,0xc6,0x9c,0x67,0x4a,0x3e,0xe7, + 0xda,0xb9,0x51,0x35,0xae,0xad,0x18,0x4e,0x00,0x63,0x52,0xb5,0x1d,0x63,0x17,0xb0, + 0xf3,0xee,0x25,0x8b,0xc7,0x01,0x8c,0x6f,0x58,0x6b,0xc2,0x5e,0xc9,0x20,0xd2,0xd3, + 0xa9,0x34,0xd7,0x95,0x69,0x2b,0x54,0x93,0x0e,0xd5,0x56,0x54,0x4d,0xda,0x85,0x56, + 0xbd,0x92,0xee,0xcc,0xa4,0x84,0x9c,0xbc,0x52,0x2a,0x65,0xf2,0x54,0x77,0xca,0x52, + 0x7c,0xcf,0x0a,0x5e,0x51,0x21,0xc8,0x25,0xc3,0xd3,0xa9,0xd2,0xb4,0x49,0xea,0x34, + 0xe5,0x27,0xab,0x05,0xad,0x31,0x86,0xbc,0x51,0xed,0x8c,0x9f,0x23,0xbf,0xe0,0x8a, + 0x80,0x66,0xcf,0x89,0xc6,0xfa,0x4a,0x9f,0xe8,0x52,0xd6,0x1e,0x62,0x99,0xd1,0x5a, + 0xca,0x1f,0x35,0x21,0x86,0xfe,0xb8,0xbd,0x41,0xd5,0xe3,0x9f,0xb2,0x0b,0x2b,0x32, + 0x5b,0x51,0xf2,0x0b,0xb4,0x47,0xa9,0x55,0xd1,0x2e,0x2a,0x81,0xd8,0x9e,0xcb,0xbb, + 0x0a,0x1a,0x19,0x77,0x85,0x2e,0x0f,0xac,0x08,0xc7,0x3e,0x9a,0xd0,0x32,0x82,0x9d, + 0x4c,0x29,0x24,0x7b,0xff,0x9a,0xb8,0x0e,0xc1,0xfe,0x60,0x4e,0x61,0xa3,0x18,0x28, + 0xae,0x2d,0x6f,0x7d,0x78,0xf7,0x59,0x55,0x78,0x77,0xe6,0x0e,0x3c,0x04,0x66,0xf6, + 0x6c,0x93,0x26,0xd4,0x66,0x1a,0x7a,0x6a,0x20,0x24,0x72,0x38,0x0e,0x09,0x28,0xb4, + 0xd7,0x32,0x43,0x8c,0x07,0x36,0xf0,0x38,0xcc,0x1f,0x74,0x5a,0xd2,0xd9,0x04,0xc3, + 0xe9,0x97,0xa9,0x66,0x6d,0xdb,0x59,0x73,0xd2,0x43,0x76,0xd5,0x24,0xb8,0xbb,0x3f, + 0x9b,0xbb,0x13,0xc7,0x53,0x8a,0x00,0x4e,0xf9,0x48,0xf5,0x94,0x94,0x39,0xe0,0x54, + 0xa3,0x2d,0x56,0x0c,0x6e,0x9f,0x9b,0x61,0xde,0xe0,0xb3,0xac,0x54,0xa7,0x71,0x3b, + 0xaf,0xbb,0x54,0xc2,0x5d,0x8e,0x54,0x2d,0xed,0x95,0x8a,0xc9,0x73,0x34,0xed,0xf4, + 0x17,0xe5,0x02,0xa8,0x36,0x6d,0x55,0xc1,0x35,0x14,0x85,0x3b,0xd9,0x27,0xe8,0x97, + 0x12,0x91,0x29,0x62,0xa7,0xb3,0x86,0xca,0x54,0xd1,0x0c,0x52,0x8f,0x09,0x9d,0x44, + 0xa9,0xe8,0xcc,0xfd,0xfc,0x4e,0x33,0x07,0xdd,0x8e,0xc6,0x18,0xff,0x45,0x54,0x24, + 0x0a,0x3d,0xe1,0x90,0xce,0x1b,0x63,0x1a,0x19,0x50,0xc7,0x98,0xd3,0x0a,0x99,0x12, + 0x32,0x5a,0xd7,0x17,0x04,0x2b,0x81,0x99,0x53,0x8e,0x75,0x77,0xa6,0x68,0x56,0x82, + 0x4b,0x3f,0x0f,0x2a,0x8e,0x79,0x6c,0x19,0xaf,0x1f,0x07,0xf3,0x87,0x21,0x03,0xa1, + 0xab,0x62,0x1e,0x9a,0xa3,0x02,0x9a,0x3b,0xf8,0xce,0x7d,0x49,0xde,0xce,0x49,0x6b, + 0x11,0x56,0x4e,0xd2,0xb6,0x72,0xde,0x82,0x2b,0x68,0xae,0x3d,0x0a,0x8b,0xfd,0xdb, + 0x14,0xc1,0x63,0x8b,0xd7,0x1f,0xa8,0x4e,0xa9,0xa7,0x97,0x96,0xd2,0x3b,0xdb,0x2d, + 0x1a,0xee,0x7e,0x3d,0x3a,0x6f,0x54,0x13,0x11,0x17,0x8b,0x69,0x9b,0x07,0x8d,0x3b, + 0x31,0x1c,0x77,0xe7,0x82,0xce,0x2b,0xd2,0x1e,0xa1,0xee,0x07,0x95,0xbf,0xb9,0xf9, + 0xc0,0xb5,0x80,0x33,0x9d,0x8c,0x06,0x54,0x48,0x45,0x9d,0x19,0xce,0x71,0xfa,0xa8, + 0xd4,0xc3,0xbf,0x5a,0x18,0x24,0x81,0x5b,0xc6,0x3e,0xeb,0x38,0x74,0x9c,0x39,0x45, + 0x9b,0xb2,0x87,0x39,0x61,0xdf,0x84,0x40,0x17,0x8d,0x3a,0x9d,0xcf,0x86,0xe8,0x89, + 0x95,0x1d,0x25,0x4a,0x77,0x8c,0xf9,0x07,0x8c,0x0f,0x56,0x2a,0x57,0x8d,0x8e,0xd3, + 0x13,0x1a,0x1e,0x28,0x6e,0xca,0x0a,0xd1,0x1f,0xe8,0x50,0x7f,0x29,0x1a,0x25,0x27, + 0x55,0xb8,0xd0,0x89,0x23,0x3e,0xd0,0x41,0x46,0x7a,0x7a,0xd2,0x00,0x5f,0x26,0x98, + 0x28,0xa4,0x84,0x30,0xd6,0xe8,0x9d,0x8f,0xdc,0x70,0x63,0xf4,0x35,0xd6,0x02,0x2a, + 0x3b,0x8e,0x71,0xa2,0xbb,0x5d,0x2c,0xe1,0xcc,0xb2,0x3e,0x67,0x92,0x0f,0xec,0x40, + 0x24,0x2d,0xa8,0xca,0x75,0x70,0x62,0x03,0x57,0xc6,0x46,0xdc,0xcf,0xc8,0xab,0xfc, + 0x89,0x5e,0xe8,0xbc,0x8b,0x41,0x6a,0xf2,0xd6,0x76,0x7a,0xe5,0x8e,0xd1,0x74,0x73, + 0xb9,0x3a,0x3e,0xec,0x2f,0x29,0x7e,0x5c,0xae,0x92,0xab,0xd7,0x8d,0x4c,0x43,0x14, + 0x65,0xc5,0x38,0x39,0x56,0x57,0xc5,0x5e,0x23,0x74,0x26,0x8e,0x55,0x6e,0x4a,0x47, + 0xdc,0x0b,0xab,0x6e,0x41,0xc7,0x5f,0x86,0x5d,0x9e,0x48,0x3d,0x2d,0x6e,0xc6,0x29, + 0x47,0xd5,0x52,0xa6,0x64,0x92,0x3e,0xcd,0x77,0xf1,0x94,0xa4,0xca,0x31,0x74,0xc3, + 0xf2,0xe3,0x6c,0xf9,0x71,0xbc,0xe5,0x4b,0xd4,0x96,0xfe,0x6a,0x98,0xe2,0x59,0xa8, + 0x69,0xba,0x70,0xb8,0x5c,0x0e,0x73,0x21,0xa4,0xc9,0x56,0x31,0x7f,0xd1,0x83,0x68, + 0x4f,0x67,0xba,0xb5,0x65,0x2e,0x1f,0xb1,0x51,0x11,0x53,0x05,0xdd,0x9b,0x6d,0x0c, + 0xd3,0xa1,0x25,0x4a,0x21,0x96,0xe4,0xe1,0x8b,0xaf,0x8e,0x96,0xf9,0x9d,0x92,0x8f, + 0xd9,0xd7,0x78,0xff,0xcb,0x51,0xac,0xca,0x32,0x94,0x03,0x7a,0x0f,0xd9,0x07,0x4c, + 0xd0,0x35,0xb4,0xee,0x19,0xcb,0xbf,0xd3,0xd9,0x60,0x3a,0x67,0x69,0xa7,0x50,0x34, + 0x0c,0x5d,0xe3,0x0f,0xa4,0xdb,0x37,0xcb,0x3e,0xbc,0xde,0xff,0x85,0xcc,0x73,0xb7, + 0xfe,0xc1,0x57,0x84,0xbe,0x42,0x15,0xfc,0x90,0xf9,0x9e,0xe0,0x2a,0xae,0x0d,0x39, + 0x26,0x9e,0xce,0x15,0x22,0x14,0xa8,0x9e,0xee,0x50,0xa6,0xd9,0xc8,0xbb,0x6e,0x43, + 0x45,0x87,0x2c,0xc9,0x54,0x86,0x64,0xd4,0x5c,0xab,0x00,0xa2,0xdc,0x85,0xdd,0x32, + 0x77,0x79,0x17,0x03,0x9a,0x13,0x33,0xcf,0x2f,0x1e,0xe0,0x0b,0x0f,0x87,0x00,0xeb, + 0x89,0x87,0xc3,0xac,0x70,0x71,0x88,0xd6,0xe2,0x78,0x48,0x4f,0x38,0x1c,0x0f,0x87, + 0x99,0x94,0xe1,0xda,0x47,0x13,0x9d,0x28,0x25,0xf3,0x2c,0xa4,0x59,0x73,0x16,0x98, + 0x68,0x4d,0x11,0xd9,0xa8,0x2d,0x61,0x10,0x83,0xce,0x43,0x06,0x89,0x95,0xc4,0x06, + 0x16,0x3c,0x55,0x5c,0x67,0xf5,0x3d,0xf8,0x78,0xb0,0x8a,0x28,0x45,0x7a,0x72,0x4a, + 0x98,0x7b,0x71,0x17,0xb6,0x6c,0xab,0x0d,0x37,0x5e,0x02,0x6a,0x62,0xcb,0xbe,0x1c, + 0x14,0xaa,0x7f,0x7c,0x34,0x9d,0xd7,0x97,0x18,0x05,0x26,0xa6,0x21,0xeb,0xfe,0x2c, + 0x14,0xd8,0x0e,0xd3,0xa9,0x78,0x56,0x36,0x9b,0x45,0xe1,0xdd,0xe0,0x66,0x46,0xde, + 0xb9,0x78,0xe6,0xca,0x76,0x86,0x9a,0xa6,0xbd,0xa0,0xae,0x2e,0x8a,0x92,0xc9,0xac, + 0xd6,0x6b,0xd1,0x99,0x1a,0xd9,0xfe,0x89,0x52,0x73,0x8d,0x8f,0x57,0xaa,0x7f,0xa1, + 0x47,0x70,0x80,0xb1,0xf2,0x47,0x5a,0xfb,0x39,0x87,0x4c,0xc0,0xac,0x72,0x40,0xfb, + 0xf6,0x72,0x1f,0x06,0xd9,0x65,0x66,0x78,0x8e,0xa8,0xb6,0xe1,0x06,0x00,0x71,0x17, + 0x54,0x49,0x48,0x9f,0x7c,0x56,0x72,0x0a,0xe8,0x7c,0xd6,0xe9,0x57,0x2f,0xe6,0x29, + 0x18,0x9f,0x59,0x12,0x28,0xb2,0xe6,0x23,0x2a,0xf9,0x70,0xc6,0xf6,0x26,0x8b,0xe2, + 0x19,0xe6,0x33,0x3a,0xc3,0x29,0x41,0x96,0x3a,0x7f,0xa2,0x2b,0xd6,0x65,0x5e,0x29, + 0xec,0x10,0x23,0x23,0xb5,0x38,0xf1,0x0b,0x71,0xc1,0xce,0xec,0x8d,0x3e,0xc6,0xf4, + 0x91,0x21,0x74,0x57,0x25,0x20,0xf9,0xe5,0x5c,0x22,0x45,0xea,0xd2,0x24,0x81,0x66, + 0x2d,0x2d,0xf1,0xf7,0xf6,0x0a,0x9b,0x83,0x04,0xea,0x8f,0xfb,0x2c,0x06,0x00,0x62, + 0xd9,0x0c,0x84,0x9c,0x19,0x81,0x4d,0x43,0x51,0x22,0xdf,0x93,0xfd,0xc2,0xce,0x7b, + 0x81,0x4c,0x17,0x8e,0xc1,0x01,0x70,0xed,0xf0,0xdd,0x2e,0xee,0x7a,0x59,0xac,0x3a, + 0xd0,0xff,0x49,0x62,0x3f,0x23,0xbd,0x1b,0xb7,0xc6,0x3f,0xab,0xc2,0xd0,0xc2,0xa8, + 0xea,0xcf,0x3a,0x82,0xa6,0x63,0xb4,0x70,0x21,0x24,0xba,0x49,0xf7,0xd9,0x09,0x86, + 0xbd,0xe4,0xc5,0xf2,0x6b,0x72,0x65,0xf3,0x4f,0xc3,0x3e,0x89,0xf0,0x79,0xb4,0xcc, + 0x28,0xac,0xd7,0x21,0xb1,0x46,0x37,0x35,0x8a,0x84,0x87,0x59,0x19,0xaf,0x1c,0x53, + 0xa2,0xef,0xb9,0xdf,0xf0,0xa2,0x67,0xd3,0x61,0x38,0x16,0xea,0x8d,0x57,0xe6,0xca, + 0xa8,0xd2,0xb1,0x43,0x2b,0x0e,0x23,0x0e,0x29,0xb6,0xfb,0x29,0xba,0xa9,0x4b,0xa3, + 0x06,0xb5,0xed,0xbc,0x31,0x78,0xd2,0x80,0x3e,0xd0,0x89,0xf1,0x27,0x50,0x2b,0x40, + 0x55,0x3d,0x87,0x32,0xd8,0x98,0xbb,0x09,0x25,0x1c,0x0e,0x50,0x27,0xd9,0x77,0x60, + 0x0a,0x54,0xd0,0xb5,0xc7,0x23,0x5d,0x87,0xa8,0x1e,0xd8,0xac,0x6f,0xfe,0xdc,0x6e, + 0xfe,0x0d,0x50,0x9a,0x3b,0x4d,0x0b,0xdf,0xc1,0xd9,0x9d,0x75,0xf1,0x32,0xac,0xc9, + 0x38,0xaf,0x85,0x72,0xee,0x08,0x7e,0x9b,0xbb,0x9f,0xee,0x19,0xfe,0xdd,0xe7,0x35, + 0x8c,0x23,0xcb,0x30,0xfb,0x26,0x75,0x7c,0xe8,0xe3,0x3b,0xcf,0x35,0xc3,0x3c,0x57, + 0x84,0x56,0xba,0x7b,0x5f,0x8f,0xf5,0xac,0x8c,0xf5,0xcc,0xc5,0xfa,0xf7,0xbd,0x0f, + 0x6f,0x5f,0xbf,0xfd,0xa9,0xc5,0xa1,0x4f,0x80,0x34,0x57,0x21,0x7d,0xd0,0x66,0x2e, + 0x4f,0xca,0xc9,0x2a,0xac,0x66,0x82,0x95,0x6f,0x85,0xb1,0xb9,0xc9,0x3b,0x6a,0x2c, + 0x5c,0x22,0x33,0xd2,0xbd,0x6d,0x87,0x8b,0x09,0x8f,0xc1,0x52,0x6c,0x16,0x99,0xa5, + 0x2e,0xf6,0x6a,0x85,0x7a,0x8a,0xbd,0x99,0x86,0x53,0x5c,0xdf,0xc6,0x69,0xb9,0x8d, + 0xd3,0x15,0x6d,0xe4,0x3b,0x7f,0x1e,0x4f,0x37,0x1d,0xd6,0x62,0x09,0xb4,0x64,0xf2, + 0x51,0xcf,0xdf,0x60,0xfb,0xc1,0x07,0xca,0x1a,0x39,0xc6,0xac,0xb9,0x38,0x90,0xbe, + 0xca,0xf8,0xaa,0xa3,0xd8,0x8e,0x30,0x01,0xe4,0x72,0x94,0x5c,0xda,0xf8,0x84,0xd7, + 0x7e,0x15,0x01,0xa7,0x7a,0x47,0xff,0x64,0x3e,0xce,0xee,0x69,0x23,0x81,0xd8,0xcd, + 0xa4,0x77,0x99,0x81,0xe7,0x93,0x95,0x79,0xcd,0x9d,0x1d,0x64,0x3f,0x9f,0xd8,0x99, + 0xcf,0x27,0xc8,0x8a,0xa4,0x2a,0x36,0x26,0x8c,0x6b,0x25,0xcb,0xd2,0x10,0x28,0x0f, + 0xa8,0x75,0xec,0x56,0x11,0xbe,0xec,0xe2,0x9c,0x7d,0x88,0xba,0x09,0x7b,0x87,0x16, + 0xe7,0x13,0x69,0xa2,0x33,0xcb,0x91,0x58,0x26,0x1a,0x01,0x59,0x32,0x3a,0x4b,0x93, + 0x43,0x95,0xd0,0xb9,0x08,0x51,0x8f,0x0b,0x9e,0xf7,0x11,0x36,0x2b,0x0d,0x9e,0xcc, + 0xb3,0x26,0xf3,0x70,0xe0,0x8d,0x02,0xd1,0x6f,0x32,0x56,0x2d,0x5d,0x3a,0x76,0x5f, + 0xef,0xd5,0xd9,0xb5,0x4d,0x01,0xac,0x96,0x4b,0x1d,0x4d,0x07,0x37,0x28,0xef,0x8e, + 0xb1,0x84,0xe9,0x69,0xe5,0x2f,0x2b,0x3b,0x86,0xa0,0xe2,0xb6,0x98,0xf2,0x10,0x08, + 0xd5,0x31,0x5e,0x57,0x87,0xf4,0xc7,0xd0,0xb0,0xa3,0xb1,0xec,0xc5,0x28,0x36,0x5f, + 0x46,0xe4,0x0a,0x57,0x59,0x8e,0xf9,0xe6,0x75,0xa0,0x50,0xdc,0xbe,0xcf,0x2a,0xce, + 0x2d,0x8c,0x54,0x3c,0xe8,0x23,0xf5,0x19,0xa2,0x76,0x18,0x81,0x9c,0xc8,0x91,0xe3, + 0xc3,0x0c,0xac,0x31,0xbf,0x9b,0x34,0xa2,0x3f,0x38,0xc5,0x02,0x8e,0xae,0x5c,0xa2, + 0x5a,0x05,0x16,0x7f,0xd4,0xa8,0x69,0xad,0x2a,0x3e,0x21,0x96,0x5c,0x68,0xc3,0x74, + 0x53,0xe6,0xee,0x0f,0x79,0x8b,0x06,0x40,0x2d,0xcb,0x51,0x6e,0x5a,0x7a,0x39,0xd9, + 0x92,0x23,0x99,0xd9,0x20,0x1b,0x92,0x40,0xe7,0x50,0xbc,0x63,0xda,0x2c,0x54,0xaf, + 0xe0,0x6c,0x63,0x05,0x86,0x2d,0xaa,0xac,0x2c,0x1d,0x64,0x10,0xb3,0x2e,0x17,0x5e, + 0x25,0xa5,0x43,0x02,0x3d,0x8a,0x75,0x39,0xb0,0x04,0x34,0xf9,0xa4,0xd9,0xcc,0xa0, + 0xd0,0xe4,0x12,0xf9,0xbe,0x07,0xb5,0x30,0xde,0x40,0xbe,0x9c,0x76,0x60,0x06,0xe5, + 0xee,0xd2,0xf8,0x91,0xf2,0xa9,0xc1,0x9f,0xc0,0x48,0xdc,0x4f,0x4c,0x32,0x3a,0x08, + 0x12,0x35,0x07,0x6f,0x09,0x7e,0xed,0xc3,0x49,0x43,0x14,0x62,0xdb,0xc5,0x77,0x16, + 0x5a,0x67,0x44,0x3d,0x64,0xe4,0x8f,0xfd,0x2c,0x7e,0x90,0x65,0x8d,0x8e,0xea,0x6a, + 0x1b,0x37,0x73,0x70,0xc1,0x49,0x0a,0xa9,0xed,0x97,0x46,0x4a,0x90,0x53,0xb5,0x6a, + 0x33,0x63,0x03,0xbb,0x86,0x01,0xcc,0x03,0x2e,0x3f,0xf4,0xff,0xf9,0xba,0x27,0x89, + 0xec,0xeb,0x83,0xd5,0x24,0xc2,0xff,0x41,0x59,0x62,0x05,0x52,0x2e,0x83,0x18,0x93, + 0xa8,0xd4,0xd5,0x68,0xd8,0xa2,0xf0,0x76,0x27,0x9c,0xc9,0x9c,0x6d,0x6e,0x95,0x66, + 0xad,0x99,0xd2,0x3c,0x65,0x9d,0x08,0x66,0x7c,0xbd,0x67,0xc1,0x28,0xb5,0xf8,0x2f, + 0x97,0xd8,0xa2,0x3f,0x55,0x31,0xcd,0x08,0x43,0xcc,0xb0,0xa8,0x00,0x4d,0x9a,0x09, + 0x23,0x46,0x0f,0xcd,0x84,0x9a,0xb1,0x2a,0x3e,0xd9,0x86,0x1d,0xa0,0x2c,0xd5,0x00, + 0x65,0x8b,0x9c,0x58,0x26,0x70,0x63,0xdb,0x94,0xa6,0x4c,0x55,0x69,0xca,0xb9,0xcd, + 0x47,0x64,0x7e,0xd2,0x7c,0xc2,0x39,0x61,0x1d,0x1b,0x99,0x44,0x71,0xf0,0xad,0x66, + 0x7f,0x17,0x5d,0xda,0x17,0xe5,0x37,0x96,0x02,0xb0,0x0e,0x1e,0x0e,0xd5,0x9c,0x67, + 0x75,0x35,0xdf,0x41,0x7f,0xd7,0xe0,0xe6,0xe2,0xec,0x80,0x7f,0xbd,0x7a,0xf7,0xa8, + 0xbc,0xfe,0x4c,0x18,0x8a,0x1d,0x1e,0x53,0xba,0x83,0xea,0xe4,0x88,0x98,0x01,0x9b, + 0xb4,0x0e,0x3f,0xad,0xab,0xb0,0xb9,0x5c,0xda,0xef,0xdb,0xbb,0xe5,0xfa,0x94,0x86, + 0x1c,0x59,0x4d,0x02,0x85,0x9e,0x14,0x41,0x40,0xed,0xc2,0x1f,0xda,0x5f,0xde,0xe8, + 0xaf,0x1c,0x87,0x22,0x1d,0xc9,0x27,0x30,0xa1,0x35,0xfb,0x46,0xb6,0x2b,0x50,0xd9, + 0x46,0x82,0x78,0xe2,0x43,0xac,0xd9,0x4f,0x65,0x83,0xf6,0x5d,0x6c,0xd9,0x8e,0xe4, + 0x5f,0x5b,0xf9,0x43,0xd2,0x9d,0xd3,0x25,0x77,0xb4,0x51,0xee,0xeb,0x98,0x1b,0x1a, + 0xfa,0x4a,0x21,0x36,0x5b,0xe1,0x5f,0xae,0xeb,0x58,0x1e,0xc2,0x84,0x2f,0x20,0x91, + 0xd5,0xce,0x5d,0x2e,0xea,0xe8,0x2c,0x4d,0x17,0xe2,0x9d,0x80,0x6e,0x06,0xa1,0xab, + 0x5a,0x64,0x5d,0x33,0xcb,0x26,0x33,0x3c,0xd0,0x85,0x25,0xfa,0x9d,0x82,0x56,0xe8, + 0x2f,0x29,0x1a,0x85,0xb1,0xa9,0x7a,0xf2,0xc7,0xe4,0xc4,0x3c,0xf4,0x29,0x74,0x71, + 0xc6,0xd6,0x40,0x4a,0x2c,0xad,0x80,0x23,0x1f,0xf1,0x24,0x21,0xa6,0xab,0xa7,0x07, + 0x6a,0x2a,0xcd,0x95,0xa0,0xa5,0x45,0x8a,0x20,0xe4,0x5a,0x54,0x03,0xb5,0xb4,0x69, + 0xbd,0x1b,0x24,0x91,0x64,0x65,0x04,0x42,0x6a,0x75,0xed,0x19,0x62,0x6b,0x92,0xc1, + 0x96,0x73,0xba,0x53,0xcc,0xed,0x6b,0x01,0xa7,0x2d,0x8c,0x88,0x35,0xcc,0x54,0xf9, + 0xd1,0xf4,0xca,0xca,0xad,0xf0,0x17,0x58,0xde,0x53,0x15,0x0e,0xf6,0xcb,0xa5,0xfb, + 0xde,0x20,0x83,0xe9,0x31,0xef,0xaa,0x62,0xb7,0x99,0xae,0x0d,0x70,0x18,0xc6,0x7a, + 0x75,0xea,0x84,0xfc,0xa3,0xa5,0x0e,0xb4,0x2d,0x5d,0xd5,0xe8,0xb9,0xd0,0x5d,0x7e, + 0x9c,0x6d,0x9d,0x17,0xd9,0x89,0xa6,0x0e,0x85,0xc9,0x71,0x11,0xbc,0xb1,0xa4,0x78, + 0xdc,0xdc,0xc4,0x9f,0x06,0x2b,0x79,0xe9,0x81,0xcd,0x5f,0x8e,0x64,0x0d,0xf7,0x2e, + 0x1a,0x72,0x34,0x28,0xed,0x2d,0x1f,0x8b,0xd4,0x94,0xdb,0xc9,0xf1,0x6d,0xe5,0x0f, + 0x32,0x1f,0xd8,0xc5,0xd5,0xb3,0x87,0x9b,0xff,0x57,0x77,0xa7,0xbb,0x7c,0x79,0x42, + 0x0a,0xd2,0xd6,0xee,0x94,0x68,0xdf,0x8c,0x11,0x81,0xea,0xc9,0x15,0xef,0x0c,0xcd, + 0xec,0xf3,0x13,0x40,0xf2,0xe5,0x86,0xac,0x32,0x64,0x31,0x84,0x67,0x71,0xde,0x3c, + 0x69,0xcf,0x60,0xe8,0xd1,0x55,0x68,0xb1,0x1b,0xe8,0xdf,0x9e,0xb2,0x88,0x15,0xd6, + 0xdc,0x3c,0xb5,0x10,0x7c,0x0b,0x7c,0xa1,0xbd,0x86,0x23,0xcb,0x9e,0xef,0x91,0x37, + 0x6b,0x62,0x2f,0xc5,0x5a,0x53,0xbd,0x15,0xd8,0x99,0x3a,0x0b,0x5d,0xe3,0x84,0xe4, + 0x71,0xc2,0x5d,0xda,0x6a,0x0a,0x63,0x60,0x35,0x2e,0x7a,0x06,0xe7,0x20,0xfd,0x06, + 0xb4,0x9a,0x2c,0x83,0x6a,0x19,0xe4,0xa1,0xc5,0x93,0x17,0x9c,0x6f,0x8b,0x15,0x23, + 0x2a,0x47,0xd4,0x43,0x5d,0x47,0x30,0xd1,0x2b,0xad,0x18,0x6c,0xed,0x0d,0x3c,0x33, + 0x6f,0xa8,0xd5,0x1c,0x5e,0xd1,0xa6,0x74,0xc1,0x37,0x55,0x7c,0x3d,0x03,0xfa,0xad, + 0x7f,0xb0,0x87,0xa1,0x8f,0x99,0x72,0x62,0x53,0x57,0xdc,0x11,0xd7,0x43,0x5f,0xcb, + 0x7f,0x61,0x4b,0xbe,0xa0,0x08,0x9f,0xbb,0x38,0xb2,0x43,0xde,0x93,0x61,0xa2,0xac, + 0x55,0x7e,0x99,0x8c,0x82,0x70,0x22,0xe5,0xe5,0xe5,0xfa,0x62,0x05,0x8f,0x50,0xbf, + 0x37,0xd3,0xd4,0xeb,0x69,0x5e,0xcb,0xd6,0xc8,0x17,0x7e,0x29,0x8f,0xb4,0x14,0x1d, + 0xfa,0xe5,0x05,0x77,0xdb,0x12,0xe5,0xf6,0xb0,0x1e,0x4e,0x66,0x08,0xe8,0x4f,0x85, + 0x92,0xd3,0x0f,0x61,0x99,0x55,0xab,0xf5,0x0b,0xe4,0x85,0x99,0x6c,0xfe,0xfa,0xfc, + 0x69,0x69,0xe9,0x7e,0xda,0xdc,0xf5,0xa6,0x84,0xb5,0x76,0xeb,0xec,0xd0,0x80,0xd1, + 0x61,0xec,0x23,0x87,0x13,0x4e,0xa7,0xbb,0x11,0xb9,0xb3,0x6a,0x19,0x70,0xf8,0xbb, + 0x9c,0xd5,0x97,0x16,0x26,0xe7,0xe0,0xd5,0xa7,0xa8,0x3b,0x9e,0xd7,0x10,0x64,0xd4, + 0xfd,0xf4,0x33,0x0c,0x10,0xc1,0x5f,0x56,0x0d,0xf3,0x75,0x12,0xad,0x9d,0x9f,0xb9, + 0x6a,0xe7,0xb0,0x62,0xb4,0x1f,0x61,0x05,0xd7,0x6d,0xff,0x1c,0xdb,0x9d,0x5c,0xea, + 0xe6,0x52,0x15,0x9f,0x3c,0x34,0x74,0x23,0xd8,0xc7,0xed,0x45,0xe3,0x2a,0x3c,0x50, + 0x63,0x4e,0xc7,0x31,0xa4,0xc6,0x3e,0x3c,0x61,0x1d,0x18,0xb3,0x98,0x76,0xa9,0x73, + 0xf0,0x19,0x3d,0x5d,0x45,0x36,0xaa,0x15,0x59,0xc8,0x8b,0x78,0xff,0xdd,0x18,0x0c, + 0x83,0x12,0x18,0x3e,0xa1,0xa3,0x19,0xe3,0xf2,0x61,0x7f,0x72,0x36,0x4f,0xd6,0xad, + 0xb0,0x4c,0xeb,0xfb,0xe5,0x83,0x4a,0x6e,0xb7,0x5c,0x16,0x49,0x22,0xa5,0x38,0x8b, + 0xf3,0x1a,0xce,0xe2,0x65,0x4c,0x8d,0xed,0x3b,0xa6,0x70,0x69,0x22,0x77,0x54,0x20, + 0xa9,0x19,0x6e,0x0f,0xf7,0x8a,0x74,0x69,0x64,0x32,0x26,0xfd,0x85,0x7c,0x84,0x76, + 0x6e,0x93,0xcf,0x6b,0x00,0x55,0x96,0x52,0x92,0x85,0x38,0x5d,0x69,0x61,0x32,0x34, + 0xe1,0x22,0xd4,0x0f,0x00,0x5b,0x81,0x0e,0xd3,0xac,0x7d,0xdf,0xf4,0x5d,0xb8,0x74, + 0x74,0x64,0x5c,0x4f,0xe0,0xe1,0x30,0xb3,0xe4,0xc1,0x27,0x76,0xbb,0xd8,0x04,0x6c, + 0xcf,0xdb,0x9b,0xbb,0xf2,0xea,0xdf,0x4e,0x49,0xa2,0x94,0xb0,0xe8,0xb9,0xcf,0x2b, + 0x9d,0x93,0x8e,0x88,0x84,0x72,0x4d,0x2e,0xbe,0x3f,0xe6,0xcb,0x69,0x33,0x79,0x20, + 0x1c,0x14,0x76,0x73,0xd3,0x99,0x20,0xb1,0xf3,0x56,0xc9,0xbd,0x39,0x33,0x69,0x20, + 0xd0,0x6e,0x77,0x84,0xa4,0x8e,0x69,0x8a,0x45,0x92,0xa4,0xa9,0x34,0xa9,0x9e,0x97, + 0x52,0x2a,0xdb,0x5c,0x89,0xa1,0x23,0xcb,0x36,0x15,0x72,0x7a,0xc5,0x9c,0x8c,0xe3, + 0x35,0x4c,0x41,0x96,0xd9,0xfb,0xf8,0x8e,0x56,0x39,0xe3,0xa5,0x2c,0x4d,0x65,0x8d, + 0xa0,0x84,0x1e,0x46,0x99,0x19,0x1e,0x7b,0x34,0xba,0xa2,0x4a,0xbe,0x80,0x48,0xdb, + 0xd5,0xeb,0x12,0x95,0x5c,0xab,0x29,0xe4,0x73,0x7a,0x72,0x0d,0x01,0xdc,0x15,0x5a, + 0x29,0x75,0x2f,0x37,0x95,0x58,0xf4,0x41,0x8e,0x7a,0xd1,0x4b,0x75,0xab,0xf3,0x5e, + 0xec,0x36,0xf1,0xdf,0x6a,0x11,0x48,0x2e,0x16,0x99,0xd8,0x06,0x57,0xc3,0x5e,0xce, + 0x8b,0x24,0xea,0x38,0xf1,0x30,0x8e,0x82,0xa7,0xbb,0x38,0xf5,0x90,0x63,0xa2,0xac, + 0x74,0xc9,0xf1,0x0c,0x8f,0x46,0x8f,0xbc,0x05,0x75,0x1f,0x3c,0x52,0x9c,0x46,0x77, + 0xe0,0x1e,0xb9,0x85,0x95,0xa6,0x7a,0x5d,0xfd,0x0f,0xcc,0xd8,0xaa,0x15,0x38,0x4f, + 0x1a,0xf6,0x69,0x70,0xc5,0x5e,0x23,0x65,0x64,0xad,0x1d,0x80,0x6b,0x2a,0x70,0xf7, + 0xd4,0xcd,0xdd,0xd2,0xfb,0x93,0xe5,0xb2,0x56,0x2b,0xf3,0x91,0x17,0x3b,0xcd,0x75, + 0xeb,0xb7,0xae,0x49,0x1e,0xc3,0xf8,0x77,0xf4,0xd0,0x37,0xd2,0x1f,0x94,0x49,0x54, + 0x5b,0x15,0x86,0x40,0x40,0xc4,0xb8,0xe6,0x75,0x85,0xa9,0x2a,0x69,0x59,0x70,0x90, + 0xc8,0xdd,0x9e,0x00,0x37,0xea,0x83,0xa2,0xbd,0x16,0x39,0xea,0x87,0xbf,0x77,0x0a, + 0x12,0xd2,0xa5,0x98,0xa3,0x2d,0xa2,0x6b,0x42,0xf6,0xe5,0x7d,0xec,0x7b,0x17,0xa1, + 0x6c,0x61,0xea,0x74,0x91,0x14,0xfa,0x24,0xec,0xb9,0xf3,0xd0,0x1a,0x5b,0x7f,0x64, + 0xe4,0x59,0x25,0xc1,0xa9,0x43,0xef,0x53,0xeb,0xbf,0xf7,0xdf,0xbd,0x6d,0x18,0x4f, + 0xfa,0x08,0x08,0x11,0xa9,0x7c,0xe8,0xe1,0xc5,0x92,0xa2,0x23,0xe1,0xd4,0xb6,0x55, + 0x62,0xb4,0xdd,0x0f,0xde,0xc5,0x95,0xe1,0xc0,0x3d,0x13,0x1a,0x47,0x55,0x02,0x07, + 0xb6,0xdc,0x85,0xee,0x7c,0xe6,0x8f,0x8e,0x1a,0x9e,0xfa,0x56,0x14,0x4f,0x7e,0x30, + 0x7a,0x77,0xcf,0x6b,0x6d,0xc4,0xdc,0x0f,0x6b,0xf6,0x64,0xbe,0x12,0x86,0x02,0xcf, + 0x26,0x82,0x24,0x2a,0xcf,0x92,0x41,0x0f,0x96,0x2b,0xac,0x8e,0x01,0xc2,0x2c,0x3a, + 0xd1,0x9f,0xe5,0x72,0x95,0x2a,0xc6,0x5e,0xbe,0x01,0xb3,0x65,0x22,0x2f,0x74,0xb8, + 0x8a,0xea,0xe5,0x9b,0x3f,0xd1,0xe2,0x4d,0x75,0x03,0x84,0x7e,0x1e,0xb2,0x5e,0xf3, + 0x9a,0x41,0xa8,0xd2,0x6d,0x99,0x90,0xf0,0x0c,0x89,0x5d,0xaf,0x57,0x89,0xd1,0x9c, + 0x24,0x13,0x1f,0x30,0xb4,0xc9,0x19,0x1f,0x54,0xab,0x76,0xcc,0x28,0xc3,0x48,0x6c, + 0x62,0x69,0x4d,0x99,0x9e,0xd8,0x30,0x70,0x4d,0x8e,0x7e,0x4c,0xeb,0x4f,0xf3,0xfa, + 0x0d,0x56,0xf4,0x08,0xa9,0x3b,0x5e,0x54,0xfb,0x39,0x7f,0x30,0xd5,0x31,0xe0,0x98, + 0xee,0x77,0x09,0x31,0x41,0xad,0xb7,0xd4,0x22,0x3d,0x87,0x1b,0x93,0x71,0x8a,0xc6, + 0x36,0xb1,0x85,0x4c,0x77,0xd3,0x4a,0x65,0x36,0x72,0x65,0x55,0xea,0xbc,0x41,0xd5, + 0xf1,0x88,0x28,0x48,0x89,0xc7,0x79,0x22,0xb3,0x53,0x2f,0x35,0x96,0x8c,0xa8,0x6d, + 0x0a,0x7b,0xd9,0xfe,0x58,0x84,0x37,0xc0,0xf2,0x17,0x51,0x66,0x7c,0x30,0x00,0x9b, + 0x9b,0x7e,0xb9,0x32,0x9e,0x44,0x12,0xa9,0xba,0x80,0x81,0xf3,0xa2,0xa1,0xea,0x5b, + 0x31,0x9b,0x14,0xdc,0xd8,0x86,0x54,0xd4,0x23,0x0b,0x00,0x5a,0xc9,0x18,0xd3,0xd0, + 0x83,0xfb,0x79,0xc8,0xec,0x7e,0xf1,0xb7,0xc9,0xc0,0xc1,0x40,0x6c,0x40,0xdc,0xdd, + 0x29,0x2f,0xf3,0xd4,0x3b,0xb5,0xc1,0x11,0xcb,0x55,0xb1,0xa8,0x9c,0x2e,0xd3,0xe8, + 0xb6,0x31,0xb9,0x7c,0x64,0xdc,0xdd,0x77,0xe8,0xb9,0xf5,0x88,0xec,0xf7,0xbf,0x46, + 0xff,0xe5,0xc2,0xca,0xad,0x71,0xd3,0x48,0x19,0x45,0x7c,0xe6,0xea,0x54,0x71,0xb8, + 0xb9,0x39,0xb9,0xac,0x94,0x72,0xfc,0x6a,0x39,0xa3,0x6a,0x28,0xed,0xef,0xaa,0xac, + 0x34,0x98,0x71,0x8d,0xa9,0x53,0xb5,0x65,0x14,0xf7,0xe2,0x63,0xd6,0x29,0x6e,0x8a, + 0x32,0x48,0xbc,0x92,0x04,0x93,0xcb,0x0e,0x6b,0xb2,0x5a,0x66,0x89,0x31,0xd0,0xc2, + 0xd7,0xb8,0xf2,0xb4,0x44,0x64,0xb5,0xc4,0x70,0xa7,0x26,0x09,0x50,0x32,0x35,0x9c, + 0x53,0x81,0xb8,0x82,0xb1,0xe9,0x41,0x81,0xe1,0x03,0xb5,0xb0,0xea,0xbc,0xa0,0xbd, + 0xf1,0xa7,0x66,0x96,0xea,0x95,0xef,0x92,0x9d,0xa7,0x4d,0x47,0xfc,0x2b,0xeb,0xf6, + 0xcb,0xac,0x59,0x87,0xb5,0x0e,0x5e,0x6f,0x38,0xcb,0xf8,0x57,0x31,0x91,0xab,0x9f, + 0xfd,0xa9,0x83,0x87,0x55,0x1b,0x3b,0x95,0xda,0x32,0x63,0x29,0x91,0x01,0xc2,0xd9, + 0x62,0x22,0x1f,0x4f,0xfc,0xc1,0x2c,0x90,0x7e,0xe1,0xcd,0xe6,0xa7,0xca,0x5d,0x66, + 0xf2,0x67,0x78,0x52,0x4e,0x40,0xa1,0x8b,0x92,0xf0,0xde,0xe3,0x02,0xff,0x58,0xa4, + 0xcc,0x40,0x3a,0x60,0x65,0xca,0xb2,0x04,0x7f,0xd2,0xbb,0x29,0x4b,0x4b,0x02,0x9c, + 0xa7,0xb3,0x6f,0xe9,0x5e,0x9f,0xee,0x94,0x19,0xf7,0xd3,0xc3,0x81,0x58,0x94,0x8c, + 0x27,0xec,0xa5,0x92,0x4c,0xf2,0xf2,0x10,0x58,0x74,0xb4,0xa4,0xfc,0x51,0xbf,0xf3, + 0x09,0x4c,0x37,0xaf,0x01,0x8c,0xc1,0x59,0x07,0xca,0x3c,0x9e,0xda,0xfe,0x7c,0xa7, + 0xf9,0x05,0xdc,0xbc,0xb6,0xed,0xd2,0xee,0x1b,0x97,0x9b,0x7f,0x11,0x4d,0x1a,0xc1, + 0x87,0xbe,0x48,0x22,0x3a,0x00,0xaa,0x28,0x04,0x4a,0xc8,0xda,0x47,0xe5,0xa9,0x8b, + 0x02,0xd9,0x59,0x3a,0xa7,0xce,0x5c,0xbc,0xcc,0xc2,0x07,0x2e,0x89,0xbe,0x96,0xc6, + 0x9d,0x04,0x0f,0x17,0x1f,0xc4,0xe2,0x7b,0x72,0x85,0xca,0x7a,0xc2,0xcd,0xd7,0xd8, + 0x00,0xa2,0x7f,0x1c,0x8b,0x45,0x3d,0xcc,0x11,0xb3,0x1b,0x99,0x94,0x0c,0x16,0xa1, + 0x03,0x97,0x39,0x6c,0x6c,0x03,0x4b,0x75,0x02,0x7c,0xa7,0x9c,0x94,0xf1,0x9d,0x6d, + 0x6e,0x7a,0x73,0x1d,0xcb,0x19,0x4f,0xc8,0xcd,0x4d,0xe9,0x30,0x63,0xd1,0x2b,0x19, + 0xcf,0x98,0xf2,0x94,0x91,0xf8,0x23,0x1b,0xf3,0x1c,0x93,0x2b,0x15,0x32,0xe3,0x5e, + 0x2e,0x67,0x0d,0x78,0x7e,0x3a,0x9e,0x90,0x15,0xbe,0x4c,0x22,0xa5,0x9b,0xd8,0xce, + 0xd0,0x26,0x22,0x97,0x97,0x4d,0xc5,0xbc,0x0d,0xe1,0x07,0x77,0x1d,0x08,0x43,0x1d, + 0x47,0xd5,0x2c,0x63,0x0d,0xa5,0x13,0x83,0x26,0x46,0x98,0x67,0x07,0x24,0xea,0x2b, + 0x99,0x70,0x7a,0xcd,0x8e,0x47,0x86,0x2a,0x05,0x03,0x9d,0x58,0xca,0x5c,0x4c,0x5b, + 0x79,0xd2,0x79,0xa3,0xd6,0xcc,0x51,0xf5,0xdb,0xa2,0x5c,0x0b,0x84,0xd1,0xc8,0xe8, + 0x25,0x34,0xc0,0xa2,0x36,0xac,0x99,0xe6,0x0a,0x2e,0x86,0x78,0x95,0x32,0x00,0x77, + 0xa3,0xa3,0x67,0x5f,0x73,0x4e,0xcd,0x0e,0x76,0x69,0xa8,0xdb,0xe4,0xeb,0x95,0x91, + 0x97,0xf3,0x69,0x9d,0xec,0x8d,0xfb,0xce,0x2d,0x13,0x16,0xa4,0x98,0x1e,0x18,0x2c, + 0x86,0xd4,0xb9,0x99,0x98,0x0c,0x37,0xa4,0x4b,0xef,0xba,0xaa,0x3a,0xd1,0xb2,0x48, + 0x1e,0x6f,0xe3,0xfe,0x56,0x09,0x2d,0x13,0x54,0xbd,0xbc,0x94,0xfa,0xe7,0xc7,0xc1, + 0x2d,0x58,0x01,0x5b,0xae,0x61,0x3a,0x5b,0xce,0x7a,0xac,0x3d,0xbb,0x35,0xe0,0xca, + 0xcc,0x5c,0xc6,0x3d,0x65,0x01,0x12,0xe4,0x98,0xf0,0x03,0xbf,0x44,0x05,0x47,0x1d, + 0x64,0x62,0x7a,0x4e,0xb5,0x63,0x40,0xb8,0x66,0xd8,0x50,0x10,0x30,0x4b,0x52,0xfe, + 0xa4,0x8e,0x92,0x31,0x01,0x3e,0xa1,0x73,0xb9,0x6b,0x56,0xe2,0xb0,0x7e,0xd6,0x57, + 0xdb,0xae,0xeb,0x8c,0x5e,0x85,0x2e,0xe7,0x11,0x47,0xe8,0x36,0xeb,0xe4,0x74,0xc2, + 0xf6,0x84,0xbf,0x82,0x6c,0x14,0x63,0x14,0x38,0xf2,0x28,0xe3,0x30,0xf0,0x9a,0x4f, + 0xc6,0x42,0xae,0x7b,0xb1,0xed,0xf3,0xb5,0xfe,0xff,0x20,0xb9,0xee,0x3c,0x92,0xb9, + 0x8c,0x97,0x6f,0x73,0x89,0xef,0xc4,0xeb,0x54,0xb6,0xe8,0xd7,0x83,0xec,0xaa,0x3b, + 0xa4,0x4b,0xc7,0x64,0x61,0x9f,0x14,0xe7,0xa5,0xb9,0x60,0x0a,0xad,0x21,0x27,0xd5, + 0x51,0xc2,0x5a,0xe7,0x2c,0x0c,0x27,0xa7,0xda,0xeb,0xe0,0x0a,0x2f,0x82,0x62,0x93, + 0x7b,0xc1,0xfb,0x4f,0x62,0x59,0x41,0xf5,0x7f,0x5b,0x5b,0x4c,0x74,0x0d,0x47,0x41, + 0xb9,0x70,0xa5,0xa0,0x4f,0xa1,0x2c,0x4c,0x66,0xe3,0x09,0xe3,0xda,0xd1,0x2f,0x93, + 0x23,0xe7,0x74,0x2e,0xee,0x3c,0x65,0x8f,0xcb,0x1f,0xfa,0xe4,0xed,0x96,0xda,0x39, + 0xea,0xb2,0x35,0xcd,0x39,0x45,0x8e,0xba,0x62,0x77,0xe5,0x2f,0xf9,0x14,0x18,0xbd, + 0x0f,0x4a,0xc1,0x33,0xd7,0x1c,0x74,0xae,0xcf,0xef,0x01,0xa8,0x3d,0x13,0x26,0x72, + 0xc2,0xb4,0x23,0x8f,0xb5,0x27,0xdd,0x99,0xb9,0x1a,0x9a,0x9d,0x54,0x12,0x82,0x06, + 0x01,0x08,0xc1,0x88,0xd4,0x52,0x00,0xf9,0x48,0xce,0xb1,0x5b,0x5f,0x5d,0x33,0xbe, + 0xd6,0xaf,0xaf,0x25,0x1b,0x36,0xf6,0x94,0x47,0xa4,0x9b,0x94,0x63,0x59,0xcd,0x28, + 0x57,0x04,0x10,0x43,0x9f,0x3a,0x65,0xe0,0xea,0x4c,0xaf,0x32,0xe4,0x73,0xa2,0x50, + 0xec,0xf6,0x82,0xc9,0x0d,0xa7,0xba,0x11,0x3c,0x24,0x27,0x0c,0x86,0x0d,0xf8,0xf4, + 0x96,0x6d,0x79,0x2b,0x4d,0xa8,0x71,0x99,0x96,0xc3,0x41,0x5b,0xd5,0xba,0x44,0xff, + 0xba,0xd9,0x78,0xb6,0x63,0x0a,0x89,0x57,0x1c,0xcb,0xdf,0x6f,0x18,0xc7,0x8c,0xa7, + 0x72,0xc8,0x62,0x44,0x57,0xa6,0x57,0x28,0x9f,0x30,0xc7,0x06,0xff,0x82,0xea,0xc9, + 0xcc,0x85,0xb8,0xfd,0xe0,0x8c,0x06,0x17,0xcd,0xe8,0x4c,0x2c,0x00,0xf6,0x67,0xe8, + 0x1c,0x9a,0x5a,0xda,0x28,0x71,0xb5,0xb6,0x32,0x2e,0x95,0xd8,0x03,0x3f,0x52,0x7b, + 0x60,0xeb,0x96,0x2d,0x7b,0x7a,0x8d,0x17,0xfa,0xa8,0xab,0x56,0xee,0x80,0x4e,0xd5, + 0x6b,0x39,0xc1,0x22,0xac,0x2f,0xb6,0x99,0xa0,0x1e,0x16,0x0c,0x32,0x7e,0xbf,0x41, + 0x8c,0x76,0xa4,0x76,0x4f,0xda,0x01,0x95,0x48,0xb1,0x96,0xc0,0xae,0xc0,0xcb,0x36, + 0x84,0x2b,0x98,0xda,0xbf,0xd4,0x1e,0x6d,0x21,0x06,0x9c,0xfb,0x8c,0x16,0xeb,0xe1, + 0x8c,0xf4,0xc7,0xdc,0x0e,0x4f,0xcf,0xb7,0xcc,0xf5,0xa9,0x17,0x78,0x22,0x9d,0x1b, + 0xfd,0x5e,0xcc,0x47,0xc3,0x17,0x1b,0xff,0x7f,0x1d,0xfe,0xbd,0xf6,0xd7,0xea,0x01, + 0x00, }; const uint8_t WEBCONFIG_HTML_SUCCESS[] PROGMEM = { diff --git a/src/helpers/esp32/WebConfigServer.cpp b/src/helpers/esp32/WebConfigServer.cpp index b8c1765ac..16991e63f 100644 --- a/src/helpers/esp32/WebConfigServer.cpp +++ b/src/helpers/esp32/WebConfigServer.cpp @@ -45,6 +45,7 @@ static_assert(sizeof(WEBCONFIG_AP_PREFIX) <= 28, #include "helpers/esp32/WiFiRadioPolicy.h" #include "helpers/esp32/WiFiAccessPointPolicy.h" #include "helpers/esp32/WiFiStationPolicy.h" +#include "helpers/esp32/ManagementPassword.h" // ESPAsyncWebServer closes every ordinary response, so splitting the UI into // many HTTP requests exhausts a lossy link's TCP/WiFi resources. Its ordinary @@ -805,23 +806,22 @@ static bool setupAccessPointStarted() { #endif } -static bool setupAccessPointReady(const char* ssid, int channel) { +static bool setupAccessPointReady(const char* ssid, int channel, const char* password) { wifi_mode_t mode = WIFI_MODE_NULL; wifi_config_t config = {}; uint8_t protocol = 0; const size_t ssid_len = strlen(ssid); -#ifdef WEBCONFIG_AP_PASSWORD - const wifi_auth_mode_t auth = WEBCONFIG_AP_PASSWORD[0] + const wifi_auth_mode_t auth = password && password[0] ? WIFI_AUTH_WPA2_PSK : WIFI_AUTH_OPEN; -#else - const wifi_auth_mode_t auth = WIFI_AUTH_OPEN; -#endif return setupAccessPointStarted() && esp_wifi_get_mode(&mode) == ESP_OK && (mode & WIFI_MODE_AP) && esp_wifi_get_config(WIFI_IF_AP, &config) == ESP_OK && config.ap.ssid_len == ssid_len && memcmp(config.ap.ssid, ssid, ssid_len) == 0 && config.ap.ssid_hidden == 0 && config.ap.authmode == auth + && (!password || !password[0] + || strncmp(reinterpret_cast(config.ap.password), password, + sizeof(config.ap.password)) == 0) && config.ap.channel == channel && esp_wifi_get_protocol(WIFI_IF_AP, &protocol) == ESP_OK && protocol == mesh::wifi::kAccessPointProtocolMask @@ -856,6 +856,14 @@ bool WebConfigServer::startSetupMode(char reply[]) { strcpy(reply, "Err: webconfig busy"); return false; } + initializeManagementPassword(); + mesh::esp32::managementPassword::Snapshot credential; + if (!mesh::esp32::managementPassword::snapshot(credential)) { + strcpy(reply, "Err: administrator credentials unavailable"); + return false; + } + const char* ap_password = mesh::esp32::managementPassword::apPasswordEligible( + credential.password) ? credential.password : nullptr; // Publish the foreground owner before changing interfaces. The background // worker must not power down the station underneath this AP startup. requestNetworkAccess(); @@ -896,11 +904,7 @@ bool WebConfigServer::startSetupMode(char reply[]) { } const bool configured = scan_prepared && station_ok && WiFi.softAPConfig(ap_ip, ap_ip, ap_mask); -#ifdef WEBCONFIG_AP_PASSWORD - ap_ok = configured && WiFi.softAP(_ap_ssid, WEBCONFIG_AP_PASSWORD, ap_channel); -#else - ap_ok = configured && WiFi.softAP(_ap_ssid, nullptr, ap_channel); -#endif + ap_ok = configured && WiFi.softAP(_ap_ssid, ap_password, ap_channel); if (ap_ok) { // ESP-NOW can leave the persistent AP protocol mask with the proprietary // LR bit set. The driver then reports a healthy SoftAP, but ordinary @@ -912,7 +916,7 @@ bool WebConfigServer::startSetupMode(char reply[]) { if (ap_protocol_result == ESP_OK) { const uint32_t start_started = millis(); do { - ap_ok = setupAccessPointReady(_ap_ssid, ap_channel); + ap_ok = setupAccessPointReady(_ap_ssid, ap_channel, ap_password); if (!ap_ok) delay(20); } while (!ap_ok && millis() - start_started < 300); } @@ -941,18 +945,22 @@ bool WebConfigServer::startSetupMode(char reply[]) { _dns->start(53, "*", ip); // captive portal: every name resolves to us _mode = MODE_SETUP; - if (!promote_lan) createServer(); _was_setup_ap = true; - NodeSnapshot node = {}; - _cb->getNodeSnapshot(node); - _initial_setup = _wifi_ssid[0] == 0 && node.admin_password[0] != 0; + _initial_setup = _wifi_ssid[0] == 0 && credential.password[0] != 0; + _setup_provisioning_privilege = _initial_setup && ap_password != nullptr; + _ap_auth_generation = credential.generation; + _ap_rekey_generation = _ap_rekey_after = _ap_rekey_deadline = 0; _setup_started_at = millis(); _last_activity = _setup_started_at; + if (!promote_lan) createServer(); refreshNetworkPowerHold(_setup_started_at); // Keep the pre-AP scan results for the picker. Only an explicit browser // rescan needs to leave the AP's home channel after clients have joined. - sprintf(reply, "WebConfig AP started: join '%s' then open http://%s/", _ap_ssid, ip.toString().c_str()); + snprintf(reply, 160, "WebConfig AP: join '%s', http://%s/ (%s)", _ap_ssid, + ip.toString().c_str(), ap_password ? "WiFi: admin password" + : credential.password[0] ? "open WiFi; admin login required" + : "open WiFi; no admin password"); return true; } @@ -965,6 +973,7 @@ bool WebConfigServer::startLanMode(char reply[]) { strcpy(reply, "Err: WiFi not connected"); return false; } + initializeManagementPassword(); _mode = MODE_LAN; _setup_started_at = 0; _wifi_reconnect_tracker.noteConnected(); @@ -1121,6 +1130,8 @@ void WebConfigServer::finalizeTeardown() { _was_setup_ap = false; _keep_wifi_on_stop = false; _initial_setup = false; + _setup_provisioning_privilege = false; + _ap_auth_generation = _ap_rekey_generation = _ap_rekey_after = _ap_rekey_deadline = 0; _setup_started_at = 0; _stopping = false; _stop_warn_at = 0; @@ -1138,7 +1149,14 @@ void WebConfigServer::finalizeTeardown() { _setup_wifi_handoff_ip[0] = 0; _batch_kind = BATCH_CONFIG; _admin_pwd_set = false; - _session_token[0] = 0; + { + WCLock lock(_mux); + clearSessionLocked(); + memset(_batch_owner_token, 0, sizeof(_batch_owner_token)); + _batch_reauth_required = false; + _batch_reauth_delivered = false; + _batch_reauth_until = 0; + } _stats_json[0] = 0; _board_cmds = 0; _board_cmds_probed = false; @@ -1161,8 +1179,48 @@ void WebConfigServer::probeBoardCommands() { _board_cmds_probed = true; } +void WebConfigServer::serviceSetupPassword(uint32_t now) { + if (_mode != MODE_SETUP || _stopping) return; + mesh::esp32::managementPassword::Snapshot credential; + if (!mesh::esp32::managementPassword::snapshot(credential)) return; + { + WCLock lock(_mux); + if (credential.generation == _ap_auth_generation || _reboot_at) return; + if (_ap_rekey_generation != credential.generation) { + _ap_rekey_generation = credential.generation; + _ap_rekey_after = WebConfigBatch::scheduleAt(now, 3000); + _ap_rekey_deadline = WebConfigBatch::scheduleAt(now, 30000); + } + if (_batch_state == BATCH_PENDING || handlerRefCount() != 0) return; + if (_batch_reauth_required && !_batch_reauth_delivered + && !WebConfigBatch::deadlineReached(now, _ap_rekey_deadline)) return; + if (!WebConfigBatch::deadlineReached(now, _ap_rekey_after)) return; + } + // Reserve outside the password callback: it already owns a ChangeGuard. + // AP restart and an accepted OTA upload must never race one another. + mesh::esp32::managementPassword::ChangeGuard rekey; + if (!rekey.acquired() + || !mesh::esp32::managementPassword::snapshot(credential)) return; + const char* password = mesh::esp32::managementPassword::apPasswordEligible( + credential.password) ? credential.password : nullptr; + const bool ready = mesh::wifi::startAccessPoint(_ap_ssid, true, password); + WCLock lock(_mux); + if (ready) { + _ap_auth_generation = credential.generation; + _ap_rekey_generation = _ap_rekey_after = _ap_rekey_deadline = 0; + if (!password) _setup_provisioning_privilege = false; + } else { + // An early SDK failure can leave the previous AP and its obsolete key live. + // Fail closed while retaining STA/the shared radio for the bounded retry. + WiFi.softAPdisconnect(true); + _ap_rekey_after = WebConfigBatch::scheduleAt(now, 5000); + mesh::usbDebugPort().println("WebConfig: AP password restart failed; retrying"); + } +} + void WebConfigServer::tick(uint32_t now) { refreshNetworkPowerHold(now); + serviceSetupPassword(now); if (_stopping) { uint32_t refs = handlerRefCount(); switch (WebConfigBatch::stopStep(refs, _stop_warned, _stop_warn_at, now)) { @@ -1394,6 +1452,10 @@ void WebConfigServer::tick(uint32_t now) { void WebConfigServer::finishBatch(uint32_t now) { WCLock lock(_mux); _batch_state = BATCH_DONE; + if (_batch_reauth_required) { + _batch_reauth_until = WebConfigBatch::scheduleAt( + now, WebConfigBatch::kReauthReceiptMs); + } const uint32_t reboot_at = WebConfigBatch::finishRebootAt(_batch_reboot, _batch_all_ok, now); if (reboot_at != 0) { @@ -1461,14 +1523,34 @@ void WebConfigServer::drainBatch(uint32_t now) { // clients (iPhones especially) to drop off mid-save. if (_batch_next == 0) { WCLock prefs_lock(_mux); + mesh::esp32::managementPassword::Snapshot credential; + if (!mesh::esp32::managementPassword::snapshot(credential) + || credential.generation != _batch_auth_generation) { + cancelStaleBatchLocked(now); + return; + } _cb->onConfigBatchStart(); + _batch_started = true; } else if (WebConfigBatch::drainMustWait(_batch_next, _batch_count, now, _batch_last_cmd)) { return; // let the WiFi task breathe between flash writes } if (_batch_next < _batch_count) { WCLock prefs_lock(_mux); + mesh::esp32::managementPassword::Snapshot credential; + if (!mesh::esp32::managementPassword::snapshot(credential) + || credential.generation != _batch_auth_generation) { + cancelStaleBatchLocked(now); + return; + } BatchEntry& e = _batch[_batch_next++]; + const bool password_command = _batch_kind == BATCH_CLI + ? wcCliEchoesSecret(e.cmd) : wcIsAdminPasswordKey(e.key); + char requested_password[16] = {}; + if (password_command) { + strncpy(requested_password, e.cmd + strlen("password "), + sizeof(requested_password) - 1); + } e.reply[0] = 0; uint32_t t0 = millis(); if (_batch_kind == BATCH_CLI) { @@ -1529,9 +1611,14 @@ void WebConfigServer::drainBatch(uint32_t now) { } } else { _cb->execCommand(e.cmd, e.reply); - // The CLI password command echoes the new secret. Never return it to a - // browser client, especially over the open setup AP. - if (admin_pwd) strcpy(e.reply, "OK"); + // Mask only a confirmed save. An error must remain visible and prevent + // the batch from rebooting into settings that may not have persisted. + if (admin_pwd && WebConfigBatch::cliPasswordChanged(e.reply)) { + strcpy(e.reply, "OK"); + _admin_pwd_set = true; + } else if (admin_pwd && e.reply[0] == 0) { + strcpy(e.reply, "Error: password save was not confirmed"); + } // Keep the response snapshot current after MQTT/companion CLI handlers // persist a WiFi field. The browser can then soft-reload without a stale // value even before the requested reboot happens. @@ -1549,6 +1636,27 @@ void WebConfigServer::drainBatch(uint32_t now) { _batch_all_ok = WebConfigBatch::nextAllOk( _batch_all_ok, strncmp(e.reply, "OK", 2) == 0); } + mesh::esp32::managementPassword::Snapshot committed; + const bool have_committed = mesh::esp32::managementPassword::snapshot(committed); + if (!have_committed + || committed.generation != _batch_auth_generation) { + if (have_committed && password_command && WebConfigBatch::cliPasswordChanged(e.reply) + && fixedTimeEquals(committed.password, requested_password, + sizeof(committed.password))) { + // This accepted batch changed its own credential. Keep only a scoped + // receipt capability; the old cookie no longer authorizes any API. + _batch_auth_generation = committed.generation; + _batch_reauth_required = true; + _batch_reauth_until = WebConfigBatch::scheduleAt( + millis(), WebConfigBatch::kReauthReceiptMs); + clearSessionLocked(); + } else { + memset(requested_password, 0, sizeof(requested_password)); + cancelStaleBatchLocked(now); + return; + } + } + memset(requested_password, 0, sizeof(requested_password)); _batch_last_cmd = millis(); // Config entries are named by their (non-secret) key. A CLI command is // deliberately not logged: the operator can see what they typed, and a @@ -1588,6 +1696,7 @@ void WebConfigServer::drainBatch(uint32_t now) { { WCLock prefs_lock(_mux); _cb->onConfigBatchEnd(); + _batch_started = false; } bool wifi_credentials_changed = false; @@ -1866,38 +1975,112 @@ void WebConfigServer::collectBody(AsyncWebServerRequest* req, uint8_t* data, siz if (req->_tempObject) memcpy((uint8_t*)req->_tempObject + index, data, len); } -bool WebConfigServer::checkAuth(AsyncWebServerRequest* req) { - _last_activity = millis(); +void WebConfigServer::initializeManagementPassword() { + // Called only by loop-owned startup, after preferences have loaded. HTTP + // authentication must never read a setter's temporary, uncommitted RAM. + mesh::esp32::managementPassword::Snapshot current; + if (mesh::esp32::managementPassword::snapshot(current)) return; + NodeSnapshot node = {}; + _cb->getNodeSnapshot(node); + mesh::esp32::managementPassword::initialize(node.admin_password); +} + +void WebConfigServer::clearSessionLocked() { + memset(_session_token, 0, sizeof(_session_token)); + _session_generation = 0; + _session_last_seen = 0; +} + +static bool webConfigCookieMatches(AsyncWebServerRequest* req, const char* expected) { + if (!req || !expected || !expected[0] || !req->hasHeader("Cookie")) return false; + const String& cookies = req->getHeader("Cookie")->value(); + const int idx = cookies.indexOf("wcs="); + if (idx < 0 || (int)cookies.length() < idx + 4 + 32) return false; + const String token = cookies.substring(idx + 4, idx + 4 + 32); + return fixedTimeEquals(token.c_str(), expected, 32); +} + +bool WebConfigServer::checkAuthLocked(AsyncWebServerRequest* req, uint32_t* generation) { if (_mode == MODE_SETUP) { // AP+STA is used for scans and saved-network recovery. A first-time setup // may provision a new password from the physical AP. Losing access to a // saved WiFi network must not grant that same password-reset privilege. if (!req || !req->client() || req->client()->localIP() != WiFi.softAPIP()) return false; - if (_initial_setup || _wifi_ssid[0] == 0) { noteNetworkActivity(); return true; } } else if (_mode != MODE_LAN) { return false; } - NodeSnapshot node = {}; - { - WCLock lock(_mux); - _cb->getNodeSnapshot(node); + mesh::esp32::managementPassword::Snapshot current; + if (!mesh::esp32::managementPassword::snapshot(current)) return false; + if (generation) *generation = current.generation; + if (_session_generation != current.generation) clearSessionLocked(); + if ((_mode == MODE_SETUP && _setup_provisioning_privilege + && _ap_auth_generation == current.generation + && mesh::esp32::managementPassword::apPasswordEligible(current.password)) + || current.password[0] == 0) { + noteNetworkActivity(); + return true; } - if (node.admin_password[0] == 0) { noteNetworkActivity(); return true; } - if (_session_token[0] == 0) return false; - if (!req->hasHeader("Cookie")) return false; - const String& cookies = req->getHeader("Cookie")->value(); - int idx = cookies.indexOf("wcs="); - if (idx < 0 || (int)cookies.length() < idx + 4 + 32) return false; - String token = cookies.substring(idx + 4, idx + 4 + 32); - uint32_t now = millis(); - if ((uint32_t)(now - _session_last_seen) > WEBCONFIG_SESSION_TTL_MS) return false; - if (!fixedTimeEquals(token.c_str(), _session_token, 32)) return false; + const uint32_t now = millis(); + if ((uint32_t)(now - _session_last_seen) > WEBCONFIG_SESSION_TTL_MS) { + clearSessionLocked(); + return false; + } + if (!webConfigCookieMatches(req, _session_token)) return false; _session_last_seen = now; // sliding expiry noteNetworkActivity(); return true; } +bool WebConfigServer::checkAuth(AsyncWebServerRequest* req) { + _last_activity = millis(); + WCLock lock(_mux); + return checkAuthLocked(req); +} + +void WebConfigServer::beginBatchAuthorizationLocked(uint32_t generation) { + _batch_auth_generation = generation; + memcpy(_batch_owner_token, _session_token, sizeof(_batch_owner_token)); + _batch_reauth_required = false; + _batch_reauth_delivered = false; + _batch_reauth_until = 0; + _batch_started = false; +} + +void WebConfigServer::cancelStaleBatchLocked(uint32_t now) { + while (_batch_next < _batch_count) { + strcpy(_batch[_batch_next++].reply, + "Error: administrator password changed; sign in again"); + } + _batch_all_ok = false; + _batch_reauth_required = false; + _batch_reauth_delivered = false; + _batch_reauth_until = 0; + memset(_batch_owner_token, 0, sizeof(_batch_owner_token)); + if (_standalone_wifi_dirty) { + _standalone_wifi_dirty = false; + reloadStandaloneWiFi(); + } + if (_batch_started) _cb->onConfigBatchEnd(); + _batch_started = false; + _batch_state = BATCH_DONE; + (void)now; +} + +bool WebConfigServer::resultReceiptAllowedLocked(AsyncWebServerRequest* req, + const char* reqid, BatchKind kind, uint32_t now) { + if (_mode != MODE_SETUP && _mode != MODE_LAN) return false; + if (!_batch_reauth_required || _batch_kind != kind || !reqid + || strcmp(reqid, _batch_reqid) != 0 || !_batch_reauth_until + || WebConfigBatch::deadlineReached(now, _batch_reauth_until) + || !webConfigCookieMatches(req, _batch_owner_token)) return false; + if (_mode == MODE_SETUP && (!req->client() + || req->client()->localIP() != WiFi.softAPIP())) return false; + mesh::esp32::managementPassword::Snapshot current; + return mesh::esp32::managementPassword::snapshot(current) + && current.generation == _batch_auth_generation; +} + // --------------------------------------------------------------------------- // Handlers (async_tcp task - no CLI/prefs writes, no radio access) // --------------------------------------------------------------------------- @@ -1969,12 +2152,29 @@ void WebConfigServer::handleStatus(AsyncWebServerRequest* req) { } const bool has_mqtt = _mqtt_prefs != NULL; - DynamicJsonDocument doc(896); + DynamicJsonDocument doc(1024); doc["mode"] = (_mode == MODE_SETUP) ? "setup" : "lan"; doc["auth"] = authed; doc["needs_setup"] = (_wifi_ssid[0] == 0); doc["needs_password"] = _initial_setup; - doc["password_supported"] = node.admin_password[0] != 0; + mesh::esp32::managementPassword::Snapshot credential; + const bool have_credential = mesh::esp32::managementPassword::snapshot(credential); + doc["password_supported"] = have_credential && credential.password[0] != 0; + if (_mode == MODE_SETUP) { + char joined_password[65] = {}; + const bool known = mesh::wifi::accessPointJoinPassword( + _ap_ssid, joined_password, sizeof(joined_password)); + doc["ap_security"] = !known ? "unavailable" : joined_password[0] + ? "admin_password" : have_credential && credential.password[0] + ? "open_admin_login" : "open_no_password"; + memset(joined_password, 0, sizeof(joined_password)); + WCLock lock(_mux); + doc["ap_restart_pending"] = _ap_rekey_generation != 0 && !_reboot_at; + if (_ap_rekey_generation && !_reboot_at && _ap_rekey_after) { + doc["ap_restart_in_ms"] = WebConfigBatch::deadlineReached(millis(), _ap_rekey_after) + ? 1u : _ap_rekey_after - millis(); + } + } doc["name"] = (const char*)node.name; char node_id[17]; for (int i = 0; i < 8; i++) sprintf(&node_id[i * 2], "%02x", _pub_key[i]); @@ -2050,18 +2250,17 @@ void WebConfigServer::handleLogin(AsyncWebServerRequest* req) { req->send(401, "application/json", "{\"error\":\"auth\"}"); return; } - if (_initial_setup || _wifi_ssid[0] == 0) { - noteNetworkActivity(); - req->send(200, "application/json", "{\"ok\":true}"); - return; - } } - NodeSnapshot node = {}; - { - WCLock lock(_mux); - _cb->getNodeSnapshot(node); + WCLock lock(_mux); + mesh::esp32::managementPassword::Snapshot credential; + if (!mesh::esp32::managementPassword::snapshot(credential)) { + req->send(503, "application/json", "{\"error\":\"credentials unavailable\"}"); + return; } - if (node.admin_password[0] == 0) { + if (credential.password[0] == 0 || (_mode == MODE_SETUP + && _setup_provisioning_privilege + && _ap_auth_generation == credential.generation + && mesh::esp32::managementPassword::apPasswordEligible(credential.password))) { noteNetworkActivity(); req->send(200, "application/json", "{\"ok\":true}"); return; @@ -2086,14 +2285,26 @@ void WebConfigServer::handleLogin(AsyncWebServerRequest* req) { return; } const char* pwd = doc["password"] | ""; - if (!fixedTimeEquals(pwd, node.admin_password, sizeof(node.admin_password))) { + // Parsing can yield to the mesh loop. Verify the current committed mirror + // again before publishing a token, not a pre-parse preference snapshot. + if (!mesh::esp32::managementPassword::snapshot(credential) + || !fixedTimeEquals(pwd, credential.password, sizeof(credential.password))) { _login_throttle.noteFailure(client, now); req->send(401, "application/json", "{\"error\":\"wrong password\"}"); return; } _login_throttle.noteSuccess(client); - for (int i = 0; i < 4; i++) sprintf(&_session_token[i * 8], "%08lx", (unsigned long)esp_random()); + char token[33] = {}; + for (int i = 0; i < 4; i++) sprintf(&token[i * 8], "%08lx", (unsigned long)esp_random()); + mesh::esp32::managementPassword::Snapshot latest; + if (!mesh::esp32::managementPassword::snapshot(latest) + || latest.generation != credential.generation) { + req->send(401, "application/json", "{\"error\":\"password changed; sign in again\"}"); + return; + } + memcpy(_session_token, token, sizeof(_session_token)); _session_last_seen = now; + _session_generation = credential.generation; noteNetworkActivity(); AsyncWebServerResponse* res = req->beginResponse(200, "application/json", "{\"ok\":true}"); @@ -2105,8 +2316,9 @@ void WebConfigServer::handleLogin(AsyncWebServerRequest* req) { void WebConfigServer::handleLogout(AsyncWebServerRequest* req) { if (_mode == MODE_OFF) { req->send(503); return; } - if (!checkAuth(req)) { req->send(401, "application/json", "{\"error\":\"auth\"}"); return; } - _session_token[0] = 0; + WCLock lock(_mux); + if (!checkAuthLocked(req)) { req->send(401, "application/json", "{\"error\":\"auth\"}"); return; } + clearSessionLocked(); AsyncWebServerResponse* res = req->beginResponse(200, "application/json", "{\"ok\":true}"); res->addHeader("Set-Cookie", "wcs=; Max-Age=0; Path=/"); req->send(res); @@ -2262,6 +2474,11 @@ void WebConfigServer::handleConfigPost(AsyncWebServerRequest* req) { } WCLock lock(_mux); + uint32_t auth_generation = 0; + if (!checkAuthLocked(req, &auth_generation)) { + req->send(401, "application/json", "{\"error\":\"auth\"}"); + return; + } const WebConfigBatch::State bstate = toSpecState(_batch_state); const bool reqid_matches = _batch_kind == BATCH_CONFIG && strcmp(reqid, _batch_reqid) == 0; @@ -2394,6 +2611,7 @@ void WebConfigServer::handleConfigPost(AsyncWebServerRequest* req) { _batch_reboot = reboot_after; _batch_reboot_armed = false; _batch_all_ok = true; + beginBatchAuthorizationLocked(auth_generation); strncpy(_batch_reqid, reqid, sizeof(_batch_reqid) - 1); _batch_reqid[sizeof(_batch_reqid) - 1] = 0; _standalone_wifi_dirty = false; @@ -2423,11 +2641,6 @@ void WebConfigServer::handleConfigResult(AsyncWebServerRequest* req) { req->send(503); return; } - if (!checkAuth(req)) { - mesh::usbDebugPort().println("WC: result read -> 401"); - req->send(401, "application/json", "{\"error\":\"auth\"}"); - return; - } if (!req->hasParam("reqid")) { req->send(400, "application/json", "{\"error\":\"bad reqid\"}"); return; @@ -2444,6 +2657,12 @@ void WebConfigServer::handleConfigResult(AsyncWebServerRequest* req) { "WC: result entry mode=%d state=%d\n", (int)_mode, (int)_batch_state); WCLock lock(_mux); + const bool authenticated = checkAuthLocked(req); + if (!authenticated && !resultReceiptAllowedLocked( + req, requested_reqid.c_str(), BATCH_CONFIG, millis())) { + req->send(401, "application/json", "{\"error\":\"auth\"}"); + return; + } // A CLI sequence occupying the shared slot is not a config save, whatever the // reqid says: its entries have no `key` and its results belong to the // terminal's reader. Treat it as unknown here (and vice versa there). @@ -2469,6 +2688,7 @@ void WebConfigServer::handleConfigResult(AsyncWebServerRequest* req) { StaticJsonDocument<96> pending; pending["state"] = "pending"; pending["reqid"] = (const char*)_batch_reqid; + pending["reauth_required"] = _batch_reauth_required && !authenticated; String out; serializeJson(pending, out); req->send(200, "application/json", out); @@ -2483,6 +2703,12 @@ void WebConfigServer::handleConfigResult(AsyncWebServerRequest* req) { doc["reboot"] = WebConfigBatch::doneReportsReboot(_batch_reboot, _batch_all_ok); doc["all_ok"] = _batch_all_ok; + doc["reauth_required"] = _batch_reauth_required && !authenticated; + if (_batch_reauth_required && !_batch_reauth_delivered) { + _batch_reauth_delivered = true; + if (_ap_rekey_generation) + _ap_rekey_after = WebConfigBatch::scheduleAt(millis(), 3000); + } doc["reqid"] = (const char*)_batch_reqid; if (_setup_wifi_handoff_ip[0]) { doc["wifi_ip"] = (const char*)_setup_wifi_handoff_ip; @@ -2491,7 +2717,9 @@ void WebConfigServer::handleConfigResult(AsyncWebServerRequest* req) { for (int i = 0; i < _batch_count; i++) { JsonObject r = results.createNestedObject(); r["key"] = (const char*)_batch[i].key; - r["reply"] = (const char*)_batch[i].reply; + r["reply"] = authenticated ? (const char*)_batch[i].reply + : WebConfigBatch::cliWriteSucceeded(_batch[i].reply) ? "OK" + : "Error: setting failed; sign in again for details"; } // State stays DONE (re-readable) until the next POST claims the slot. const uint32_t result_now = millis(); @@ -2549,6 +2777,12 @@ void WebConfigServer::closeTerminal() { void WebConfigServer::serviceTerminal(uint32_t now) { WCLock lock(_mux); if (!_terminal) return; + mesh::esp32::managementPassword::Snapshot credential; + if (!mesh::esp32::managementPassword::snapshot(credential) + || credential.generation != _terminal_auth_generation) { + closeTerminal(); + return; + } if (now - _terminal->last_seen > (_terminal->closed ? 5000UL : 60000UL)) { closeTerminal(); return; @@ -2644,6 +2878,15 @@ void WebConfigServer::handleTerminalPost(AsyncWebServerRequest* req) { return; } WCLock lock(_mux); + uint32_t auth_generation = 0; + if (!checkAuthLocked(req, &auth_generation)) { + req->send(401, "application/json", "{\"error\":\"auth\"}"); + return; + } + if (_terminal && _terminal_auth_generation != auth_generation) { + req->send(409, "application/json", "{\"error\":\"terminal session expired after password change\"}"); + return; + } if (_terminal && strcmp(session, _terminal->session) != 0) { if (!_terminal->closed || _terminal->attached) { req->send(409, "application/json", "{\"error\":\"another browser owns the terminal\"}"); @@ -2666,6 +2909,7 @@ void WebConfigServer::handleTerminalPost(AsyncWebServerRequest* req) { return; } strlcpy(_terminal->session, session, sizeof(_terminal->session)); + _terminal_auth_generation = auth_generation; } if (_terminal->closed) { req->send(409, "application/json", "{\"error\":\"terminal session closed\"}"); @@ -2757,6 +3001,11 @@ void WebConfigServer::handleCliPost(AsyncWebServerRequest* req) { } WCLock lock(_mux); + uint32_t auth_generation = 0; + if (!checkAuthLocked(req, &auth_generation)) { + req->send(401, "application/json", "{\"error\":\"auth\"}"); + return; + } // Replay/Busy exactly as a config save classifies them: a repeated POST is // acknowledged rather than executed twice, and a different sequence while one // is still draining is refused. @@ -2856,6 +3105,7 @@ void WebConfigServer::handleCliPost(AsyncWebServerRequest* req) { _batch_reboot = defer_reboot; _batch_reboot_armed = false; _batch_all_ok = true; + beginBatchAuthorizationLocked(auth_generation); strncpy(_batch_reqid, reqid, sizeof(_batch_reqid) - 1); _batch_reqid[sizeof(_batch_reqid) - 1] = 0; _batch_state = BATCH_PENDING; // tick() picks it up on the loop task @@ -2888,7 +3138,6 @@ void WebConfigServer::handleCliResult(AsyncWebServerRequest* req) { "{\"error\":\"terminal disabled; set wifi.cli on\"}"); return; } - if (!checkAuth(req)) { req->send(401, "application/json", "{\"error\":\"auth\"}"); return; } if (!req->hasParam("reqid")) { req->send(400, "application/json", "{\"error\":\"bad reqid\"}"); return; @@ -2905,6 +3154,13 @@ void WebConfigServer::handleCliResult(AsyncWebServerRequest* req) { } WCLock lock(_mux); + const bool authenticated = checkAuthLocked(req); + const bool receipt_only = !authenticated && resultReceiptAllowedLocked( + req, requested_reqid.c_str(), BATCH_CLI, millis()); + if (!authenticated && !receipt_only) { + req->send(401, "application/json", "{\"error\":\"auth\"}"); + return; + } // A config save occupying the slot is not this client's sequence, whatever // the reqid says; treat it as unknown rather than serving `set` results // through the terminal's reader. @@ -2937,15 +3193,27 @@ void WebConfigServer::handleCliResult(AsyncWebServerRequest* req) { doc["reqid"] = (const char*)_batch_reqid; doc["total"] = _batch_count; doc["from"] = from; + doc["reauth_required"] = _batch_reauth_required && !authenticated; JsonArray results = doc.createNestedArray("results"); for (int i = from; i < from + page; i++) { JsonObject r = results.createNestedObject(); // The command is deliberately NOT echoed: it may hold a password or token, // and the client already has the sequence it sent. It matches by index. - r["ok"] = !WebConfigBatch::cliReplyIsFailure(_batch[i].reply); - r["reply"] = (const char*)_batch[i].reply; + const bool failed = WebConfigBatch::cliReplyIsFailure(_batch[i].reply); + r["ok"] = !failed; + // Receipt authority is deliberately weaker than an authenticated terminal. + // Do not rely on a growing list of secret getters or echoing commands. + r["reply"] = !receipt_only ? (const char*)_batch[i].reply + : failed ? "Error: command failed; sign in again for details" + : WebConfigBatch::cliWriteSucceeded(_batch[i].reply) ? "OK" + : "Sign in again to read this result"; } if (final_read) { + if (_batch_reauth_required && !_batch_reauth_delivered) { + _batch_reauth_delivered = true; + if (_ap_rekey_generation) + _ap_rekey_after = WebConfigBatch::scheduleAt(millis(), 3000); + } doc["all_ok"] = _batch_all_ok; const bool rebooting = WebConfigBatch::cliRebootAllowed(_batch_reboot, _batch_all_ok); doc["reboot"] = rebooting; diff --git a/src/helpers/esp32/WebConfigServer.h b/src/helpers/esp32/WebConfigServer.h index b16e370c1..bf966c8d9 100644 --- a/src/helpers/esp32/WebConfigServer.h +++ b/src/helpers/esp32/WebConfigServer.h @@ -5,18 +5,21 @@ // companion builds. The UI removes MQTT controls when no bridge is present. // // Two modes: -// - SETUP: open SoftAP + captive portal, raised automatically on first boot +// - SETUP: admin-password SoftAP + captive portal, raised on first boot // when no WiFi is configured (wifi_ssid empty), or manually via // `start webconfig ap`. A credential save joins in AP+STA mode, reports the // assigned LAN IP, then reboots; the AP auto-stops after an idle timeout. +// Legacy short/non-ASCII admin credentials use open WiFi plus HTTP login. // - LAN: bound to an existing or portal-owned STA connection. Infrastructure -// roles require the node admin password; companions use their trusted LAN. +// roles use the committed node admin password. Explicit legacy passwordless +// configurations retain their local no-password policy. // // Concurrency model: AsyncWebServer handlers run on the async_tcp task and // must never touch the CLI, prefs persistence, or the radio. Config writes // and browser-terminal commands are marshaled to tick() - called from // MyMesh::loop() on the Arduino loop task - and run through the existing CLI -// handlers there. Prefs-struct reads and request state are guarded by _mux. +// handlers there. Request state is guarded by _mux; authentication uses the +// separately published committed credential generation, never temporary prefs. // // The master switch and standalone WiFi credentials use independent NVS // namespaces, so role-specific prefs-file layouts remain untouched. @@ -317,6 +320,7 @@ private: bool _keep_wifi_on_stop = false; bool _was_setup_ap = false; bool _initial_setup = false; + bool _setup_provisioning_privilege = false; uint32_t _setup_started_at = 0; uint32_t _connect_deadline = 0; char _wifi_ssid[32] = {0}; @@ -329,6 +333,10 @@ private: // sends the password with the rest, so it never needed the memory. bool _admin_pwd_set = false; char _ap_ssid[33] = {0}; + uint32_t _ap_auth_generation = 0; + uint32_t _ap_rekey_generation = 0; + uint32_t _ap_rekey_after = 0; + uint32_t _ap_rekey_deadline = 0; WiFiReconnectPolicy::Tracker _wifi_reconnect_tracker; bool _retry_saved_wifi_in_setup = false; bool _setup_reconnect_in_progress = false; @@ -349,7 +357,13 @@ private: bool _batch_reboot = false; bool _batch_reboot_armed = false; bool _batch_all_ok = true; + bool _batch_started = false; char _batch_reqid[24] = {0}; + uint32_t _batch_auth_generation = 0; + char _batch_owner_token[33] = {0}; + bool _batch_reauth_required = false; + bool _batch_reauth_delivered = false; + uint32_t _batch_reauth_until = 0; bool _standalone_wifi_dirty = false; bool _setup_wifi_handoff_pending = false; uint32_t _setup_wifi_handoff_deadline = 0; @@ -358,9 +372,12 @@ private: WebTerminalStream* _terminal = NULL; mesh::RoomWebMailbox* _room_mailbox = NULL; - // LAN-mode session (single slot; new login evicts the old session) + // Browser login session, bound to the committed credential generation. + // One slot: a new login evicts the old session in LAN or recovery AP mode. char _session_token[33] = {0}; uint32_t _session_last_seen = 0; + uint32_t _session_generation = 0; + uint32_t _terminal_auth_generation = 0; WebConfigLoginThrottle::Tracker _login_throttle; // Once set (via /api/portal/exit), OS captive probes get native "success" @@ -401,9 +418,17 @@ private: void serviceRoom(uint32_t now); void closeTerminal(); void serviceSetupWiFiHandoff(uint32_t now); + void serviceSetupPassword(uint32_t now); void finishBatch(uint32_t now); void finalizeTeardown(); + void initializeManagementPassword(); + void clearSessionLocked(); bool checkAuth(AsyncWebServerRequest* req); + bool checkAuthLocked(AsyncWebServerRequest* req, uint32_t* generation = nullptr); + bool resultReceiptAllowedLocked(AsyncWebServerRequest* req, const char* reqid, + BatchKind kind, uint32_t now); + void beginBatchAuthorizationLocked(uint32_t generation); + void cancelStaleBatchLocked(uint32_t now); static void collectBody(AsyncWebServerRequest* req, uint8_t* data, size_t len, size_t index, size_t total); diff --git a/src/helpers/esp32/WiFiAccessPointPolicy.h b/src/helpers/esp32/WiFiAccessPointPolicy.h index 7585ad1d4..d3c522005 100644 --- a/src/helpers/esp32/WiFiAccessPointPolicy.h +++ b/src/helpers/esp32/WiFiAccessPointPolicy.h @@ -2,6 +2,7 @@ #include #include +#include #include namespace mesh { @@ -17,7 +18,7 @@ inline bool accessPointStarted() { // Arduino setters and a configured netif IP can outlive the AP_START event. // Read the live driver before telling an operator that the hotspot is ready. -inline bool openAccessPointReady(const char* ssid, int channel) { +inline bool accessPointReady(const char* ssid, int channel, const char* password) { wifi_mode_t mode = WIFI_MODE_NULL; wifi_config_t config = {}; uint8_t protocol = 0; @@ -27,13 +28,43 @@ inline bool openAccessPointReady(const char* ssid, int channel) { && esp_wifi_get_config(WIFI_IF_AP, &config) == ESP_OK && config.ap.ssid_len == length && memcmp(config.ap.ssid, ssid, length) == 0 - && config.ap.ssid_hidden == 0 && config.ap.authmode == WIFI_AUTH_OPEN + && config.ap.ssid_hidden == 0 + && config.ap.authmode == (password && password[0] ? WIFI_AUTH_WPA2_PSK : WIFI_AUTH_OPEN) + && (!password || !password[0] + || strncmp(reinterpret_cast(config.ap.password), password, + sizeof(config.ap.password)) == 0) && config.ap.channel == channel && esp_wifi_get_protocol(WIFI_IF_AP, &protocol) == ESP_OK && protocol == kAccessPointProtocolMask && static_cast(WiFi.softAPIP()) != 0; } +inline bool openAccessPointReady(const char* ssid, int channel) { + return accessPointReady(ssid, channel, nullptr); +} + +// Physical join QR codes must describe the AP that is actually running. A +// freshly saved admin password can precede its deferred AP rekey by 750ms. +inline bool accessPointJoinPassword(const char* ssid, char* output, size_t capacity) { + if (!output || !capacity) return false; + output[0] = 0; + if (!ssid || !ssid[0] || !accessPointStarted()) return false; + wifi_config_t config = {}; + const size_t ssid_length = strlen(ssid); + if (ssid_length > sizeof(config.ap.ssid)) return false; + if (esp_wifi_get_config(WIFI_IF_AP, &config) != ESP_OK + || config.ap.ssid_len != ssid_length + || memcmp(config.ap.ssid, ssid, config.ap.ssid_len) != 0) return false; + if (config.ap.authmode == WIFI_AUTH_OPEN) return true; + if (config.ap.authmode != WIFI_AUTH_WPA2_PSK) return false; + size_t length = 0; + while (length < sizeof(config.ap.password) && config.ap.password[length]) ++length; + if (length < 8 || length == sizeof(config.ap.password) || length >= capacity) return false; + memcpy(output, config.ap.password, length); + output[length] = 0; + return true; +} + inline bool finishAccessPointScan() { // A failed Arduino scan can still have an active SDK scanner. scanDelete() // only releases results; cancel that scanner before enabling AP beacons. @@ -58,12 +89,12 @@ inline bool scanBeforeAccessPoint() { return finishAccessPointScan(); } -inline bool startOpenAccessPoint(const char* ssid, bool reuse_existing) { +inline bool startAccessPoint(const char* ssid, bool reuse_existing, const char* password) { if (!accessPointCompatibleWithLongRange()) return false; const int channel = accessPointChannel(); // Repeated OTA commands retain joined clients when the AP is already live. if (reuse_existing && applyAccessPointProtocolMask() == ESP_OK - && openAccessPointReady(ssid, channel)) return true; + && accessPointReady(ssid, channel, password)) return true; const bool connected = WiFi.status() == WL_CONNECTED && static_cast(WiFi.localIP()) != 0; @@ -82,13 +113,13 @@ inline bool startOpenAccessPoint(const char* ssid, bool reuse_existing) { const IPAddress ip(192, 168, 4, 1); const IPAddress mask(255, 255, 255, 0); bool ready = WiFi.softAPConfig(ip, ip, mask) - && WiFi.softAP(ssid, nullptr, channel) + && WiFi.softAP(ssid, password, channel) && applyAccessPointProtocolMask() == ESP_OK; if (ready) { ready = false; const uint32_t started = millis(); do { - ready = openAccessPointReady(ssid, channel); + ready = accessPointReady(ssid, channel, password); if (!ready) delay(20); } while (!ready && millis() - started < 300); } @@ -96,6 +127,20 @@ inline bool startOpenAccessPoint(const char* ssid, bool reuse_existing) { return ready; } +inline bool startOpenAccessPoint(const char* ssid, bool reuse_existing) { + return startAccessPoint(ssid, reuse_existing, nullptr); +} + +// Existing short/non-ASCII admin passwords retain HTTP authentication and an +// explicitly reported open-AP compatibility path; never invent a second secret. +inline bool startManagementAccessPoint(const char* ssid, bool reuse_existing) { + mesh::esp32::managementPassword::Snapshot current; + if (!mesh::esp32::managementPassword::snapshot(current)) return false; + const char* password = mesh::esp32::managementPassword::apPasswordEligible(current.password) + ? current.password : nullptr; + return startAccessPoint(ssid, reuse_existing, password); +} + inline void stopTemporaryAccessPointRadio(bool started_radio) { // Removing AP releases its shared LR constraint. The station policy checks // the live SDK mode and cannot re-enable LR while AP is still present. diff --git a/src/helpers/ui/WiFiSetupQrDisplay.h b/src/helpers/ui/WiFiSetupQrDisplay.h index 170eed05c..5c366be63 100644 --- a/src/helpers/ui/WiFiSetupQrDisplay.h +++ b/src/helpers/ui/WiFiSetupQrDisplay.h @@ -2,10 +2,29 @@ #include "DisplayDriver.h" #include "WiFiSetupQrPayload.h" +#if defined(ESP_PLATFORM) || defined(ESP32_PLATFORM) +#include "../esp32/WiFiAccessPointPolicy.h" +#endif namespace mesh { namespace ui { +inline bool buildCurrentWiFiSetupQrPayload(char* payload, size_t payload_size, + const char* ssid) { +#if defined(ESP_PLATFORM) || defined(ESP32_PLATFORM) + char password[65]; + if (!mesh::wifi::accessPointJoinPassword(ssid, password, sizeof(password))) + return false; + return buildWiFiSetupQrPayload(payload, payload_size, ssid, password); +#else + const char* password = nullptr; +#ifdef WEBCONFIG_AP_PASSWORD + password = WEBCONFIG_AP_PASSWORD; +#endif + return buildWiFiSetupQrPayload(payload, payload_size, ssid, password); +#endif +} + // Render a setup-AP join QR at the largest size that still leaves the right // half of compact displays available for a short textual fallback/reference. // A Version 1 QR, including its four-module quiet zone, is exactly 58 pixels @@ -16,12 +35,7 @@ inline bool drawWiFiSetupQr(DisplayDriver& display, const char* ssid, const char* address, bool compact_border = false, const char* action = nullptr) { char payload[256]; - const char* password = nullptr; -#ifdef WEBCONFIG_AP_PASSWORD - password = WEBCONFIG_AP_PASSWORD; -#endif - if (!buildWiFiSetupQrPayload( - payload, sizeof(payload), ssid, password)) { + if (!buildCurrentWiFiSetupQrPayload(payload, sizeof(payload), ssid)) { return false; } diff --git a/test/fixtures/async_ota_completion.cpp b/test/fixtures/async_ota_completion.cpp index c0ef86a14..2ca3ac8ae 100644 --- a/test/fixtures/async_ota_completion.cpp +++ b/test/fixtures/async_ota_completion.cpp @@ -1,4 +1,6 @@ #include +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST 1 +#include #include #include #include @@ -38,13 +40,15 @@ int xTaskCreate(Task task, const char*, unsigned, void*, unsigned, void*) { // algorithm; both vectors are fixed independently of the uploader callbacks. const char fixture_md5[]="7dea362b3fac8e00956a4952a3d4f474"; const char fixture_corrupt_md5[]="33cdeccccebe80329f1fdbee7f5874cb"; -struct Parameter { String text=fixture_md5; String value() { return text; } }; +struct Parameter { String text=fixture_md5; const String& value() { return text; } }; struct Response { int code; String body; - void addHeader(const char*, const char*) {} + std::vector> headers; + void addHeader(const char* key, const char* value) { headers.emplace_back(key, value); } }; unsigned fixture_now=0; +unsigned millis() { return fixture_now; } struct Client { unsigned _rx_timeout=0, _rx_last_packet=fixture_now; bool closed=false; @@ -70,6 +74,10 @@ struct Request { Response* queued_response=nullptr; std::function disconnected; Parameter md5; + Parameter authorization; + bool authorization_present = false; + bool hasHeader(const char*) { return authorization_present; } + Parameter* getHeader(const char*) { return &authorization; } Client connection; Request() { accept(&connection); } ~Request() { free(_tempObject); delete queued_response; } @@ -92,9 +100,12 @@ using AsyncWebServerRequest=Request; static AsyncWebServerRequest* ota_upload_owner=nullptr; using AsyncWebServerResponse=Response; struct AsyncWebServer { + std::vector> gets; std::function completion; std::function upload; - template void on(const char*, int, F) {} + template void on(const char*, int method, F callback) { + assert(method == HTTP_GET); gets.push_back(callback); + } template void on(const char*, int method, F callback, U chunks) { assert(method==HTTP_POST); completion=callback; upload=chunks; } @@ -154,12 +165,14 @@ struct UpdateFake { } Update; struct AsyncElegantOtaClass { AsyncWebServer* _server=nullptr; - bool _authRequired=false; + bool _authRequired=false, _managementPassword=false; + bool authenticateRequest(AsyncWebServerRequest*, uint32_t* generation=nullptr); String _username, _password, _id="fixture"; void begin(AsyncWebServer*, const char*, const char*); void restart(); bool setEnabled(bool); }; +@AUTH@ @BEGIN@ @RESTART@ @@ -178,6 +191,63 @@ int main() { server.upload(&request,"firmware",0,data,sizeof(data),true); in_network_callback=false; }; +#ifdef TEST_OTA_MANAGEMENT_PASSWORD + { + using namespace mesh::esp32::managementPassword; + ota._managementPassword = true; + Request unpublished; + server.gets[0](&unpublished); assert(unpublished.code == 503 && Update.begins == 0); + assert(publish("password")); + auto authorize = [](Request& request, const char* value = "Basic YWRtaW46cGFzc3dvcmQ=") { + request.authorization_present = true; request.authorization.text = value; + }; + assert(server.gets.size() == 2); + for (auto& get : server.gets) { + Request absent; get(&absent); assert(absent.code == 401); + assert(absent.queued_response->headers.size() == 2); + assert(absent.queued_response->headers[0].first == "WWW-Authenticate" + && absent.queued_response->headers[0].second == "Basic realm=\"MeshCore admin\", charset=\"UTF-8\""); + assert(absent.queued_response->headers[1].first == "Cache-Control" + && absent.queued_response->headers[1].second == "no-store"); + Request wrong; authorize(wrong, "Basic wrong"); get(&wrong); assert(wrong.code == 401); + Request good; authorize(good); get(&good); assert(good.code == 200); + } + Request wrong_post; authorize(wrong_post, "Basic wrong"); + upload(wrong_post); complete(wrong_post); + assert(wrong_post.code == 401 && Update.begins == 0 && Update.writes == 0 && !uploadActive()); + assert(publish("different")); + Request stale; authorize(stale); upload(stale); assert(stale.code == 401 && Update.begins == 0); + const char* updated = "Basic YWRtaW46ZGlmZmVyZW50"; + { + ChangeGuard saving; assert(saving.acquired()); + Request blocked; authorize(blocked, updated); upload(blocked); + assert(blocked.code == 409 && Update.begins == 0 && !uploadActive()); + } + uint8_t half[4] = {}; + Request partial; authorize(partial, updated); + server.upload(&partial, "firmware", 0, half, sizeof(half), false); + assert(Update.begins == 1 && Update.writes == 1 && uploadActive()); + { + ChangeGuard changing; assert(!changing.acquired()); + assert(!publish("not-committed")); + } + // Authentication is rechecked on every chunk before touching Update. + authorize(partial, "Basic wrong"); + server.upload(&partial, "firmware", sizeof(half), half, sizeof(half), true); + assert(partial.code == 401 && Update.writes == 1 && Update.ends == 0); + in_network_callback = true; partial.disconnected(); in_network_callback = false; + assert(!uploadActive() && !ota_upload_busy.load() && Update.aborts == 1 && !pending_task); + Request valid; authorize(valid, updated); upload(valid); + assert(uploadActive() && Update.writes == 2); + complete(valid); + assert(valid.code == 200 && Update.boot_commits == 1 && uploadActive()); + in_network_callback = true; valid.disconnected(); in_network_callback = false; + assert(!uploadActive() && pending_task); + auto task = pending_task; pending_task = nullptr; task(nullptr); + assert(ESP.restarts == 1); + return 0; + } +#endif #if defined(TEST_OTA_SECOND_FILE) || defined(TEST_OTA_INCOMPLETE_POST) { Request rejected; diff --git a/test/fixtures/webconfig_ap_start.cpp b/test/fixtures/webconfig_ap_start.cpp index 65f3a294e..7ffd78627 100644 --- a/test/fixtures/webconfig_ap_start.cpp +++ b/test/fixtures/webconfig_ap_start.cpp @@ -8,6 +8,12 @@ #include #include #include +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST +#include +namespace password = mesh::esp32::managementPassword; +#ifndef TEST_ADMIN_PASSWORD +#define TEST_ADMIN_PASSWORD "" +#endif using esp_err_t = int; using wifi_mode_t = int; @@ -46,13 +52,14 @@ struct IPAddress { struct wifi_config_t { struct { uint8_t ssid[32] = {}; + uint8_t password[64] = {}; uint8_t ssid_len = 0, ssid_hidden = 0, channel = 1; wifi_auth_mode_t authmode = WIFI_AUTH_OPEN; } ap; }; enum class Fault { None, StaleSsid, HiddenSsid, WrongChannel, WrongProtocol, MissingMode, - NotStarted, ZeroIp, DelayedStart, StaleOnce, SetterFailure, WrongAuth, StillConnected, + NotStarted, ZeroIp, DelayedStart, StaleOnce, SetterFailure, WrongAuth, WrongPassword, StillConnected, ModeSetterFailure, IpConfigSetterFailure, StaProtocolSetterFailure, SdkModeReadFailure, SdkConfigReadFailure, SdkProtocolReadFailure }; @@ -60,12 +67,8 @@ enum class ScanBehavior { Complete, SlowComplete, Failure, Stuck, StopDelayed, Unstoppable, FacadeFailedActive, FacadeFailedStopRejected }; -constexpr wifi_auth_mode_t expectedAuth() { -#ifdef WEBCONFIG_AP_PASSWORD - return WEBCONFIG_AP_PASSWORD[0] ? WIFI_AUTH_WPA2_PSK : WIFI_AUTH_OPEN; -#else - return WIFI_AUTH_OPEN; -#endif +wifi_auth_mode_t expectedAuth() { + return password::apPasswordEligible(TEST_ADMIN_PASSWORD) ? WIFI_AUTH_WPA2_PSK : WIFI_AUTH_OPEN; } void delay(unsigned amount); struct WiFiFake { @@ -122,11 +125,9 @@ struct WiFiFake { return true; } bool softAP(const char* ssid, const char* password, int channel) { -#ifdef WEBCONFIG_AP_PASSWORD - assert(password != nullptr && strcmp(password, WEBCONFIG_AP_PASSWORD) == 0); -#else - assert(password == nullptr); -#endif + if (expectedAuth() == WIFI_AUTH_WPA2_PSK) { + assert(password != nullptr && strcmp(password, TEST_ADMIN_PASSWORD) == 0); + } else assert(password == nullptr); assert(channel == 6); ++ap_calls; polls = 0; if (fault == Fault::SetterFailure) return false; @@ -142,6 +143,8 @@ struct WiFiFake { live_config.ap.authmode = fault == Fault::WrongAuth ? (expectedAuth() == WIFI_AUTH_OPEN ? WIFI_AUTH_WPA2_PSK : WIFI_AUTH_OPEN) : expectedAuth(); + if (password) strcpy(reinterpret_cast(live_config.ap.password), + fault == Fault::WrongPassword ? "obsolete-key" : password); ap_ip = fault == Fault::ZeroIp ? IPAddress() : planned_ip; ap_started = fault != Fault::NotStarted && fault != Fault::DelayedStart; // Every injected state error deliberately returns success here. @@ -279,7 +282,7 @@ struct DNSServer { }; unsigned DNSServer::starts = 0; struct NodeSnapshot { char admin_password[16] = {}; }; -struct Callbacks { void getNodeSnapshot(NodeSnapshot& node) { strcpy(node.admin_password, "configured"); } }; +struct Callbacks { void getNodeSnapshot(NodeSnapshot& node) { strcpy(node.admin_password, TEST_ADMIN_PASSWORD); } }; struct AsyncResponseStream { std::string state; unsigned networks = 0; }; struct AsyncWebServerRequest { int status = 0; @@ -327,6 +330,9 @@ struct WebConfigServer { bool _owns_wifi = true, _stopping = false; bool _retry_saved_wifi_in_setup = true, _setup_reconnect_in_progress = true; bool _was_setup_ap = false, _initial_setup = false; + bool _setup_provisioning_privilege = false; + uint32_t _ap_auth_generation = 0, _ap_rekey_generation = 0; + uint32_t _ap_rekey_after = 0, _ap_rekey_deadline = 0; uint32_t _setup_reconnect_deadline = 5, _setup_started_at = 5, _last_activity = 0; const uint8_t _pub_key[2] = {0x62, 0xF2}; char _ap_ssid[33] = {}, _wifi_ssid[32] = {}; @@ -339,6 +345,7 @@ struct WebConfigServer { void createServer() { ++servers; } void requestNetworkAccess() {} void refreshNetworkPowerHold(uint32_t) {} + void initializeManagementPassword(); bool startSetupMode(char reply[]); bool checkAuth(AsyncWebServerRequest*) const { return auth_allowed; } void handleScan(AsyncWebServerRequest* req); @@ -361,11 +368,20 @@ void requireEndpoint(const WebConfigServer& portal, const char* reply, bool cach assert(WiFi.scan_result == (cached_scan ? 2 : WIFI_SCAN_FAILED)); assert(!WiFi.sdk_scan_active && WiFi.sdk_scan_stops == (stopped_scan ? 1u : 0u)); assert(!WiFi.auto_reconnect && !portal._retry_saved_wifi_in_setup); - assert(strstr(reply, "join 'MC-62F2' then open http://192.168.4.1/")); + assert(strstr(reply, "join 'MC-62F2', http://192.168.4.1/")); + assert(strstr(reply, expectedAuth() == WIFI_AUTH_WPA2_PSK + ? "WiFi: admin password" : TEST_ADMIN_PASSWORD[0] + ? "open WiFi; admin login required" : "open WiFi; no admin password")); + assert(portal._setup_provisioning_privilege == (expectedAuth() == WIFI_AUTH_WPA2_PSK)); + if (expectedAuth() == WIFI_AUTH_WPA2_PSK) + assert(strcmp(reinterpret_cast(WiFi.live_config.ap.password), TEST_ADMIN_PASSWORD) == 0); assert(portal.servers == 1); assert(WiFi.initialized && WiFi.driver_stops == 0 && WiFi.driver_deinits == 0); } void reset(Fault fault = Fault::None) { + auto& state = password::detail::state(); + { password::detail::Lock lock(state); state.current = {}; + state.changing = state.uploading = state.rotating = false; } WiFi = WiFiFake{}; WiFi.fault = fault; clock_ms = 100; DNSServer::starts = 0; mesh::wireless::control().disabled = false; @@ -383,10 +399,11 @@ int main() { } for (Fault fault : {Fault::StaleSsid, Fault::HiddenSsid, Fault::WrongChannel, Fault::WrongProtocol, Fault::MissingMode, Fault::NotStarted, - Fault::ZeroIp, Fault::SetterFailure, Fault::WrongAuth, Fault::StillConnected, + Fault::ZeroIp, Fault::SetterFailure, Fault::WrongAuth, Fault::WrongPassword, Fault::StillConnected, Fault::ModeSetterFailure, Fault::IpConfigSetterFailure, Fault::StaProtocolSetterFailure, Fault::SdkModeReadFailure, Fault::SdkConfigReadFailure, Fault::SdkProtocolReadFailure}) { + if (fault == Fault::WrongPassword && expectedAuth() == WIFI_AUTH_OPEN) continue; reset(fault); WiFi.shared_espnow = true; WebConfigServer portal; char reply[160] = {}; diff --git a/test/fixtures/webconfig_login_handler.cpp b/test/fixtures/webconfig_login_handler.cpp index cbd363a99..2f64a2982 100644 --- a/test/fixtures/webconfig_login_handler.cpp +++ b/test/fixtures/webconfig_login_handler.cpp @@ -5,6 +5,9 @@ #include #include #include +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST +#include +namespace password = mesh::esp32::managementPassword; static uint32_t now_ms=100000, random_word=0x12345678; uint32_t millis() { return now_ms; } uint32_t esp_random() { return ++random_word; } @@ -37,11 +40,17 @@ struct WebConfigServer { enum { MODE_OFF, MODE_SETUP, MODE_LAN }; int _mode=MODE_SETUP, _mux=0; char _wifi_ssid[33]="SavedNet", _session_token[33] = {}; - bool _initial_setup=false; + bool _initial_setup=false, _setup_provisioning_privilege=false; uint32_t _last_activity=0, _session_last_seen=0; + uint32_t _session_generation=0, _ap_auth_generation=0; WebConfigLoginThrottle::Tracker _login_throttle; Callback callback; Callback* _cb=&callback; - WebConfigServer() { strcpy(callback.node.admin_password, "existing-secret"); } + WebConfigServer() { + // A candidate preference can differ while a save is in flight or failed. + // The HTTP handler must authenticate the committed mirror instead. + strcpy(callback.node.admin_password, "temporary-RAM"); + assert(password::publish("existing-secret")); + } void noteNetworkActivity() {} void handleLogin(AsyncWebServerRequest*); }; @@ -64,6 +73,8 @@ int main() { assert(login(portal, attacker, "existing-secret")==429 && last_reply==kLocked); assert(login(portal, owner, "existing-secret")==200); assert(strlen(portal._session_token)==32); + password::Snapshot committed; assert(password::snapshot(committed)); + assert(portal._session_generation==committed.generation); assert(login(portal, attacker, "existing-secret")==429 && last_reply==kLocked); now_ms+=30000; assert(login(portal, attacker, "existing-secret")==200); diff --git a/test/fixtures/webconfig_ota_handoff.cpp b/test/fixtures/webconfig_ota_handoff.cpp index 1d9bdd0f1..3ae25734e 100644 --- a/test/fixtures/webconfig_ota_handoff.cpp +++ b/test/fixtures/webconfig_ota_handoff.cpp @@ -42,19 +42,25 @@ struct WebConfigServer { Mode _mode = MODE_LAN; bool _stopping = false, _keep_wifi_on_stop = false, _was_setup_ap = false; bool _owns_wifi = true, _stop_warned = false, _initial_setup = false; + bool _setup_provisioning_privilege = false; bool _retry_saved_wifi_in_setup = false, _setup_reconnect_in_progress = false; bool _batch_reboot_armed = false, _setup_wifi_handoff_pending = false; bool _admin_pwd_set = false, _board_cmds_probed = false; + bool _batch_reauth_required = false, _batch_reauth_delivered = false; uint32_t _stop_warn_at = 0, _setup_started_at = 0, _connect_deadline = 0; uint32_t _setup_reconnect_deadline = 0, _reboot_at = 0, _batch_state = 0; uint32_t _batch_next = 0, _setup_wifi_handoff_deadline = 0, _batch_kind = 0; uint32_t _board_cmds = 0; uint32_t _network_activity_until = 0; + uint32_t _ap_auth_generation = 0, _ap_rekey_generation = 0; + uint32_t _ap_rekey_after = 0, _ap_rekey_deadline = 0; + uint32_t _batch_reauth_until = 0, _session_generation = 0, _session_last_seen = 0; void* _mux = nullptr; struct Terminal { bool running = false; struct { bool pending = false; } queue; }; Terminal* _terminal = nullptr; char _wifi_ssid[32] = {}, _setup_wifi_handoff_ip[16] = {}; char _session_token[16] = {}, _stats_json[16] = {}; + char _batch_owner_token[33] = {}; bool routes = true; void detachRoutes() { routes = false; } void closeTerminal() {} @@ -66,6 +72,7 @@ struct WebConfigServer { void requestStop(); bool stopForOTA(char*); void finalizeTeardown(); + void clearSessionLocked(); ~WebConfigServer() { delete _room_mailbox; } }; @METHODS@ @@ -77,6 +84,13 @@ int main() { portal._owns_wifi = owns_wifi; portal._was_setup_ap = setup; portal._mode = setup ? WebConfigServer::MODE_SETUP : WebConfigServer::MODE_LAN; + strcpy(portal._session_token, "old-session"); + strcpy(portal._batch_owner_token, "old-batch-session"); + portal._batch_reauth_required = true; + portal._batch_reauth_delivered = portal._setup_provisioning_privilege = true; + portal._ap_auth_generation = portal._ap_rekey_generation = 42; + portal._ap_rekey_after = portal._ap_rekey_deadline = 42; + portal._batch_reauth_until = portal._session_generation = portal._session_last_seen = 42; WiFi = WiFiFake{}; WiFi.ap = setup; WiFi.sta = !setup; @@ -94,6 +108,12 @@ int main() { portal.requestStop(); // A duplicate stop cannot revoke the handoff. portal.finalizeTeardown(); // Existing requests have finally drained. assert(portal._room_mailbox == nullptr); + assert(!portal._session_token[0] && !portal._batch_owner_token[0]); + assert(!portal._batch_reauth_required && !portal._batch_reauth_until + && !portal._session_generation && !portal._session_last_seen); + assert(!portal._batch_reauth_delivered && !portal._setup_provisioning_privilege); + assert(!portal._ap_auth_generation && !portal._ap_rekey_generation + && !portal._ap_rekey_after && !portal._ap_rekey_deadline); assert(WiFi.ap && WiFi.sta && WiFi.stops == 0); assert(WiFi.ap_stops == unsigned(setup)); assert(portal.callbacks.stops == 1 && !portal._keep_wifi_on_stop); diff --git a/test/fixtures/webconfig_password_batch.cpp b/test/fixtures/webconfig_password_batch.cpp new file mode 100644 index 000000000..d6eb52840 --- /dev/null +++ b/test/fixtures/webconfig_password_batch.cpp @@ -0,0 +1,79 @@ +// Production generation gates and post-command commit handling, fake CLI only. +#include +#include +#include +#include +#include +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST +#include +#include +namespace password = mesh::esp32::managementPassword; +using WCLock = std::lock_guard; +uint32_t millis() { return 1000; } +struct Callbacks { unsigned starts = 0, ends = 0; + void onConfigBatchStart() { ++starts; } + void onConfigBatchEnd() { ++ends; } +}; +struct WebConfigServer { + struct BatchEntry { char reply[160] = {}; } _batch[3]; + enum State { BATCH_IDLE, BATCH_PENDING, BATCH_DONE } _batch_state = BATCH_PENDING; + unsigned _batch_next = 0, _batch_count = 3, executed = 0, reloads = 0; + bool _batch_started = false, _batch_all_ok = true, _standalone_wifi_dirty = false; + bool _batch_reauth_required = false, _batch_reauth_delivered = false, post_completed = false; + uint32_t _batch_auth_generation = 0, _batch_reauth_until = 0; + uint32_t _session_generation = 0, _session_last_seen = 5; + char _batch_owner_token[33] = {}, _session_token[33] = "0123456789abcdef0123456789abcdef"; + std::mutex _mux; + Callbacks callbacks; Callbacks* _cb = &callbacks; + WebConfigServer() { password::Snapshot value; assert(password::snapshot(value)); + _session_generation = value.generation; beginBatchAuthorizationLocked(value.generation); } + void reloadStandaloneWiFi() { ++reloads; } + void clearSessionLocked(); + void beginBatchAuthorizationLocked(uint32_t); + void cancelStaleBatchLocked(uint32_t); + void startBatch(uint32_t); + void beforeCommand(uint32_t); + void afterCommand(bool, const char*, const char*, uint32_t); +}; +@METHODS@ +void reset() { + auto& state = password::detail::state(); + { password::detail::Lock lock(state); state.current = {}; state.changing = state.uploading = state.rotating = false; } + assert(password::initialize("original")); +} +void commit(const char* secret) { + password::ChangeGuard change; assert(change.acquired()); assert(change.publish(secret)); +} +int main() { + reset(); WebConfigServer saved; saved.startBatch(100); assert(saved.callbacks.starts == 1); + saved.beforeCommand(100); assert(saved.executed == 1); + commit("next-password"); saved._batch_next = 1; + saved.afterCommand(true, "next-password", "OK", 100); + assert(saved.post_completed && saved._batch_reauth_required && saved._batch_reauth_until == 121000); + assert(!saved._session_token[0] && saved._session_generation == 0 && saved._session_last_seen == 0); + assert(saved._batch_owner_token[0]); // Only the scoped result receipt survives. + saved.beforeCommand(200); assert(saved.executed == 2); // Own batch may continue. + // Failed persistence changes no committed generation or general login. + reset(); WebConfigServer failed; failed.startBatch(100); + failed.afterCommand(true, "next-password", "Error: save unconfirmed", 100); + assert(failed.post_completed && !failed._batch_reauth_required && failed._session_token[0]); + // Saving the same password is a successful no-op, not a session rotation. + commit("original"); failed.afterCommand(true, "original", "OK", 100); + assert(!failed._batch_reauth_required && failed._session_token[0]); + // A different transport's change before any command prevents callback entry. + reset(); WebConfigServer stale; commit("external"); stale.startBatch(100); + assert(stale.callbacks.starts == 0 && stale._batch_state == WebConfigServer::BATCH_DONE); + assert(stale._batch_next == 3 && !stale._batch_all_ok && !stale._batch_owner_token[0]); + for (const auto& entry : stale._batch) assert(strstr(entry.reply, "sign in again")); + // A change between two commands balances the transaction and reloads staged WiFi. + reset(); WebConfigServer between; between.startBatch(100); between._batch_next = 1; + between._standalone_wifi_dirty = true; commit("external"); between.beforeCommand(200); + assert(between.executed == 0 && between.callbacks.ends == 1 && between.reloads == 1); + assert(!between._batch_started && !between._batch_reauth_required && !between._batch_all_ok); + // A mismatched successful-looking reply cannot mint a receipt for another save. + reset(); WebConfigServer mismatch; mismatch.startBatch(100); commit("external"); + mismatch.afterCommand(true, "requested", "OK", 100); + assert(!mismatch.post_completed && !mismatch._batch_reauth_required && !mismatch._batch_owner_token[0]); + assert(mismatch.callbacks.ends == 1 && mismatch._batch_state == WebConfigServer::BATCH_DONE); + puts("WebConfig committed password/batch generation checks passed"); +} diff --git a/test/fixtures/webconfig_password_receipt.cpp b/test/fixtures/webconfig_password_receipt.cpp new file mode 100644 index 000000000..5e69585c1 --- /dev/null +++ b/test/fixtures/webconfig_password_receipt.cpp @@ -0,0 +1,45 @@ +// Execute production result projection with real JSON. Auth capability gates +// are exercised separately by webconfig_recovery_auth.cpp. +#include +#include +#include +#include +#include +struct Entry { char key[16]; char reply[160]; }; +struct Results { + int _batch_count = 4; + Entry _batch[4] = { + {"password", "OK"}, + {"other", "> arbitrary-private-value"}, + {"other", "Error: arbitrary-private-error"}, + {"other", "OK - arbitrary-private-success"} + }; + std::string config(bool authenticated) { + DynamicJsonDocument doc(4096); + JsonArray results = doc.createNestedArray("results"); +@CONFIG_LOOP@ + std::string out; serializeJson(doc, out); return out; + } + std::string cli(bool receipt_only) { + const int from = 0, page = _batch_count; + DynamicJsonDocument doc(4096); + JsonArray results = doc.createNestedArray("results"); +@CLI_LOOP@ + std::string out; serializeJson(doc, out); return out; + } +}; +int main() { + Results value; + const auto config_receipt = value.config(false), cli_receipt = value.cli(true); + for (const auto* receipt : {&config_receipt, &cli_receipt}) { + assert(receipt->find("arbitrary-private") == std::string::npos); + assert(receipt->find("OK") != std::string::npos); + assert(receipt->find("sign in again") != std::string::npos); + } + assert(cli_receipt.find("Sign in again to read this result") != std::string::npos); + // Fresh current-generation authentication permits the same batch to be + // reread with complete details, without executing its commands again. + assert(value.config(true).find("arbitrary-private-error") != std::string::npos); + assert(value.cli(false).find("arbitrary-private-value") != std::string::npos); + assert(value.cli(false).find("arbitrary-private-success") != std::string::npos); +} diff --git a/test/fixtures/webconfig_password_sessions.cpp b/test/fixtures/webconfig_password_sessions.cpp new file mode 100644 index 000000000..13119f7e9 --- /dev/null +++ b/test/fixtures/webconfig_password_sessions.cpp @@ -0,0 +1,104 @@ +// Only WiFi endpoints and clock are doubles; the service method is production. +#include +#include +#include +#include +#include +#include +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST +#include +#include +namespace password = mesh::esp32::managementPassword; +using WCLock = std::lock_guard; +struct WiFiFake { + bool ap_live = true, sta_live = true; + unsigned disconnects = 0; + bool softAPdisconnect(bool off) { + assert(off); ++disconnects; ap_live = false; return true; + } +} WiFi; +namespace mesh { +struct Debug { void println(const char*) {} }; +Debug& usbDebugPort() { static Debug port; return port; } +namespace wifi { +bool ready = true; +unsigned starts = 0; +std::string last_password; +bool startAccessPoint(const char* ssid, bool reuse, const char* secret) { + assert(strcmp(ssid, "MC-1234") == 0 && reuse); + ++starts; last_password = secret ? secret : ""; + // Independent SDK model: mode(STA) may fail before touching the existing AP. + if (!ready) return false; + WiFi.ap_live = true; return true; +} +}} +struct WebConfigServer { + enum Mode { MODE_OFF, MODE_LAN, MODE_SETUP } _mode = MODE_SETUP; + enum BatchState { BATCH_IDLE, BATCH_PENDING, BATCH_DONE } _batch_state = BATCH_IDLE; + bool _stopping = false, _setup_provisioning_privilege = true; + bool _batch_reauth_required = false, _batch_reauth_delivered = false; + uint32_t _ap_auth_generation = 0, _ap_rekey_generation = 0; + uint32_t _ap_rekey_after = 0, _ap_rekey_deadline = 0, _reboot_at = 0; + char _ap_ssid[33] = "MC-1234"; + std::mutex _mux; + unsigned refs = 0; + unsigned handlerRefCount() const { return refs; } + WebConfigServer() { password::Snapshot value; assert(password::snapshot(value)); _ap_auth_generation = value.generation; } + void serviceSetupPassword(uint32_t now); +}; +@METHODS@ +void reset() { + auto& state = password::detail::state(); + { password::detail::Lock lock(state); state.current = {}; state.changing = state.uploading = state.rotating = false; } + assert(password::initialize("original")); + WiFi = {}; mesh::wifi::ready = true; mesh::wifi::starts = 0; mesh::wifi::last_password.clear(); +} +void commit(const char* secret) { + password::ChangeGuard change; assert(change.acquired()); assert(change.publish(secret)); +} +int main() { + reset(); WebConfigServer portal; + portal.serviceSetupPassword(100); assert(mesh::wifi::starts == 0); + commit("next-password"); + portal._batch_state = WebConfigServer::BATCH_PENDING; + portal.serviceSetupPassword(100); portal.serviceSetupPassword(4000); + assert(mesh::wifi::starts == 0); + portal._batch_state = WebConfigServer::BATCH_DONE; portal.refs = 1; + portal.serviceSetupPassword(4000); assert(mesh::wifi::starts == 0); + portal.refs = 0; portal._batch_reauth_required = true; + portal.serviceSetupPassword(4000); assert(mesh::wifi::starts == 0); + // Delivery gets a bounded grace period, then the live key follows the saved one. + portal._batch_reauth_delivered = true; portal._ap_rekey_after = 7000; + portal.serviceSetupPassword(6999); assert(mesh::wifi::starts == 0); + password::Snapshot current; assert(password::snapshot(current)); + assert(password::beginUpload(current.generation)); + portal.serviceSetupPassword(7000); assert(mesh::wifi::starts == 0); + password::endUpload(); portal.serviceSetupPassword(7000); + assert(mesh::wifi::starts == 1 && mesh::wifi::last_password == "next-password"); + assert(portal._ap_auth_generation == current.generation && portal._ap_rekey_generation == 0); + assert(WiFi.ap_live && WiFi.sta_live && WiFi.disconnects == 0); + // A client that never receives its receipt cannot postpone rekey indefinitely. + reset(); WebConfigServer no_receipt; commit("another-pass"); + no_receipt._batch_reauth_required = true; + no_receipt.serviceSetupPassword(100); no_receipt.serviceSetupPassword(30099); + assert(mesh::wifi::starts == 0); + no_receipt.serviceSetupPassword(30100); assert(mesh::wifi::starts == 1); + // Legacy short/non-ASCII admin credentials retain HTTP access on an open AP. + for (const char* secret : {"short", "long-\xc3\xa9-pass"}) { + reset(); WebConfigServer legacy; commit(secret); + legacy.serviceSetupPassword(100); legacy.serviceSetupPassword(3100); + assert(mesh::wifi::starts == 1 && mesh::wifi::last_password.empty()); + assert(!legacy._setup_provisioning_privilege && WiFi.ap_live && WiFi.sta_live); + } + // A failed restart must not leave an indefinitely usable old-key AP behind. + reset(); WebConfigServer failed; const auto old_generation = failed._ap_auth_generation; + commit("next-password"); mesh::wifi::ready = false; + failed.serviceSetupPassword(100); failed.serviceSetupPassword(3100); + assert(mesh::wifi::starts == 1 && !WiFi.ap_live && WiFi.sta_live && WiFi.disconnects == 1); + assert(failed._ap_auth_generation == old_generation && failed._ap_rekey_generation != 0); + failed.serviceSetupPassword(8099); assert(mesh::wifi::starts == 1); + mesh::wifi::ready = true; failed.serviceSetupPassword(8100); + assert(mesh::wifi::starts == 2 && WiFi.ap_live && WiFi.sta_live); + assert(failed._ap_auth_generation != old_generation && failed._ap_rekey_generation == 0); + puts("WebConfig password session/rekey checks passed"); +} diff --git a/test/fixtures/webconfig_recovery_auth.cpp b/test/fixtures/webconfig_recovery_auth.cpp index 17b4a110a..66393bb3a 100644 --- a/test/fixtures/webconfig_recovery_auth.cpp +++ b/test/fixtures/webconfig_recovery_auth.cpp @@ -5,6 +5,23 @@ #include #include #include +#include +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST +#include +namespace password = mesh::esp32::managementPassword; +static void resetCredential(const char* value) { + { + auto& state = password::detail::state(); + password::detail::Lock lock(state); + state.current = password::Snapshot{}; + state.changing = state.uploading = state.rotating = false; + } + assert(password::initialize(value)); +} +static void commitCredential(const char* value) { + password::ChangeGuard change; + assert(change.acquired() && change.publish(value)); +} struct String : std::string { using std::string::string; String(std::string value) : std::string(std::move(value)) {} @@ -12,15 +29,22 @@ struct String : std::string { String substring(int begin, int end) const { return substr(begin, end-begin); } }; static uint32_t now_ms=10, random_word=0x12345678; +static bool rotate_during_login=false; uint32_t millis() { return now_ms; } -uint32_t esp_random() { return ++random_word; } +uint32_t esp_random() { + if (rotate_during_login) { + rotate_during_login=false; + commitCredential("rotated-secret"); + } + return ++random_word; +} static constexpr uint32_t WEBCONFIG_SESSION_TTL_MS=10000; struct NodeSnapshot { char admin_password[16] = {}; }; struct Callback { NodeSnapshot node; void getNodeSnapshot(NodeSnapshot& result) { result=node; } }; -struct WCLock { explicit WCLock(int) {} }; +struct WCLock { std::unique_lock lock; explicit WCLock(std::mutex& m) : lock(m) {} }; struct WiFiMock { int softAPIP() const { return 4; } } WiFi; struct Client { int local_ip=4; uint32_t remote=0; @@ -46,15 +70,26 @@ struct AsyncWebServerRequest { }; struct WebConfigServer { enum { MODE_OFF, MODE_SETUP, MODE_LAN }; - int _mode=MODE_SETUP, _mux=0; + enum BatchKind { BATCH_CONFIG, BATCH_CLI }; + int _mode=MODE_SETUP; + std::mutex _mux; char _wifi_ssid[33]="SavedNet", _session_token[33] = {}; - bool _initial_setup=false, config_accepted=false; + bool _initial_setup=false, _setup_provisioning_privilege=false, config_accepted=false; uint32_t _last_activity=0, _session_last_seen=0; + uint32_t _session_generation=0, _ap_auth_generation=0; + uint32_t _batch_auth_generation=0, _batch_reauth_until=0; + bool _batch_reauth_required=false, _batch_reauth_delivered=false, _batch_started=false; + BatchKind _batch_kind=BATCH_CONFIG; + char _batch_owner_token[33]={}, _batch_reqid[24]="0123456789abcdef"; WebConfigLoginThrottle::Tracker _login_throttle; Callback callback; Callback* _cb=&callback; - WebConfigServer() { strcpy(callback.node.admin_password, "existing-secret"); } + WebConfigServer() { strcpy(callback.node.admin_password, "existing-secret"); resetCredential("existing-secret"); } unsigned network_activity = 0; void noteNetworkActivity() { ++network_activity; } bool checkAuth(AsyncWebServerRequest*); + bool checkAuthLocked(AsyncWebServerRequest*, uint32_t* generation=nullptr); + void clearSessionLocked(); + void beginBatchAuthorizationLocked(uint32_t); + bool resultReceiptAllowedLocked(AsyncWebServerRequest*, const char*, BatchKind, uint32_t); void handleLogin(AsyncWebServerRequest*); void handleLogout(AsyncWebServerRequest*); void checkConfigPost(AsyncWebServerRequest*); @@ -101,14 +136,18 @@ int main() { // First provisioning remains possible and retains its AP-only privilege // through a save batch that changes SSID before the confirmation arrives. portal._mode=WebConfigServer::MODE_SETUP; portal._wifi_ssid[0]=0; + portal._setup_provisioning_privilege=true; + password::Snapshot credential; assert(password::snapshot(credential)); + portal._ap_auth_generation=credential.generation; portal._initial_setup=true; assert(portal.checkAuth(&attacker)); strcpy(portal._wifi_ssid, "ProvisionedNet"); assert(portal.checkAuth(&attacker)); portal.handleLogin(&attacker); assert(attacker.status==200); attacker.socket.local_ip=9; assert(!portal.checkAuth(&attacker)); portal.handleLogin(&attacker); assert(attacker.status==401); attacker.socket.local_ip=4; - // Companion images deliberately have no administrator password or CLI - // password management. Keep that explicit no-password deployment policy. + // Explicit legacy passwordless deployments retain their no-password policy. portal._initial_setup=false; portal.callback.node.admin_password[0]=0; + portal._setup_provisioning_privilege=false; + resetCredential(""); assert(portal.checkAuth(&attacker)); portal.handleLogin(&attacker); assert(attacker.status==200); // A spent login budget blocks new logins without revoking an existing // authenticated session, on either the saved-network AP or the LAN. @@ -130,5 +169,87 @@ int main() { active.checkConfigPost(&owner); assert(active.config_accepted); assert(token==active._session_token); } + for (int mode : {WebConfigServer::MODE_SETUP, WebConfigServer::MODE_LAN}) { + WebConfigServer active; active._mode=mode; + AsyncWebServerRequest owner; owner.password("existing-secret"); + active.handleLogin(&owner); assert(owner.status==200); + owner.header.cookies=std::string("wcs=")+active._session_token; + const std::string original_cookie=owner.header.cookies; + password::Snapshot before; assert(password::snapshot(before)); + active.beginBatchAuthorizationLocked(before.generation); + // A setter's temporary RAM and failed-save rollback never reach auth. + strcpy(active.callback.node.admin_password, "temporary"); + assert(active.checkAuth(&owner)); + AsyncWebServerRequest unsaved; unsaved.password("temporary"); + active.handleLogin(&unsaved); assert(unsaved.status==401); + strcpy(active.callback.node.admin_password, "existing-secret"); + commitCredential("existing-secret"); + assert(active.checkAuth(&owner)); // same credential is not a rotation + + commitCredential("new-secret"); + password::Snapshot after; assert(password::snapshot(after)); + assert(after.generation!=before.generation); + assert(!active.checkAuth(&owner)); + active.config_accepted=false; active.checkConfigPost(&owner); + assert(owner.status==401 && !active.config_accepted); + // Only an actual owning password batch grants this short-lived result + // receipt; external rotation alone does not create one. + assert(!active.resultReceiptAllowedLocked(&owner, active._batch_reqid, + WebConfigServer::BATCH_CONFIG, now_ms)); + active._batch_auth_generation=after.generation; + active._batch_reauth_required=true; + active._batch_reauth_until=WebConfigBatch::scheduleAt(now_ms, WebConfigBatch::kReauthReceiptMs); + assert(active.resultReceiptAllowedLocked(&owner, active._batch_reqid, + WebConfigServer::BATCH_CONFIG, now_ms)); + assert(!active.resultReceiptAllowedLocked(&owner, "fedcba9876543210", + WebConfigServer::BATCH_CONFIG, now_ms)); + assert(!active.resultReceiptAllowedLocked(&owner, active._batch_reqid, + WebConfigServer::BATCH_CLI, now_ms)); + AsyncWebServerRequest other; other.header.cookies="wcs=00000000000000000000000000000000"; + assert(!active.resultReceiptAllowedLocked(&other, active._batch_reqid, + WebConfigServer::BATCH_CONFIG, now_ms)); + assert(!active.resultReceiptAllowedLocked(&owner, active._batch_reqid, + WebConfigServer::BATCH_CONFIG, active._batch_reauth_until)); + owner.password("existing-secret"); active.handleLogin(&owner); assert(owner.status==401); + owner.password("new-secret"); active.handleLogin(&owner); assert(owner.status==200); + owner.header.cookies=std::string("wcs=")+active._session_token; + assert(active.checkAuth(&owner)); + owner.header.cookies=original_cookie; assert(!active.checkAuth(&owner)); + // Even changing back cannot revive the first generation's cookie/receipt. + commitCredential("existing-secret"); + assert(!active.checkAuth(&owner)); + assert(!active.resultReceiptAllowedLocked(&owner, active._batch_reqid, + WebConfigServer::BATCH_CONFIG, now_ms)); + } + { + WebConfigServer active; + AsyncWebServerRequest first_setup; + active._wifi_ssid[0]=0; + active._initial_setup=active._setup_provisioning_privilege=true; + password::Snapshot before; assert(password::snapshot(before)); + active._ap_auth_generation=before.generation; + assert(active.checkAuth(&first_setup)); + active.beginBatchAuthorizationLocked(before.generation); // no initial cookie + commitCredential("new-secret"); + assert(!active.checkAuth(&first_setup)); // old WPA association is not auth + first_setup.password("new-secret"); active.handleLogin(&first_setup); + assert(first_setup.status==200 && active._session_token[0]); + first_setup.header.cookies=std::string("wcs=")+active._session_token; + assert(active.checkAuth(&first_setup)); + } + { + WebConfigServer active; + active._wifi_ssid[0]=0; active._initial_setup=true; + commitCredential("short"); + AsyncWebServerRequest open_ap; + assert(!active.checkAuth(&open_ap)); // short legacy password still needs HTTP login + open_ap.password("short"); active.handleLogin(&open_ap); assert(open_ap.status==200); + } + { + WebConfigServer active; AsyncWebServerRequest login; + login.password("existing-secret"); rotate_during_login=true; + active.handleLogin(&login); + assert(login.status==401 && active._session_token[0]==0); + } puts("WebConfig recovery authentication regression checks passed"); } diff --git a/test/fixtures/wifi_ota_start.cpp b/test/fixtures/wifi_ota_start.cpp index 6cd875f5a..cef1a13e4 100644 --- a/test/fixtures/wifi_ota_start.cpp +++ b/test/fixtures/wifi_ota_start.cpp @@ -9,6 +9,9 @@ #include #include #include +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST 1 +#include +static const bool published_password = mesh::esp32::managementPassword::publish("short"); #define MESH_DEBUG_PRINTLN(...) ((void)0) constexpr int WL_CONNECTED = 3; @@ -17,7 +20,7 @@ using wifi_mode_t = int; constexpr int WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2; constexpr int WIFI_MODE_NULL = WIFI_OFF, WIFI_MODE_AP = WIFI_AP; constexpr int ESP_OK = 0, WIFI_IF_AP = 1, WIFI_IF_STA = 0; -constexpr int WIFI_AUTH_OPEN = 0; +constexpr int WIFI_AUTH_OPEN = 0, WIFI_AUTH_WPA2_PSK = 3; constexpr int WIFI_SCAN_RUNNING = -1, WIFI_SCAN_FAILED = -2, AP_STARTED_BIT = 1; constexpr int LISTEN = 10; bool async_bind_allowed = true; @@ -29,6 +32,7 @@ bool constrain_espnow_channel = true; struct wifi_config_t { struct { uint8_t ssid[32] = {}; + uint8_t password[64] = {}; uint8_t ssid_len = 0, ssid_hidden = 0, channel = 1; int authmode = WIFI_AUTH_OPEN; } ap; @@ -86,11 +90,13 @@ struct WiFiFake { return allow_ap; } bool softAP(const char* ssid, const char* password, int channel = 1) { - assert(ssid && strlen(ssid) <= 32 && password == nullptr); + assert(ssid && strlen(ssid) <= 32); ap_channel = channel; ++starts; ap = allow_ap; radio = true; if (ap) { live_config = {}; + live_config.ap.authmode = password && password[0] ? WIFI_AUTH_WPA2_PSK : WIFI_AUTH_OPEN; + if (password) strcpy(reinterpret_cast(live_config.ap.password), password); const char* live_ssid = fault == Fault::Ssid ? "old-hotspot" : ssid; live_config.ap.ssid_len = uint8_t(strlen(live_ssid)); memcpy(live_config.ap.ssid, live_ssid, strlen(live_ssid)); @@ -181,6 +187,8 @@ struct AsyncWebServer { struct Elegant { bool busy = false; void setID(const char*) {} + void useManagementPassword() {} + bool authenticateRequest(AsyncWebServerRequest*) { return true; } void begin(AsyncWebServer*) {} bool setEnabled(bool enabled) { return enabled || !busy; } } AsyncElegantOTA; @@ -198,6 +206,7 @@ struct ESP32Board { const char* getManufacturerName() const { return "test"; } bool startOTAUpdate(const char*, char*, bool); bool stopOTAUpdate(char*); + static bool rotateOTAAccessPoint(void*) { return true; } }; struct LightweightServer { bool allow = true, running = false, allow_stop = true; diff --git a/test/test_async_web_lifecycle.py b/test/test_async_web_lifecycle.py index d04d53662..f0ccaf82b 100644 --- a/test/test_async_web_lifecycle.py +++ b/test/test_async_web_lifecycle.py @@ -41,6 +41,7 @@ static std::atomic ota_upload_busy{false};""" rx=tcp[tcp.index(" // RX Timeout"):tcp.index(" // Everything is fine")] return (fixture.replace("@REBOOT_STATE@",state) .replace("@UPLOAD_STATE@",extract_braced(source,"struct OtaUploadState")+";") + .replace("@AUTH@",extract_braced(source,"bool AsyncElegantOtaClass::authenticateRequest(")) .replace("@BEGIN@",begin) .replace("@RESTART@",extract_braced(source,"void AsyncElegantOtaClass::restart()")) .replace("@ACCEPT_TIMEOUT@",accept).replace("@RX_TIMEOUT@",rx)) @@ -68,6 +69,17 @@ static std::atomic ota_upload_busy{false};""" with self.assertRaises(AssertionError): self.compile_and_run(old,"-DESP32=1","-DTEST_OTA_BODY_TIMEOUT=1") + def test_management_auth_precedes_all_routes_and_upload_side_effects(self): + fixture = self.uploader_fixture() + self.compile_and_run(fixture, "-DESP32=1", "-DTEST_OTA_MANAGEMENT_PASSWORD=1") + # Exercise the actual chunk gate: omitting authentication must admit a + # wrong password and fail the zero-flash-effects assertion above. + gate = " if (!authenticateRequest(request, &authenticated_generation)) return;" + old = fixture.replace(gate, " authenticated_generation = mesh::esp32::managementPassword::detail::state().current.generation;") + self.assertNotEqual(old, fixture) + with self.assertRaises(AssertionError): + self.compile_and_run(old, "-DESP32=1", "-DTEST_OTA_MANAGEMENT_PASSWORD=1") + def premature_commit_fixture(self, fixture): commit=extract_braced(fixture,"if (state && state->file_final") end=extract_braced(commit,"if (!Update.end(true))") diff --git a/test/test_companion_admin_password.py b/test/test_companion_admin_password.py new file mode 100644 index 000000000..dc5fbd996 --- /dev/null +++ b/test/test_companion_admin_password.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python3 +"""Fault-inject the real Companion NVS credential store, including reboot reads.""" +from pathlib import Path +import os +import subprocess +import tempfile +import unittest + +ROOT = Path(__file__).resolve().parents[1] + +PREFERENCES = r''' +#pragma once +#include +#include +#include +enum PreferenceType { PT_INVALID, PT_U8, PT_STR }; +struct Disk { + bool begin_ok = true, has_password = false, has_pending = false; + PreferenceType password_type = PT_STR, pending_type = PT_U8; + std::string password; + unsigned char pending = 0; + int writes = 0, fail_write = 0, reads = 0, fail_read = 0; + bool corrupt_read = false; +} disk; +class Preferences { + public: + bool begin(const char* name, bool read_only) { + return !strcmp(name, "mesh-admin") && !read_only && disk.begin_ok; + } + void end() {} + bool isKey(const char* name) { return !strcmp(name, "password") ? disk.has_password : disk.has_pending; } + PreferenceType getType(const char* name) { return !strcmp(name, "password") ? disk.password_type : disk.pending_type; } + unsigned char getUChar(const char*, unsigned char fallback) { + if (++disk.reads == disk.fail_read || !disk.has_pending || disk.pending_type != PT_U8) return fallback; + return disk.pending; + } + size_t putUChar(const char*, unsigned char value) { + if (++disk.writes == disk.fail_write) return 0; + disk.has_pending = true; disk.pending_type = PT_U8; disk.pending = value; return 1; + } + size_t putString(const char*, const char* value) { + if (++disk.writes == disk.fail_write) return 0; + disk.has_password = true; disk.password_type = PT_STR; disk.password = value; return strlen(value); + } + size_t getString(const char*, char* output, size_t size) { + if (++disk.reads == disk.fail_read || disk.password.size() + 1 > size) return 0; + memcpy(output, disk.password.c_str(), disk.password.size() + 1); + if (disk.corrupt_read) output[0] ^= 1; + return disk.password.size() + 1; + } +}; +''' + + +class CompanionAdminPasswordTest(unittest.TestCase): + def test_migration_rotation_power_loss_and_explicit_repair(self): + source = r''' +#include +#include +using namespace mesh::esp32::companionAdminPassword; +void fresh() { disk = Disk{}; } +void reboot() { disk.writes = disk.reads = disk.fail_write = disk.fail_read = 0; disk.corrupt_read = false; } +void unavailable() { + char value[CAPACITY]; memset(value, 'X', sizeof(value)); + assert(!load(value, "factory")); + for (char c : value) assert(c == 0); +} +int main() { + char value[CAPACITY]; + fresh(); assert(load(value, "factory") && !strcmp(value, "factory")); + assert(!disk.has_password); // Loading never overwrites saved state. + for (const char* invalid : {"", "1234567890123456", "abc\rdef", "abc\ndef"}) { + assert(!save(invalid)); assert(disk.writes == 0); + assert(!load(value, invalid)); + } + assert(!save(nullptr)); + for (const char* valid_password : {"a", "123456789012345", "a:b ", "\303\251"}) { + assert(save(valid_password)); reboot(); + assert(load(value, "different-default") && !strcmp(value, valid_password)); + } + fresh(); disk.begin_ok = false; unavailable(); assert(!save("replacement")); + fresh(); disk.has_password = true; + for (const char* malformed : {"", "1234567890123456", "bad\rpassword", "bad\npassword"}) { + disk.password = malformed; unavailable(); + } + disk.password = std::string("valid\0hidden", 12); unavailable(); + disk.password = "saved-password"; disk.password_type = PT_U8; unavailable(); + disk.password_type = PT_STR; disk.has_pending = true; + disk.pending_type = PT_STR; unavailable(); + disk.pending_type = PT_U8; disk.pending = 1; unavailable(); + disk.pending = 0; assert(load(value, "factory") && !strcmp(value, "saved-password")); + disk.has_password = false; unavailable(); // A partial save cannot become factory login. + for (int failing_write = 1; failing_write <= 3; ++failing_write) { + fresh(); assert(save("old-password")); reboot(); + disk.fail_write = failing_write; + assert(!save("new-password")); reboot(); + if (failing_write == 1) assert(load(value, "factory") && !strcmp(value, "old-password")); + else unavailable(); // Pending survives power loss / failed data or commit writes. + assert(save("repaired")); reboot(); + assert(load(value, "factory") && !strcmp(value, "repaired")); + } + for (int failing_read = 1; failing_read <= 3; ++failing_read) { + fresh(); assert(save("old-password")); reboot(); + disk.fail_read = failing_read; assert(!save("new-password")); reboot(); + if (failing_read < 3) unavailable(); + else assert(load(value, "factory") && !strcmp(value, "new-password")); + // A failed final read is honestly unconfirmed: reboot may see the durable new value. + } + fresh(); disk.corrupt_read = true; assert(!save("new-password")); reboot(); unavailable(); + fresh(); assert(save("saved-password")); reboot(); + disk.fail_read = 1; unavailable(); reboot(); + disk.fail_read = 2; unavailable(); +} +''' + with tempfile.TemporaryDirectory(prefix="companion-admin-") as temporary: + work = Path(temporary) + (work / "Preferences.h").write_text(PREFERENCES) + (work / "test.cpp").write_text(source) + result = subprocess.run([os.environ.get("CXX", "g++"), "-std=c++11", "-Wall", "-Wextra", "-Werror", + "-fsanitize=address,undefined", "-fno-sanitize-recover=all", "-fno-pie", "-no-pie", + "-DESP32_PLATFORM=1", '-DWIFI_SSID=""', "-I", str(work), "-I", str(ROOT / "src"), + str(work / "test.cpp"), "-o", str(work / "test")], capture_output=True, text=True, timeout=60) + self.assertEqual(result.returncode, 0, result.stderr) + result = subprocess.run([str(work / "test")], capture_output=True, text=True, timeout=15) + self.assertEqual(result.returncode, 0, result.stdout + result.stderr) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/test_esp32_async_web_build_paths.py b/test/test_esp32_async_web_build_paths.py new file mode 100644 index 000000000..5d7cb5434 --- /dev/null +++ b/test/test_esp32_async_web_build_paths.py @@ -0,0 +1,94 @@ +"""Verify the actual middleware's cloned-library project-header dependency.""" +import fnmatch +import importlib.util +from pathlib import Path +import shutil +import subprocess +import tempfile +import unittest + +ROOT = Path(__file__).resolve().parents[1] +SPEC = importlib.util.spec_from_file_location("web_build_fix", ROOT / "scripts/esp32_async_web_fix.py") +FIX = importlib.util.module_from_spec(SPEC) +SPEC.loader.exec_module(FIX) + + +class Node: + def __init__(self, path): + self.path = Path(path) + + def srcnode(self): + return self + + def get_abspath(self): + return str(self.path.resolve()) + + +class Clone: + def __init__(self, source_dir, build_dir): + self.variables = {"$PROJECT_DIR": str(ROOT), "$PROJECT_SRC_DIR": str(source_dir), + "$BUILD_DIR": str(build_dir)} + self.paths = [] + self.middleware = [] + + def subst(self, value): + return self.variables[value] + + def PrependUnique(self, **values): + self.paths = [p for p in values["CPPPATH"] if p not in self.paths] + self.paths + + def AppendUnique(self, **values): + self.paths += [p for p in values["CPPPATH"] if p not in self.paths] + + def File(self, value): + return Node(value) + + def AddBuildMiddleware(self, callback, pattern): + self.middleware.append((callback, pattern)) + + +class AsyncWebBuildPathTest(unittest.TestCase): + def test_cached_and_direct_library_clones_can_include_current_project_header(self): + compiler = shutil.which("g++") or shutil.which("clang++") + self.assertIsNotNone(compiler) + with tempfile.TemporaryDirectory(prefix="ota-build-path-") as temporary: + work = Path(temporary) + source_dir = work / "custom application src" + project_header = source_dir / "helpers/esp32/ManagementPassword.h" + project_header.parent.mkdir(parents=True) + shutil.copyfile(ROOT / "src/helpers/esp32/ManagementPassword.h", project_header) + stale = work / "libdeps/target/AsyncElegantOTA/src/AsyncElegantOTA.cpp" + stale.parent.mkdir(parents=True) + stale.write_text("// obsolete cached dependency\n") + direct = ROOT / "arch/esp32/AsyncElegantOTA/src/AsyncElegantOTA.cpp" + for index, source in enumerate((stale, direct)): + with self.subTest(source=source.name, cached=index == 0): + clone = Clone(source_dir, work / ("build-" + str(index))) + FIX.install(clone) + matches = [(callback, pattern) for callback, pattern in clone.middleware + if fnmatch.fnmatch(str(source), pattern)] + self.assertEqual(len(matches), 1) + patched = matches[0][0](clone, Node(source)).path + self.assertEqual(patched.read_bytes(), direct.read_bytes()) + for header in ("AsyncElegantOTA.h", "Hash.h", "elegantWebpage.h"): + self.assertEqual((patched.parent / header).read_bytes(), (direct.parent / header).read_bytes()) + self.assertIn(str(source_dir), clone.paths) + probe = work / "probe.cpp" + probe.write_text('#define MESH_MANAGEMENT_PASSWORD_HOST_TEST 1\n' + '#include \n' + 'int main() { return mesh::esp32::managementPassword::validPassword("password") ? 0 : 1; }\n') + command = [compiler, "-std=c++11", *["-I" + path for path in clone.paths], + "-fsyntax-only", str(probe)] + result = subprocess.run(command, capture_output=True, text=True, timeout=30) + self.assertEqual(result.returncode, 0, result.stderr) + # Recreate the failed production clone by omitting only + # the project src path. It must fail at the exact header. + result = subprocess.run([part for part in command if part != "-I" + str(source_dir)], + capture_output=True, text=True, timeout=30) + self.assertNotEqual(result.returncode, 0) + self.assertIn("helpers/esp32/ManagementPassword.h", result.stderr) + self.assertEqual(stale.read_text(), "// obsolete cached dependency\n") + + +if __name__ == "__main__": + unittest.main() diff --git a/test/test_esp32_full_power_lifecycle.py b/test/test_esp32_full_power_lifecycle.py index d398a5a8b..23f57eb24 100644 --- a/test/test_esp32_full_power_lifecycle.py +++ b/test/test_esp32_full_power_lifecycle.py @@ -18,6 +18,8 @@ FLAGS = ["-DESP32_PLATFORM=1", "-DESP_PLATFORM=1", "-DADMIN_PASSWORD=1", "-DWEBCONFIG_UNCONFIGURED_SETUP_TIMEOUT_MS=1800000"] FIXTURE = r''' +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST 1 +#include #include #include #include @@ -101,6 +103,7 @@ struct Prefs { int bridge_enabled = 0, espnow_bridge_enabled = 0, rs232_bridge_enabled = 0; bool battery_alert_enabled = false; const char* node_name = "test"; + const char* password = "password"; float freq = 915, bw = 125; uint8_t sf = 7, cr = 5, disable_fwd = 0; }; struct ObserverPrefs { char wifi_ssid[33] = {}; }; diff --git a/test/test_esp32_management_password.py b/test/test_esp32_management_password.py new file mode 100644 index 000000000..620b5ca7c --- /dev/null +++ b/test/test_esp32_management_password.py @@ -0,0 +1,172 @@ +"""Execute the shared credential mirror, Basic parser, and upload/change leases.""" +import base64 +from pathlib import Path +import os +import subprocess +import tempfile +import unittest + +ROOT = Path(__file__).resolve().parents[1] + + +class ManagementPasswordTest(unittest.TestCase): + def compile_run(self, source, extra_source=None): + with tempfile.TemporaryDirectory(prefix="management-password-") as temporary: + directory = Path(temporary) + files = [] + for name, text in (("test.cpp", source), ("other.cpp", extra_source)): + if text is not None: + path = directory / name + path.write_text(text) + files.append(str(path)) + result = subprocess.run([os.environ.get("CXX", "g++"), "-std=c++11", "-Wall", "-Wextra", "-Werror", + "-pthread", "-DMESH_MANAGEMENT_PASSWORD_HOST_TEST=1", "-I", str(ROOT / "src"), + *files, "-o", str(directory / "test")], capture_output=True, text=True, timeout=45) + self.assertEqual(result.returncode, 0, result.stdout + result.stderr) + result = subprocess.run([str(directory / "test")], capture_output=True, text=True, timeout=15) + self.assertEqual(result.returncode, 0, result.stdout + result.stderr) + + def test_parser_exact_boundaries_and_unusual_credentials(self): + cases = [] + for password in ("a", "1234567", "12345678", "123456789012345", "a:b\\;\" ", "ééééééé"): + encoded = base64.b64encode(("admin:" + password).encode()).decode() + literal = '"' + ''.join('\\%03o' % byte for byte in password.encode()) + '"' + cases.append(f'assert(basicAuthorizationMatches("Basic {encoded}", {literal}));') + cases.append(f'assert(basicAuthorizationMatches("bAsIc {encoded}", {literal}));') + cases.append(f'assert(!basicAuthorizationMatches("Basic {encoded}x", {literal}));') + wrong = base64.b64encode(("other:" + password).encode()).decode() + cases.append(f'assert(!basicAuthorizationMatches("Basic {wrong}", {literal}));') + self.compile_run(r''' +#include +#include +using namespace mesh::esp32::managementPassword; +int main() { + assert(!validPassword(nullptr) && !validPassword("") && !validPassword("1234567890123456")); + assert(!validPassword("abc\rdef") && !validPassword("abc\ndef")); + assert(validPassword("123456789012345") && validPassword("\303\251")); + assert(!apPasswordEligible("1234567") && apPasswordEligible("12345678")); + assert(apPasswordEligible("123456789012345") && !apPasswordEligible("1234567890123456")); + assert(!apPasswordEligible("1234567\177") && !apPasswordEligible("1234567\303\251")); + assert(!basicAuthorizationMatches(nullptr, "password")); + assert(!basicAuthorizationMatches("Basic YWRtaW46", "")); + @CASES@ +} +'''.replace("@CASES@", "\n".join(cases))) + + def test_empty_legacy_mirror_then_committed_rotation_and_upload_reservations(self): + self.compile_run(r''' +#include +#include +using namespace mesh::esp32::managementPassword; +int main() { + Snapshot before, after; + assert(!snapshot(before)); + assert(!publish("") && initialize("") && snapshot(before) && before.generation == 1); + assert(!available() && authenticateBasic("Basic YWRtaW46", 100) == AuthResult::Unavailable); + assert(!initialize("different") && !publish("bad\npassword")); + assert(publish("password") && snapshot(before) && before.generation == 2); + assert(available() && publish("password") && snapshot(after) && after.generation == before.generation); + { + ChangeGuard failed_save; + assert(failed_save.acquired()); + assert(!beginUpload(before.generation)); + assert(!publish("unsaved")); + ChangeGuard competing; assert(!competing.acquired()); + // Simulate the caller's persistent save failing: do not publish. + } + assert(snapshot(after) && !strcmp(after.password, "password") && after.generation == before.generation); + { + UploadGuard upload(before.generation); + assert(upload.acquired() && uploadActive()); + ChangeGuard change; assert(!change.acquired()); + assert(!publish("different")); + UploadGuard competitor(before.generation); assert(!competitor.acquired()); + assert(authenticateBasic("Basic YWRtaW46cGFzc3dvcmQ=", 100) == AuthResult::Authorized); + } + assert(!uploadActive()); + { + ChangeGuard saved; assert(saved.acquired()); + assert(!saved.publish("") && saved.publish("different")); + assert(!beginUpload(before.generation)); + } + assert(snapshot(after) && after.generation == before.generation + 1); + assert(!beginUpload(before.generation)); + assert(authenticateBasic("Basic YWRtaW46cGFzc3dvcmQ=", 101) == AuthResult::Unauthorized); + uint32_t generation = 0; + assert(authenticateBasic("Basic YWRtaW46ZGlmZmVyZW50", 102, &generation) == AuthResult::Authorized); + assert(generation == after.generation); +} +''') + + def test_bounded_login_budget_and_prompt(self): + self.compile_run(r''' +#include +#include +using namespace mesh::esp32::managementPassword; +int main() { + assert(publish("password")); + for (int i = 0; i != 20; ++i) assert(authenticateBasic(nullptr, 100) == AuthResult::Unauthorized); + for (int i = 0; i != 5; ++i) assert(authenticateBasic("Basic wrong", 100) == AuthResult::Unauthorized); + assert(authenticateBasic("Basic YWRtaW46cGFzc3dvcmQ=", 101) == AuthResult::Throttled); + assert(authenticateBasic("Basic YWRtaW46cGFzc3dvcmQ=", 30100) == AuthResult::Authorized); +} +''') + + def test_deferred_ap_rotation_is_owner_bound_and_excludes_uploads(self): + self.compile_run(r''' +#include +#include +using namespace mesh::esp32::managementPassword; +int calls = 0; +bool rotate(void* owner) { + assert(owner == &calls); ++calls; + Snapshot current; assert(snapshot(current) && !strcmp(current.password, "new-password")); + ChangeGuard change; assert(!change.acquired()); + UploadGuard upload(current.generation); assert(!upload.acquired()); + return true; +} +int main() { + assert(publish("password")); + Snapshot current; snapshot(current); + watchOtaAccessPoint(&calls, rotate, current.generation); + assert(publish("new-password")); + service(0xfffffff0U); service(733); assert(calls == 0); + service(734); assert(calls == 1); service(5000); assert(calls == 1); + snapshot(current); watchOtaAccessPoint(&calls, rotate, current.generation); + assert(publish("third-value")); + forgetOtaAccessPoint(reinterpret_cast(1)); + forgetOtaAccessPoint(&calls); service(6000); service(7000); assert(calls == 1); +} +''') + + def test_one_registry_across_translation_units_and_threaded_snapshots(self): + other = r''' +#include +bool other_publish() { return mesh::esp32::managementPassword::publish("from-other"); } +''' + self.compile_run(r''' +#include +#include +#include +#include +using namespace mesh::esp32::managementPassword; +bool other_publish(); +int main() { + assert(other_publish()); Snapshot current; assert(snapshot(current) && !strcmp(current.password, "from-other")); + std::atomic done(false); + std::thread writer([&] { + for (int i = 0; i < 10000; ++i) assert(publish(i & 1 ? "AAAAAAAAAAAAAAA" : "BBBBBBBBBBBBBBB")); + done.store(true); + }); + while (!done.load()) { + assert(snapshot(current)); + assert(!strcmp(current.password, "from-other") || !strcmp(current.password, "AAAAAAAAAAAAAAA") + || !strcmp(current.password, "BBBBBBBBBBBBBBB")); + } + writer.join(); +} +''', other) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/test_heltec_v4_wifi_setup_page.py b/test/test_heltec_v4_wifi_setup_page.py index e0c745d48..e0fcc19d0 100644 --- a/test/test_heltec_v4_wifi_setup_page.py +++ b/test/test_heltec_v4_wifi_setup_page.py @@ -83,9 +83,50 @@ class HeltecV4WiFiSetupPageTest(unittest.TestCase): page = ui[page_start:page_end] self.assertLess( page.index("drawCompactCompanionWiFiSetupPage("), - page.index("buildWiFiSetupQrPayload("), + page.index("buildCurrentWiFiSetupQrPayload("), ) + def test_qr_payload_uses_live_ap_password_and_refuses_unknown_state(self): + header = (ROOT / "src/helpers/ui/WiFiSetupQrDisplay.h").read_text() + helper = extract_braced(header, "inline bool buildCurrentWiFiSetupQrPayload(") + source = r''' +#include +#include +#include +#define WEBCONFIG_AP_PASSWORD "compiled-other" +static bool known = true; +static const char* live_password = "old;pass"; +namespace mesh { namespace wifi { +bool accessPointJoinPassword(const char* ssid, char* out, size_t capacity) { + if (!known || strcmp(ssid, "setup") || strlen(live_password) >= capacity) return false; + strcpy(out, live_password); return true; +} +} namespace ui { +@HELPER@ +} } +int main() { + char payload[256] = {}; +#if defined(ESP32_PLATFORM) + assert(mesh::ui::buildCurrentWiFiSetupQrPayload(payload, sizeof(payload), "setup")); + assert(!strcmp(payload, "WIFI:T:WPA;S:setup;P:old\\;pass;;")); + live_password = "new-admin"; + assert(mesh::ui::buildCurrentWiFiSetupQrPayload(payload, sizeof(payload), "setup")); + assert(!strcmp(payload, "WIFI:T:WPA;S:setup;P:new-admin;;")); + live_password = ""; + assert(mesh::ui::buildCurrentWiFiSetupQrPayload(payload, sizeof(payload), "setup")); + assert(!strcmp(payload, "WIFI:S:setup;;")); + assert(!mesh::ui::buildCurrentWiFiSetupQrPayload(payload, sizeof(payload), "wrong")); + known = false; + assert(!mesh::ui::buildCurrentWiFiSetupQrPayload(payload, sizeof(payload), "setup")); +#else + assert(mesh::ui::buildCurrentWiFiSetupQrPayload(payload, sizeof(payload), "setup")); + assert(!strcmp(payload, "WIFI:T:WPA;S:setup;P:compiled-other;;")); +#endif +} +'''.replace("@HELPER@", helper) + self.compile_and_run(source, "-DESP32_PLATFORM=1") + self.compile_and_run(source) + def test_short_click_leaves_page_and_hold_toggles_session_ap(self): ui = UI.read_text(encoding="utf-8") home = ui[ui.index("class HomeScreen :") :] diff --git a/test/test_indicator_render_profile.py b/test/test_indicator_render_profile.py index f3b0f2e64..ca75a0af1 100644 --- a/test/test_indicator_render_profile.py +++ b/test/test_indicator_render_profile.py @@ -184,7 +184,7 @@ int main() { self.assertIn("37, setup_ssid", page) self.assertIn("static constexpr int qr_size = 105;", page) self.assertIn("payload, qr_x, 55, qr_size", page) - self.assertIn("mesh::ui::buildWiFiSetupQrPayload", page) + self.assertIn("mesh::ui::buildCurrentWiFiSetupQrPayload", page) self.assertIn("display.setCompactText(true);", page) self.assertGreaterEqual(page.count("display.setCompactText(false);"), 2) self.assertNotIn("startFrame", page) diff --git a/test/test_lightweight_ota_auth.py b/test/test_lightweight_ota_auth.py new file mode 100644 index 000000000..b99e7bad9 --- /dev/null +++ b/test/test_lightweight_ota_auth.py @@ -0,0 +1,122 @@ +"""Run the production lightweight HTTP parser/upload gate with in-memory sockets.""" +from pathlib import Path +import unittest + +from test_replay_reset_integration import extract_braced +import test_wifi_ota_start as wifi_start + +ROOT = Path(__file__).resolve().parents[1] + +FIXTURE = r''' +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +uint32_t clock_ms = 100; +uint32_t millis() { return clock_ms; } +void delay(unsigned time) { clock_ms += time; } +int reboots = 0; +void esp_restart() { ++reboots; } +constexpr int U_FLASH = 0; +struct WiFiClient { + std::string input, output; + size_t position = 0; + bool open = true; + explicit WiFiClient(const std::string& wire) : input(wire) {} + bool connected() const { return open; } + int available() const { return input.size() - position; } + int read() { return available() ? uint8_t(input[position++]) : -1; } + int read(uint8_t* out, size_t count) { + count = count < size_t(available()) ? count : available(); + memcpy(out, input.data() + position, count); position += count; return count; + } + void print(const char* value) { output += value; } + void printf(const char* format, ...) { + char text[512]; va_list args; va_start(args, format); + int count = vsnprintf(text, sizeof(text), format, args); va_end(args); + assert(count >= 0 && size_t(count) < sizeof(text)); output.append(text, count); + } + size_t write(const uint8_t* value, size_t count) { output.append(reinterpret_cast(value), count); return count; } + void stop() { open = false; } +}; +struct ESP32Board { void setInhibitSleep(bool) {} } board; +struct UpdateFake { + int begins = 0, writes = 0, ends = 0, aborts = 0; + bool begin(size_t, int) { ++begins; return true; } + size_t write(uint8_t*, size_t count) { ++writes; return count; } + void abort() { ++aborts; } + bool end() { ++ends; return true; } + const char* errorString() { return "fixture"; } +} Update; +class LightweightOTAServer { +public: + bool running = true; + ESP32Board* board = &::board; + int pages = 0, logs = 0; + void sendPage(WiFiClient& client) { ++pages; client.print("HTTP/1.1 200 OK"); } + void sendLog(WiFiClient& client) { ++logs; client.print("HTTP/1.1 200 OK"); } +@METHODS@ +}; +int main() { + using namespace mesh::esp32::managementPassword; + LightweightOTAServer server; + auto request = [&](const char* method, const char* path, const std::string& headers, const std::string& body = "") { + WiFiClient client(std::string(method) + " " + path + " HTTP/1.1\r\n" + headers + "\r\n" + body); + server.handleClient(client); return client.output; + }; + assert(request("GET", "/update", "").find("503 Service Unavailable") != std::string::npos); + assert(publish("password")); + const std::string good = "Authorization: Basic YWRtaW46cGFzc3dvcmQ=\r\n"; + for (const char* path : {"/", "/update", "/log"}) { + const auto absent = request("GET", path, ""); + assert(absent.find("401 Unauthorized") != std::string::npos + && absent.find("WWW-Authenticate: Basic realm=\"MeshCore admin\", charset=\"UTF-8\"") != std::string::npos); + assert(request("GET", path, "Authorization: Basic wrong\r\n").find("401 Unauthorized") != std::string::npos); + assert(request("GET", path, good).find("200 OK") != std::string::npos); + } + assert(server.pages == 2 && server.logs == 1 && Update.begins == 0); + assert(request("GET", "/update", "Authorization:\r\n" + good).find("401 Unauthorized") != std::string::npos); + assert(request("GET", "/update", std::string("Authorization: ") + std::string(100, 'x') + "\r\n").find("401 Unauthorized") != std::string::npos); + const std::string payload(8, '\0'); + assert(request("POST", "/update", "Content-Length: 8\r\n", payload).find("401 Unauthorized") != std::string::npos); + assert(Update.begins == 0 && Update.writes == 0 && reboots == 0); + assert(publish("different")); + assert(request("GET", "/log", good).find("401 Unauthorized") != std::string::npos); + const std::string updated = "Authorization: Basic YWRtaW46ZGlmZmVyZW50\r\n"; + assert(request("GET", "/log", updated).find("200 OK") != std::string::npos); + { + ChangeGuard changing; assert(changing.acquired()); + assert(request("POST", "/update", updated + "Content-Length: 8\r\n", payload).find("409 Conflict") != std::string::npos); + assert(!uploadActive() && Update.begins == 0); + } + assert(request("POST", "/update", updated + "Content-Length: 8\r\n", payload).find("200 OK") != std::string::npos); + assert(Update.begins == 1 && Update.writes == 1 && Update.ends == 1 && reboots == 1 && !uploadActive()); +} +''' + + +class LightweightOtaAuthTest(unittest.TestCase): + compile_and_run = wifi_start.WiFiOtaStartTest.compile_and_run + + def test_http_routes_and_upload_admission_use_committed_admin(self): + source = (ROOT / "src/helpers/ESP32Board.cpp").read_text() + methods = "\n".join(extract_braced(source, signature) for signature in ( + " static void sendResponse(", " bool readLine(", " void sendUpdateError(", + " void receiveUpdate(", " void handleClient(")) + fixture = FIXTURE.replace("@METHODS@", methods) + self.compile_and_run(fixture) + gate = " if (auth != mesh::esp32::managementPassword::AuthResult::Authorized) {" + old = fixture.replace(gate, " if (false) {") + self.assertNotEqual(old, fixture) + with self.assertRaises(AssertionError): + self.compile_and_run(old) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/test_management_password_commands.py b/test/test_management_password_commands.py new file mode 100644 index 000000000..c01b8364d --- /dev/null +++ b/test/test_management_password_commands.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +"""Exercise production role setters against failed saves and active flash uploads.""" +from pathlib import Path +import os +import subprocess +import tempfile +import unittest + +ROOT = Path(__file__).resolve().parents[1] + + +class ManagementPasswordCommandsTest(unittest.TestCase): + def test_infrastructure_and_companion_publish_only_confirmed_saves(self): + cli = (ROOT / "src/helpers/CommonCLI.cpp").read_text() + start = cli.index(' } else if (memcmp(command, "password ", 9) == 0) {') + end = cli.index(' } else if (memcmp(command, "clear stats",', start) + infrastructure = cli[start:end].replace('} else if (', 'if (', 1) + '\n }\n' + companion = (ROOT / "examples/companion_radio/MyMesh.cpp").read_text() + start = companion.index('bool MyMesh::handleLocalControlCommand(') + end = companion.index(' if (mesh::powerdiag::handleCommand(', start) + companion = companion[start:end] + ' return false;\n}\n' + source = r''' +#include +#include +#include +#include +#include +using namespace mesh::esp32::managementPassword; +bool save_ok = true; int saves = 0; +bool durableSave() { + ++saves; Snapshot current; assert(snapshot(current)); + UploadGuard blocked(current.generation); assert(!blocked.acquired()); + return save_ok; +} +namespace mesh { namespace esp32 { namespace companionAdminPassword { +bool save(const char*) { return durableSave(); } +} } } +struct StrHelper { + static void strncpy(char* out, const char* in, size_t size) { ::strncpy(out, in, size); out[size - 1] = 0; } +}; +struct NodePrefs { char password[16] = "password"; }; +class CommonCLI { + public: + NodePrefs prefs; NodePrefs* _prefs = &prefs; + bool trySavePrefs() { return durableSave(); } + void command(char* command, char* reply) { +@INFRASTRUCTURE@ + } +}; +class MyMesh { + public: + char _management_password[16] = "password"; + bool _management_password_ready = true; + bool handleLocalControlCommand(const char*, char*, size_t); + void command(char* command, char* reply) { handleLocalControlCommand(command, reply, 160); } +}; +@COMPANION@ +void unchanged(uint32_t generation) { + Snapshot current; assert(snapshot(current)); + assert(current.generation == generation && !strcmp(current.password, "password")); +} +template void test(Role& role) { + char command[80], reply[160]; Snapshot initial; + assert(publish("password") && snapshot(initial)); + for (const char* value : {"", "1234567890123456", "bad\nvalue", "bad\rvalue"}) { + snprintf(command, sizeof(command), "password %s", value); + reply[0] = 0; const int before = saves; role.command(command, reply); + assert(!strncmp(reply, "Error:", 6) && saves == before); unchanged(initial.generation); + } + save_ok = false; strcpy(command, "password replacement"); role.command(command, reply); + assert(strstr(reply, "unconfirmed")); unchanged(initial.generation); + save_ok = true; + { + UploadGuard upload(initial.generation); assert(upload.acquired()); + const int before = saves; role.command(command, reply); + assert(strstr(reply, "busy") && saves == before); unchanged(initial.generation); + } + role.command(command, reply); assert(!strcmp(reply, "password now: replacement")); + Snapshot changed; assert(snapshot(changed)); + assert(!strcmp(changed.password, "replacement") && changed.generation == initial.generation + 1); + role.command(command, reply); assert(snapshot(changed) && changed.generation == initial.generation + 1); + strcpy(command, "password leading space"); role.command(command, reply); + assert(snapshot(changed) && !strcmp(changed.password, " leading space")); +} +int main() { + CommonCLI infrastructure; test(infrastructure); + assert(!strcmp(infrastructure.prefs.password, " leading space")); + MyMesh companion; test(companion); + assert(companion._management_password_ready && !strcmp(companion._management_password, " leading space")); +} +'''.replace("@INFRASTRUCTURE@", infrastructure).replace("@COMPANION@", companion) + with tempfile.TemporaryDirectory(prefix="management-command-") as temporary: + work = Path(temporary) + (work / "test.cpp").write_text(source) + result = subprocess.run([os.environ.get("CXX", "g++"), "-std=c++11", "-Wall", "-Wextra", "-Werror", + "-fsanitize=address,undefined", "-fno-sanitize-recover=all", "-fno-pie", "-no-pie", + "-DMESH_MANAGEMENT_PASSWORD_HOST_TEST=1", "-DESP_PLATFORM=1", "-DESP32_PLATFORM=1", '-DWIFI_SSID=""', + "-I", str(ROOT / "src"), str(work / "test.cpp"), "-o", str(work / "test")], + capture_output=True, text=True, timeout=60) + self.assertEqual(result.returncode, 0, result.stderr) + result = subprocess.run([str(work / "test")], capture_output=True, text=True, timeout=15) + self.assertEqual(result.returncode, 0, result.stdout + result.stderr) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/test_repeater_password_normalization.py b/test/test_repeater_password_normalization.py new file mode 100644 index 000000000..0e7502621 --- /dev/null +++ b/test/test_repeater_password_normalization.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +"""Exercise production Repeater normalization before the actual password setter.""" +from pathlib import Path +import os +import subprocess +import tempfile +import unittest + +ROOT = Path(__file__).resolve().parents[1] + + +class RepeaterPasswordNormalizationTest(unittest.TestCase): + def test_password_bytes_reach_the_setter_on_esp32_only(self): + repeater = (ROOT / "examples/simple_repeater/MyMesh.cpp").read_text() + start = repeater.index(" char* command_end = command + strlen(command);") + end = repeater.index("\n\n", start) + trimming = repeater[start:end] + start = repeater.index(" while (*command == ' ') command++;", end) + end = repeater.index(" mesh::cli::normalizeCommandVerb(command);", start) + end += len(" mesh::cli::normalizeCommandVerb(command);") + normalization = trimming + "\n" + repeater[start:end] + cli = (ROOT / "src/helpers/CommonCLI.cpp").read_text() + start = cli.index(' } else if (memcmp(command, "password ", 9) == 0) {') + end = cli.index(' } else if (memcmp(command, "clear stats",', start) + setter = cli[start:end].replace("} else if (", "if (", 1) + "\n }\n" + source = r''' +#include +#include +#include +#include +#include +using namespace mesh::esp32::managementPassword; +char* normalize(char* command, char* reply) { +@NORMALIZATION@ + return command; +} +struct StrHelper { + static void strncpy(char* out, const char* in, size_t capacity) { + ::strncpy(out, in, capacity); out[capacity - 1] = 0; + } +}; +struct Prefs { char password[16] = "password"; }; +struct CommonCLI { + Prefs prefs; Prefs* _prefs = &prefs; unsigned saves = 0; + bool trySavePrefs() { ++saves; return true; } + void command(char* command, char* reply) { +@SETTER@ + } +}; +void normalized(const char* input, const char* expected, const char* prefix = "") { + char command[100], reply[160] = {}; + strcpy(command, input); + assert(!strcmp(normalize(command, reply), expected)); + assert(!strcmp(reply, prefix)); +} +int main() { + normalized(" aB|Get name \t\r\n", "get name", "aB|"); + normalized(" Passwordx value \t\r\n", "passwordx value"); +#ifdef ESP_PLATFORM + normalized(" aB|PaSsWoRd leading \t", "password leading \t", "aB|"); + normalized("password secret123 ", "password secret123 "); + normalized("Password secret123\r\n", "password secret123\r\n"); + CommonCLI cli; + assert(publish("password")); + char command[100] = " aB|PaSsWoRd leading ", reply[160] = {}; + cli.command(normalize(command, reply), reply); + assert(cli.saves == 1 && !strcmp(cli.prefs.password, " leading ")); + Snapshot current; assert(snapshot(current)); + assert(!strcmp(current.password, " leading ")); + const uint32_t generation = current.generation; + for (const char* invalid : {"password secret123\r\n", "password bad\nvalue", "password bad\rvalue", "password "}) { + strcpy(command, invalid); + cli.command(normalize(command, reply), reply); + assert(!strncmp(reply, "Error:", 6) && cli.saves == 1); + assert(!strcmp(cli.prefs.password, " leading ")); + assert(snapshot(current) && current.generation == generation); + } +#else + normalized(" aB|PaSsWoRd leading \t\r\n", "password leading", "aB|"); + normalized("password secret123 ", "password secret123"); + normalized("Password secret123\r\n", "password secret123"); +#endif +} +'''.replace("@NORMALIZATION@", normalization).replace("@SETTER@", setter) + source = source.replace("#include ", "#include \n#include ") + with tempfile.TemporaryDirectory(prefix="repeater-password-") as temporary: + work = Path(temporary) + for platform in ("ESP_PLATFORM", "NRF52_PLATFORM", "STM32_PLATFORM"): + with self.subTest(platform=platform): + self._compile_and_run(work, source, platform) + # The old blanket trim must demonstrably break this regression. + mutant = source.replace('if (strcmp(command_verb, "password ") != 0)', + 'if (true)') + result = self._compile_and_run(work, mutant, "ESP_PLATFORM", expect_pass=False) + self.assertNotEqual(result.returncode, 0) + + def _compile_and_run(self, work, source, platform, expect_pass=True): + (work / "test.cpp").write_text(source) + result = subprocess.run([ + os.environ.get("CXX", "g++"), "-std=c++11", "-Wall", "-Wextra", "-Werror", + "-fsanitize=address,undefined", "-fno-sanitize-recover=all", "-fno-pie", "-no-pie", + "-DMESH_MANAGEMENT_PASSWORD_HOST_TEST=1", f"-D{platform}=1", + "-I", str(ROOT / "src"), str(work / "test.cpp"), "-o", str(work / "test"), + ], capture_output=True, text=True, timeout=60) + self.assertEqual(result.returncode, 0, result.stderr) + result = subprocess.run([str(work / "test")], capture_output=True, text=True, timeout=15) + if expect_pass: + self.assertEqual(result.returncode, 0, result.stdout + result.stderr) + return result + + +if __name__ == "__main__": + unittest.main() diff --git a/test/test_sensor_webconfig_capabilities.py b/test/test_sensor_webconfig_capabilities.py index ec58d4259..e8b533ee0 100644 --- a/test/test_sensor_webconfig_capabilities.py +++ b/test/test_sensor_webconfig_capabilities.py @@ -130,6 +130,8 @@ for value in "${BUILD_APPLICATION_EXPECTATIONS[@]}"; do printf 'A:%s\0' "$value" start = source.index(' } else if (memcmp(command, "start ota", 9)') ota = source[start:source.index(' } else if (memcmp(command, "clock", 5)', start)] fixture = r''' +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST 1 +#include #include #include #include @@ -153,7 +155,7 @@ struct Board { } bool stopOTAUpdate(char* reply) { ++stops; strcpy(reply, "Stopped OTA"); return true; } }; -struct Prefs { const char* node_name = "sensor"; }; +struct Prefs { const char* node_name = "sensor"; char password[16] = "password"; }; struct CLI { Callbacks* _callbacks; Board* _board; diff --git a/test/test_webconfig_ap_start.py b/test/test_webconfig_ap_start.py index 7307594f5..2033afff0 100644 --- a/test/test_webconfig_ap_start.py +++ b/test/test_webconfig_ap_start.py @@ -29,7 +29,7 @@ class WebConfigApStartTest(unittest.TestCase): helper += extract_braced(source, "static bool setupAccessPointReady(") + "\n" if "static bool scanSetupNetworks(" in source: helper += extract_braced(source, "static bool scanSetupNetworks(") - method = extract_braced(source, "bool WebConfigServer::startSetupMode(") + method = extract_braced(source, "void WebConfigServer::initializeManagementPassword(") + "\n" + extract_braced(source, "bool WebConfigServer::startSetupMode(") scan_handler = extract_braced(source, "void WebConfigServer::handleScan(") policy = (ROOT / "src/helpers/esp32/WiFiRadioPolicy.h").read_text(encoding="utf-8") mask = policy[policy.index("static constexpr uint8_t kAccessPointProtocolMask ="):] @@ -51,19 +51,22 @@ class WebConfigApStartTest(unittest.TestCase): binary = work / "webconfig-ap-start.exe" sanitizer = (["-fsanitize=address,undefined", "-fno-sanitize-recover=all", "-fno-pie", "-no-pie"] if sys.platform.startswith("linux") else []) - for arduino_major, protected in ((2, False), (2, True), (3, False), (3, True)): - with self.subTest(arduino_major=arduino_major, protected=protected): - security_flags = ['-DWEBCONFIG_AP_PASSWORD="testpass"'] if protected else [] - compiled = subprocess.run([compiler, "-std=c++17", "-Wall", "-Wextra", - *sanitizer, f"-DESP_ARDUINO_VERSION_MAJOR={arduino_major}", - *security_flags, - str(generated), "-o", str(binary)], - capture_output=True, text=True, timeout=60) - self.assertEqual(compiled.returncode, 0, compiled.stdout + compiled.stderr) - checked = subprocess.run([str(binary)], capture_output=True, - text=True, timeout=15) - self.assertEqual(checked.returncode, 0, checked.stdout + checked.stderr) - self.assertIn("WebConfig AP startup regression checks passed", checked.stdout) + for arduino_major in (2, 3): + for password in ("", "runtimepass", "short", "long-é-pass"): + with self.subTest(arduino_major=arduino_major, password_kind="protected" if password == "runtimepass" else "legacy"): + security_flags = ['-DTEST_ADMIN_PASSWORD="' + password + '"'] + # This obsolete build secret must never select AP security. + security_flags += ['-DWEBCONFIG_AP_PASSWORD="unused-old-key"'] + compiled = subprocess.run([compiler, "-std=c++17", "-Wall", "-Wextra", + *sanitizer, f"-DESP_ARDUINO_VERSION_MAJOR={arduino_major}", + *security_flags, "-I" + str(ROOT / "src"), + str(generated), "-o", str(binary)], + capture_output=True, text=True, timeout=60) + self.assertEqual(compiled.returncode, 0, compiled.stdout + compiled.stderr) + checked = subprocess.run([str(binary)], capture_output=True, + text=True, timeout=15) + self.assertEqual(checked.returncode, 0, checked.stdout + checked.stderr) + self.assertIn("WebConfig AP startup regression checks passed", checked.stdout) if __name__ == "__main__": diff --git a/test/test_webconfig_lost_reply.py b/test/test_webconfig_lost_reply.py index a3b573423..6a23b9a7e 100644 --- a/test/test_webconfig_lost_reply.py +++ b/test/test_webconfig_lost_reply.py @@ -44,6 +44,10 @@ class LostReplyWebConfigTest(unittest.TestCase): allowed = extract_braced(server, "static bool isAllowedSetKey(") secret = extract_braced(server, "static bool isSecretKey(") post = extract_braced(server, "void WebConfigServer::handleConfigPost(") + auth = "\n".join(extract_braced(server, signature) for signature in ( + "static bool fixedTimeEquals(", "static bool webConfigCookieMatches(", + "void WebConfigServer::clearSessionLocked(", "bool WebConfigServer::checkAuthLocked(", + "bool WebConfigServer::checkAuth(", "void WebConfigServer::beginBatchAuthorizationLocked(")) get = extract_braced(server, "void WebConfigServer::handleConfigGet(") # Execute the actual snapshot-to-radio JSON branch. WiFi/MQTT fields # after this boundary are unrelated and require peripheral fixtures. @@ -61,11 +65,24 @@ class LostReplyWebConfigTest(unittest.TestCase): #include #include #include +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST 1 +#include #include "helpers/WebConfigKeys.h" #include "helpers/WebConfigBatch.h" -using String = std::string; +struct String : std::string { + using std::string::string; + String(std::string value) : std::string(std::move(value)) {} + int indexOf(const char* value) const { auto pos = find(value); return pos == npos ? -1 : int(pos); } + String substring(int begin, int end) const { return substr(begin, end - begin); } + size_t write(uint8_t value) { push_back(char(value)); return 1; } + size_t write(const uint8_t* data, size_t count) { append(reinterpret_cast(data), count); return count; } +}; struct WCLock { explicit WCLock(int) {} }; uint32_t millis() { return 1; } +static constexpr uint32_t WEBCONFIG_SESSION_TTL_MS = 120000; +struct WiFiMock { int softAPIP() const { return 4; } } WiFi; +struct Client { int localIP() const { return 4; } }; +struct Header { String cookies = "wcs=0123456789abcdef0123456789abcdef"; const String& value() const { return cookies; } }; namespace mesh { struct Port { template void printf(const char*, Args...) {} }; Port& usbDebugPort() { static Port port; return port; } @@ -75,11 +92,16 @@ static const char SECRET_SENTINEL[] = "********"; @ALLOWED@ @SECRET@ struct AsyncWebServerRequest { + Client socket; + Header header; String input, output; void* _tempObject = nullptr; int status = 0; explicit AsyncWebServerRequest(String body = "") : input(body) { _tempObject = input.data(); } size_t contentLength() const { return input.size(); } + Client* client() { return &socket; } + bool hasHeader(const char*) const { return !header.cookies.empty(); } + Header* getHeader(const char*) { return &header; } void send(int code, const char* = nullptr, const String& body = "") { status = code; output = body; } }; struct WebConfigServer { @@ -95,9 +117,15 @@ struct WebConfigServer { static constexpr size_t MAX_BODY = 4096; static constexpr int MAX_BATCH = WebConfigBatch::kMaxBatch; int _mode = MODE_LAN, _mux = 0, _batch_kind = BATCH_CONFIG; - bool authorized = true, _initial_setup = false, _batch_reboot = false; + bool _initial_setup = false, _setup_provisioning_privilege = false, _batch_reboot = false; bool _batch_reboot_armed = false, _batch_all_ok = true; bool _standalone_wifi_dirty = false, _setup_wifi_handoff_pending = false; + bool _batch_reauth_required = false, _batch_reauth_delivered = false, _batch_started = false; + uint32_t _session_generation = 0, _session_last_seen = 1, _last_activity = 0; + uint32_t _batch_auth_generation = 0, _batch_reauth_until = 0; + uint32_t _ap_auth_generation = 0; + char _session_token[33] = "0123456789abcdef0123456789abcdef"; + char _batch_owner_token[33] = {}, _wifi_ssid[33] = "fixture-network"; uint32_t _setup_wifi_handoff_deadline = 0, _diag_until = 0; char _setup_wifi_handoff_ip[32] = {}, _batch_reqid[17] = {}; int _batch_count = 0, _batch_next = 0; @@ -106,16 +134,27 @@ struct WebConfigServer { WebConfigBatch::State _batch_state = WebConfigBatch::State::Idle; static constexpr auto BATCH_PENDING = WebConfigBatch::State::Pending; static WebConfigBatch::State toSpecState(WebConfigBatch::State state) { return state; } - bool checkAuth(AsyncWebServerRequest*) { return authorized; } + WebConfigServer() { + mesh::esp32::managementPassword::Snapshot current; + assert(mesh::esp32::managementPassword::snapshot(current)); + _session_generation = current.generation; + } + void noteNetworkActivity() {} + void clearSessionLocked(); + bool checkAuthLocked(AsyncWebServerRequest*, uint32_t* generation = nullptr); + bool checkAuth(AsyncWebServerRequest*); + void beginBatchAuthorizationLocked(uint32_t); void handleConfigGet(AsyncWebServerRequest*); void handleConfigPost(AsyncWebServerRequest*); }; +@AUTH_HELPERS@ @GET@ @POST@ String writeBody(const char* value) { return String("{\"reqid\":\"0123456789abcdef\",\"set\":{\"lost.reply\":") + value + "}}"; } int main() { + assert(mesh::esp32::managementPassword::publish("password")); const char* modes[] = {"off", "no", "yes"}; for (int value : {0, 1, 2, 255}) { WebConfigServer server; @@ -155,7 +194,7 @@ int main() { infrastructure.handleConfigPost(&forged); assert(forged.status == 400 && forged.output.find("setting unavailable") != String::npos); assert(infrastructure._batch_count == 0); - infrastructure.authorized = false; + infrastructure.clearSessionLocked(); AsyncWebServerRequest unauthorized(writeBody("\"yes\"")); infrastructure.handleConfigPost(&unauthorized); assert(unauthorized.status == 401 && infrastructure._batch_count == 0); @@ -164,7 +203,7 @@ int main() { } '''.replace("@CAPABILITY@", capability).replace("@SNAPSHOT@", snapshot).replace( "@BATCH_ENTRY@", batch_entry).replace("@ALLOWED@", allowed).replace( - "@SECRET@", secret).replace("@GET@", get).replace("@POST@", post) + "@SECRET@", secret).replace("@AUTH_HELPERS@", auth).replace("@GET@", get).replace("@POST@", post) def test_actual_json_strings_and_capability_gated_settings_batch(self): # The shared compiler helper needs the production helper include path. diff --git a/test/test_webconfig_password_sessions.py b/test/test_webconfig_password_sessions.py new file mode 100644 index 000000000..6d8923a99 --- /dev/null +++ b/test/test_webconfig_password_sessions.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 +"""Execute production credential-generation and AP-rekey decisions offline.""" +from pathlib import Path +import shutil +import subprocess +import sys +import tempfile +import unittest + +from test_replay_reset_integration import extract_braced + +ROOT = Path(__file__).resolve().parents[1] + + +class WebConfigPasswordSessionsTest(unittest.TestCase): + def compile_run(self, source, expect_rejection=False, includes=()): + compiler = shutil.which("g++") or shutil.which("clang++") + self.assertIsNotNone(compiler) + with tempfile.TemporaryDirectory(prefix="webconfig-password-sessions-") as directory: + work = Path(directory) + generated = work / "fixture.cpp" + generated.write_text(source) + binary = work / "fixture" + sanitizer = (["-fsanitize=address,undefined", "-fno-sanitize-recover=all", + "-fno-pie", "-no-pie"] if sys.platform.startswith("linux") else []) + compiled = subprocess.run([compiler, "-std=c++17", "-Wall", "-Wextra", + *sanitizer, "-I" + str(ROOT / "src"), + *("-I" + str(path) for path in includes), str(generated), "-o", str(binary)], + capture_output=True, text=True, timeout=60) + self.assertEqual(compiled.returncode, 0, compiled.stderr) + checked = subprocess.run([str(binary)], capture_output=True, text=True, timeout=10) + if expect_rejection: + self.assertNotEqual(checked.returncode, 0, checked.stdout + checked.stderr) + self.assertIn("Assertion", checked.stderr) + else: + self.assertEqual(checked.returncode, 0, checked.stdout + checked.stderr) + + def rekey_fixture(self): + source = (ROOT / "src/helpers/esp32/WebConfigServer.cpp").read_text() + method = extract_braced(source, "void WebConfigServer::serviceSetupPassword(") + return (ROOT / "test/fixtures/webconfig_password_sessions.cpp").read_text().replace("@METHODS@", method) + + def test_rekey_receipt_upload_and_failure_lifecycle(self): + self.compile_run(self.rekey_fixture()) + + def test_failed_rekey_must_remove_old_key_access_point(self): + fixture = self.rekey_fixture() + # An early platform failure leaves the old AP intact unless the owner + # explicitly removes it. Prove the fixture detects that original bug. + old = fixture.replace(" WiFi.softAPdisconnect(true);\n", "", 1) + self.assertNotEqual(old, fixture) + self.compile_run(old, expect_rejection=True) + + def batch_fixture(self): + source = (ROOT / "src/helpers/esp32/WebConfigServer.cpp").read_text() + methods = "\n".join(extract_braced(source, signature) for signature in ( + "static bool fixedTimeEquals(", + "void WebConfigServer::clearSessionLocked(", + "void WebConfigServer::beginBatchAuthorizationLocked(", + "void WebConfigServer::cancelStaleBatchLocked(")) + drain = extract_braced(source, "void WebConfigServer::drainBatch(") + start = drain[drain.index(" if (_batch_next == 0)"):drain.index(" } else if")] + methods += "\nvoid WebConfigServer::startBatch(uint32_t now) {\n" + start + "\n }\n}\n" + first_guard = drain.index(" WCLock prefs_lock", drain.index(" } else if")) + guard = drain[first_guard:drain.index(" BatchEntry& e", first_guard)] + methods += "\nvoid WebConfigServer::beforeCommand(uint32_t now) {\n" + guard + "\n++executed;\n}\n" + post = drain[drain.index(" mesh::esp32::managementPassword::Snapshot committed;"):drain.index(" _batch_last_cmd =")] + methods += "\nvoid WebConfigServer::afterCommand(bool password_command, const char* requested, const char* reply, uint32_t now) {\nchar requested_password[16] = {}; strcpy(requested_password, requested);\nBatchEntry e = {}; strcpy(e.reply, reply);\n" + post + "\npost_completed = true;\n}\n" + return (ROOT / "test/fixtures/webconfig_password_batch.cpp").read_text().replace("@METHODS@", methods) + + def test_committed_password_revokes_session_and_stale_queue(self): + self.compile_run(self.batch_fixture()) + + def test_successful_commit_must_revoke_general_session(self): + fixture = self.batch_fixture() + old = fixture.replace(" clearSessionLocked();", "", 1) + self.assertNotEqual(old, fixture) + self.compile_run(old, expect_rejection=True) + + def receipt_fixture(self): + source = (ROOT / "src/helpers/esp32/WebConfigServer.cpp").read_text() + config = extract_braced(source, "void WebConfigServer::handleConfigResult(") + cli = extract_braced(source, "void WebConfigServer::handleCliResult(") + config_loop = extract_braced(config, " for (int i = 0;") + cli_loop = extract_braced(cli, " for (int i = from;") + return (ROOT / "test/fixtures/webconfig_password_receipt.cpp").read_text().replace( + "@CONFIG_LOOP@", config_loop).replace("@CLI_LOOP@", cli_loop) + + def receipt_json_include(self): + header = next((ROOT / ".pio/libdeps").glob("*/ArduinoJson/src/ArduinoJson.h"), None) + self.assertIsNotNone(header, "native dependency headers are required") + return (header.parent,) + + def test_old_cookie_receipt_sanitizes_every_arbitrary_reply(self): + self.compile_run(self.receipt_fixture(), includes=self.receipt_json_include()) + + def test_unfiltered_cli_receipt_fails_executable_regression(self): + fixture = self.receipt_fixture() + old = fixture.replace('r["reply"] = !receipt_only ?', 'r["reply"] = true ?', 1) + self.assertNotEqual(old, fixture) + self.compile_run(old, expect_rejection=True, includes=self.receipt_json_include()) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/test_webconfig_recovery_auth.py b/test/test_webconfig_recovery_auth.py index 0240d1460..22f319d5c 100644 --- a/test/test_webconfig_recovery_auth.py +++ b/test/test_webconfig_recovery_auth.py @@ -41,7 +41,11 @@ class WebConfigRecoveryAuthTest(unittest.TestCase): def fixture(self): source = (ROOT / "src/helpers/esp32/WebConfigServer.cpp").read_text() methods = "\n".join(extract_braced(source, signature) for signature in ( - "static bool fixedTimeEquals(", "bool WebConfigServer::checkAuth(", + "static bool fixedTimeEquals(", "static bool webConfigCookieMatches(", + "void WebConfigServer::clearSessionLocked(", + "bool WebConfigServer::checkAuthLocked(", "bool WebConfigServer::checkAuth(", + "void WebConfigServer::beginBatchAuthorizationLocked(", + "bool WebConfigServer::resultReceiptAllowedLocked(", "void WebConfigServer::handleLogin(", "void WebConfigServer::handleLogout(")) # The actual config POST entry gate must reject a replacement password # before parsing or queueing it; exercise its exact production prefix. @@ -55,7 +59,8 @@ class WebConfigRecoveryAuthTest(unittest.TestCase): def test_old_interface_only_fallback_fails_executable_regression(self): fixture = self.fixture() - old = fixture.replace("if (_initial_setup || _wifi_ssid[0] == 0) { noteNetworkActivity(); return true; }", "return true;", 1) + old = fixture.replace(" } else if (_mode != MODE_LAN) {", + " return true;\n } else if (_mode != MODE_LAN) {", 1) self.assertNotEqual(old, fixture) self.compile_run(old, expect_rejection=True) @@ -64,7 +69,7 @@ class WebConfigRecoveryAuthTest(unittest.TestCase): signature = "void WebConfigServer::handleLogout(" start = fixture.index(signature, fixture.index("@METHODS@") if "@METHODS@" in fixture else 0) prefix, logout = fixture[:start], fixture[start:] - gate = ' if (!checkAuth(req)) { req->send(401, "application/json", "{\\"error\\":\\"auth\\"}"); return; }\n' + gate = ' if (!checkAuthLocked(req)) { req->send(401, "application/json", "{\\"error\\":\\"auth\\"}"); return; }\n' old = prefix + logout.replace(gate, "", 1) self.assertNotEqual(old, fixture) self.compile_run(old, expect_rejection=True) diff --git a/test/test_webconfig_secret_masking.py b/test/test_webconfig_secret_masking.py index 2db4724f0..00eb787f2 100644 --- a/test/test_webconfig_secret_masking.py +++ b/test/test_webconfig_secret_masking.py @@ -3,6 +3,9 @@ import gzip from pathlib import Path import re +import shutil +import subprocess +import tempfile import unittest @@ -131,6 +134,78 @@ class WebConfigSecretMaskingTest(unittest.TestCase): self.assertIn("_mode != MODE_LAN", handler) self.assertIn("checkAuth(req)", handler) + def password_reply_fixture(self): + batch = function_body(self.server, "void WebConfigServer::drainBatch(", + "void WebConfigServer::attachRoutes(") + start = batch.index(" _cb->execCommand(e.cmd, e.reply);") + snippet = batch[start:batch.index(" // Keep the response snapshot", start)] + return r''' +#include +#include +#include +struct Callback { + const char* result; + void execCommand(char*, char* reply) { strcpy(reply, result); } +}; +struct Fixture { + Callback cb{}, *_cb = &cb; + bool _admin_pwd_set = false; + struct { char cmd[160] = "password new-secret"; char reply[160] = {}; } e; + bool run(const char* reply) { + cb.result = reply; + _admin_pwd_set = false; + const bool admin_pwd = true; +@SNIPPET@ + if (e.reply[0] == 0) strcpy(e.reply, "OK"); + return WebConfigBatch::nextAllOk(true, strncmp(e.reply, "OK", 2) == 0); + } +}; +int main() { + Fixture fixture; + assert(fixture.run("password now: new-secret")); + assert(!strcmp(fixture.e.reply, "OK") && fixture._admin_pwd_set); + assert(fixture.run("OK")); + for (const char* error : {"Error: save unconfirmed; reboot may differ", + "Error: unsupported command", ""}) { + const bool saved = fixture.run(error); + assert(!saved && !fixture._admin_pwd_set); + assert(strncmp(fixture.e.reply, "Error:", 6) == 0); + assert(WebConfigBatch::finishRebootAt(true, saved, 10) == 0); + if (error[0]) assert(!strcmp(fixture.e.reply, error)); + } +} +'''.replace("@SNIPPET@", snippet) + + def compile_password_reply_fixture(self, fixture, *, reject=False): + compiler = shutil.which("g++") or shutil.which("clang++") + if not compiler: + self.skipTest("host C++ compiler unavailable") + with tempfile.TemporaryDirectory(prefix="webconfig-password-reply-") as tmp: + path = Path(tmp) + source = path / "test.cpp" + binary = path / "test" + source.write_text(fixture) + result = subprocess.run([compiler, "-std=c++17", "-include", "initializer_list", + "-I", str(ROOT / "src"), str(source), "-o", str(binary)], + capture_output=True, text=True, timeout=30) + self.assertEqual(result.returncode, 0, result.stderr) + result = subprocess.run([str(binary)], capture_output=True, text=True, timeout=10) + if reject: + self.assertNotEqual(result.returncode, 0) + self.assertIn("Assertion", result.stderr) + else: + self.assertEqual(result.returncode, 0, result.stderr) + + def test_password_form_masks_success_but_preserves_failed_save(self): + self.compile_password_reply_fixture(self.password_reply_fixture()) + + def test_old_unconditional_password_mask_fails_regression(self): + fixture = self.password_reply_fixture() + old = fixture.replace("if (admin_pwd && WebConfigBatch::cliPasswordChanged(e.reply)) {", + "if (admin_pwd) {", 1) + self.assertNotEqual(old, fixture) + self.compile_password_reply_fixture(old, reject=True) + if __name__ == "__main__": unittest.main() diff --git a/test/test_webconfig_ui_runtime.py b/test/test_webconfig_ui_runtime.py index de2162e7b..a24015a8b 100644 --- a/test/test_webconfig_ui_runtime.py +++ b/test/test_webconfig_ui_runtime.py @@ -964,5 +964,180 @@ window.addEventListener("load",function(){ self.assertIn('data-test-capture="clear"', dom) + def test_password_save_receipt_reauth_preserves_results_and_never_resends(self): + for case in ("saved", "partial", "failed", "legacy401", "login_retry", "reboot"): + with self.subTest(case=case): + status, config = self.setup_values() + status.update(mode="setup" if case == "legacy401" else "lan") + prelude = r'''''' % (json.dumps(case), json.dumps(status), json.dumps(config)) + dom = self.run_page(prelude, virtual_time=1900) + for attr, expected in (("posts", "1"), ("wrong-login", "false"), + ("early-refresh", "0"), ("storage-writes", "0"), + ("login-visible", "false")): + self.assertIn(f'data-test-{attr}="{expected}"', dom) + self.assertIn('data-test-logins="%s"' % ( + "0" if case == "failed" else "2" if case == "login_retry" else "1"), dom) + self.assertIn('data-test-polls="%s"' % ("2" if case in ("failed", "legacy401") else "3"), dom) + self.assertIn('data-test-reboot="%s"' % str(case == "reboot").lower(), dom) + self.assertIn('data-test-password-cleared="%s"' % str(case != "failed").lower(), dom) + self.assertIn('data-test-password-dirty="%s"' % str(case == "failed").lower(), dom) + self.assertIn('data-test-wizard-visible="%s"' % str(case == "legacy401").lower(), dom) + if case == "partial": + self.assertIn('data-test-name-dirty="true"', dom) + self.assertIn('data-test-name-error="true"', dom) + self.assertIn('data-test-name-detail="true"', dom) + self.assertIn("some settings were rejected. The node will not reboot.", dom) + if case == "failed": + self.assertIn('data-test-password-error="true"', dom) + if case == "login_retry": + self.assertIn('data-test-intermediate-login="true"', dom) + self.assertIn('data-test-intermediate-note="Settings saved.', dom) + + def test_cli_password_receipt_uses_last_success_and_stream_never_replays(self): + for streaming in (False, True): + with self.subTest(streaming=streaming): + status, config = self.setup_values() + status.update(mode="lan", cli=True, terminal_stream=streaming) + prelude = r'''''' % (json.dumps(streaming), json.dumps(status), json.dumps(config)) + dom = self.run_page(prelude, virtual_time=1800) + for attr, expected in (("posts", "1"), ("logins", "1"), + ("wrong-login", "false"), ("early-refresh", "0"), ("busy", "false"), + ("login-visible", "false"), ("reboot", "false")): + self.assertIn(f'data-test-{attr}="{expected}"', dom) + self.assertIn('data-test-stream-reset="true"', dom) + if not streaming: + self.assertIn('data-test-withheld="true"', dom) + self.assertIn('data-test-error-detail="true"', dom) + + def test_admin_password_validation_counts_utf8_bytes(self): + status, config = self.setup_values() + status.update(mode="lan") + vectors = ["", "a" * 15, "a" * 16, "é" * 7 + "a", "é" * 8, + "🙂" * 3 + "abc", "🙂" * 4, "line\nbreak", "line\rbreak", "\ud800"] + prelude = r'''''' % (json.dumps(status), json.dumps(config), json.dumps(vectors)) + dom = self.run_page(prelude) + self.assertIn('data-test-password-validation="valid,valid,invalid,valid,invalid,valid,invalid,invalid,invalid,invalid"', dom) + + if __name__ == "__main__": unittest.main() diff --git a/test/test_wifi_ota_lifecycle.py b/test/test_wifi_ota_lifecycle.py index c26557896..81d9cc951 100644 --- a/test/test_wifi_ota_lifecycle.py +++ b/test/test_wifi_ota_lifecycle.py @@ -24,6 +24,9 @@ SCENARIOS = ( STUBS = r''' #include +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST 1 +#include +static const bool published_password = mesh::esp32::managementPassword::publish("short"); #include #include #include @@ -40,11 +43,12 @@ constexpr int WL_CONNECTED = 3, WL_DISCONNECTED = 6, HTTP_GET = 0; enum wifi_mode_t { WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2 }; constexpr wifi_mode_t WIFI_MODE_NULL = WIFI_OFF; constexpr wifi_mode_t WIFI_MODE_AP = WIFI_AP; -constexpr int WIFI_IF_STA = 0, WIFI_IF_AP = 1, WIFI_AUTH_OPEN = 0; +constexpr int WIFI_IF_STA = 0, WIFI_IF_AP = 1, WIFI_AUTH_OPEN = 0, WIFI_AUTH_WPA2_PSK = 3; constexpr int WIFI_SCAN_RUNNING = -1, AP_STARTED_BIT = 1; struct wifi_config_t { struct { uint8_t ssid[32] = {}; + uint8_t password[64] = {}; uint8_t ssid_len = 0, ssid_hidden = 0, channel = 1; int authmode = WIFI_AUTH_OPEN; } ap; @@ -104,13 +108,15 @@ struct MockWiFi { configured_ap_ip = ip; return ap_config_ok; } - bool softAP(const char* ssid, const char*, int channel = 1) { + bool softAP(const char* ssid, const char* password, int channel = 1) { assert(channel == 1); ++ap_start_calls; if (ap_start_ok) { sdk_initialized = sdk_started = sdk_ap_active = true; initialized_cache = started_cache = true; ap_ip = configured_ap_ip; + ap_config.ap.authmode = password && password[0] ? WIFI_AUTH_WPA2_PSK : WIFI_AUTH_OPEN; + if (password) strcpy(reinterpret_cast(ap_config.ap.password), password); ap_config.ap.ssid_len = strlen(ssid); memcpy(ap_config.ap.ssid, ssid, strlen(ssid)); ap_config.ap.channel = channel; @@ -167,6 +173,8 @@ struct AsyncWebServer { }; struct MockElegantOTA { void setID(const char*) {} + void useManagementPassword() {} + bool authenticateRequest(AsyncWebServerRequest*) { return true; } void begin(AsyncWebServer* server) { assert(server != nullptr); } bool setEnabled(bool) { return true; } } AsyncElegantOTA; @@ -182,6 +190,7 @@ public: ~ESP32Board() { delete ota_server; } const char* getManufacturerName() const { return "test board"; } bool startOTAUpdate(const char* id, char reply[], bool force_ap); + static bool rotateOTAAccessPoint(void*) { return true; } @OTA_RUNNING@ } board; @@ -408,7 +417,7 @@ class WifiOtaLifecycleTests(unittest.TestCase): def assert_healthy_ota(self, scenario, url, ap_starts): observation = self.observations[scenario] self.assertTrue(observation["first_started"] and observation["started"]) - network = "Join WiFi MeshCore-OTA" if url == "192.168.4.1" else "Use same WiFi/LAN" + network = "Join WiFi MeshCore-OTA (OPEN compatibility; HTTP admin login)" if url == "192.168.4.1" else "Use same WiFi/LAN" self.assertEqual(observation["reply"], f"Started: http://{url}/update - WiFi on; {network}") self.assertEqual(observation["server_count"], 1) self.assertEqual(observation["server_begin_calls"], 1) diff --git a/test/test_wifi_ota_start.py b/test/test_wifi_ota_start.py index 788783ced..3537a9ac3 100644 --- a/test/test_wifi_ota_start.py +++ b/test/test_wifi_ota_start.py @@ -103,6 +103,7 @@ struct PortalImpl { void* callback_context = nullptr; volatile bool* active = nullptr; uint32_t close_ap_at = 0, recovery_interval_ms = 0; + uint32_t ap_password_generation = 0, rekey_generation = 0, rekey_at = 0; char recovery_ssid[32] = {}, ap_name[33] = {}; bool recovery_connecting = false; }; @@ -168,6 +169,142 @@ int main() { with self.subTest(arduino_major=major): self.compile_and_run(fixture, f"-DESP_ARDUINO_VERSION_MAJOR={major}") + def test_management_ap_uses_current_password_and_rekeys_after_response_grace(self): + source = (ROOT / "src/helpers/ESP32Board.cpp").read_text() + lightweight, elegant = source.split("#elif defined(ADMIN_PASSWORD) && !defined(DISABLE_WIFI_OTA)", 1) + for implementation, flags in ((lightweight, ["-DLIGHTWEIGHT_WIFI_OTA=1"]), (elegant, [])): + with self.subTest(flags=flags): + methods = "\n".join(extract_braced(implementation, signature) for signature in ( + "bool ESP32Board::startOTAUpdate(", "bool ESP32Board::stopOTAUpdate(")) + methods += "\n" + extract_braced(source, "bool ESP32Board::rotateOTAAccessPoint(") + fixture = self.ap_fixture().split("int main() {", 1)[0] + fixture = fixture.replace("static bool rotateOTAAccessPoint(void*) { return true; }", + "static bool rotateOTAAccessPoint(void*);") + fixture = fixture.replace("@METHODS@", methods) + r''' +int main() { + using namespace mesh::esp32::managementPassword; + assert(publish("password")); + ESP32Board board; char reply[160]; + assert(board.startOTAUpdate("fixture", reply, true)); + assert(strstr(reply, "(admin password)") && WiFi.connected); + assert(WiFi.live_config.ap.authmode == WIFI_AUTH_WPA2_PSK); + assert(!strcmp(reinterpret_cast(WiFi.live_config.ap.password), "password")); + const unsigned starts = WiFi.starts; + assert(board.startOTAUpdate("fixture", reply, true) && WiFi.starts == starts); + // Reuse must check the actual driver password, not just authmode/SSID. + strcpy(reinterpret_cast(WiFi.live_config.ap.password), "stale-password"); + assert(board.startOTAUpdate("fixture", reply, true) && WiFi.starts == starts + 1); + Snapshot current; snapshot(current); + { + UploadGuard upload(current.generation); assert(upload.acquired()); + assert(!publish("new-password")); + assert(!board.stopOTAUpdate(reply) && strstr(reply, "upload active")); + } + assert(publish("new-password")); + const unsigned before = WiFi.starts; + service(100); service(849); assert(WiFi.starts == before); + service(850); assert(WiFi.starts == before + 1 && WiFi.connected); + assert(!strcmp(reinterpret_cast(WiFi.live_config.ap.password), "new-password")); + assert(publish("tiny")); service(1000); service(1750); + assert(WiFi.live_config.ap.authmode == WIFI_AUTH_OPEN && WiFi.connected); + assert(board.startOTAUpdate("fixture", reply, true) && strstr(reply, "OPEN compatibility")); + assert(board.stopOTAUpdate(reply)); + assert(!WiFi.ap && WiFi.connected); // Preserve the station owner. +} +''' + self.compile_and_run(fixture, *flags, "-DESP_ARDUINO_VERSION_MAJOR=2") + + def test_ota_refuses_missing_or_empty_published_admin_before_network_effects(self): + source = (ROOT / "src/helpers/ESP32Board.cpp").read_text() + lightweight, elegant = source.split("#elif defined(ADMIN_PASSWORD) && !defined(DISABLE_WIFI_OTA)", 1) + for implementation, flags in ((lightweight, ["-DLIGHTWEIGHT_WIFI_OTA=1"]), (elegant, [])): + methods = "\n".join(extract_braced(implementation, signature) for signature in ( + "bool ESP32Board::startOTAUpdate(", "bool ESP32Board::stopOTAUpdate(")) + fixture = self.ap_fixture().split("int main() {", 1)[0] + fixture = fixture.replace('static const bool published_password = mesh::esp32::managementPassword::publish("short");', "") + fixture = fixture.replace("@METHODS@", methods) + r''' +int main() { + ESP32Board board; char reply[160]; + assert(!board.startOTAUpdate("fixture", reply, true)); + assert(!WiFi.starts && !server_starts && !board.inhibit_sleep); + assert(mesh::esp32::managementPassword::initialize("")); + assert(!board.startOTAUpdate("fixture", reply, true)); + assert(!WiFi.starts && !server_starts && !board.inhibit_sleep); +} +''' + self.compile_and_run(fixture, *flags, "-DESP_ARDUINO_VERSION_MAJOR=2") + + def test_elegant_root_and_log_do_not_bypass_management_auth(self): + source = (ROOT / "src/helpers/ESP32Board.cpp").read_text() + elegant = source.split("#elif defined(ADMIN_PASSWORD) && !defined(DISABLE_WIFI_OTA)", 1)[1] + handlers = [] + for path in ("/", "/log"): + marker = 'async_ota_host->on("' + path + '", HTTP_GET, [](AsyncWebServerRequest *request)' + body = extract_braced(elegant, marker) + body = body[body.index("{"):] + handlers.append("void handle" + str(len(handlers)) + "(AsyncWebServerRequest* request) " + body) + fixture = r''' +#include +struct AsyncWebServerRequest { + int replies = 0; + template void send(Args...) { ++replies; } +}; +struct Auth { + bool permitted = false; + int checks = 0; + bool authenticateRequest(AsyncWebServerRequest*) { ++checks; return permitted; } +} AsyncElegantOTA; +static const char* home_buf = "fixture"; +int SPIFFS = 0; +@HANDLERS@ +int main() { + for (auto handler : {handle0, handle1}) { + AsyncWebServerRequest request; + AsyncElegantOTA.permitted = false; handler(&request); assert(request.replies == 0); + AsyncElegantOTA.permitted = true; handler(&request); assert(request.replies == 1); + } + assert(AsyncElegantOTA.checks == 4); +} +''' + fixture = '#include \n' + fixture.replace("@HANDLERS@", "\n".join(handlers)) + self.compile_and_run(fixture) + old = fixture.replace(" if (!AsyncElegantOTA.authenticateRequest(request)) return;", "") + self.assertNotEqual(old, fixture) + with self.assertRaises(AssertionError): + self.compile_and_run(old) + + def test_join_password_describes_live_ap_during_rekey_grace(self): + fixture = self.ap_fixture().split("static unsigned server_starts", 1)[0] + r''' +int main() { + using namespace mesh::esp32::managementPassword; + char password[65] = "old-value"; + assert(!mesh::wifi::accessPointJoinPassword("setup", password, sizeof(password)) && !password[0]); + assert(publish("password")); + assert(mesh::wifi::startManagementAccessPoint("setup", false)); + assert(mesh::wifi::accessPointJoinPassword("setup", password, sizeof(password))); + assert(!strcmp(password, "password")); + assert(publish("different")); + assert(mesh::wifi::accessPointJoinPassword("setup", password, sizeof(password))); + assert(!strcmp(password, "password")); // Registry leads actual AP during reply grace. + assert(!mesh::wifi::accessPointJoinPassword("other", password, sizeof(password)) && !password[0]); + assert(!mesh::wifi::accessPointJoinPassword("setup", password, 4) && !password[0]); + assert(mesh::wifi::startManagementAccessPoint("setup", false)); + assert(mesh::wifi::accessPointJoinPassword("setup", password, sizeof(password))); + assert(!strcmp(password, "different")); + WiFi.live_config.ap.authmode = 99; + assert(!mesh::wifi::accessPointJoinPassword("setup", password, sizeof(password)) && !password[0]); + WiFi.live_config.ap.authmode = WIFI_AUTH_WPA2_PSK; + memset(WiFi.live_config.ap.password, 'x', sizeof(WiFi.live_config.ap.password)); + assert(!mesh::wifi::accessPointJoinPassword("setup", password, sizeof(password)) && !password[0]); + WiFi.live_config.ap.authmode = WIFI_AUTH_OPEN; + assert(mesh::wifi::accessPointJoinPassword("setup", password, sizeof(password)) && !password[0]); + WiFi.fault = Fault::ConfigRead; + assert(!mesh::wifi::accessPointJoinPassword("setup", password, sizeof(password)) && !password[0]); +} +''' + for major in (2, 3): + self.compile_and_run(fixture, f"-DESP_ARDUINO_VERSION_MAJOR={major}") + def test_minimal_ota_never_reports_a_stale_sdk_hotspot_as_started(self): implementation = (ROOT / "src/helpers/ESP32Board.cpp").read_text().split( "#elif defined(ADMIN_PASSWORD) && !defined(DISABLE_WIFI_OTA)", 1)[0] @@ -194,6 +331,8 @@ int main() { start = cli.index(' } else if (memcmp(command, "start ota", 9)') end = cli.index(' } else if (memcmp(command, "clock", 5)', start) fixture = r''' +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST 1 +#include #include #include #include @@ -237,6 +376,8 @@ int main() { start = cli.index(' } else if (memcmp(command, "start ota", 9)') end = cli.index(' } else if (memcmp(command, "clock", 5)', start) fixture = r''' +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST 1 +#include #include #include #include @@ -276,6 +417,7 @@ struct Board { } board; struct Prefs { const char* node_name = "test"; + const char* password = "password"; bool bridge_enabled = false, espnow_bridge_enabled = false; } prefs; struct CLI { @@ -344,6 +486,7 @@ int main() { methods = "\n".join(extract_braced(source, signature) for signature in ( "void WebConfigServer::requestStop(", "bool WebConfigServer::stopForOTA(", "void WebConfigServer::finalizeTeardown(", + "void WebConfigServer::clearSessionLocked(", "bool WebConfigServer::isNetworkForegroundActive(", "void WebConfigServer::refreshNetworkPowerHold(")) fixture = (ROOT / "test/fixtures/webconfig_ota_handoff.cpp").read_text() @@ -354,6 +497,8 @@ int main() { start = cli.index(' } else if (memcmp(command, "start ota", 9)') end = cli.index(' } else if (memcmp(command, "clock", 5)', start) fixture = r''' +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST 1 +#include #include #include #include @@ -396,6 +541,7 @@ struct Board { } board; struct Prefs { const char* node_name = "test"; + const char* password = "password"; bool bridge_enabled = true, espnow_bridge_enabled = true; } prefs; struct CLI { @@ -476,6 +622,8 @@ int main() { def test_background_bridge_retry_waits_until_ota_stops(self): fixture = r''' +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST 1 +#include #include #include uint32_t now = 0; @@ -541,6 +689,8 @@ int main() { source = (ROOT / "examples/companion_radio/MyMesh.cpp").read_text() command = extract_braced(source, 'if (strcmp(command, "start ota") == 0') fixture = r''' +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST 1 +#include #include #include #include @@ -596,6 +746,8 @@ int main() { implementation = source[source.index("class LightweightOTAServer {"):] method = extract_braced(implementation, "bool end()") fixture = r''' +#define MESH_MANAGEMENT_PASSWORD_HOST_TEST 1 +#include #include #include static unsigned delays = 0; diff --git a/test/test_wifi_setup_auth.py b/test/test_wifi_setup_auth.py new file mode 100644 index 000000000..9b0072c22 --- /dev/null +++ b/test/test_wifi_setup_auth.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 +"""Execute the legacy setup portal's production HTTP gate with fake clients.""" +from pathlib import Path +import os +import subprocess +import tempfile +import unittest + +from test_replay_reset_integration import extract_braced + +ROOT = Path(__file__).resolve().parents[1] + + +class WiFiSetupAuthTest(unittest.TestCase): + def test_setup_http_uses_current_admin_before_reading_or_saving_form(self): + production = (ROOT / "src/helpers/WiFiSetupPortal.cpp").read_text() + methods = "\n".join(extract_braced(production, signature) for signature in ( + "static bool readLine(", "static void sendResponse(", "static void handleClient(")) + source = r''' +#include +#include +#include +#include +#include +#include +#include +#include +uint32_t now = 100; +uint32_t millis() { return now; } +void delay(unsigned value) { now += value; } +struct WiFiClient { + std::string input, output; + size_t position = 0, bodies = 0; + explicit WiFiClient(std::string text) : input(text) {} + bool connected() { return true; } + bool available() { return position < input.size(); } + int read() { return available() ? static_cast(input[position++]) : -1; } + size_t readBytes(char* out, size_t count) { + ++bodies; size_t size = std::min(count, input.size() - position); + memcpy(out, input.data() + position, size); position += size; return size; + } + void printf(const char* format, ...) { + char buffer[2048]; va_list args; va_start(args, format); + int size = vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); + assert(size >= 0 && size < int(sizeof(buffer))); output.append(buffer, size); + } + void write(const uint8_t* bytes, size_t count) { output.append(reinterpret_cast(bytes), count); } +}; +static const uint8_t MESH_HTML_WIFI_SETUP[] = {1, 2, 3}; +static const size_t MESH_HTML_WIFI_SETUP_LEN = sizeof(MESH_HTML_WIFI_SETUP); +struct PortalImpl {}; +int saves = 0; +void handleSave(PortalImpl*, WiFiClient&, const char* body) { + assert(!strcmp(body, "ssid=test")); ++saves; + // Association/persistence cannot overlap a password rotation or upload. + using namespace mesh::esp32::managementPassword; + Snapshot current; assert(snapshot(current)); + assert(!publish("unconfirmed")); + UploadGuard upload(current.generation); assert(!upload.acquired()); +} +@METHODS@ +WiFiClient request(const std::string& text, int status) { + WiFiClient client(text); PortalImpl portal; + handleClient(&portal, client); + assert(client.output.find("HTTP/1.1 " + std::to_string(status) + " ") == 0); + assert(client.output.find("Cache-Control: no-store") != std::string::npos); + return client; +} +std::string get(const std::string& auth) { return "GET / HTTP/1.1\r\n" + auth + "\r\n"; } +std::string post(const std::string& auth, const std::string& body = "ssid=test") { + return "POST /save HTTP/1.1\r\nContent-Length: 9\r\n" + auth + "\r\n" + body; +} +int main() { + using namespace mesh::esp32::managementPassword; + const std::string old = "Authorization: Basic YWRtaW46cGFzc3dvcmQ=\r\n"; + const std::string next = "Authorization: Basic YWRtaW46bmV3LXBhc3N3b3Jk\r\n"; + request(get(old), 503); assert(publish("password")); + auto prompt = request(get(""), 401); + assert(prompt.output.find("WWW-Authenticate: Basic realm=\"MeshCore\"") != std::string::npos); + assert(request(post(""), 401).bodies == 0 && saves == 0); + assert(request(post("Authorization: Basic wrong\r\n"), 401).bodies == 0 && saves == 0); + request(get(old), 200); request(post(old), 200); assert(saves == 1); + assert(publish("new-password")); + assert(request(post(old), 401).bodies == 0 && saves == 1); + request(get(next), 200); request(post(next), 200); assert(saves == 2); + assert(request(post(next + next), 401).bodies == 0 && saves == 2); + request(get("Authorization: Basic " + std::string(100, 'A') + "\r\n"), 401); + request(post(next, "short"), 408); + { + ChangeGuard change; assert(change.acquired()); + assert(request(post(next), 409).bodies == 0 && saves == 2); + } + request("POST /save HTTP/1.1\r\nContent-Length: 256\r\n" + next + "\r\n", 400); + now += 30000; + for (unsigned i = 0; i < 5; ++i) request(get("Authorization: Basic wrong\r\n"), 401); + request(get(next), 429); now += 30000; request(get(next), 200); +} +'''.replace("@METHODS@", methods) + # The production save helper writes its own success response. + source = source.replace('assert(!strcmp(body, "ssid=test")); ++saves;', + 'assert(!strcmp(body, "ssid=test")); ++saves; client.printf("HTTP/1.1 200 OK\\r\\nCache-Control: no-store\\r\\n\\r\\n");') + source = source.replace('void handleSave(PortalImpl*, WiFiClient&,', 'void handleSave(PortalImpl*, WiFiClient& client,') + with tempfile.TemporaryDirectory(prefix="wifi-setup-auth-") as temporary: + work = Path(temporary) + (work / "test.cpp").write_text(source) + result = subprocess.run([os.environ.get("CXX", "g++"), "-std=c++11", "-Wall", "-Wextra", "-Werror", + "-fsanitize=address,undefined", "-fno-sanitize-recover=all", "-fno-pie", "-no-pie", + "-DMESH_MANAGEMENT_PASSWORD_HOST_TEST=1", "-I", str(ROOT / "src"), + str(work / "test.cpp"), "-o", str(work / "test")], capture_output=True, text=True, timeout=60) + self.assertEqual(result.returncode, 0, result.stderr) + result = subprocess.run([str(work / "test")], capture_output=True, text=True, timeout=15) + self.assertEqual(result.returncode, 0, result.stdout + result.stderr) + + +if __name__ == "__main__": + unittest.main() diff --git a/webui/index.html b/webui/index.html index 475245561..ff62c052f 100644 --- a/webui/index.html +++ b/webui/index.html @@ -226,12 +226,13 @@ body.tab-cli{padding-bottom:0} aria-label="Open console">>_
+

Admin login

-

Enter this node's admin password (the same one used for remote CLI admin).

+

Enter this node's admin password.

@@ -287,10 +288,10 @@ body.tab-cli{padding-bottom:0}

Admin password

-

Replaces the factory password. It is used to sign in here later and to administer the node remotely over the mesh.

+

One admin password for this node's configuration page, firmware uploads, and protected setup WiFi.

-
Maximum 15 characters.
+
Maximum 15 UTF-8 bytes. Use 8-15 printable ASCII characters to also protect the setup WiFi.
@@ -375,7 +376,7 @@ body.tab-cli{padding-bottom:0}

Admin password

-
Signs in here and authenticates remote admin commands over the mesh. Leave blank to keep the current password. Maximum 15 characters.
+
Used for this node's configuration page and firmware uploads. Leave blank to keep the current password. Maximum 15 UTF-8 bytes. Use 8-15 printable ASCII characters to also protect the setup WiFi with this password.
@@ -678,6 +679,7 @@ function shortVer(){ function api(path,opts){ opts=opts||{}; + var authEpoch=loginEpoch; if(!opts.cache)opts.cache="no-store"; // iOS caches plain-HTTP API GETs across sessions if(opts.timeout&&window.AbortController){ // The CNA sheet can leave a fetch hanging forever on a dead connection; @@ -686,7 +688,7 @@ function api(path,opts){ setTimeout(function(){ctl.abort()},opts.timeout); } return fetch(path,opts).then(function(r){ - if(r.status===401){showLogin();throw new Error("auth")} + if(r.status===401){if(authEpoch===loginEpoch)showLogin();var authError=new Error("auth");authError.status=401;authError.staleAuth=authEpoch!==loginEpoch;throw authError} // An error response need not carry JSON -- a bare 404 from handleNotFound // has an empty body. Letting the parse failure escape would strip the HTTP // status off the error and leave callers unable to tell "no such endpoint" @@ -790,22 +792,69 @@ function boot(){ function show(v){["#v-login","#v-wizard","#v-app"].forEach(function(id){$(id).classList.add("hide")});$(v).classList.remove("hide"); document.body.classList.remove("tab-cli"); // re-armed by the tab click when the CLI is the one shown updateSaveBar()} -function showLogin(){show("#v-login")} +function showLogin(note){ + st.authed=false; + if(note!==undefined){$("#login-note").textContent=note;$("#login-note").classList.toggle("hide",!note)} + show("#v-login"); +} /* ---------- login ---------- */ +var loginEpoch=0,loginResume=null; +function loginRequest(password){ + return fetch("/api/login",{method:"POST",headers:{"Content-Type":"application/json"}, + body:JSON.stringify({password:password})}) + .then(function(r){return r.json().then(function(j){return{s:r.status,j:j}})}); +} $("#login-form").addEventListener("submit",function(ev){ ev.preventDefault(); - var btn=$("#login-btn");btn.disabled=true;$("#login-err").textContent=""; - fetch("/api/login",{method:"POST",headers:{"Content-Type":"application/json"}, - body:JSON.stringify({password:$("#login-pwd").value})}) - .then(function(r){return r.json().then(function(j){return{s:r.status,j:j}})}) + var btn=$("#login-btn");if(btn.disabled)return; + var epoch=++loginEpoch,password=$("#login-pwd").value; + $("#login-pwd").value="";btn.disabled=true;$("#login-err").textContent=""; + loginRequest(password) .then(function(x){ + if(epoch!==loginEpoch)return; btn.disabled=false; - if(x.s===200){st.authed=true;$("#login-pwd").value="";if(st.mode==="setup"){showWizard()}else{enterApp()}} + if(x.s===200){ + st.authed=true; + var resume=loginResume;loginResume=null; + if(resume)resume();else if(st.mode==="setup"){showWizard()}else{enterApp()} + } else $("#login-err").textContent=x.j.error||"login failed"; - }).catch(function(){btn.disabled=false;$("#login-err").textContent="connection error"}); + }).catch(function(){if(epoch===loginEpoch){btn.disabled=false;$("#login-err").textContent="connection error"}}); + password=""; }); -function doLogout(){post("/api/logout",{}).then(function(){st.authed=false;showLogin()}).catch(function(){})} +function doLogout(){post("/api/logout",{}).then(function(){++loginEpoch;loginResume=null;showLogin("")}).catch(function(){})} + +// A password save revokes the old session. Keep only a single in-memory login +// attempt, then let the ordinary form resume the same result read if needed. +// Never retry a settings/terminal POST: it may already have executed. +function reauthenticateOnce(auth,note,resume,keepView){ + var view=auth&&auth.view||($("#v-wizard").classList.contains("hide")?"#v-app":"#v-wizard"); + var epoch=++loginEpoch,password=auth&&!auth.attempted?auth.password:""; + if(auth){auth.attempted=true;auth.password="";auth.view=view;auth.restored=false} + st.authed=false;clearInterval(st.statsTimer);st.statsTimer=0; + $("#login-note").textContent=note;$("#login-note").classList.remove("hide"); + $("#login-pwd").value="";$("#login-err").textContent=""; + function restored(){if(auth)auth.restored=true;if(!keepView)show(view);if(resume)resume()} + loginResume=restored; + if(!keepView)showLogin(note); + var btn=$("#login-btn");btn.disabled=!!password; + if(!password)return; + loginRequest(password).then(function(x){ + if(epoch!==loginEpoch)return; + btn.disabled=false; + if(x.s===200){st.authed=true;loginResume=null;restored()} + else $("#login-err").textContent=x.j.error||"Sign in with the current admin password"; + }).catch(function(){if(epoch===loginEpoch){btn.disabled=false;$("#login-err").textContent="Couldn't sign in automatically. Enter the current admin password."}}); + password=""; +} +function forgetSubmittedPassword(submitted){ + var password=submitted&&submitted.password; + if(!password)return; + if(st.dirty.password===password)delete st.dirty.password; + $$('[data-k="password"],[data-cfm="password"]').forEach(function(el){if(el.value===password)el.value=""}); + delete submitted.password; +} /* ---------- config load / bind ---------- */ function cfgVal(k){ // map a `set` key to its current value string, from st.cfg @@ -1221,6 +1270,7 @@ function chipFor(el,ok,msg){ lab.querySelector("label").appendChild(c); } function saveChanges(extra,cb){ + $("#login-note").textContent="";$("#login-note").classList.add("hide"); var setmap={}; // Clear old presets first, then assign new presets, then apply their fields. // This lets an operator move a unique preset to an empty slot in one save. @@ -1236,8 +1286,9 @@ function saveChanges(extra,cb){ if((extra&&extra.reboot)||("wifi.ssid" in setmap)||("wifi.pwd" in setmap)||("espnow.channel" in setmap)||("bluetooth.mac" in setmap)||("bluetooth.stealth" in setmap))body.reboot=true; if(Object.keys(setmap).length===0&&!body.reboot){toast("Nothing to save");return} var reqid=mkReqId();body.reqid=reqid; + var auth={password:setmap.password||"",attempted:false,view:$("#v-wizard").classList.contains("hide")?"#v-app":"#v-wizard"}; $("#save-btn").disabled=true; - post("/api/config",body).then(function(){pollResult(cb,0,0,true,reqid,setmap)}) + post("/api/config",body).then(function(){pollResult(cb,0,0,true,reqid,setmap,auth)}) .catch(function(e){ if(e.message==="auth"){$("#save-btn").disabled=false;if(cb)cb(null,false);return} if(e.status===400||e.status===413){ @@ -1258,14 +1309,14 @@ function saveChanges(extra,cb){ return; } if(e.status===409){ - if(e.reqid===reqid){pollResult(cb,0,0,true,reqid,setmap);return} + if(e.reqid===reqid){pollResult(cb,0,0,true,reqid,setmap,auth);return} $("#save-btn").disabled=false; if(cb)cb(null,false);else toast("Another change is being applied - retry shortly"); return; } // A network failure can lose the response after the POST landed. Poll the // result by request ID so another or stale save cannot be mistaken for it. - pollResult(cb,0,0,false,reqid,setmap); + pollResult(cb,0,0,false,reqid,setmap,auth); }); } function appSave(){ @@ -1281,17 +1332,20 @@ function appSave(){ // acked: the node returned 202 for the POST, so the batch will be processed. // A requested reboot happens only if every command succeeds. This still lets // callers distinguish "confirmation lost" from "save never sent". -function pollResult(cb,errs,idles,acked,reqid,submitted){ +function pollResult(cb,errs,idles,acked,reqid,submitted,auth){ errs=errs||0;idles=idles||0; + auth=auth||{password:submitted&&submitted.password||"",attempted:false}; function fail(){$("#save-btn").disabled=false; - if(cb)cb(null,acked);else toast(acked?"Saved, but confirmation was lost - reload to verify":"Save failed - check connection and retry")} + auth.password=""; + if(auth.receiptSeen){toast("The save result was received. Sign in or reconnect to read the detailed replies.");return} + if(cb)cb(null,acked);else toast(acked?"Settings sent, but confirmation was lost - reload to verify":"Save failed - check connection and retry")} api("/api/config/result?reqid="+encodeURIComponent(reqid),{timeout:4000}).then(function(r){ if(r.reqid!==reqid){fail();return} - if(r.state==="pending"){setTimeout(function(){pollResult(cb,0,idles,true,reqid,submitted)},400);return} + if(r.state==="pending"){setTimeout(function(){pollResult(cb,0,idles,true,reqid,submitted,auth)},400);return} if(r.state!=="done"){ // idle: the POST likely never arrived - but give it a moment in case // it's still in flight after a connection blip - if(idles<4){setTimeout(function(){pollResult(cb,errs,idles+1,acked,reqid,submitted)},700);return} + if(idles<4){setTimeout(function(){pollResult(cb,errs,idles+1,acked,reqid,submitted,auth)},700);return} fail();return; } $("#save-btn").disabled=false; @@ -1307,8 +1361,20 @@ function pollResult(cb,errs,idles,acked,reqid,submitted){ if(el)chipFor(el,ok,ok?"OK":it.reply.replace(/^Err(or)?[:,]?\s*/i,"")); }); $("#radio-warn").classList.toggle("hide",!radioReboot); - if(cb){cb(r);return} - if(fails)toast(fails+" setting(s) rejected - see fields"); + var failed=fails>0||r.all_ok===false; + function reauthAfterReceipt(){ + if(!r.reauth_required){auth.password="";return false} + auth.receiptSeen=true; + forgetSubmittedPassword(submitted); + if(auth.restored){if(!r.reboot||failed)loadConfigSoft();return true} + var note=failed?"The admin password changed, but some settings were rejected. The node will not reboot." + :r.reboot?"Settings saved. The node is rebooting.":"Settings saved. The admin password changed."; + if(st.mode==="setup"&&!r.reboot)note+=" The setup WiFi may restart. Rejoin it with the new admin password if prompted."; + reauthenticateOnce(auth,note,function(){pollResult(cb,0,0,true,reqid,submitted,auth)},!!r.reboot&&!failed); + return true; + } + if(cb){cb(r);reauthAfterReceipt();return} + if(failed)toast(fails?fails+" setting(s) rejected - see fields":"Some settings were rejected - see fields"); else if(r.reboot){ st.dirty={}; var bluetoothAddressChanged=submitted&&("bluetooth.mac" in submitted); @@ -1321,16 +1387,20 @@ function pollResult(cb,errs,idles,acked,reqid,submitted){ ? "The node is restarting with the saved stealth flag. Its address policy is unchanged. When enabling stealth, pair once; afterward reconnect using the saved device." : "The node is restarting with the saved WiFi settings. Reconnect to that network and open the node at its router-assigned address.", false,bluetoothAddressChanged?"Bluetooth address saved [OK] - rebooting":bluetoothStealthChanged?"Bluetooth stealth saved [OK] - rebooting":"Settings saved [OK] - rebooting",r.wifi_ip,rebootSeconds(r)); + reauthAfterReceipt(); return; }else toast("Saved [OK]"); - loadConfigSoft(); + if(!reauthAfterReceipt())loadConfigSoft(); }).catch(function(e){ - if(e.message==="auth"){fail();return} + if(e.message==="auth"){ + reauthenticateOnce(auth,auth.receiptSeen?"The save result was received. Sign in to read its details.":"Settings were sent. Sign in to read the saved result.",function(){pollResult(cb,errs,idles,acked,reqid,submitted,auth)},false); + return; + } if(e.status===400||e.status===404){fail();return} // Transient network error: the save itself can knock the phone off the // AP for a moment (flash writes stall WiFi). Keep polling - the device // holds the result until we manage to read it. - if(errs<20){setTimeout(function(){pollResult(cb,errs+1,idles,acked,reqid,submitted)},700);return} + if(errs<20){setTimeout(function(){pollResult(cb,errs+1,idles,acked,reqid,submitted,auth)},700);return} fail(); }); } @@ -1373,10 +1443,8 @@ function enterApp(){ }); } // Setup-mode shortcut: straight past the guided steps into the terminal, for -// operators who already have a config to paste. Setup mode authenticates by -// proximity to the AP, so this hands the whole command surface to anyone in -// range -- the same trust the wizard already extends, since it can set the admin -// password and reflash the node's identity too. +// operators who already have a config to paste. The server's setup WiFi and +// admin-login policy also applies here; showing a tab grants no extra access. function enterConsole(){ enterApp(); $('#tabs button[data-t="cli"]').click(); @@ -1720,6 +1788,11 @@ function adminPwdError(finishing){ var p=eff("password"),c=$('[data-cfm="password"]').value; if(finishing&&st.needsPassword&&!p)return"Set an admin password"; if((p||c)&&p!==c)return"Admin passwords do not match"; + if(p){ + var bytes=0; + try{bytes=encodeURIComponent(p).replace(/%[0-9A-F]{2}/g,"x").length}catch(e){return"Admin password must be valid UTF-8"} + if(bytes>15||/[\r\n]/.test(p))return"Admin password must be 1-15 UTF-8 bytes with no line breaks"; + } return""; } function buildReview(){ @@ -1778,8 +1851,8 @@ function wizardSave(){ return; } var fails=(r.results||[]).filter(function(x){return!/^OK/i.test(x.reply)}); - if(fails.length){ - $("#wz-err").textContent=fails.map(function(x){return x.key+": "+x.reply}).join(" * "); + if(fails.length||r.all_ok===false){ + $("#wz-err").textContent=fails.length?fails.map(function(x){return x.key+": "+x.reply}).join(" * "):"Some settings were rejected. Review the fields before trying again."; return; } if(r.wifi_ip){ @@ -2529,9 +2602,10 @@ function cliRun(cmds){ cliBusy(true); cliGap(); var reqid=mkReqId(); + var auth=cliPasswordContext(cmds); var status=cliEcho("sys",cmds.length>1?"running 0/"+cmds.length+"...":"..."); post("/api/cli",{reqid:reqid,cmds:cmds}).then(function(){ - cliPoll(reqid,cmds,0,status,0,0); + cliPoll(reqid,cmds,0,status,0,0,auth); }).catch(function(e){ if(e.message==="auth"){cliBusy(false);status.remove();return} // No such endpoint: this firmware predates the console (or was built @@ -2541,9 +2615,14 @@ function cliRun(cmds){ if(e.status===400||e.status===413){cliEnd(status,e.message||"Rejected by the node.");return} // Ambiguous: the request may have landed even though the reply was lost. // Poll for it rather than reporting a failure that did not happen. - cliPoll(reqid,cmds,0,status,0,0); + cliPoll(reqid,cmds,0,status,0,0,auth); }); } +function cliPasswordContext(cmds){ + var password=""; + cmds.forEach(function(c){if(/^password /i.test(c))password=c.slice(9)}); + return{password:password,attempted:false,required:false,view:"#v-app",output:[]}; +} // Stream replies for every role. Companion sessions also own recipient/login // state and keep reading after completion to show ACKs and RF replies. @@ -2585,6 +2664,7 @@ function cliStreamSend(){ if(cliStream.session===session)cliStreamPoll(); }).catch(function(e){ if(cliStream.session!==session)return; + if(e.status===401){cliStreamAuthorizationLost(false);return} if(e.status>=400&&e.status<500||e.status===503){ cliEcho("err",e.message||"Command rejected."); if(e.status===400){cliStream.seq--;cliStream.job=null;cliBusy(false)} @@ -2595,6 +2675,13 @@ function cliStreamSend(){ cliStreamPoll(); }); } +function cliStreamAuthorizationLost(mayHaveRun){ + var job=cliStream.job; + var auth=cliPasswordContext(mayHaveRun&&job?[job.cmds[job.index]]:[]); + var note="Terminal authorization changed. Sign in to continue; the command will not be resent."; + cliEcho("err",note);cliStreamReset(); + reauthenticateOnce(auth,note,loadConfigSoft,false); +} function cliStreamPoll(){ clearTimeout(cliStream.timer); if(!cliStream.session||cliStream.polling)return; @@ -2610,7 +2697,11 @@ function cliStreamPoll(){ if(r.output&&cliStream.job)cliStream.job.started=Date.now(); if(r.more){cliStream.timer=setTimeout(cliStreamPoll,0);return} var job=cliStream.job; - if(r.closed){cliStreamReset();return} + if(r.closed){ + if(job&&/^password /i.test(job.cmds[job.index]))cliStreamAuthorizationLost(true); + else cliStreamReset(); + return; + } if(job&&r.seq===job.seq&&r.done){ cliAfter([job.cmds[job.index]],{}); cliStream.out=null; @@ -2624,6 +2715,7 @@ function cliStreamPoll(){ }).catch(function(e){ cliStream.polling=false; if(cliStream.session!==session){cliStreamPoll();return} + if(e.status===401){if(e.staleAuth)cliStreamReset();else cliStreamAuthorizationLost(true);return} if(e.status===401||e.status===403||e.status===404||++cliStream.errors>20){ cliEcho("err",e.message||"Terminal disconnected.");cliStreamReset();return; } @@ -2640,66 +2732,91 @@ function cliEnd(status,msg){ status.className="err";status.textContent=msg; $("#term-out").scrollTop=$("#term-out").scrollHeight; } -function cliPoll(reqid,cmds,from,status,errs,idles){ +function cliPoll(reqid,cmds,from,status,errs,idles,auth){ + auth=auth||cliPasswordContext(cmds); api("/api/cli/result?reqid="+encodeURIComponent(reqid)+"&from="+from,{timeout:5000}) .then(function(r){ if(r.state!=="idle"&&r.reqid!==reqid){cliEnd(status,"Lost track of this sequence -- reload to check the node's state.");return} if(r.state==="idle"){ // the POST may still be in flight after a connection blip - if(idles<5){setTimeout(function(){cliPoll(reqid,cmds,from,status,errs,idles+1)},400);return} + if(idles<5){setTimeout(function(){cliPoll(reqid,cmds,from,status,errs,idles+1,auth)},400);return} cliEnd(status,"The node never received the command.");return; } + auth.required=auth.required||!!r.reauth_required; + if(r.reauth_required)auth.receiptSeen=true; + if(auth.replaceReceipt&&!r.reauth_required){ + auth.output.forEach(function(el){el.remove()});auth.output=[];auth.replaceReceipt=false; + } (r.results||[]).forEach(function(x,i){ // The node never echoes the command back -- it may hold a password or a // token, and we already have the sequence we sent. Match by index. - cliEcho("cmd",cmds[from+i]||""); + auth.output.push(cliEcho("cmd",cmds[from+i]||"")); // `ok` is advisory; the node's own convention is authoritative, and only // failure has a fixed shape there ("Err"/"ERR:"/"Error:"). var ok=(x.ok!=null)?x.ok:!/^\s*err/i.test(x.reply||""); + if(!auth.attempted&&ok&&/^password /i.test(cmds[from+i]||""))auth.password=cmds[from+i].slice(9); // Getters answer "> value" -- that leading marker is the serial console's // way of setting a value apart, and here it collides with the prompt glyph // that means "you typed this". Drop it; the colour already says "reply". var reply=(x.reply||"").replace(/^>\s?/,""); - if(reply)cliEcho(ok?"rep":"err",reply); + if(reply)auth.output.push(cliEcho(ok?"rep":"err",reply)); }); from+=(r.results||[]).length; // "running" also covers "finished, but more results are still to be paged // over", so keep polling until the node says done. if(r.state!=="done"){ if(cmds.length>1)status.textContent="running "+from+"/"+cmds.length+"..."; - setTimeout(function(){cliPoll(reqid,cmds,from,status,0,0)},250); + setTimeout(function(){cliPoll(reqid,cmds,from,status,0,0,auth)},250); return; } status.remove(); cliBusy(false); - cliAfter(cmds,r); + if(auth.required)r.reauth_required=true; + cliAfter(cmds,r,auth); }).catch(function(e){ - if(e.message==="auth"){cliBusy(false);status.remove();return} - if(e.status===400||e.status===404){cliEnd(status,"The node no longer has a result for this sequence.");return} - if(errs<20){setTimeout(function(){cliPoll(reqid,cmds,from,status,errs+1,idles)},700);return} - cliEnd(status,"Lost the connection while the sequence was running -- reload to check the node's state."); + if(e.message==="auth"){ + reauthenticateOnce(auth,"Commands were sent. Sign in to read their results; they will not be resent.",function(){cliPoll(reqid,cmds,from,status,errs,idles,auth)},false); + return; + } + if(e.status===400||e.status===404){cliEnd(status,auth.receiptSeen?"The command result was received, but its detailed replies are no longer available.":"The node no longer has a result for this sequence.");return} + if(errs<20){setTimeout(function(){cliPoll(reqid,cmds,from,status,errs+1,idles,auth)},700);return} + cliEnd(status,auth.receiptSeen?"The command result was received. Reconnect to read its detailed replies.":"Lost the connection while the sequence was running -- reload to check the node's state."); }); } // A CLI `set` writes the same prefs the forms edit, so re-read them or the // other tabs keep showing stale values. -function cliAfter(cmds,r){ +function cliAfter(cmds,r,auth){ + auth=auth||cliPasswordContext(cmds); var touched=false; cmds.forEach(function(c){ if(/^password\s/.test(c))cli.pwd=true; if(/^(set|password)\s/.test(c))touched=true; }); // Same prefix dispatch as the risk list: `poweroff now` powers off too. - if(touched)loadConfigSoft(); + var reauth=r&&r.reauth_required&&!(auth&&auth.restored); + var failed=r&&(r.reboot_withheld||r.all_ok===false); + function finishAuth(){ + if(!reauth){if(auth)auth.password="";return} + reauthenticateOnce(auth||cliPasswordContext(cmds),failed?"The admin password changed, but a command was rejected. The node will not reboot.":"The command results are complete. Sign in with the new admin password.", + function(){ + auth.required=false;auth.replaceReceipt=true;cliBusy(true); + var status=cliEcho("sys","Reading authenticated command results..."); + cliPoll(r.reqid,cmds,0,status,0,0,auth); + },!!r.reboot&&!failed); + } + if(touched&&!reauth)loadConfigSoft(); // A `reboot` in the sequence is not run by the CLI -- Board::reboot() never // returns, so the node answers it and schedules the restart for after this // read. It withholds it when any command failed, exactly as a config save // does; say which happened rather than leaving the operator to guess. - if(r&&r.reboot_withheld){ + if(failed){ cliEcho("err","Not rebooting -- a setting was rejected. Fix it and run \"reboot\" again."); + finishAuth(); return; } if(r&&r.reboot){ showReboot("The node is restarting. This page will try to reconnect automatically.",true); + finishAuth(); return; } // clkreboot / poweroff / erase-and-flash take the node down themselves, so @@ -2708,6 +2825,7 @@ function cliAfter(cmds,r){ if(/^(poweroff|shutdown)/.test(c))showReboot("The node is powering off. Reconnect power to bring it back.",false,"Powering off..."); else if(/^clkreboot/.test(c))showReboot("The node is restarting. This page will try to reconnect automatically.",true); }); + finishAuth(); } /* ---------- CLI: fit ----------